I'm trying to create a simple Bluetooth server as a prototype on a Raspberry Pi board (GUI app). I've gotten the Bluetooth dongle installed and working (and visible in a BT Scan from my Android phone).
In my test program, after I issue the .Listen2(UUID) method, first the _Connected event fires with a "Success" value of false (I don't see why it should be firing at all), then I see the following message in the log:
The app continues to run and I can still see it as a discoverable device. I haven't tried writing a B4A app to connect to it yet, I wanted to understand what was happening here before I moved on.
The server code I've created as a class and it's pretty basic:
Is this a problem with the Pi or am I doing something incorrectly?
In my test program, after I issue the .Listen2(UUID) method, first the _Connected event fires with a "Success" value of false (I don't see why it should be firing at all), then I see the following message in the log:
B4X:
Program started.
---- before listen command ----
---- after Listen2 command ----
java.lang.NullPointerException
at anywheresoftware.b4j.objects.Bluetooth$3.run(Bluetooth.java:183)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
The server code I've created as a class and it's pretty basic:
B4X:
Sub Class_Globals
Private moCaller As Object
Private msBaseEvent As String
Private moBT As Bluetooth
Private const UUID As String = "2f19f11d-952c-4b7e-9b13-d794c1ee896a" 'random UUID for this test
Private moClient As BluetoothConnection
Private moStream As AsyncStreams
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(CallingObject As Object, BaseEvent As String)
moCaller = CallingObject
If BaseEvent <> "" Then
msBaseEvent = BaseEvent & "_"
End If
moBT.Initialize("BT")
End Sub
Public Sub IsEnabled As Boolean
Return moBT.IsEnabled
End Sub
Public Sub StartServer
' make sure the Pi is discoverable via shell command
Dim poSh As Shell
poSh.Initialize("MakeDisc", "sudo", Array As String("hciconfig", "hci0", "piscan"))
poSh.WorkingDirectory = File.DirApp
poSh.Run(30000) ' 30 second timeout
End Sub
Public Sub StopServer
moBT.StopListening
End Sub
Public Sub DisconnectClient
If moStream.IsInitialized Then
moStream.Close
End If
Try
moClient.Disconnect
Catch
Log("clsBTServer - error disconnecting client: " & LastException)
End Try
If SubExists(moCaller, msBaseEvent & "ClientDisconnected") Then
CallSubDelayed(moCaller, msBaseEvent & "ClientDisconnected")
End If
End Sub
Public Sub SendToClient(Data As String)
If moStream.IsInitialized Then
moStream.Write(Data.GetBytes("UTF8"))
End If
End Sub
Private Sub BT_Connected (Success As Boolean, Connection As BluetoothConnection)
If Success Then
moClient = Connection
' open async conection
moStream.InitializePrefix(moClient.InputStream, True, moClient.OutputStream, "AStreams")
If SubExists(moCaller, msBaseEvent & "ClientConnected") Then
CallSubDelayed2(moCaller, msBaseEvent & "ClientConnected", moClient)
End If
Else
If SubExists(moCaller, msBaseEvent & "Error") Then
CallSubDelayed2(moCaller, msBaseEvent & "Error", "Client failed to connect.")
End If
End If
End Sub
Private Sub MakeDisc_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
Dim psResp As String = ""
If Not(Success) Then
psResp = StdErr
Else
Log("---- before listen command ----")
moBT.Listen2(UUID)
Log("---- after Listen2 command ----")
psResp = "Listening with UUID [" & UUID & "]"
End If
If SubExists(moCaller, msBaseEvent & "StartServer") Then
CallSubDelayed3(moCaller, msBaseEvent & "StartServer", Success, psResp)
End If
End Sub
Private Sub AStreams_NewData (Buffer() As Byte)
Dim psMsg As String
psMsg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
If psMsg.Length > 2 Then
ParseCommand(psMsg)
End If
End Sub
' Raised when the client has terminted the connection
Private Sub AStreams_Terminated
DisconnectClient
End Sub
Private Sub AStreams_Error
DisconnectClient
End Sub
Private Sub ParseCommand(Cmd As String)
Select Case Cmd.SubString2(0, 4).Trim.ToLowerCase
Case "ack:"
SendToClient("ACK:OK")
Case Else
SendToClient("ERR:001")
End Select
End Sub
Is this a problem with the Pi or am I doing something incorrectly?