Work on bluetooth stack

This commit is contained in:
MaMe82
2018-09-20 19:04:37 +02:00
parent 1bc13d74b2
commit 7bfe6d2159
6 changed files with 384 additions and 311 deletions

View File

@@ -3,335 +3,57 @@ package service
import (
"errors"
"fmt"
"github.com/mame82/P4wnP1_go/service/util"
"github.com/mame82/P4wnP1_go/service/bluetooth"
"github.com/mame82/mblue-toolz/toolz"
"log"
"net"
"os/exec"
"regexp"
"strconv"
"strings"
"sync"
)
const (
bt_dev_name string = "hci0"
BT_MINIMUM_BLUEZ_VERSION_MAJOR = 5
BT_MINIMUM_BLUEZ_VERSION_MINOR = 43
)
const (
BT_AGENT_MODE_DISPLAY_YES_NO = BtAgentMode("DisplayYesNo")
BT_AGENT_MODE_DISPLAY_ONLY = BtAgentMode("DisplayOnly")
BT_AGENT_MODE_KEYBOARD_ONLY = BtAgentMode("KeyboardOnly")
BT_AGENT_MODE_NO_INPUT_NO_OUTPUT = BtAgentMode("NoInputNoOutput")
)
type BtAgentMode string
type BtService struct {
DevName string
ServiceAvailable bool
Controller *bluetooth.Controller
BrName string
PathBtConf string
bridgeIfDeployed bool
Agent *BtAgent
Adapter *BtAdapter
Agent *bluetooth.DefaultAgent
}
type BtAdapter struct {
/*
--set <property> <value>
Where `property` is one of:
Name
Discoverable
DiscoverableTimeout
Pairable
PairableTimeout
Powered
root@raspberrypi:~# bt-adapter -i
[hci0]
Name: raspberrypi
Address: B8:27:EB:8E:44:43
Alias: raspberrypi [rw]
Class: 0x0
Discoverable: 0 [rw]
DiscoverableTimeout: 180 [rw]
Discovering: 0
Pairable: 1 [rw]
PairableTimeout: 0 [rw]
Powered: 1 [rw]
UUIDs: [00001801-0000-1000-8000-00805f9b34fb, AVRemoteControl, PnPInformation, 00001800-0000-1000-8000-00805f9b34fb, AVRemoteControlTarget]
*/
*sync.Mutex
Address net.HardwareAddr
DeviceName string
Name string // Not changeable
Alias string
Discoverable bool
DiscoverableTimeout uint64
Pairable bool
PairableTimeout uint64
Powered bool
}
var (
reAdapterAddress = regexp.MustCompile("(?m)Address: ([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})")
reAdapterName = regexp.MustCompile("(?m)Name: (.*)\n")
reAdapterAlias = regexp.MustCompile("(?m)Alias: (.*) \\[")
reAdapterDiscoverable = regexp.MustCompile("(?m)Discoverable: ([01])")
reAdapterDiscoverableTimeout = regexp.MustCompile("(?m)DiscoverableTimeout: ([0-9]+)")
reAdapterPairable = regexp.MustCompile("(?m)Pairable: ([01])")
reAdapterPairableTimeout = regexp.MustCompile("(?m)PairableTimeout: ([0-9]+)")
reAdapterPowered = regexp.MustCompile("(?m)Powered: ([01])")
eAdapterParseOutput = errors.New("Error parsing output of `bt-adapter -i`")
eAdapterSetAdapter = errors.New("Error setting adapter options with `bt-adapter -s`")
)
func (bAd *BtAdapter) DeploySate() (err error) {
proc := exec.Command("/usr/bin/bt-adapter", "-s", "Alias", bAd.Alias, "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
proc = exec.Command("/usr/bin/bt-adapter", "-s", "Discoverable", BoolToIntStr(bAd.Discoverable), "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
proc = exec.Command("/usr/bin/bt-adapter", "-s", "DiscoverableTimeout", strconv.Itoa(int(bAd.DiscoverableTimeout)), "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
proc = exec.Command("/usr/bin/bt-adapter", "-s", "Pairable", BoolToIntStr(bAd.Pairable), "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
proc = exec.Command("/usr/bin/bt-adapter", "-s", "PairableTimeout", strconv.Itoa(int(bAd.PairableTimeout)), "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
proc = exec.Command("/usr/bin/bt-adapter", "-s", "Powered", BoolToIntStr(bAd.Powered), "-a", bAd.DeviceName)
if proc.Run() != nil {
return eAdapterSetAdapter
}
bAd.updateMembers()
return
}
// Updates members via `bt-adapter -i`
func (bAd *BtAdapter) updateMembers() (err error) {
proc := exec.Command("/usr/bin/bt-adapter", "-i", "-a", bAd.DeviceName)
res, err := proc.CombinedOutput()
if err != nil {
return errors.New(fmt.Sprintf("Error running `bt-adapter -i -a %s`: %s\niw output: %s", bAd.DeviceName, err, res))
}
output := string(res)
strAdapterAddress := ""
strAdapterName := ""
strAdapterAlias := ""
strAdapterDiscoverable := ""
strAdapterDiscoverableTimeout := ""
strAdapterPairable := ""
strAdapterPairableTimeout := ""
strAdapterPowered := ""
if matches := reAdapterAddress.FindStringSubmatch(output); len(matches) > 1 {
strAdapterAddress = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterName.FindStringSubmatch(output); len(matches) > 1 {
strAdapterName = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterAlias.FindStringSubmatch(output); len(matches) > 1 {
strAdapterAlias = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterDiscoverable.FindStringSubmatch(output); len(matches) > 1 {
strAdapterDiscoverable = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterDiscoverableTimeout.FindStringSubmatch(output); len(matches) > 1 {
strAdapterDiscoverableTimeout = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterPairable.FindStringSubmatch(output); len(matches) > 1 {
strAdapterPairable = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterPairableTimeout.FindStringSubmatch(output); len(matches) > 1 {
strAdapterPairableTimeout = matches[1]
} else {
return eAdapterParseOutput
}
if matches := reAdapterPowered.FindStringSubmatch(output); len(matches) > 1 {
strAdapterPowered = matches[1]
} else {
return eAdapterParseOutput
}
/*
fmt.Println("strAdapterAddress", strAdapterAddress)
fmt.Println("strAdapterName", strAdapterName)
fmt.Println("strAdapterAlias", strAdapterAlias)
fmt.Println("strAdapterDiscoverable", strAdapterDiscoverable)
fmt.Println("strAdapterDiscoverableTimeout", strAdapterDiscoverableTimeout)
fmt.Println("strAdapterPairable", strAdapterPairable)
fmt.Println("strAdapterPairableTimeout", strAdapterPairableTimeout)
fmt.Println("strAdapterPowered", strAdapterPowered)
*/
if bAd.Address, err = net.ParseMAC(strAdapterAddress); err != nil {
return err
}
if bAd.Discoverable, err = strconv.ParseBool(strAdapterDiscoverable); err != nil {
return err
}
if bAd.DiscoverableTimeout, err = strconv.ParseUint(strAdapterDiscoverableTimeout, 10, 64); err != nil {
return err
}
if bAd.Pairable, err = strconv.ParseBool(strAdapterPairable); err != nil {
return err
}
if bAd.PairableTimeout, err = strconv.ParseUint(strAdapterPairableTimeout, 10, 64); err != nil {
return err
}
if bAd.Powered, err = strconv.ParseBool(strAdapterPowered); err != nil {
return err
}
bAd.Name = strAdapterName
bAd.Alias = strAdapterAlias
/*
log.Printf("adapter: %+v\n", bAd)
*/
return
}
func NewBtAdapter() (bAd *BtAdapter, err error) {
bAd = &BtAdapter{
Mutex: &sync.Mutex{},
}
err = bAd.updateMembers()
if err != nil {
return nil, err
}
return
}
type BtAgent struct {
*exec.Cmd
*sync.Mutex //mutex for wpa-supplicant proc
mode BtAgentMode
pinFilePath string
logger *util.TeeLogger
}
func (ba *BtAgent) Start(mode BtAgentMode) (err error) {
log.Printf("Starting bt-agent with mode '%s'...\n", ba.mode)
ba.Lock()
defer ba.Unlock()
ba.mode = mode
//stop if already running
if ba.Cmd != nil {
// avoid deadlock
ba.Unlock()
ba.Stop()
ba.Lock()
}
ba.Cmd = exec.Command("/usr/bin/bt-agent", "-c", string(ba.mode))
ba.Cmd.Stdout = ba.logger.LogWriter
ba.Cmd.Stderr = ba.logger.LogWriter
err = ba.Cmd.Start()
if err != nil {
ba.Cmd.Wait()
return errors.New(fmt.Sprintf("Error starting bt-agent '%v'", err))
}
log.Println("... bt-agent started")
return nil
}
func (ba *BtAgent) Stop() (err error) {
log.Println("Stopping bt-agent...")
ba.Lock()
defer ba.Unlock()
if ba.Cmd == nil {
log.Println("bt-agent already stopped")
}
if ba.Process == nil {
return errors.New("Couldn't access bt-agent process")
}
ba.Process.Kill()
ba.Process.Wait()
if ba.ProcessState == nil {
return errors.New("Couldn't access bt-agent process state")
}
if !ba.ProcessState.Exited() {
return errors.New("bt-agent didn't terminate after SIGKILL")
}
ba.Cmd = nil
return nil
}
func NewBtAgent() (res *BtAgent) {
res = &BtAgent{
Mutex: &sync.Mutex{},
mode: BT_AGENT_MODE_NO_INPUT_NO_OUTPUT,
pinFilePath: "",
logger: util.NewTeeLogger(true),
}
res.logger.SetPrefix("bt-agent: ")
return res
}
func NewBtService() (res *BtService) {
res = &BtService{
Agent: NewBtAgent(),
DevName: bt_dev_name,
Agent: bluetooth.NewDefaultAgent("4321"),
BrName: BT_ETHERNET_BRIDGE_NAME,
PathBtConf: "",
}
if err := res.CheckExternalBinaries(); err != nil {
panic(err)
// ToDo Check if bluetooth service is loaded
if c,err := bluetooth.FindFirstAvailableController(); err == nil {
res.ServiceAvailable = true
res.Controller = c
} else {
res.ServiceAvailable = false
return
}
if err := CheckBluezVersion(); err != nil {
panic(err)
}
// ToDo Check if bluetooth service is loaded
if btAdp, errAd := NewBtAdapter(); errAd != nil {
panic(errAd)
} else {
res.Adapter = btAdp
fmt.Println(err)
res.ServiceAvailable = false
return
}
return
}
// ToDo: Move all controller specific tasks to controller
func (bt *BtService) StartNAP() (err error) {
if !bt.ServiceAvailable { return bluetooth.ErrBtSvcNotAvailable
}
log.Println("Bluetooth: starting NAP...")
// assure bnep module is loaded
if err = CheckBnep(); err != nil {
@@ -343,27 +65,40 @@ func (bt *BtService) StartNAP() (err error) {
log.Println("Bridge exists already")
}
// start bt-agent with "No Input, No Output" capabilities
if err = bt.Agent.Start(BT_AGENT_MODE_NO_INPUT_NO_OUTPUT); err != nil {
// Register custom agent bt-agent with "No Input, No Output" capabilities
if err = bt.Agent.Start(toolz.AGENT_CAP_NO_INPUT_NO_OUTPUT); err != nil {
return err
}
// Disable simple secure pairing to make PIN requests work
bt.Controller.SetPowered(false)
bt.Controller.SetSSP(false)
bt.Controller.SetPowered(true)
// Configure adapter
fmt.Println("Reconfigure adapter to be discoverable and pairable")
bt.Adapter.Alias = "P4wnP1"
bt.Adapter.Discoverable = true
bt.Adapter.DiscoverableTimeout = 0
bt.Adapter.Pairable = true
bt.Adapter.PairableTimeout = 0
if err = bt.Adapter.DeploySate(); err != nil {
return err
} else {
log.Printf("... reconfiguration succeeded: %+v\n", bt.Adapter)
}
err = bt.Controller.SetAlias("P4wnP1")
if err != nil { return }
err = bt.Controller.SetDiscoverableTimeout(0)
if err != nil { return }
err = bt.Controller.SetPairableTimeout(0)
if err != nil { return }
err = bt.Controller.SetDiscoverable(true)
if err != nil { return }
err = bt.Controller.SetPairable(true)
// Enable PAN networking for bridge
nw,err := toolz.NetworkServer(bt.Controller.DBusPath)
if err != nil { return }
//defer nw.Close()
err = nw.Register(toolz.UUID_NETWORK_SERVER_NAP, BT_ETHERNET_BRIDGE_NAME)
if err != nil { return }
return
}
func (bt *BtService) StopNAP() (err error) {
if !bt.ServiceAvailable { return bluetooth.ErrBtSvcNotAvailable }
log.Println("Bluetooth: stopping NAP...")
//Stop bt-agent
@@ -372,6 +107,18 @@ func (bt *BtService) StopNAP() (err error) {
// Delete bridge interface
bt.DisableBridge()
// Unregister pan service
nw,err := toolz.NetworkServer(bt.Controller.DBusPath)
//if err != nil { return }
defer nw.Close()
err = nw.Unregister("pan")
//if err != nil { return }
err = bt.Controller.SetDiscoverable(false)
//if err != nil { return }
err = bt.Controller.SetPairable(false)
//if err != nil { return }
return
}
@@ -437,6 +184,8 @@ func CheckBnep() error {
ToDo: The binaries used (bluez-tools) should be replaced by custom functions interfacing with bluez D-Bus API, later on.
Example: https://github.com/muka/go-bluetooth
*/
/*
func (bt BtService) CheckExternalBinaries() error {
bins := []string{"modprobe", "lsmod", "bt-adapter", "bt-agent", "bt-device", "bt-network", "bluetoothd"}
for _, bin := range bins {
@@ -447,7 +196,10 @@ func (bt BtService) CheckExternalBinaries() error {
}
return nil
}
*/
// ToDo: Get rid of this as soon as an API function is found
// btmgt tool is able to determine Bluez version, mgmt-api is only able to determine Management version (which should be 1.14)
func GetBluezVersion() (major int, minor int, err error) {
eGeneral := errors.New("Couldn't retrieve bluez version")
proc := exec.Command("/usr/sbin/bluetoothd", "-v")

View File

@@ -0,0 +1,172 @@
package bluetooth
import (
"github.com/godbus/dbus"
"net"
//"github.com/mame82/P4wnP1_go/service"
"github.com/mame82/mblue-toolz/btmgmt"
"github.com/mame82/mblue-toolz/dbusHelper"
"github.com/mame82/mblue-toolz/toolz"
"github.com/pkg/errors"
)
/*
This code assumes that the first bluetooth controller never gets detached,
as it should be the case for a Pi Zero W. It doesn't account for plug&play Bluetooth controllers.
Attaching an additional controller (f.e. USB) could lead to errors, which aren't handled by this code.
*/
type Controller struct {
DBusPath dbus.ObjectPath // The path of the controller, used by DBus (f.e. 'hci0')
Index uint16 // The index of the controller, when "Bluetooth Management Socket" is used (mgmt-api)
adapter *toolz.Adapter1
}
func (c *Controller) SetSSP(val bool) (err error) {
mgmt,err := btmgmt.NewBtMgmt()
if err != nil { return ErrChgSetting }
s,err := mgmt.SetSecureSimplePairing(c.Index, val)
if err != nil || s.SecureSimplePairing != val {
return ErrChgSetting
}
return
}
func (c *Controller) StartDiscovery() error {
return c.adapter.StartDiscovery()
}
func (c *Controller) StopDiscovery() error {
return c.adapter.StopDiscovery()
}
/* Properties */
func (c *Controller) GetAddress() (res net.HardwareAddr, err error) {
return c.adapter.GetAddress()
}
func (c *Controller) GetAddressType() (res string, err error) {
return c.adapter.GetAddressType()
}
func (c *Controller) GetName() (res string, err error) {
return c.adapter.GetName()
}
func (c *Controller) SetAlias(val string) (err error) {
return c.adapter.SetAlias(val)
}
func (c *Controller) GetAlias() (res string, err error) {
return c.adapter.GetAlias()
}
func (c *Controller) GetClass() (res uint32, err error) {
return c.adapter.GetClass()
}
func (c *Controller) GetPowered() (res bool, err error) {
return c.adapter.GetPowered()
}
func (c *Controller) SetPowered(val bool) (err error) {
return c.adapter.SetPowered(val)
}
func (c *Controller) GetDiscoverable() (res bool, err error) {
return c.adapter.GetDiscoverable()
}
func (c *Controller) SetDiscoverable(val bool) (err error) {
return c.adapter.SetDiscoverable(val)
}
func (c *Controller) GetPairable() (res bool, err error) {
return c.adapter.GetPairable()
}
func (c *Controller) SetPairable(val bool) (err error) {
return c.adapter.SetPairable(val)
}
func (c *Controller) SetDiscoverableTimeout(val uint32) (err error) {
return c.adapter.SetDiscoverableTimeout(val)
}
func (c *Controller) GetDiscoverableTimeout() (res uint32, err error) {
return c.adapter.GetDiscoverableTimeout()
}
func (c *Controller) SetPairableTimeout(val uint32) (err error) {
return c.adapter.SetPairableTimeout(val)
}
func (c *Controller) GetPairableTimeout() (res uint32, err error) {
return c.adapter.GetPairableTimeout()
}
func (c *Controller) GetDiscovering() (res bool, err error) {
return c.adapter.GetDiscovering()
}
func (c *Controller) GetUUIDs() (res []string, err error) {
return c.adapter.GetUUIDs()
}
func (c *Controller) GetModalias() (res string, err error) {
return c.adapter.GetModalias()
}
func FindFirstAvailableController() (ctl *Controller, err error) {
// use btmgmt to fetch first controller index
mgmt,err := btmgmt.NewBtMgmt()
if err != nil { return nil, err }
cil,err := mgmt.ReadControllerIndexList()
if err != nil { return nil, err }
ctl = &Controller{}
if len(cil.Indices) > 0 {
ctl.Index = cil.Indices[0]
} else {
return nil, ErrBtSvcNotAvailable
}
// retrieve additional info for the controller from mgmt-api
ci,err := mgmt.ReadControllerInformation(ctl.Index)
if err != nil { return nil,err }
// grab DBus object path of all available Adapters (=controller) from DBus API
om,err := dbusHelper.NewObjectManager()
defer om.Close()
if err != nil { return nil,err }
pathAdapters,err := om.GetAllObjectsPathOfInterface(toolz.DBusNameAdapter1Interface)
if err != nil { return nil,err }
for _,pathAdapter := range pathAdapters {
// create adapter object
adp,err := toolz.Adapter(pathAdapter)
if err != nil { continue } // skip adapter
hciAdapterAddr,err := adp.GetAddress()
if err != nil {
adp.Close()
continue
} // skip adapter
// compare address of Controller from mmgmt-api with the adapter from adapter-api
if compareHwAddr(hciAdapterAddr, ci.Address.Addr) {
ctl.DBusPath = pathAdapter
ctl.adapter = adp
break // exit for loop
} else {
adp.Close()
}
}
if ctl.adapter == nil {
return nil,errors.New("Found controller via 'bluetooth management socket', but no match on DBus API")
}
return
}

View File

@@ -0,0 +1,115 @@
package bluetooth
import (
"fmt"
"github.com/godbus/dbus"
"github.com/mame82/mblue-toolz/bt_uuid"
"github.com/mame82/mblue-toolz/dbusHelper"
"github.com/mame82/mblue-toolz/toolz"
)
type DefaultAgent struct {
pincode string // only used if Secure Simple Pairing is disabled and currentCap = DISPLAY_ONLY
currentCap toolz.AgentCapability
}
// ------------ START OF AGENT INTERFACE IMPLEMENTATION ------------
func (a *DefaultAgent) RegistrationPath() string {
return toolz.AgentDefaultRegisterPath
}
func (a *DefaultAgent) Release() *dbus.Error {
fmt.Println("DefaultAgent release called")
return nil
}
func (a *DefaultAgent) RequestPinCode(device dbus.ObjectPath) (pincode string, err *dbus.Error) {
fmt.Println("DefaultAgent request pincode called, returning string '12345'")
// Called when SSP is off and currentCap != CAP_NO_INPUT_NO_OUTPUT, we could use a pre-generated PIN
// and the remote device has to enter the same one
return a.pincode, nil
}
func (a *DefaultAgent) DisplayPinCode(device dbus.ObjectPath, pincode string) *dbus.Error {
fmt.Printf("DefaultAgent display pincode called, code: '%s'\n", pincode)
return nil
}
func (a *DefaultAgent) RequestPasskey(device dbus.ObjectPath) (passkey uint32, err *dbus.Error) {
fmt.Println("DefaultAgent request passkey called, returning integer 1337")
// Called with SSP on and Cap == AGENT_CAP_KEYBOARD_ONLY
// The needed passkey is random, we can't know the correct return value upfront (in contrast to a PIN
// which has to be entered on both devices and match)
return 1337, nil
}
func (a *DefaultAgent) DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint16) *dbus.Error {
fmt.Printf("DefaultAgent display passkey called, passkey: %d\n", passkey)
return nil
}
func (a *DefaultAgent) RequestConfirmation(device dbus.ObjectPath, passkey uint32) *dbus.Error {
fmt.Printf("DefaultAgent request confirmation called for passkey: %d\n", passkey)
// Called when SSP on and
// currentCap == AGENT_CAP_DISPLAY_ONLY ||
// currentCap == AGENT_CAP_KEYBOARD_DISPLAY ||
// currentCap == AGENT_CAP_DISPLAY_YES_NO
fmt.Println("... rejecting passkey")
return toolz.ErrRejected
}
func (a *DefaultAgent) RequestAuthorization(device dbus.ObjectPath) *dbus.Error {
fmt.Println("DefaultAgent request authorization called")
fmt.Println("... rejecting")
return toolz.ErrRejected
}
func (a *DefaultAgent) AuthorizeService(device dbus.ObjectPath, uuid string) *dbus.Error {
devStr,_ := dbusHelper.DBusDevPathToHwAddr(device) // ignore error
/*
// alternate way to retrieve the device address (and call functions of the device)
if d,e := toolz.Device(device); e == nil {
addr,_ := d.GetAddress()
fmt.Println(addr)
}
*/
fmt.Printf("DefaultAgent authorize service called for UUID: %s from %s\n", uuid, devStr)
switch uuid {
case bt_uuid.BNEP_SVC_UUID:
fmt.Println("... granting BNEP access")
return nil
default:
fmt.Println("... rejecting")
return toolz.ErrRejected
}
return toolz.ErrRejected
}
func (a *DefaultAgent) Cancel() *dbus.Error {
fmt.Println("DefaultAgent cancel called")
return nil
}
// ------------ END OF AGENT INTERFACE IMPLEMENTATION ------------
func (a *DefaultAgent) Start(cap toolz.AgentCapability) (err error) {
a.currentCap = cap
return toolz.RegisterDefaultAgent(a, cap)
}
func (a *DefaultAgent) Stop() (err error) {
return toolz.UnregisterAgent(a.RegistrationPath())
}
func (a *DefaultAgent) SetPIN(pin string) {
a.pincode = pin
}
func NewDefaultAgent(pincode string) (res *DefaultAgent) {
return &DefaultAgent{
pincode: pincode,
currentCap: toolz.AGENT_CAP_NO_INPUT_NO_OUTPUT,
}
}

View File

@@ -0,0 +1,10 @@
package bluetooth
import "errors"
var (
ErrBtSvcNotAvailable = errors.New("No bluetooth available")
ErrBtNoMgmt = errors.New("Couldn't access bluetooth mgmt-api")
ErrChgSetting = errors.New("Couldn't change controller setting to intended value")
)

10
service/bluetooth/util.go Normal file
View File

@@ -0,0 +1,10 @@
package bluetooth
import "net"
func compareHwAddr(a net.HardwareAddr, b net.HardwareAddr) bool {
for idx,_ := range a {
if a[idx] != b[idx] { return false }
}
return true
}

View File

@@ -17,6 +17,7 @@ type GlobalServiceState struct {
StoredNetworkSettings map[string]*pb.EthernetInterfaceSettings
// Wifi *WifiState
WifiSvc *WiFiService
BtSvc *BtService
}
func InitGlobalServiceState() (err error) {
@@ -44,7 +45,14 @@ func InitGlobalServiceState() (err error) {
IpAddress4: "172.24.0.1",
Netmask4: "255.255.255.0",
}
// state.Wifi = NewWifiState(GetDefaultWiFiSettings(), wifi_if_name)
state.StoredNetworkSettings[BT_ETHERNET_BRIDGE_NAME] = &pb.EthernetInterfaceSettings{
Name: BT_ETHERNET_BRIDGE_NAME,
Enabled: true,
Mode: pb.EthernetInterfaceSettings_MANUAL,
IpAddress4: "172.26.0.1",
Netmask4: "255.255.255.0",
}
state.WifiSvc = NewWifiService()
@@ -52,10 +60,14 @@ func InitGlobalServiceState() (err error) {
state.EvMgr = NewEventManager(20)
state.UsbGM,err = NewUSBGadgetManager()
if err != nil { return }
state.BtSvc = NewBtService()
ledState, err := NewLed(false)
if err != nil { return }
state.Led = ledState
return nil
}
@@ -70,6 +82,8 @@ func (state *GlobalServiceState) GetInterfaceSettingsByInterfaceName(ifname stri
func (state *GlobalServiceState) StartService() {
state.EvMgr.Start()
// ToDo: Remove this, till the service is able to deploy startup settings
state.BtSvc.StartNAP()
}
func (state *GlobalServiceState) StopService() {