package rpc import ( "fmt" "net/http" "time" "forge.cadoles.com/Pyxis/orion/openwrt" "github.com/gorilla/rpc" "github.com/gorilla/rpc/json" ) // OrionService is the JSON-RPC API type OrionService struct { UCI *openwrt.UCI } // NewOrionService create a new OrionService ! func NewOrionService() *OrionService { uci := openwrt.NewUCI() return &OrionService{ UCI: uci, } } // UCIArgs argument structure for exported method OwrtListWifiDevices type UCIArgs struct{} // UCIResponse is the response structure for exposed method OwrtListWifiDevices type UCIResponse struct { Devices []map[string]string } // OwrtListWifiDevices offers an RPC Method to list Wifi nics in a OpenWRT device. func (o *OrionService) OwrtListWifiDevices(r *http.Request, args *UCIArgs, reply *UCIResponse) error { o.UCI.LoadWirelessConf() devs := o.UCI.GetWifiDevices() reply.Devices = devs return nil } // ListIfaceArgs argument structure for exported method OwrtListWifiDevices type ListIfaceArgs struct{} // ListIfaceResponse is the response structure for exposed method OwrtListWifiDevices type ListIfaceResponse struct { Interfaces []*openwrt.UCIWirelessInterface } // OwrtListWifiInterfaces offers an RPC Method to list wifi interfaces in a OpenWRT device. func (o *OrionService) OwrtListWifiInterfaces(r *http.Request, args *ListIfaceArgs, reply *ListIfaceResponse) error { o.UCI.LoadWirelessConf() reply.Interfaces = o.UCI.GetWifiIfaces() return nil } // CreateIfaceArgs argument structure for exported method OwrtCreateWifiInterface type CreateIfaceArgs struct { Iface *openwrt.UCIWirelessInterface Cleanup bool } // CreateIfaceResponse argument structure for exported method OwrtCreateWifiInterface type CreateIfaceResponse struct { Iface *openwrt.UCIWirelessInterface Errors []*openwrt.Action } // OwrtCreateWifiInterface Create a WifiInterface in openwrt func (o *OrionService) OwrtCreateWifiInterface(r *http.Request, args *CreateIfaceArgs, reply *CreateIfaceResponse) error { reply.Iface = nil if args.Cleanup == true { o.UCI.LoadWirelessConf() w := o.UCI.GetWifiIfaces() for _, iface := range w { iface.Delete(o.UCI) } o.UCI.Commit() o.UCI.Reload() time.Sleep(3 * time.Second) } o.UCI.LoadWirelessConf() create := args.Iface.Create(o.UCI) if create.ReturnCode != 0 { reply.Errors = append(reply.Errors, create) return nil } create = args.Iface.SysAdd(o.UCI) if create.ReturnCode == 233 { delete := args.Iface.SysDel(o.UCI) if delete.ReturnCode != 0 { reply.Errors = append(reply.Errors, delete) return nil } create = args.Iface.SysAdd(o.UCI) if create.ReturnCode != 0 { reply.Errors = append(reply.Errors, create) return nil } } create = args.Iface.Up(o.UCI) if create.ReturnCode != 0 { reply.Errors = append(reply.Errors, create) return nil } create = args.Iface.Save(o.UCI) if create.ReturnCode != 0 { reply.Errors = append(reply.Errors, create) return nil } reply.Iface = args.Iface return nil } // ConnectIfaceArgs argument structure for exported method OwrtCreateWifiInterface type ConnectIfaceArgs struct { Iface *openwrt.UCIWirelessInterface SSID string Key string } // ConnectIfaceResponse argument structure for exported method OwrtCreateWifiInterface type ConnectIfaceResponse struct { status int Errors []string } // OwrtConnectWifiInterface connects a given Wifi Interface to a given SSID func (o *OrionService) OwrtConnectWifiInterface(r *http.Request, args *ConnectIfaceArgs, reply *ConnectIfaceResponse) error { o.UCI.LoadWirelessConf() iface := o.UCI.GetWifiIface(args.Iface.Index) cells := iface.Scan() for _, cell := range cells { if cell.Ssid == args.SSID { cn := iface.Connect(o.UCI, cell, args.Key) if cn.ReturnCode != 0 { reply.status = cn.ReturnCode reply.Errors = append(reply.Errors, cn.Stdout, cn.Stderr, cn.Command) } reply.status = 0 return nil } } reply.status = 1 msg := fmt.Sprintf("Wifi Cell with SSID %s is not available !", args.SSID) reply.Errors = append(reply.Errors, msg) return nil } // NewServer returns a new configured JSON-RPC server func NewServer() *rpc.Server { server := rpc.NewServer() server.RegisterCodec(json.NewCodec(), "application/json") if err := server.RegisterService(NewOrionService(), "Orion"); err != nil { panic(err) } return server }