diff --git a/service/defaults.go b/service/defaults.go index 7b9622c..b47c65b 100644 --- a/service/defaults.go +++ b/service/defaults.go @@ -13,9 +13,21 @@ const ( USB_ETHERNET_BRIDGE_NAME = "usbeth" BT_ETHERNET_BRIDGE_MAC = "44:22:26:12:14:16" BT_ETHERNET_BRIDGE_NAME = "bteth" - + WIFI_ETHERNET_IFACE_NAME = "wlan0" ) +func GetDefaultNetworkSettingsBluetooth() (*pb.EthernetInterfaceSettings) { + ifSettings := &pb.EthernetInterfaceSettings{ + Name: BT_ETHERNET_BRIDGE_NAME, + Enabled: true, + Mode: pb.EthernetInterfaceSettings_MANUAL, + IpAddress4: "172.26.0.1", + Netmask4: "255.255.255.0", + DhcpServerSettings: GetDefaultDHCPConfigBluetooth(), + } + return ifSettings +} + func GetDefaultNetworkSettingsUSB() (*pb.EthernetInterfaceSettings) { //configure 172.24.0.1/255.255.255.252 for usbeth ifSettings := &pb.EthernetInterfaceSettings { @@ -32,7 +44,7 @@ func GetDefaultNetworkSettingsUSB() (*pb.EthernetInterfaceSettings) { func GetDefaultNetworkSettingsWiFi() (*pb.EthernetInterfaceSettings) { ifSettings := &pb.EthernetInterfaceSettings { Enabled: true, - Name: "wlan0", + Name: WIFI_ETHERNET_IFACE_NAME, Mode: pb.EthernetInterfaceSettings_DHCP_SERVER, IpAddress4: "172.24.0.1", Netmask4: "255.255.255.0", @@ -46,7 +58,7 @@ func GetDefaultDHCPConfigUSB() (settings *pb.DHCPServerSettings) { //CallbackScript: "/bin/evilscript", DoNotBindInterface: false, //only bind to given interface ListenInterface: USB_ETHERNET_BRIDGE_NAME, - LeaseFile: "/tmp/dnsmasq_" + USB_ETHERNET_BRIDGE_NAME + ".leases", + LeaseFile: nameLeaseFileDHCPSrv(USB_ETHERNET_BRIDGE_NAME), ListenPort: 0, //No DNS, DHCP only NotAuthoritative: false, //be authoritative Ranges: []*pb.DHCPServerRange{ @@ -63,12 +75,31 @@ func GetDefaultDHCPConfigUSB() (settings *pb.DHCPServerSettings) { return } +func GetDefaultDHCPConfigBluetooth() (settings *pb.DHCPServerSettings) { + settings = &pb.DHCPServerSettings{ + //CallbackScript: "/bin/evilscript", + DoNotBindInterface: false, //only bind to given interface + ListenInterface: BT_ETHERNET_BRIDGE_NAME, + LeaseFile: nameLeaseFileDHCPSrv(BT_ETHERNET_BRIDGE_NAME), + ListenPort: 0, //No DNS, DHCP only + NotAuthoritative: false, //be authoritative + Ranges: []*pb.DHCPServerRange{ + &pb.DHCPServerRange{RangeLower: "172.26.0.2", RangeUpper: "172.26.0.20", LeaseTime: "5m"}, + }, + Options: map[uint32]string{ + 3: "", //Disable option: Router + 6: "", //Disable option: DNS + }, + } + return +} + func GetDefaultDHCPConfigWiFi() (settings *pb.DHCPServerSettings) { settings = &pb.DHCPServerSettings{ //CallbackScript: "/bin/evilscript", DoNotBindInterface: false, //only bind to given interface - ListenInterface: "wlan0", - LeaseFile: "/tmp/dnsmasq_wlan0.leases", + ListenInterface: WIFI_ETHERNET_IFACE_NAME, + LeaseFile: nameLeaseFileDHCPSrv(WIFI_ETHERNET_IFACE_NAME), ListenPort: 0, //No DNS, DHCP only NotAuthoritative: false, //be authoritative Ranges: []*pb.DHCPServerRange{ diff --git a/service/network.go b/service/network.go index 79409bd..8813b58 100644 --- a/service/network.go +++ b/service/network.go @@ -13,107 +13,99 @@ import ( "errors" ) +var ( + ErrUnmanagedInterface = errors.New("Not a managed network interface") +) + +func NewNetworkManager() (nm *NetworkManager, err error){ + nm = &NetworkManager{ + ManagedInterfaces: make(map[string]*NetworkInterfaceManager), + } + + // Add managed interfaces + + // USB + err = nm.AddManagedInterface(GetDefaultNetworkSettingsUSB()) + if err != nil { return } + // WiFi + err = nm.AddManagedInterface(GetDefaultNetworkSettingsWiFi()) + if err != nil { return } + // Bluetooth + err = nm.AddManagedInterface(GetDefaultNetworkSettingsBluetooth()) + if err != nil { return } + + return nm, nil +} -func ReInitNetworkInterface(ifName string) (err error) { +type NetworkManager struct { + ManagedInterfaces map[string]*NetworkInterfaceManager +} + +func (nm *NetworkManager) AddManagedInterface(startupConfig *pb.EthernetInterfaceSettings) (err error) { + nim,err := NewNetworkInterfaceManager(startupConfig.Name, startupConfig) + if err != nil { return err } + nm.ManagedInterfaces[startupConfig.Name] = nim + return +} + +func (nm *NetworkManager) GetManagedInterfaceNames() (ifnames []string) { + ifnames = make([]string, len(nm.ManagedInterfaces)) + i:=0 + for name,_ := range nm.ManagedInterfaces { + ifnames[i] = name + i += 1 + } + return +} + +func (nm *NetworkManager) GetManagedInterface(name string) (nim *NetworkInterfaceManager, err error) { + if nim, exists := nm.ManagedInterfaces[name]; exists { + return nim, nil + } else { + return nil, ErrUnmanagedInterface + } +} + + + +type NetworkInterfaceState struct { + InterfacePresent bool + CurrentSettings *pb.EthernetInterfaceSettings +} + +// ToDo: interface watcher (up/down --> auto redeploy) +type NetworkInterfaceManager struct { + InterfaceName string + state *NetworkInterfaceState +} + +func (nim *NetworkInterfaceManager) GetState() (res *NetworkInterfaceState) { + return nim.state +} + +func (nim *NetworkInterfaceManager) ReDeploy() (err error) { + /* if settings, existing := ServiceState.StoredNetworkSettings[ifName]; existing { log.Printf("Redeploying stored Network settings for interface '%s' ...\n", ifName) return ConfigureInterface(settings) } else { return errors.New(fmt.Sprintf("No stored interface settings found for '%s'\n", ifName)) } + */ + return nim.DeploySettings(nim.state.CurrentSettings) } -func ParseIPv4Mask(maskstr string) (net.IPMask, error) { - mask := net.ParseIP(maskstr) - if mask == nil { return nil, errors.New("Couldn't parse netmask") } - - net.ParseCIDR(maskstr) - return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]), nil -} - -func IpNetFromIPv4AndNetmask(ipv4 string, netmask string) (*net.IPNet, error) { - mask, err := ParseIPv4Mask(netmask) - if err != nil { return nil, err } - - ip := net.ParseIP(ipv4) - if mask == nil { return nil, errors.New("Couldn't parse IP") } - - netw := ip.Mask(mask) - - return &net.IPNet{IP: netw, Mask: mask}, nil -} - - - -func CreateBridge(name string) (err error) { - return netlink.CreateBridge(name, false) -} - -func setInterfaceMac(name string, mac string) error { - return netlink.SetMacAddress(name, mac) -} - -func DeleteBridge(name string) error { - return netlink.DeleteBridge(name) -} - -//Uses sysfs (not IOCTL) -func SetBridgeSTP(name string, stp_on bool) (err error) { - value := "0" - if (stp_on) { value = "1" } - return ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/stp_state", name), []byte(value), os.ModePerm) -} - -func SetBridgeForwardDelay(name string, fd uint) (err error) { - return ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/forward_delay", name), []byte(fmt.Sprintf("%d", fd)), os.ModePerm) -} - - - -func CheckInterfaceExistence(name string) (res bool, err error) { - _, err = net.InterfaceByName(name) - if err != nil { - return false, err - } - return true, err -} - -func NetworkLinkUp(name string) (err error) { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - - err = netlink.NetworkLinkUp(iface) - return -} - -func AddInterfaceToBridgeIfExistent(bridgeName string, ifName string) (err error) { - br, err := net.InterfaceByName(bridgeName) - if err != nil { - return err - } - iface, err := net.InterfaceByName(ifName) - if err != nil { - return err - } - - err = netlink.AddToBridge(iface, br) - if err != nil { - return err - } - log.Printf("Interface %s added to bridge %s", ifName, bridgeName) - - //enable interface - NetworkLinkUp(ifName) - return nil -} - -func ConfigureInterface(settings *pb.EthernetInterfaceSettings) (err error) { +func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfaceSettings) (err error) { //Get Interface iface, err := net.InterfaceByName(settings.Name) - if err != nil { return err } + if err != nil { + nim.state.InterfacePresent = false + //return err + return nil //Not having the interface present isn't an error + } else { + nim.state.InterfacePresent = true + } //stop DHCP server / client if still running running, _, err := IsDHCPServerRunning(settings.Name) @@ -223,7 +215,138 @@ func ConfigureInterface(settings *pb.EthernetInterfaceSettings) (err error) { //Store latest settings settings.SettingsInUse = true - ServiceState.StoredNetworkSettings[settings.Name] = settings + + //ServiceState.StoredNetworkSettings[settings.Name] = settings + nim.state.CurrentSettings = settings return nil -} \ No newline at end of file +} + +func NewNetworkInterfaceManager(ifaceName string, startupSettings *pb.EthernetInterfaceSettings) (nim *NetworkInterfaceManager, err error) { + nim = &NetworkInterfaceManager{ + InterfaceName: ifaceName, + state: &NetworkInterfaceState{}, + } + nim.state.CurrentSettings = startupSettings + nim.ReDeploy() + + // Deploy startup configuration, to have an initial, defined state + + /* + // Startup settings (always DHCP client, Interface up) + nim.state.CurrentSettings = &pb.EthernetInterfaceSettings{ + Name: ifaceName, + Mode: pb.EthernetInterfaceSettings_DHCP_CLIENT, + Enabled: true, + SettingsInUse: true, + DhcpServerSettings: &pb.DHCPServerSettings{ + CallbackScript: "", + DoNotBindInterface: false, + LeaseFile: nameLeaseFileDHCPSrv(ifaceName), + ListenInterface: ifaceName, + ListenPort: 0, + NotAuthoritative: false, + Options: map[uint32]string{ + 3: "", + 6: "", + }, + Ranges: []*pb.DHCPServerRange{}, + StaticHosts: []*pb.DHCPServerStaticHost{}, + }, + } + */ + + return +} + + +/* HELPER */ +func nameLeaseFileDHCPSrv(nameIface string) (lf string) { + return "/tmp/dnsmasq_" + nameIface + ".leases" +} + +func ParseIPv4Mask(maskstr string) (net.IPMask, error) { + mask := net.ParseIP(maskstr) + if mask == nil { return nil, errors.New("Couldn't parse netmask") } + + net.ParseCIDR(maskstr) + return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]), nil +} + +func IpNetFromIPv4AndNetmask(ipv4 string, netmask string) (*net.IPNet, error) { + mask, err := ParseIPv4Mask(netmask) + if err != nil { return nil, err } + + ip := net.ParseIP(ipv4) + if mask == nil { return nil, errors.New("Couldn't parse IP") } + + netw := ip.Mask(mask) + + return &net.IPNet{IP: netw, Mask: mask}, nil +} + + + +func CreateBridge(name string) (err error) { + return netlink.CreateBridge(name, false) +} + +func setInterfaceMac(name string, mac string) error { + return netlink.SetMacAddress(name, mac) +} + +func DeleteBridge(name string) error { + return netlink.DeleteBridge(name) +} + +//Uses sysfs (not IOCTL) +func SetBridgeSTP(name string, stp_on bool) (err error) { + value := "0" + if (stp_on) { value = "1" } + return ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/stp_state", name), []byte(value), os.ModePerm) +} + +func SetBridgeForwardDelay(name string, fd uint) (err error) { + return ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/forward_delay", name), []byte(fmt.Sprintf("%d", fd)), os.ModePerm) +} + + + +func CheckInterfaceExistence(name string) (res bool, err error) { + _, err = net.InterfaceByName(name) + if err != nil { + return false, err + } + return true, err +} + +func NetworkLinkUp(name string) (err error) { + iface, err := net.InterfaceByName(name) + if err != nil { + return err + } + + err = netlink.NetworkLinkUp(iface) + return +} + +func AddInterfaceToBridgeIfExistent(bridgeName string, ifName string) (err error) { + br, err := net.InterfaceByName(bridgeName) + if err != nil { + return err + } + iface, err := net.InterfaceByName(ifName) + if err != nil { + return err + } + + err = netlink.AddToBridge(iface, br) + if err != nil { + return err + } + log.Printf("Interface %s added to bridge %s", ifName, bridgeName) + + //enable interface + NetworkLinkUp(ifName) + return nil +} diff --git a/service/rpc_server.go b/service/rpc_server.go index 3471704..b205f96 100644 --- a/service/rpc_server.go +++ b/service/rpc_server.go @@ -54,7 +54,7 @@ func (s *server) Stop() error { func (s *server) StoreDeployedWifiSettings(ctx context.Context, m *pb.StringMessage) (e *pb.Empty, err error) { return s.StoreWifiSettings(ctx, &pb.WifiRequestSettingsStorage{ - Settings: ServiceState.WifiSvc.State.CurrentSettings, + Settings: s.rootSvc.SubSysWifi.State.CurrentSettings, TemplateName: m.Msg, }) } @@ -87,14 +87,14 @@ func (s *server) ListStoredWifiSettings(ctx context.Context, e *pb.Empty) (sa *p } func (s *server) DeployWiFiSettings(ctx context.Context, wset *pb.WiFiSettings) (wstate *pb.WiFiState, err error) { - return ServiceState.WifiSvc.DeploySettings(wset) + return s.rootSvc.SubSysWifi.DeploySettings(wset) } func (s *server) GetWiFiState(ctx context.Context, empty *pb.Empty) (wstate *pb.WiFiState, err error) { // Update state before transmitting back - ServiceState.WifiSvc.UpdateStateFromIw() + s.rootSvc.SubSysWifi.UpdateStateFromIw() - st := ServiceState.WifiSvc.State + st := s.rootSvc.SubSysWifi.State return st, nil } @@ -103,18 +103,30 @@ func (s *server) ListenWiFiStateChanges(ctx context.Context, empty *pb.Empty) (w } func (s *server) GetDeployedEthernetInterfaceSettings(ctx context.Context, req *pb.StringMessage) (resp *pb.EthernetInterfaceSettings, err error) { + + + if mi,err := s.rootSvc.SubSysNetwork.GetManagedInterface(req.Msg); err == nil { + return mi.GetState().CurrentSettings, nil + } else { + return nil, errors.New(fmt.Sprintf("No stored (or used) settings for ethernet interface '%s'", req.Msg)) + } + /* if settings,exist := ServiceState.StoredNetworkSettings[req.Msg]; exist && settings.SettingsInUse { return settings, nil } else { return nil, errors.New(fmt.Sprintf("No stored (or used) settings for ethernet interface '%s'", req.Msg)) } + */ } func (s *server) GetAllDeployedEthernetInterfaceSettings(ctx context.Context, empty *pb.Empty) (resp *pb.DeployedEthernetInterfaceSettings, err error) { - deployed := make([]*pb.EthernetInterfaceSettings, len(ServiceState.StoredNetworkSettings)) - var i = 0 - for _,settings := range ServiceState.StoredNetworkSettings { deployed[i] = settings; i++ } - + miList := s.rootSvc.SubSysNetwork.GetManagedInterfaceNames() + deployed := make([]*pb.EthernetInterfaceSettings,len(miList)) + for idx,name := range miList { + mi,err := s.rootSvc.SubSysNetwork.GetManagedInterface(name) + if err != nil { return nil,err } + deployed[idx] = mi.GetState().CurrentSettings + } resp = &pb.DeployedEthernetInterfaceSettings{ List: deployed, } @@ -193,7 +205,7 @@ func (s *server) FSCreateTempDirOrFile(ctx context.Context, req *pb.TempDirOrFil } func (s *server) HIDGetRunningJobState(ctx context.Context, req *pb.HIDScriptJob) (res *pb.HIDRunningJobStateResult, err error) { - targetJob,err := ServiceState.UsbGM.HidCtl.GetBackgroundJobByID(int(req.Id)) + targetJob,err := s.rootSvc.SubSysUSB.HidCtl.GetBackgroundJobByID(int(req.Id)) if err != nil { return nil, err } vmID,_ := targetJob.GetVMId() // ignore error, as VM ID would be -1 in error case @@ -211,9 +223,9 @@ func (s *server) HIDGetRunningJobState(ctx context.Context, req *pb.HIDScriptJob } func (s *server) HIDGetRunningScriptJobs(ctx context.Context, rEmpty *pb.Empty) (jobs *pb.HIDScriptJobList, err error) { - if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return nil, rpcErrNoHid} - retJobs,err := ServiceState.UsbGM.HidCtl.GetAllBackgroundJobs() + retJobs,err := s.rootSvc.SubSysUSB.HidCtl.GetAllBackgroundJobs() if err != nil { return nil, err } jobs = &pb.HIDScriptJobList{} for _, aJob := range retJobs { @@ -224,10 +236,10 @@ func (s *server) HIDGetRunningScriptJobs(ctx context.Context, rEmpty *pb.Empty) func (s *server) HIDCancelAllScriptJobs(ctx context.Context, rEmpty *pb.Empty) (empty *pb.Empty, err error) { empty = &pb.Empty{} - if ServiceState.UsbGM.HidCtl == nil { return empty, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return empty, rpcErrNoHid} // Try to find script - ServiceState.UsbGM.HidCtl.CancelAllBackgroundJobs() + s.rootSvc.SubSysUSB.HidCtl.CancelAllBackgroundJobs() return } @@ -235,10 +247,10 @@ func (s *server) HIDCancelAllScriptJobs(ctx context.Context, rEmpty *pb.Empty) ( func (s *server) HIDCancelScriptJob(ctx context.Context, sJob *pb.HIDScriptJob) (empty *pb.Empty, err error) { empty = &pb.Empty{} - if ServiceState.UsbGM.HidCtl == nil { return empty, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return empty, rpcErrNoHid} // Try to find script - job,err := ServiceState.UsbGM.HidCtl.GetBackgroundJobByID(int(sJob.Id)) + job,err := s.rootSvc.SubSysUSB.HidCtl.GetBackgroundJobByID(int(sJob.Id)) if err != nil { return empty, err } job.Cancel() @@ -246,7 +258,7 @@ func (s *server) HIDCancelScriptJob(ctx context.Context, sJob *pb.HIDScriptJob) } func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptRequest) (scriptRes *pb.HIDScriptResult, err error) { - if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return nil, rpcErrNoHid} @@ -259,7 +271,7 @@ func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptReques if scriptReq.TimeoutSeconds > 0 { jobCtx,_ = context.WithTimeout(jobCtx, time.Second * time.Duration(scriptReq.TimeoutSeconds))} - scriptVal,err := ServiceState.UsbGM.HidCtl.RunScript(jobCtx, string(scriptFile)) + scriptVal,err := s.rootSvc.SubSysUSB.HidCtl.RunScript(jobCtx, string(scriptFile)) if err != nil { return nil,err } val,_ := scriptVal.Export() //Convert to Go representation, error is always nil jsonVal,err := json.Marshal(val) @@ -276,7 +288,7 @@ func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptReques } func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptRequest) (rJob *pb.HIDScriptJob, err error) { - if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return nil, rpcErrNoHid} if scriptFile, err := ioutil.ReadFile(scriptReq.ScriptPath); err != nil { return nil, errors.New(fmt.Sprintf("Couldn't load HIDScript '%s': %v\n", scriptReq.ScriptPath, err)) @@ -285,7 +297,7 @@ func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptReq jobCtx := context.Background() // ToDo: we don't retrieve the cancelFunc which should be called to free resources. Solution: use withCancel context and call cancel by go routine on timeout if scriptReq.TimeoutSeconds > 0 { jobCtx,_ = context.WithTimeout(jobCtx, time.Second * time.Duration(scriptReq.TimeoutSeconds))} - job,err := ServiceState.UsbGM.HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile)) + job,err := s.rootSvc.SubSysUSB.HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile)) if err != nil { return nil,err } rJob = &pb.HIDScriptJob{ @@ -297,15 +309,15 @@ func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptReq } func (s *server) HIDGetScriptJobResult(ctx context.Context, sJob *pb.HIDScriptJob) (scriptRes *pb.HIDScriptResult, err error) { - if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid} + if s.rootSvc.SubSysUSB.HidCtl == nil { return nil, rpcErrNoHid} // Try to find script - job,err := ServiceState.UsbGM.HidCtl.GetBackgroundJobByID(int(sJob.Id)) + job,err := s.rootSvc.SubSysUSB.HidCtl.GetBackgroundJobByID(int(sJob.Id)) if err != nil { return scriptRes, err } //ToDo: check impact/behavior, because ctx is provided by gRPC server - scriptVal,err := ServiceState.UsbGM.HidCtl.WaitBackgroundJobResult(ctx, job) + scriptVal,err := s.rootSvc.SubSysUSB.HidCtl.WaitBackgroundJobResult(ctx, job) if err != nil { return nil,err } val,_ := scriptVal.Export() //Convert to Go representation, error is always nil jsonVal,err := json.Marshal(val) @@ -326,7 +338,11 @@ func (s *server) DeployEthernetInterfaceSettings(ctx context.Context, es *pb.Eth log.Printf("Trying to deploy ethernet interface settings %v", es) empty = &pb.Empty{} - err = ConfigureInterface(es) + iname := es.Name + nim,err := s.rootSvc.SubSysNetwork.GetManagedInterface(iname) + if err != nil { return empty,err } + + err = nim.DeploySettings(es) if err != nil { log.Printf("Error deploying ethernet interface settings %v", err) } @@ -358,11 +374,11 @@ func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetS //ToDo: Former gadgets are destroyed without testing if there're changes, this should be aborted if GadgetSettingsState == GetDeployedGadgetSettings() DestroyGadget(USB_GADGET_NAME) - errg := ServiceState.UsbGM.DeployGadgetSettings(ServiceState.UsbGM.UndeployedGadgetSettings) + errg := s.rootSvc.SubSysUSB.DeployGadgetSettings(s.rootSvc.SubSysUSB.UndeployedGadgetSettings) err = nil if errg != nil { err = errors.New(fmt.Sprintf("Deploying new gadget settings failed, reverted to old ones: %v", errg)) - ServiceState.UsbGM.DeployGadgetSettings(gs_backup) //We don't catch the error, as the old settings should have been working + s.rootSvc.SubSysUSB.DeployGadgetSettings(gs_backup) //We don't catch the error, as the old settings should have been working } gs, _ = ParseGadgetState(USB_GADGET_NAME) //Return settings from deployed gadget @@ -370,17 +386,17 @@ func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetS } func (s *server) GetGadgetSettings(context.Context, *pb.Empty) (*pb.GadgetSettings, error) { - return ServiceState.UsbGM.UndeployedGadgetSettings, nil + return s.rootSvc.SubSysUSB.UndeployedGadgetSettings, nil } func (s *server) SetGadgetSettings(ctx context.Context, gs *pb.GadgetSettings) (res *pb.GadgetSettings, err error) { if err = ValidateGadgetSetting(*gs); err != nil { //We return the validation error and the current (unchanged) GadgetSettingsState - res = ServiceState.UsbGM.UndeployedGadgetSettings + res = s.rootSvc.SubSysUSB.UndeployedGadgetSettings return } - ServiceState.UsbGM.UndeployedGadgetSettings = gs - res = ServiceState.UsbGM.UndeployedGadgetSettings + s.rootSvc.SubSysUSB.UndeployedGadgetSettings = gs + res = s.rootSvc.SubSysUSB.UndeployedGadgetSettings return } diff --git a/service/service.go b/service/service.go index 47452b4..ddc0c5b 100644 --- a/service/service.go +++ b/service/service.go @@ -8,6 +8,7 @@ import ( type Service struct { SubSysState interface{} SubSysLogging interface{} + SubSysNetwork *NetworkManager SubSysDataStore *datastore.Store SubSysEvent *EventManager SubSysUSB *UsbGadgetManager @@ -21,6 +22,12 @@ type Service struct { func NewService() (svc *Service, err error) { svc = &Service{} svc.SubSysLed = NewLedService() + svc.SubSysNetwork, err = NewNetworkManager() + if err != nil { return nil,err} + svc.SubSysUSB,err = NewUSBGadgetManager(svc) + if err != nil { return nil,err} + svc.SubSysWifi = NewWifiService(svc) + svc.SubSysRPC = NewRpcServerService(svc) return } diff --git a/service/state.go b/service/state.go index 0e06eb4..89f1e05 100644 --- a/service/state.go +++ b/service/state.go @@ -3,8 +3,6 @@ package service import ( - "errors" - pb "github.com/mame82/P4wnP1_go/proto" "github.com/mame82/P4wnP1_go/service/datastore" ) @@ -22,11 +20,11 @@ type SubSysState struct { type GlobalServiceState struct { Store *datastore.Store EvMgr *EventManager - UsbGM *UsbGadgetManager +// UsbGM *UsbGadgetManager // Led *LedState HidDevPath map[string]string //stores device path for HID devices - StoredNetworkSettings map[string]*pb.EthernetInterfaceSettings - WifiSvc *WiFiService +// StoredNetworkSettings map[string]*pb.EthernetInterfaceSettings +// WifiSvc *WiFiService BtSvc *BtService } @@ -36,12 +34,9 @@ func InitGlobalServiceState() (err error) { state.Store,err = datastore.Open(cSTORE_PATH) if err != nil { return } - state.StoredNetworkSettings = make(map[string]*pb.EthernetInterfaceSettings) /* - state.StoredNetworkSettings[USB_ETHERNET_BRIDGE_NAME] = GetDefaultNetworkSettingsUSB() - state.StoredNetworkSettings["wlan0"] = GetDefaultNetworkSettingsWiFi() - */ + state.StoredNetworkSettings = make(map[string]*pb.EthernetInterfaceSettings) //pre initialize Default settings for "wlan0" and USB_ETHERNET_BRIDGE_NAME ("usbeth") state.StoredNetworkSettings[USB_ETHERNET_BRIDGE_NAME] = &pb.EthernetInterfaceSettings{ Name: USB_ETHERNET_BRIDGE_NAME, @@ -64,12 +59,13 @@ func InitGlobalServiceState() (err error) { IpAddress4: "172.26.0.1", Netmask4: "255.255.255.0", } + */ - state.WifiSvc = NewWifiService() +// state.WifiSvc = NewWifiService() state.HidDevPath = make(map[string]string) //should be initialized BEFORE UsbGadgetManager uses it state.EvMgr = NewEventManager(20) - state.UsbGM, err = NewUSBGadgetManager() +// state.UsbGM, err = NewUSBGadgetManager() if err != nil { return } @@ -85,6 +81,7 @@ func InitGlobalServiceState() (err error) { return nil } +/* func (state *GlobalServiceState) GetInterfaceSettingsByInterfaceName(ifname string) (*pb.EthernetInterfaceSettings, error) { for _, s := range state.StoredNetworkSettings { if s.Name == ifname { @@ -93,6 +90,7 @@ func (state *GlobalServiceState) GetInterfaceSettingsByInterfaceName(ifname stri } return nil, errors.New("No settings for interface " + ifname + " found") } +*/ func (state *GlobalServiceState) StartService() { state.EvMgr.Start() diff --git a/service/usb.go b/service/usb.go index 45de55d..a3c8876 100644 --- a/service/usb.go +++ b/service/usb.go @@ -77,6 +77,8 @@ const ( var rp_usbHidDevName = regexp.MustCompile("(?m)DEVNAME=(.*)\n") type UsbGadgetManager struct { + RootSvc *Service + // ToDo: variable, indicating if HIDScript is usable HidCtl *hid.HIDController // Points to an HID controller instance only if keyboard and/or mouse are enabled, nil otherwise UndeployedGadgetSettings *pb.GadgetSettings @@ -87,8 +89,10 @@ func (gm *UsbGadgetManager) HandleEvent(event hid.Event) { ServiceState.EvMgr.Emit(ConstructEventHID(event)) } -func NewUSBGadgetManager() (newUGM *UsbGadgetManager, err error) { - newUGM = &UsbGadgetManager{} +func NewUSBGadgetManager(rooSvc *Service) (newUGM *UsbGadgetManager, err error) { + newUGM = &UsbGadgetManager{ + RootSvc: rooSvc, + } defGS := GetDefaultGadgetSettings() newUGM.UndeployedGadgetSettings = &defGS //preload state with default settings err = CheckLibComposite() @@ -664,7 +668,11 @@ func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) er log.Printf("... creating network bridge for USB ethernet devices") addUSBEthernetBridge() log.Printf("... checking for stored network interface settings for USB ethernet") - ReInitNetworkInterface(USB_ETHERNET_BRIDGE_NAME) + //ReInitNetworkInterface(USB_ETHERNET_BRIDGE_NAME) + if nim,err := gm.RootSvc.SubSysNetwork.GetManagedInterface(USB_ETHERNET_BRIDGE_NAME); err == nil { + nim.ReDeploy() + } + } else { return err } diff --git a/service/wifi.go b/service/wifi.go index d31f00e..0f7542e 100644 --- a/service/wifi.go +++ b/service/wifi.go @@ -47,6 +47,8 @@ func wifiCheckExternalBinaries() error { } type WiFiService struct { + RootSvc *Service + State *pb.WiFiState //Settings *pb.WiFi2Settings @@ -381,7 +383,10 @@ func (wSvc *WiFiService) DeploySettings(newWifiSettings *pb.WiFiSettings) (wstat } // At this point, we reestablish the interface settings - ReInitNetworkInterface(wSvc.IfaceName) + //ReInitNetworkInterface(wSvc.IfaceName) + if nim,err := wSvc.RootSvc.SubSysNetwork.GetManagedInterface(wSvc.IfaceName); err == nil { + nim.ReDeploy() + } if err == nil { log.Printf("... WiFi settings deployed successfully\n") @@ -399,7 +404,7 @@ func (wSvc *WiFiService) DeploySettings(newWifiSettings *pb.WiFiSettings) (wstat return wSvc.State, nil } -func NewWifiService() (res *WiFiService) { +func NewWifiService(rootSvc *Service) (res *WiFiService) { ifName := wifi_if_name err := wifiCheckExternalBinaries() if err != nil { @@ -412,7 +417,7 @@ func NewWifiService() (res *WiFiService) { } res = &WiFiService{ - + RootSvc: rootSvc, mutexSettings: &sync.Mutex{}, CmdWpaSupplicant: nil, mutexWpaSupplicant: &sync.Mutex{},