jrowberg / bglib

BGLib implementation for Bluegiga BLE Bluetooth Smart modules
Other
240 stars 170 forks source link

Python shutdown procedure #33

Open pdeboer1987 opened 7 years ago

pdeboer1987 commented 7 years ago

Hi,

To start let me inform you the I'm using BGLib in Python 2.5. It was a straight forward conversion, so I don't expect a problem there.

The Issue:

I don't seem to be able to dispose of the BGLib object and run again. The result is that the first attempt will find a list of nearby devices. The second attempt will timeout and return an empty list having never serviced the ble_evt_gap_scan_response event.

Sorry about the formatting, I can't seem to find the way to show code correctly

import bglib,serial,time

gap_scan_response handler

def evt_find_device(sender, args):
print "evt_find_device" global devices

id = ''
data = args["data"]
if (len(data) >= 1):
    index = 0
    while index < len(data):
        dLen = data[index]
        index+=1
        dType = data[index]
        index+=1
        val = ''.join(['%c' % b for b in args["data"][index:index+dLen-1]]).strip('\0x00')
        mac = ''.join(['%02X' % b for b in args["sender"]]).strip('\0x00')
        index = index+dLen-1
        if dType == 0x08 or dType == 0x09:
            id = val.strip('\0x00')
            devices[mac] = id
    if (not devices.has_key(mac)):
        devices[mac] = id

if name == 'main': timeout = 10

bg = bglib.BGLib()
ser = serial.Serial(port="COM6",baudrate=256000)

global devices

# disconnect if we are connected already
bg.send_command(ser, bg.ble_cmd_connection_disconnect(0))
bg.check_activity(ser, 1)

# stop advertising if we are advertising already
bg.send_command(ser, bg.ble_cmd_gap_set_mode(0, 0))
bg.check_activity(ser, 1)

# stop scanning if we are scanning already
bg.send_command(ser, bg.ble_cmd_gap_end_procedure())
bg.check_activity(ser, 1)

bg.send_command(ser, bg.ble_cmd_gap_set_scan_parameters(0xC8, 0xC8, 1))
bg.check_activity(ser, 1)

devices = {}
bg.ble_evt_gap_scan_response += evt_find_device
# start scanning now
bg.send_command(ser, bg.ble_cmd_gap_discover(1))

tStart = time.time()
while (time.time() - tStart < timeout):
    # check for all incoming data (no timeout, non-blocking)
    bg.check_activity(ser)

    # don't burden the CPU
    time.sleep(0.01)
print devices

#shutdown procedure

# disconnect if we are connected already
bg.send_command(ser, bg.ble_cmd_connection_disconnect(0))
bg.check_activity(ser, 1)

# stop advertising if we are advertising already
bg.send_command(ser, bg.ble_cmd_gap_set_mode(0, 0))
bg.check_activity(ser, 1)

# stop scanning if we are scanning already
bg.send_command(ser, bg.ble_cmd_gap_end_procedure())
bg.check_activity(ser, 1)

#reconnect

#attempt number 2

bg = bglib.BGLib()

# disconnect if we are connected already
bg.send_command(ser, bg.ble_cmd_connection_disconnect(0))
bg.check_activity(ser, 1)

# stop advertising if we are advertising already
bg.send_command(ser, bg.ble_cmd_gap_set_mode(0, 0))
bg.check_activity(ser, 1)

# stop scanning if we are scanning already
bg.send_command(ser, bg.ble_cmd_gap_end_procedure())
bg.check_activity(ser, 1)

bg.send_command(ser, bg.ble_cmd_gap_set_scan_parameters(0xC8, 0xC8, 1))
bg.check_activity(ser, 1)

devices = {}
bg.ble_evt_gap_scan_response += evt_find_device
# start scanning now
bg.send_command(ser, bg.ble_cmd_gap_discover(1))

tStart = time.time()
while (time.time() - tStart < timeout):
    # check for all incoming data (no timeout, non-blocking)
    bg.check_activity(ser)

    # don't burden the CPU
    time.sleep(0.01)
print devices

pdeboer1987 commented 7 years ago

Seems like the Class Attributes:

bgapi_rx_buffer = []
bgapi_rx_expected_length = 0
busy = False
packet_mode = False
debug = False

should be Instance variables in init, otherwise their definition is carried over to the next instance.

The events should be defined in init as well, because if you had two instances, that would be bad news. I tried doing this, but for some reason that breaks the BGAPIEvent property and it doesn't return an event handler anymore.

jrowberg commented 7 years ago

You're probably correct; this was some of the first complex Python code I ever wrote, and coming from C/C++, I didn't know the Pythonic way to differentiate between class variables and instance variables (or that I C-instance-like syntax would result in C-static-like behavior).

I'm not sure about the event properties; I'd have to dig into that. I'm currently pretty occupied with other projects and not likely to be able to investigate and fix this soon myself.

pdeboer1987 commented 7 years ago

I made a branch. I'm not 100% sure it is correct.