1
votes

I am trying to implement a BLE UART service where the central can send down a request, the peripheral takes that request and forwards it to a peripheral application to do processing, and then returns a response back to the central. The design is similar to Figure 2 found in https://punchthrough.com/serial-over-ble/

I am having trouble with the last part to return data back to the central.

Below are the tx/rx characteristics I came across to implement the UART

class TxCharacteristic(Characteristic):
    def __init__(self, bus, index, service):
        Characteristic.__init__(self, bus, index, UART_TX_CHARACTERISTIC_UUID,
                                ['notify'], service)
        self.notifying = False
        GLib.io_add_watch(sys.stdin, GLib.IO_IN, self.on_console_input)

    def on_console_input(self, fd, condition):
        s = fd.readline()
        if s.isspace():
            pass
        else:
            self.send_tx(s)
        return True

    def send_tx(self, s):
        if not self.notifying:
            return
        value = []
        for c in s:
            value.append(dbus.Byte(c.encode()))
        self.PropertiesChanged(GATT_CHRC_IFACE, {'Value': value}, [])

    def StartNotify(self):
        if self.notifying:
            return
        self.notifying = True

    def StopNotify(self):
        if not self.notifying:
            return
        self.notifying = False


class RxCharacteristic(Characteristic):
    def __init__(self, bus, index, service):
        Characteristic.__init__(self, bus, index, UART_RX_CHARACTERISTIC_UUID,
                                ['write'], service)

    def WriteValue(self, value, options):
        data = bytearray(value).decode('utf-8')
        print(f'Incoming UART data: {data}')
        handle_request(data)

With a BLE scanner phone app, I can write data to the RxCharacteristic OK and when RxCharacteristic receives it, I call handle_request(data) for processing.

This is where I'm stuck. How do I get a handle or reference the TxCharacteristic so that I can call send_tx()? Is the 'notify' characteristic flag what I want or do I want a 'write' flag?

1
Yep, you want to have notification/read/write permission and notification/read/write property on that Serial data characteristic, remember a CCCD aswell :) Such that you can subscribe to the Serial data characteristic send 0x01 to the characteristic you are interested in, then the characteristic of interest should return 0x00 when the transmission is complete.Sorenp

1 Answers

1
votes

Typically with UART over BLE people use the Notify flag. The central device (phone app) will need to enable notifications so that it gets notified when values change.

Using the Nordic UART Service (NUS) is normally a good example to follow. If you do implement NUS then there are several apps that work with it.

Looking at your code, it looks like the plumbing is there to connect your console to the send_tx method. I suspect that your app isn't doing a StartNotify

It is the icon I've circled in Lime Green in the image below. This is from nRF Connect which is a generic Bluetooth Low Energy scanning and exploration tool.

Apps like Serial Bluetooth Terminal will do StartNotify automatically for NUS

enter image description here