From cbb49f5f78b6a94ff76d487285e8705a8595618e Mon Sep 17 00:00:00 2001 From: cuu Date: Thu, 7 Feb 2019 18:59:02 +0800 Subject: [PATCH] add bluetooth basic pairing and spanish --- Menu/GameShell/10_Settings/Bluetooth/agent.go | 265 ++++++++++++++++++ .../10_Settings/Bluetooth/bluetooth_page.go | 58 +++- .../10_Settings/Bluetooth/plugin_init.go | 28 +- Menu/GameShell/10_Settings/Wifi/wifi.go | 6 +- sysgo/langs/05_Spanish.ini | 107 +++++++ 5 files changed, 453 insertions(+), 11 deletions(-) create mode 100644 Menu/GameShell/10_Settings/Bluetooth/agent.go create mode 100644 sysgo/langs/05_Spanish.ini diff --git a/Menu/GameShell/10_Settings/Bluetooth/agent.go b/Menu/GameShell/10_Settings/Bluetooth/agent.go new file mode 100644 index 0000000..d5a7580 --- /dev/null +++ b/Menu/GameShell/10_Settings/Bluetooth/agent.go @@ -0,0 +1,265 @@ +package Bluetooth + +import ( + "fmt" + //"os" + //"log" + "strings" + + //"github.com/fatih/structs" + /* + "github.com/veandco/go-sdl2/ttf" + "github.com/cuu/gogame/draw" + "github.com/cuu/gogame/surface" + "github.com/cuu/gogame/rect" + + "github.com/cuu/gogame/color" + "github.com/cuu/gogame/font" + */ + "github.com/cuu/gogame/time" + "github.com/cuu/gogame/event" + "github.com/godbus/dbus" + "github.com/muka/go-bluetooth/api" + //"github.com/muka/go-bluetooth/bluez" + "github.com/muka/go-bluetooth/bluez/profile" + + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" +) + +func set_trusted(path string) { + devices ,err := api.GetDevices() + if err != nil { + fmt.Println(err) + return + } + + for i,v := range devices { + fmt.Println(i, v.Path) + if strings.Contains(v.Path,path) { + fmt.Println("Found device") + dev1,_ := v.GetClient() + err:=dev1.SetProperty("Trusted",true) + if err != nil { + fmt.Println(err) + } + } + } +} + + +type Agent struct{ + BusName string + AgentInterface string + AgentPath string + Leader *BluetoothPlugin +} + +func (self *Agent) Release() *dbus.Error { + return nil +} + +func (self *Agent) RequestPinCode(device dbus.ObjectPath) (pincode string, err *dbus.Error) { + fmt.Println("RequestPinCode",device) + set_trusted(string(device)) + return "0000",nil +} + +func (self *Agent) DisplayPinCode(device dbus.ObjectPath, pincode string) *dbus.Error { + fmt.Println( fmt.Sprintf("DisplayPinCode (%s, %s)" ,device, pincode)) + self.Leader.PairPage.ShowPinCode(string(device),pincode) + return nil +} + +func (self *Agent) RequestPasskey(device dbus.ObjectPath) (passkey uint32, err *dbus.Error) { + set_trusted(string(device)) + return 0,nil +} + +func (self *Agent) DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint16) *dbus.Error { + fmt.Println(fmt.Sprintf("DisplayPasskey %s, %06u entered %u" ,device, passkey, entered)) + self.Leader.PairPage.ShowPassKey(string(device),passkey,entered) + return nil +} + + +func (self *Agent) RequestConfirmation(device dbus.ObjectPath, passkey uint32) *dbus.Error { + fmt.Println(fmt.Sprintf("RequestConfirmation (%s, %06d)", device, passkey)) + set_trusted(string(device)) + return nil +} + + +func (self *Agent) RequestAuthorization(device dbus.ObjectPath) *dbus.Error { + fmt.Printf("RequestAuthorization (%s)\n" ,device) + return nil +} + +func (self *Agent) AuthorizeService(device dbus.ObjectPath, uuid string) *dbus.Error { + fmt.Printf("AuthorizeService (%s, %s)",device, uuid) //directly authrized + return nil +} + +func (self *Agent) Cancel() *dbus.Error { + fmt.Println("Cancel") + return nil +} + +func (self *Agent) RegistrationPath() string { + return self.AgentPath +} + +func (self *Agent) InterfacePath() string { + return self.AgentInterface +} + +func RegisterAgent(agent profile.Agent1Interface, caps string) (err error) { + //agent_path := AgentDefaultRegisterPath // we use the default path + agent_path := agent.RegistrationPath() // we use the default path + fmt.Println("The Agent Path: ", agent_path) + // Register agent + am := profile.NewAgentManager1(agent_path) + + // Export the Go interface to DBus + err = am.ExportGoAgentToDBus(agent) + if err != nil { return err } + + // Register the exported interface as application agent via AgenManager API + err = am.RegisterAgent(agent_path, caps) + if err != nil { return err } + + // Set the new application agent as Default Agent + err = am.RequestDefaultAgent(agent_path) + if err != nil { return err } + + return +} + +type BleAgentPairPage struct { + UI.Page + + Pin string + Pass string + DevObj *api.Device + Leader *BluetoothPlugin +} + +func NewBleAgentPairPage() *BleAgentPairPage { + p := &BleAgentPairPage{} + p.PageIconMargin = 20 + p.SelectedIconTopOffset = 20 + p.EasingDur = 10 + + p.Align = UI.ALIGN["SLeft"] + + p.FootMsg = [5]string{"Nav.","","","Back",""} + + return p +} + +func (self *BleAgentPairPage) Init() { + self.PosX = self.Index * self.Screen.Width + self.Width = self.Screen.Width + self.Height = self.Screen.Height + + self.CanvasHWND = self.Screen.CanvasHWND + +} + +func (self *BleAgentPairPage) ShowPinCode(device string,pincode string) { + fmt.Println( fmt.Sprintf("ShowPinCode %s %d" ,device,pincode)) + if self.Screen.CurPage() != self { + self.Screen.PushPage(self) + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + } + + self.Pin = pincode + txt := self.Pin + if len(self.Pin) > 0 { + txt = fmt.Sprintf("Pin code: %s",self.Pin) + } + + self.Screen.MsgBox.SetText(txt) + self.Screen.MsgBox.Draw() + self.Screen.SwapAndShow() +} + +func (self *BleAgentPairPage) ShowPassKey(device string,passkey uint32,entered uint16) { + fmt.Println(fmt.Sprintf("ShowPassKey %06d %d",passkey,entered) ) + if self.Screen.CurPage() != self { + self.Screen.PushPage(self) + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + } + + self.Pass = fmt.Sprintf("%06d",passkey) + txt := self.Pass + if len(self.Pass) > 0 { + txt = fmt.Sprintf("Pair code: %s",self.Pass) + } + + self.Screen.MsgBox.SetText(txt) + self.Screen.MsgBox.Draw() + self.Screen.SwapAndShow() + +} + +func (self *BleAgentPairPage) PairOKCb() { + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + + self.Screen.MsgBox.SetText("Device paired") + self.Screen.MsgBox.Draw() + self.Screen.SwapAndShow() + + time.BlockDelay(1500) + + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + self.Screen.FootBar.ResetNavText() + +} + +func (self *BleAgentPairPage) PairErrorCb( err_msg string) { + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + + self.Screen.MsgBox.SetText(err_msg) + self.Screen.MsgBox.Draw() + self.Screen.SwapAndShow() + + time.BlockDelay(1500) + + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + self.Screen.FootBar.ResetNavText() + +} + +func (self *BleAgentPairPage) KeyDown(ev *event.Event) { + + if ev.Data["Key"] == UI.CurKeys["A"] || ev.Data["Key"] == UI.CurKeys["Menu"] { + if self.DevObj != nil { + c, err := self.DevObj.GetClient() + if err != nil { + fmt.Println(err) + return + } + c.CancelPairing() + } + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + } +} + +func (self *BleAgentPairPage) Draw() { +// DoNothing +} + diff --git a/Menu/GameShell/10_Settings/Bluetooth/bluetooth_page.go b/Menu/GameShell/10_Settings/Bluetooth/bluetooth_page.go index 50f2d3e..96b5d19 100644 --- a/Menu/GameShell/10_Settings/Bluetooth/bluetooth_page.go +++ b/Menu/GameShell/10_Settings/Bluetooth/bluetooth_page.go @@ -5,6 +5,7 @@ import ( "os" "log" "strings" + "errors" "github.com/fatih/structs" "github.com/veandco/go-sdl2/ttf" @@ -17,6 +18,7 @@ import ( "github.com/cuu/gogame/color" "github.com/cuu/gogame/font" + "github.com/godbus/dbus" bleapi "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile" @@ -499,7 +501,8 @@ type BluetoothPage struct{ ADAPTER_DEV string // == adapterID Offline bool - + + Leader *BluetoothPlugin } func NewBluetoothPage() *BluetoothPage { @@ -596,11 +599,50 @@ func (self *BluetoothPage) TryConnect() { self.Screen.FootBar.UpdateNavText("Connecting") self.ShowBox("Connecting") - cur_li.(*NetItem).Device.Connect() + self.Leader.PairPage.DevObj = cur_li.(*NetItem).Device + + err := cur_li.(*NetItem).Device.Pair() + if err != nil { + fmt.Println(err) + err_msg := "" + s := err.Error() + err_msg = "Pair error" + if strings.Contains(s,"ConnectionAttemptFailed") { + err_msg = "Page Timeout" + } + if strings.Contains(s,"NoReply") { + err_msg = "NoReply,Cancelling" + dev1,_ := cur_li.(*NetItem).Device.GetClient() + dev1.CancelPairing() + + } + if strings.Contains(s,"Exists") { + err_msg = "Already Exists" + adapter,err := bleapi.GetAdapter(adapterID) + if err == nil { + err = adapter.RemoveDevice(cur_li.(*NetItem).Path) + if err != nil { + fmt.Println(err) + } + }else { + fmt.Println(err) + } + } + + self.Leader.PairPage.PairErrorCb( err_msg ) + self.Leader.PairPage.DevObj= nil + + }else{ + self.Leader.PairPage.PairOKCb() + dev1,_ := cur_li.(*NetItem).Device.GetClient() + err = dev1.SetProperty("Trusted",true) + if err != nil { + fmt.Println(err) + } + cur_li.(*NetItem).Device.Connect() + } self.HideBox() - - self.Screen.FootBar.ResetNavText() } @@ -622,11 +664,15 @@ func (self *BluetoothPage) GetDevices() ([]bleapi.Device, error) { objects := manager.GetObjects() var devices = make([]bleapi.Device, 0) + for _, path := range list { - props := (*objects)[path][bluez.Device1Interface] + object, ok := objects.Load(path) + if !ok { + return nil, errors.New("Path " + string(path) + " does not exists.") + } + props := (object.(map[string]map[string]dbus.Variant))[bluez.Device1Interface] dev, err := bleapi.ParseDevice(path, props) if err != nil { - fmt.Println(err) return nil, err } devices = append(devices, *dev) diff --git a/Menu/GameShell/10_Settings/Bluetooth/plugin_init.go b/Menu/GameShell/10_Settings/Bluetooth/plugin_init.go index ae1b1ca..b13c08f 100644 --- a/Menu/GameShell/10_Settings/Bluetooth/plugin_init.go +++ b/Menu/GameShell/10_Settings/Bluetooth/plugin_init.go @@ -8,7 +8,7 @@ import ( "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/emitter" "github.com/muka/go-bluetooth/linux" - + "github.com/muka/go-bluetooth/bluez/profile" /* "github.com/veandco/go-sdl2/ttf" @@ -27,13 +27,27 @@ import ( type BluetoothPlugin struct { UI.Plugin BluetoothPage *BluetoothPage + PairPage *BleAgentPairPage } const ( adapterID = "hci0" + BUS_NAME = "org.bluez" + AGENT_INTERFACE = "org.bluez.Agent1" + AGENT_PATH = "/gameshell/bleagentgo" + ) +func (self *BluetoothPlugin) InitAgent() { + agent := &Agent{} + agent.BusName = BUS_NAME + agent.AgentInterface = AGENT_INTERFACE + agent.AgentPath = AGENT_PATH + agent.Leader = self + RegisterAgent(agent, profile.AGENT_CAP_KEYBOARD_DISPLAY) +} + func (self *BluetoothPlugin) Init( main_screen *UI.MainScreen ) { log.Println("Reset bluetooth device") @@ -45,14 +59,20 @@ func (self *BluetoothPlugin) Init( main_screen *UI.MainScreen ) { os.Exit(1) } - - - self.BluetoothPage = NewBluetoothPage() self.BluetoothPage.SetScreen( main_screen) self.BluetoothPage.SetName("Bluetooth") + self.BluetoothPage.Leader = self self.BluetoothPage.Init() + self.PairPage = NewBleAgentPairPage() + self.PairPage.SetScreen( main_screen) + self.PairPage.SetName("Bluetooth pair") + self.PairPage.Leader = self + self.PairPage.Init() + + self.InitAgent() + err = api.On("discovery", emitter.NewCallback(func(ev emitter.Event) { //discoveryEvent := ev.GetData().(api.DiscoveredDeviceEvent) //dev := discoveryEvent.Device diff --git a/Menu/GameShell/10_Settings/Wifi/wifi.go b/Menu/GameShell/10_Settings/Wifi/wifi.go index 2c1a252..c40fab7 100644 --- a/Menu/GameShell/10_Settings/Wifi/wifi.go +++ b/Menu/GameShell/10_Settings/Wifi/wifi.go @@ -546,11 +546,15 @@ func (self *WifiList) DbusDaemonStatusChangedSig(body []interface{}) { fmt.Println(state," ", info) } + if self.Screen.CurPage() != self { + return + } + var info_str []string for _,v := range info { info_str = append(info_str, v.String()) } - + self.UpdateNetList(state,info_str,false,false) if len(info_str) > 0 { self.Screen.Draw() diff --git a/sysgo/langs/05_Spanish.ini b/sysgo/langs/05_Spanish.ini new file mode 100644 index 0000000..9fd5c71 --- /dev/null +++ b/sysgo/langs/05_Spanish.ini @@ -0,0 +1,107 @@ +[Langs] +Settings=Opciones +Retro Games=Juegos Retro +Music Player=Música +TinyCloud=TinyCloud +PowerOFF=Apagar +Reload UI=Recargar UI +freeDM=freeDM +CaveStory=CaveStory +RetroArch=RetroArch +Launching=Cargando.... +Nav=Nav +Scan=Buscar +Back=Volver +Enter=Entrar +Remove=Borrar +Backspace=Borrar +Done=Hecho +Run=Lanzar +AddToPlayList=Añadir a lista +Add to Playlist=Añadir a lista +DownloadConfirm=Confirmar descarga +MyFavGames=mis juegos favoritos +Deleting=Borrando... +AddFav=Añadir favorito +ADdFavList=Añadir a favoritos +Del=Borrar +Please upload data over Wi-Fi=Carga datos por Wi-Fi +ConfirmDeleteQ=¿Confirmar borrado? +AlreadyExisted=Ya existía +Cancel=Cancelar +Yes=Sí +ConfirmQ=¿Confirmar? +Disconnecting=Desconectando... +ConfirmUpdateToFQ=¿Confirmar actualización al %%s ? +UpdateToFQ=¿Actualizar al %%s ? +SetupGameEngineAutoQ=¿Quieres configurar autom. este motor de juego? +Downloading=Descargando... +BATOver5Pct=La batería debe ser superior al 5%% +DeleteConfirm=Confirmar borrado +FavouriteGames=Juegos favoritos +ConfirmForgetQ=¿Confirmar olvidar? +ConfirmForget=Confirmar olvidar +Disconnect=Desconectar +ConfirmDisconnectQ=¿Confirmar desconectar ? +Confirm Disconnect=Confirmar desconectar +Forget=Olvidar +Forgeting=Olvidando... +Info=Info +TryConnect=Intentar conectar +Bluetooth Info=Info Bluetooth +Connecting=Conectando +BluetoothScanning=Escaneando BT... +Scanning=Escaneando.. +ShutDownConnecting=Terminando conectar... +Select=Seleccionar +Detail=Detalle +Applying=Aplicando... +DownloadFailed=Descarga fallida +LauncherIsUpToDate=Lanzador ya actualizado +CheckWifiConnection=Comprueba tu conexión Wi-Fi +TurningOn=Encendiendo +TurningOff=Apagando +Invalid=Inválido +CheckingUpdate=Comprobando actualizaciones... +CheckingUpdateFailed=Fallo al comprobar +Update=Actualizar +Toggle=Alternar +Rescue=Rescatar +Airplane Mode=Modo avión +minutes=minutos +seconds=segundos +second=segundo +minute=Nunca +Never=Never +Power Options=Opciones de energía +Languages=Idiomas +Notify=Notificar +Setting List=Lista de opciones +Wi-Fi=Wi-Fi +Bluetooth=Bluetooth +Sound Volume=Volumen de sonido +Sound Volume=Volumen de sonido +Brightness=Brillo +BackLight Brightness=Brillo de pantalla +Storage=Almacenamiento +Timezone=Zona horaria +Timezone Selection=Seleccionar zona horaria +Notification=Notificaciones +About=Acerca de +Power off=Apagar +Buttons Layout=Disposición de botones +UpdateRetroArch=Actualizar RetroArch +Wifi scanning=Buscando Wifi... +Power option detail=Detalle opciones energía +Screen dimming=Oscurecer pantalla +Screen OFF=Apagar pantalla +Power OFF=Apagar +Power saving=Ahorro energía +Balanced=Equilibrado +Server=Servidor +Performance=Rendimiendo +Confirm Power OFF?=¿Confirmar apagado? +Reboot=Reiniciar +Shutdown=Apagar +my favorite music=mi música favorita +Check Update=Comp. Actualizaciones