Adam-Langley / pybleno

A direct port of the Bleno bluetooth LE peripheral role library to Python2/3
MIT License
68 stars 34 forks source link

onUnsubscribe not called on disconnect #49

Open sepapple opened 4 years ago

sepapple commented 4 years ago

When BLE connect disconnected, onUnsubscribe not called in Python3. I use Raspberry pi 4 as peripheral, Android as central.

Below is the peripheral code:

from pybleno import 
import time
import struct
import random

bleno = Bleno()

NAME = 'Raspberry-pi'
APPROACH_SERVICE_UUID = '19B10010-E8F2-537E-4F6C-D104768A1214'
NOTIFY_CHARACTERISTIC_UUID = '19B10012-E8F2-537E-4F6C-D104768A1214'

Raspberry_ID = 10

class NotifyCharacteristic(Characteristic):

    def __init__(self):
        Characteristic.__init__(self, {
            'uuid': NOTIFY_CHARACTERISTIC_UUID,
            'properties': ['notify','write'],
            'value': None
        })

        self._value = 0
        self._updateValueCallback = None

    def onWriteRequest(self,data,offset,withoutResponse,callback):
        print('NotifyCharacteristic - onWriteRequest')
        self._value = data
        ret = data.decode('utf-8')
        print("AndroidID: "+str(ret))
        callback(Characteristic.RESULT_SUCCESS)

    def onSubscribe(self, maxValueSize, updateValueCallback):
        global connection_ID
        print('NotifyCharacteristic - onSubscribe')
        connection_ID = round(random.random()*1000000000)
        self._updateValueCallback = updateValueCallback

    def onUnsubscribe(self):
        print('NotifyCharacteristic - onUnsubscribe')

        self._updateValueCallback = None

def onStateChange(state):
    print('on -> stateChange: ' + state)

    if (state == 'poweredOn'):
        bleno.startAdvertising(NAME, [APPROACH_SERVICE_UUID])
    else:
        bleno.stopAdvertising()

bleno.on('stateChange', onStateChange)

notifyCharacteristic = NotifyCharacteristic()

def onAdvertisingStart(error):
    print('on -> advertisingStart: ' + ('error ' + error if error else 'success'))

    if not error:
        bleno.setServices([
            BlenoPrimaryService({
                'uuid': APPROACH_SERVICE_UUID,
                'characteristics': [
                    notifyCharacteristic
                ]
            })
        ])

bleno.on('advertisingStart', onAdvertisingStart)

bleno.start()

def task():
    global raspberry_ID
    if notifyCharacteristic._updateValueCallback:
        temp = str(raspberry_ID) +','+ str(connection_ID)
        print('Sending notification with value : ' + str(temp))
        notificationBytes = str(temp).encode()
        notifyCharacteristic._updateValueCallback(notificationBytes)

while True:
    task()
    time.sleep(1)