B4J Question RPi jBluetooth Error

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
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:
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 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:
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?
 

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
moBT.IsEnabled seems to report false no matter what, even though I can see the device from a scan on another device and the hcitool scan on the Pi CLI shows the other nearby Bluetooth devices.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
It's a "pluggable" USB-BT4LE adapter that is supposed to be compatible with both LE and classic Bluetooth. It seems to work fine in the RPi GUI desktop and tests out okay from the CLI.

Can you suggest a particular make/model of USB Bluetooth dongle that is compatible with your library?
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
A helpful link with all kinds of information on the library, but I could not find any information on which particular adapters have been found to work with the library.

The one I purchased uses a Broadcom BCM20702 chipset (you indicated in your tutorial you used a Broadcom adapter) yet does not function with the library (and it does work fine with everything else on the RPi).

The one recommended by the Robobutler project is a Inateck adapter. What was the make/model of the Bluetooth adapter you used in your tutorial?
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
Mark,

Thank you for your example, I've made some progress. While I did copy the 3 Bluetooth jar files to my additional lib folder per Erel's tutorial, I lacked the following two lines in my main form:
B4X:
#AdditionalJar: bluecove-gpl-2.1.1-SNAPSHOT
#AdditionalJar: bluecove-bluez-2.1.1-SNAPSHOT
Now, when I run it, the bt.IsEnabled reports TRUE after I initialize. However, when I issue the .Listen2 method I get the following error:
B4X:
Program started.
BlueCove version 2.1.1-SNAPSHOT on bluez
javax.bluetooth.ServiceRegistrationException: Can not open SDP session. [2] No such file or directory
 at com.intel.bluetooth.BluetoothStackBlueZ.openSDPSessionImpl(Native Method)
 at com.intel.bluetooth.BluetoothStackBlueZ.getSDPSession(BluetoothStackBlueZ.java:518)
 at com.intel.bluetooth.BluetoothStackBlueZ.registerSDPRecord(BluetoothStackBlueZ.java:543)
 at com.intel.bluetooth.BluetoothStackBlueZ.rfServerOpen(BluetoothStackBlueZ.java:607)
 at com.intel.bluetooth.BluetoothRFCommConnectionNotifier.<init>(BluetoothRFCommConnectionNotifier.java:42)
 at com.intel.bluetooth.MicroeditionConnector.openImpl(MicroeditionConnector.java:377)
 at com.intel.bluetooth.MicroeditionConnector.open(MicroeditionConnector.java:162)
 at javax.microedition.io.Connector.open(Connector.java:83)
 at anywheresoftware.b4j.objects.Bluetooth$3.run(Bluetooth.java:192)
 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)
Have you experienced this issue before?
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
It is a while since I installed my bt adapter, I can't remember if I had to do an update or not. Maybe your bt dongle is not compatible - just a thought. I have not seen this error - sorry. Maybe Erel can shed some light.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
I found that post yesterday and tried it, and after setting the "-C" parameter on the daemon the browse local still failed to work.

I then found an another post on the R-Pi forum describing another person's trouble with this same issue: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=125922 About 2/3 of the way down the post, there was one line:
B4X:
sudo chmod 777 /var/run/sdp
which after I tried I found the browse local command does start working.

After the CHMOD the R-Pi will start listen mode with no errors and the B4A program will also see, and can attempt to connect to the R-Pi. However the B4A program seems to be always reporting "Connection Refused" from the R-Pi. Also, when I issue a "bt.StopListening" on the B4J it throws the following error:
B4X:
java.io.InterruptedIOException: Notifier has been closed; Failed to accept RFCOMM client connection. [9] Bad file descriptor

This is my first attempt at a Linux OS, is there some setting I need to perform to allow any Bluetooth device to connect rather than only previously paired devices?
 
Last edited:
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
Your device does not need to be paired before. I also had problems connecting to a device even though it was paired. When I did discover before, it worked fine.

I would suggest you try a discover, select device and pair system. The pairing code will be requested as usual. Worked for me.

I don't remember where I found the code in the forum but you can take all the subs and code from here:

https://www.b4x.com/android/forum/threads/solved-brainboxes-bl-819-rs232-to-bluetooth.62662/#content

Hope it helps.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
Do you mean discovering on the Pi or from the Android? Discovering on the Pi is not helpful in my case. The scenario that is being developed is using a R-Pi box that is the driving part of a "remote display terminal" that can be hung on a wall by the client (there will be no keyboard/mouse available). Once installed, the device will connect (via WiFi) to their network and then query and display queue information from their database.

For this to work, the device will need to be initially configured for their WiFi and display options once it gets there -- this means the Android phone app must be able to discover and then connect to the Pi (via Bluetooth) so it can talk to the B4j app on the Pi box and setup the network credentials (the installation locations will have no hard-wire connections available).

I can discover the Pi box just fine, but all I get from the Pi box when I attempt to connect is Connection Refused on the Android and nothing at all on the Pi box. Once I issue a bt.StopListening on the Pi box THEN it will fire a "_Connected" event with Success=False and the error I quoted above.
 
Last edited:
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
Do you mean discovering on the Pi or from the Android?

I meant from the Android device.

I can discover the Pi box just fine, but all I get from the Pi box when I attempt to connect is Connection Refused on the Android and nothing at all on the Pi box.

This sounds exactly like the problems I was having with my RPi, Android tablet and the Brainbox BL-819. Rpi connects without problems to the Brainbox. Tablet to the RPi but tablet to Brainbox refused. It would seem that bluetooth is not bluetooth!

Just another thought, if I read your code properly, you are connecting with prefix mode. I tried that with the RPi and it refused always. I could only get a non-prefix connection.

Sorry I cannot help you further.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
Just another thought, if I read your code properly, you are connecting with prefix mode. I tried that with the RPi and it refused always. I could only get a non-prefix connection.
This is a moot point at this time, as I cannot get a successful connection event to occur.

Sorry I cannot help you further.
You've been a tremendous help in pointing me in the right direction, thanks again for all your time and attention.
 
Upvote 0
Top