3

I need to make an application that communicates through an RFCOMM socket to a Raspberry Pi, without pairing. On the Android side, I have the MAC address of the RPi and I'm trying to connect to the server using this code:

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
BluetoothSocket mmSocket = null;

    try {
        mmSocket = device.createRfcommSocketToServiceRecord(UUID);
        mmSocket.connect();
        Log.d(TAG, "mmSocket returned");
    }
    ...

UUID is the same as on the server-side, and i've also tried using the createInsecureRfcommSocket method.

On the Raspberry Pi side, I used the pybluez example of an rfcomm server(here is the example)

It once worked but I don't understand why it did or why it doesn't anymore, in the sense that when I tried to initiate the connection from the phone I got a pairing request on the Raspberry Pi without a pairing request on the phone, and the socket object on android had successfully connected.

Does anyone know what I am doing wrong, or any ideas that might help me, and is such a thing even feasible. Thanks in advance.

Daniel Selvan
  • 959
  • 10
  • 23
user3808318
  • 827
  • 1
  • 8
  • 15

1 Answers1

0

I've found this unanswered question and I think I have a working solution at least for my case.

All I needed to do was to call these three commands:

sudo hciconfig hci0 piscan 
sudo hciconfig hci0 sspmode 1
sudo hciconfig hci0 class 0x400100

The first two lines make the RPi discoverable, from this answer, which also claims the RPi should pair automatically. That does NOT work for me. It still requires PIN confirmation on both devices, that's unfortunate for a headless RPi.

The third line found in this answer is crucial and it is what allows to connect RFCOMM sockets to unpaired RPi. It is possible that changing class will make other BT services stop working, not sure, I just need RFCOMM.

After this, the following example works for me with RPI 4B and my Win10 laptop:

import socket
from contextlib import closing

# MAC address of RPi, can be obtained with `bluetoothctl list` on RPi.
rpi_addr =  'e4:5f:01:7d:8A:A3' 
# 1-32, some might be used already, e.g. 3 for me, in that case bind fails.
channel = 15
def server():

    print("Creating socket")
    with closing(socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, 
    socket.BTPROTO_RFCOMM)) as s:
        print("Binding socket")
        s.bind((rpi_addr ,channel))
        print("Listening socket")
        s.listen()

        s_sock, addr = s.accept()
        with closing(s_sock):
            print ("Accepted connection from "+str(addr))

            data = s_sock.send(b"Hello from RPi")

def client():

    print("Creating socket")
    s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, 
    socket.BTPROTO_RFCOMM)
    print("Connecting socket")
    s.connect((rpi_addr,channel))
    print("Connected")

    data = s.recv(1024)

    print(f"Received {data}")
Quimby
  • 17,735
  • 4
  • 35
  • 55