Continuing work on JSON-RPC API !

This commit is contained in:
Philippe Caseiro 2018-10-05 16:12:07 +02:00 committed by William Petit
parent 6a316c53ee
commit aed2271bf7
5 changed files with 154 additions and 14 deletions

View File

@ -1,7 +1,9 @@
package rpc package rpc
import ( import (
"fmt"
"net/http" "net/http"
"time"
"forge.cadoles.com/Pyxis/orion/openwrt" "forge.cadoles.com/Pyxis/orion/openwrt"
"github.com/gorilla/rpc" "github.com/gorilla/rpc"
@ -52,11 +54,106 @@ func (o *OrionService) OwrtListWifiInterfaces(r *http.Request, args *ListIfaceAr
return nil 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 // NewServer returns a new configured JSON-RPC server
func NewServer() *rpc.Server { func NewServer() *rpc.Server {
server := rpc.NewServer() server := rpc.NewServer()
server.RegisterCodec(json.NewCodec(), "application/json") server.RegisterCodec(json.NewCodec(), "application/json")
if err := server.RegisterService(new(OrionService), "Orion"); err != nil { if err := server.RegisterService(NewOrionService(), "Orion"); err != nil {
panic(err) panic(err)
} }
return server return server

View File

@ -8,6 +8,7 @@ import (
// Action is the result of an UCI action output and return code // Action is the result of an UCI action output and return code
type Action struct { type Action struct {
*CommandResult *CommandResult
Command string
} }
// UCI "Object" // UCI "Object"
@ -34,13 +35,14 @@ func NewUCIWithExecutor(exec Executor) *UCI {
func (u *UCI) uciRun(param ...string) *Action { func (u *UCI) uciRun(param ...string) *Action {
cmd := "/sbin/uci" cmd := "/sbin/uci"
res := u.exec.Run(cmd, param...) res := u.exec.Run(cmd, param...)
return &Action{res} return &Action{res, fmt.Sprintf("%s %s", cmd, param)}
} }
// Add add an entry to UCI configuration, specify the Module and the value // Add add an entry to UCI configuration, specify the Module and the value
func (u *UCI) Add(module string, name string) *Action { func (u *UCI) Add(module string, name string) *Action {
commandRes := u.exec.Run("uci add", module, name) cmd := "uci add"
return &Action{commandRes} commandRes := u.exec.Run(cmd, module, name)
return &Action{commandRes, fmt.Sprintf("%s %s %s", cmd, module, name)}
} }
// Delete delete an entry from UCI configuration specify the entry name // Delete delete an entry from UCI configuration specify the entry name
@ -65,7 +67,7 @@ func (u *UCI) Reload() *Action {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
return &Action{cmdResult} return &Action{cmdResult, "reload_config"}
} }
// Show returns the output of uci show command // Show returns the output of uci show command
@ -86,7 +88,7 @@ func (u *UCI) LoadWirelessConf() {
u.Wireless.Load() u.Wireless.Load()
} }
// GetWifiIface returns the system name of the Interface // GetWifiIface returns the wifi Interface by Index
func (u *UCI) GetWifiIface(idx int) *UCIWirelessInterface { func (u *UCI) GetWifiIface(idx int) *UCIWirelessInterface {
ifaces := u.Wireless.Interfaces ifaces := u.Wireless.Interfaces
if len(ifaces) < idx { if len(ifaces) < idx {
@ -95,6 +97,20 @@ func (u *UCI) GetWifiIface(idx int) *UCIWirelessInterface {
return ifaces[idx] return ifaces[idx]
} }
// GetWifiIfaceByName returns the wifi Interface by Index
func (u *UCI) GetWifiIfaceByName(name string) *UCIWirelessInterface {
ifaces := u.Wireless.Interfaces
if len(ifaces) <= 0 {
return nil
}
for _, ifa := range ifaces {
if ifa.Name == name {
return ifa
}
}
return nil
}
// GetWifiIfaces wifi interfaces in configuration // GetWifiIfaces wifi interfaces in configuration
func (u *UCI) GetWifiIfaces() []*UCIWirelessInterface { func (u *UCI) GetWifiIfaces() []*UCIWirelessInterface {
return u.Wireless.Interfaces return u.Wireless.Interfaces

View File

@ -84,6 +84,10 @@ func (wc *UCIWirelessConf) parseInterfaces(lines []string) int {
} }
if key == "Device" { if key == "Device" {
wc.Interfaces[idx].Device = value wc.Interfaces[idx].Device = value
//FIXME
//dev := fmt.Sprintf("wireless.%s", value)
//path := wc.uciClient.Show(dev)
//wc.Interfaces[idx].DevicePath = strings.Split(path.Stdout, "=")[1]
} }
if key == "Mode" { if key == "Mode" {
wc.Interfaces[idx].Mode = value wc.Interfaces[idx].Mode = value
@ -167,10 +171,8 @@ func grep(lines string, pattern string) []string {
func (wc *UCIWirelessConf) Load() *UCIWirelessConf { func (wc *UCIWirelessConf) Load() *UCIWirelessConf {
conf := wc.uciClient.Show("wireless") conf := wc.uciClient.Show("wireless")
fmt.Println(conf.Stdout)
wc.parseDevicesConf(grep(conf.Stdout, "wireless.radio")) wc.parseDevicesConf(grep(conf.Stdout, "wireless.radio"))
wc.parseDefaultInterface(grep(conf.Stdout, "wireless.default_radio0")) wc.parseDefaultInterface(grep(conf.Stdout, "wireless.default_radio0"))
fmt.Println(grep(conf.Stdout, "wireless.@wifi-iface"))
wc.parseInterfaces(grep(conf.Stdout, "wireless.@wifi-iface")) wc.parseInterfaces(grep(conf.Stdout, "wireless.@wifi-iface"))
return wc return wc

View File

@ -47,8 +47,6 @@ func (wi *UCIWirelessInterface) GetSysDevName(sysDir string) string {
filepath.Walk(sysDir, func(path string, f os.FileInfo, _ error) error { filepath.Walk(sysDir, func(path string, f os.FileInfo, _ error) error {
patt := fmt.Sprintf("%s/%s/.*/address", wi.DevicePath, "net") patt := fmt.Sprintf("%s/%s/.*/address", wi.DevicePath, "net")
fmt.Println(wi.DevicePath)
fmt.Println(patt)
r, err := regexp.MatchString(patt, path) r, err := regexp.MatchString(patt, path)
if err == nil && r { if err == nil && r {
fmt.Println(path) fmt.Println(path)
@ -65,11 +63,16 @@ func (wi *UCIWirelessInterface) GetSysDevName(sysDir string) string {
// Create add a new entry for wifi interface in UCI Configuration // Create add a new entry for wifi interface in UCI Configuration
func (wi *UCIWirelessInterface) Create(uci *UCI) *Action { func (wi *UCIWirelessInterface) Create(uci *UCI) *Action {
var confPrefix string
addRes := uci.AddWireless() addRes := uci.AddWireless()
if addRes.ReturnCode != 0 { if addRes.ReturnCode != 0 {
return addRes return addRes
} }
confPrefix := fmt.Sprintf("wireless.@wifi-iface[%d]", wi.Index) if wi.Index <= 0 {
confPrefix = fmt.Sprintf("wireless.@wifi-iface[%d]", wi.Index)
} else {
confPrefix = fmt.Sprintf("wireless.@wifi-iface[%d]", len(uci.Wireless.Interfaces))
}
conf := make(map[string][]string) conf := make(map[string][]string)
conf["network"] = append(conf["network"], fmt.Sprintf("%s.network", confPrefix), wi.Network) conf["network"] = append(conf["network"], fmt.Sprintf("%s.network", confPrefix), wi.Network)
@ -125,6 +128,24 @@ func (wi *UCIWirelessInterface) SysAdd(uci *UCI) *Action {
res := uci.exec.Run(cmd, opt, phydev, what, act, wi.SysDevName, "type", tpe) res := uci.exec.Run(cmd, opt, phydev, what, act, wi.SysDevName, "type", tpe)
return &Action{ return &Action{
CommandResult: res, CommandResult: res,
Command: fmt.Sprintf("%s %s %s %s %s %s %s %s", cmd, opt, phydev, what, act, wi.SysDevName, "type", tpe),
}
}
// SysDel deletes the interface in the system using iw command
func (wi *UCIWirelessInterface) SysDel(uci *UCI) *Action {
cmd := "iw"
opt := "dev"
act := "del"
if wi.SysDevName == "" {
wi.SysDevName = fmt.Sprintf("tmp.radio%d", wi.Index)
}
res := uci.exec.Run(cmd, opt, wi.SysDevName, act)
return &Action{
CommandResult: res,
Command: fmt.Sprintf("%s %s %s %s", cmd, opt, wi.SysDevName, act),
} }
} }

View File

@ -10,7 +10,6 @@ func TestGetSysDevName(t *testing.T) {
iface.Index = 1 iface.Index = 1
iface.Device = "radioX" iface.Device = "radioX"
iface.DevicePath = "soc/soc:pcie/pci0000:00/0000:00:02.0/0000:02:00.0" iface.DevicePath = "soc/soc:pcie/pci0000:00/0000:00:02.0/0000:02:00.0"
iface.SysDevName = "wlanX"
iface.Mode = "ap" iface.Mode = "ap"
iface.Ssid = "PyxisWifi" iface.Ssid = "PyxisWifi"
iface.Bssid = "00:00:00:00:00" iface.Bssid = "00:00:00:00:00"
@ -18,8 +17,13 @@ func TestGetSysDevName(t *testing.T) {
iface.Encryption = "psk" iface.Encryption = "psk"
iface.Key = "qsmdflkjqslmdfkjqslmfkdj" iface.Key = "qsmdflkjqslmdfkjqslmfkdj"
if iface.GetSysDevName("testdata/sys/") != "wlan1" { if g, e := iface.GetSysDevName("testdata/sys/"), "wlan1"; g != e {
t.Fatalf("UCIWirelessInterface.GetDeviceSysName() failed !") t.Fatalf("UCIWirelessInterface.GetDeviceSysName() failed ! Got: %s Expect: %s", g, e)
}
iface.SysDevName = "wlanX"
if g, e := iface.GetSysDevName("testdata/sys/"), "wlanX"; g != e {
t.Fatalf("UCIWirelessInterface.GetDeviceSysName() failed ! Got: %s Expect: %s", g, e)
} }
} }