This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52832 to Linux L2CAP socket?

I'm trying to get an nRF52832 to connect to a Linux host with a BLE adapter.  The Linux host is listening for connections via an L2CAP socket, as in the (simplified) code below:

import bluetooth
import socket

# When the L2CAP layer should discard packets that couldn't be sent
L2CAP_PACKET_TIMEOUT_MS = 100

# Create L2CAP listening socket
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket and accept an incoming connection
s.bind( (socket.BDADDR_ANY, self._port), )
connectionSocket, addr = s.accept()

# Set the L2CAP timeout to a relatively low value
bluetooth.set_packet_timeout(addr[0], L2CAP_PACKET_TIMEOUT_MS)

# Send sample data
connectionSocket.send(b'Testing')
response = connectionSocket.recv()

How can I get the Nordic radio to connect to this?  I'm using SoftDevice S132 7.0.1.

I looked through the examples, but most of the examples that connect to Linux require 6LoWPAN, which we do not want to use.  I also looked through the Nordic Q&A, but the closest answer I found was from several years ago and the response is out-of-date compared to the S132 API now.

Parents
  • Hi,

    I am not familiar with the Linux host api's you are using. But I can mention we have the Object transfer service example, which is using L2CAP:
    Object Transfer Service Server Application

    Object Transfer Service client Example

    This might be useful for you to see how to set up L2CAP with our SD.

  • Those examples, unfortunately, do not work.  They all require scanning for an advertising device before connecting.  Meanwhile, the Linux L2CAP sockets don't seem to advertise or scan at all.

    Here's an even more straightforward example of the Linux side of things:

    import socket
    
    remoteMac = "00:11:22:33:44:55" # remote device's bluetooth MAC address
    port = 4123 # arbitrary port number
    
    isServer = False
    
    s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    if isServer:
        s.bind( (socket.BDADDR_ANY, port) )
        s.listen()
        s.accept()
    else:
        s.connect( (remoteMac, port) )

    When running this with isServer = False and monitoring Bluetooth activity with Wireshark, Wireshark doesn't record any scanning commands or results, instead just an HCI connect command:

    l2cap_socket_connect_attempt.pcapng

    And when running with isServer = True, Wireshark records no Bluetooth activity at all until a remote device initiates a connection.  There are no commands to begin advertising or anything similar.

    So to connect to this from the nrf52832, how do I tell the SoftDevice to initiate a connection to a remote address directly, without scanning for advertisements that don't exist?

Reply
  • Those examples, unfortunately, do not work.  They all require scanning for an advertising device before connecting.  Meanwhile, the Linux L2CAP sockets don't seem to advertise or scan at all.

    Here's an even more straightforward example of the Linux side of things:

    import socket
    
    remoteMac = "00:11:22:33:44:55" # remote device's bluetooth MAC address
    port = 4123 # arbitrary port number
    
    isServer = False
    
    s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    if isServer:
        s.bind( (socket.BDADDR_ANY, port) )
        s.listen()
        s.accept()
    else:
        s.connect( (remoteMac, port) )

    When running this with isServer = False and monitoring Bluetooth activity with Wireshark, Wireshark doesn't record any scanning commands or results, instead just an HCI connect command:

    l2cap_socket_connect_attempt.pcapng

    And when running with isServer = True, Wireshark records no Bluetooth activity at all until a remote device initiates a connection.  There are no commands to begin advertising or anything similar.

    So to connect to this from the nrf52832, how do I tell the SoftDevice to initiate a connection to a remote address directly, without scanning for advertisements that don't exist?

Children
  • Hi,

    If you are talking about using a connectionless channel I think that is only supported in BR/EDR and is used for unicasting. For L2CAP  connection oriented channels, you first need to have an LE ACL  link, then you can configure L2CAP channels on top of that. Meaning it is not possible to setup a L2CAP channel using BTLE without going through the normal advertisement /scanning procedure to create a link.

Related