Bluetooth SPP server in C/C++ for Android based device

  android, bluetooth, c++

I am running android on imx7d from NXP running Bluetooth+Wifi 1MW module.

I want to run a Bluetooth SPP server on the device. I have implemented the software in C++, Basically an RFCOMM socket. I read Android used Bluedroid instead of Bluez like Linux. But I understand the RFCOMM socket creation method is the same(not 100% sure).

I run the C++ based server software on the imx7d device, it doesn’t give any issue creating the RFCOMM SPP port. It creates the port and goes into listening mode. However, when the Android Bluetooth client app running on my phone tries to connect it, It gives the following error in the android bt stack of my imx7d based device.

[INFO:port_utils.cc(329)] port_find_mcb_dlci_port: Cannot find
allocated RFCOMM app port for DLCI 40 on 3c:28:6d:2a:b0:28,
p_mcb=0x90367c24 PORT_ParNegInd dlci:40 mtu:990 2021-11-26
09:04:36.046 583-827/com.android.bluetooth E/bt_stack:
[ERROR:port_rfc.cc(285)] PORT_ParNegInd: Disconnect RFCOMM, port not
found, dlci=40, p_mcb=0x90367c24, bd_addr=3c:28:6d:2a:b0:28

I have created the server port on channel 20, but it’s not able to find it. I am not sure what exactly is going wrong, I am stuck and not able to find the way to move ahead. Here is the code snippet.

#define BTPROTO_RFCOMM 3

/* BD Address */ typedef struct {
    uint8_t b[6]; } __attribute__((packed)) bdaddr_t;

/* ---- RFCOMM sockets ---- */ struct sockaddr_rc {
    sa_family_t rc_family;
    bdaddr_t rc_bdaddr;
    uint8_t rc_channel; };

#define BDADDR_ANY (&(bdaddr_t){{0, 0, 0, 0, 0, 0}})

/* server channel */
#define RFCOMM_SERVER_PORT_NUM 20

void BluetoothSerialPort::openConnection()
    {
        struct sockaddr_rc loc_addr;
        bdaddr_t bdaddr_any = {0, 0, 0, 0, 0, 0};
        ALOGE("Start Bluetooth SPP server...n");

        /* allocate socket */
        sockFd_ = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
        if (sockFd_ < 0)
        {
            ALOGE("Cannot start Bluetooth SPP servern");
        }
        memset(&loc_addr, 0, sizeof(loc_addr));
        loc_addr.rc_family = AF_BLUETOOTH;
        loc_addr.rc_bdaddr = bdaddr_any;
        loc_addr.rc_channel = RFCOMM_SERVER_PORT_NUM;

        if (bind(sockFd_, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0)
        {
            ALOGE("socket bind error %s", strerror(errno));
            exit(EXIT_FAILURE);
        }

        ALOGE("Listen Bluetooth SPP server on %d...n", sockFd_);
        if (listen(sockFd_, 2) < 0)
        {
            ALOGE("socket listen error %s", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

    // Runs the server.
    void BluetoothSerialPort::run()
    {
        struct sockaddr_rc client_addr;
        socklen_t opt = sizeof(client_addr);
        openConnection();
        ALOGE("Listening on Bluetooth SPP server = %d...n", sockFd_);
        /* return new socket for connection with a client */
        clientFd_ = accept(sockFd_, reinterpret_cast<struct sockaddr *>(&client_addr), &opt);
        ALOGE("connected from %sn", (char *)&client_addr.rc_bdaddr);
        if (clientFd_ == -1)
        {
            ALOGE("error accepting incoming connection: %s", strerror(errno));
        }
        else
        {

            ALOGI("got new connection");
        }

        // Create a thread and transfer the new stream to it.
        std::thread thr(std::bind(&BluetoothSerialPort::readHandler, this));
        thr.detach();
    }

Can somebody please help? Is there any mistake in the code, it prints the following line "Listening on Bluetooth SPP server" and goes into listening mode.

Thanks much,
Asma

Source: Windows Questions C++

LEAVE A COMMENT