Skip to content

Commit

Permalink
Enable running unit tests against Python 3.5 and fix issues identified.
Browse files Browse the repository at this point in the history
  • Loading branch information
peplin committed Sep 10, 2016
1 parent d72f2e7 commit ad5767e
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: python
sudo: false
python:
- '2.7'
- '3.5'
cache:
directories:
- "$HOME/.cache/pip"
Expand Down
40 changes: 21 additions & 19 deletions pygatt/backends/bgapi/bgapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@


def bgapi_address_to_hex(address):
address = hexlify(bytearray(list(reversed(address)))).upper()
address = hexlify(bytearray(
list(reversed(address)))).upper().decode('ascii')
return ':'.join(''.join(pair) for pair in zip(*[iter(address)] * 2))


Expand Down Expand Up @@ -223,7 +224,7 @@ def clear_bond(self, address=None):
self.expect(ResponsePacketType.sm_delete_bonding)

def scan(self, timeout=10, scan_interval=75, scan_window=50, active=True,
discover_mode=constants.gap_discover_mode['observation']):
discover_mode=constants.gap_discover_mode['observation'], **kwargs):
"""
Perform a scan to discover BLE devices.
Expand Down Expand Up @@ -257,7 +258,7 @@ def scan(self, timeout=10, scan_interval=75, scan_window=50, active=True,
self.expect(ResponsePacketType.gap_end_procedure)

devices = []
for address, info in self._devices_discovered.iteritems():
for address, info in self._devices_discovered.items():
devices.append({
'address': address,
'name': info.name,
Expand Down Expand Up @@ -322,7 +323,9 @@ def connect(self, address, timeout=5,
log.info("Connected to %s", address)
return device
except ExpectedResponseTimeout:
raise NotConnectedError()
exc = NotConnectedError()
exc.__cause__ = None
raise exc

def discover_characteristics(self, connection_handle):
att_handle_start = 0x0001 # first valid handle
Expand All @@ -338,11 +341,11 @@ def discover_characteristics(self, connection_handle):
timeout=10)

for char_uuid_str, char_obj in (
self._characteristics[connection_handle].iteritems()):
self._characteristics[connection_handle].items()):
log.info("Characteristic 0x%s is handle 0x%x",
char_uuid_str, char_obj.handle)
for desc_uuid_str, desc_handle in (
char_obj.descriptors.iteritems()):
char_obj.descriptors.items()):
log.info("Characteristic descriptor 0x%s is handle 0x%x",
desc_uuid_str, desc_handle)
return self._characteristics[connection_handle]
Expand Down Expand Up @@ -467,8 +470,10 @@ def expect_any(self, expected_packet_choices, timeout=None,
except queue.Empty:
if timeout is not None:
if time.time() - start_time > timeout:
raise ExpectedResponseTimeout(
exc = ExpectedResponseTimeout(
expected_packet_choices, timeout)
exc.__cause__ = None
raise exc
continue

if packet is None:
Expand All @@ -492,17 +497,14 @@ def _receive(self):
"""
log.info("Running receiver")
while self._running.is_set():
byte = self._ser.read()
if len(byte) > 0:
byte = ord(byte)
packet = self._lib.parse_byte(byte)
if packet is not None:
packet_type, args = self._lib.decode_packet(packet)
if packet_type == EventPacketType.attclient_attribute_value:
device = self._connections[args['connection_handle']]
device.receive_notification(args['atthandle'],
bytearray(args['value']))
self._receiver_queue.put(packet)
packet = self._lib.parse_byte(self._ser.read())
if packet is not None:
packet_type, args = self._lib.decode_packet(packet)
if packet_type == EventPacketType.attclient_attribute_value:
device = self._connections[args['connection_handle']]
device.receive_notification(args['atthandle'],
bytearray(args['value']))
self._receiver_queue.put(packet)
log.info("Stopping receiver")

def _ble_evt_attclient_attribute_value(self, args):
Expand Down Expand Up @@ -539,7 +541,7 @@ def _ble_evt_attclient_find_information_found(self, args):
uuid = uuid16_to_uuid(int(
bgapi_address_to_hex(args['uuid']).replace(':', ''), 16))
else:
uuid = UUID(hexlify(raw_uuid))
uuid = UUID(bytes=bytes(raw_uuid))

# TODO is there a way to get the characteristic from the packet instead
# of having to track the "current" characteristic?
Expand Down
93 changes: 47 additions & 46 deletions pygatt/backends/bgapi/bglib.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,31 +331,38 @@ def send_command(self, ser, packet):
"""
ser.write(packet)

def parse_byte(self, byte):
def parse_byte(self, new_byte):
"""
Re-build packets read in from bytes over serial one byte at a time.
byte -- the next byte to add to the packet.
new_byte -- the next bytes to add to the packet.
Returns a list of the bytes in the packet once a full packet is read.
Returns None otherwise.
"""
if new_byte is None or len(new_byte) == 0:
return None

# Convert from str or bytes to an integer for comparison
new_byte = ord(new_byte)

if (len(self.buffer) == 0 and
(byte == self._ble_event or byte == self._ble_response or
byte == self._wifi_event or byte == self._wifi_response)):
self.buffer.append(byte)
new_byte in [self._ble_event, self._ble_response,
self._wifi_event, self._wifi_response]):
self.buffer.append(new_byte)
elif len(self.buffer) == 1:
self.buffer.append(byte)
self.expected_length = 4 +\
(self.buffer[0] & 0x07) + self.buffer[1]
self.buffer.append(new_byte)
self.expected_length = (
4 + (self.buffer[0] & 0x07) + self.buffer[1])
elif len(self.buffer) > 1:
self.buffer.append(byte)
self.buffer.append(new_byte)

if (self.expected_length > 0 and
len(self.buffer) == self.expected_length):
packet = self.buffer
self.buffer = []
return packet

return None

def _decode_response_packet(self, packet_class, packet_command, payload,
Expand All @@ -368,8 +375,7 @@ def _decode_response_packet(self, packet_class, packet_command, payload,

response = {}
if packet_type == ResponsePacketType.system_address_get:
address = unpack('<6s', payload[:6])[0]
address = [ord(b) for b in address]
address = unpack('<6B', payload[:6])
response = {
'address': address
}
Expand All @@ -392,9 +398,8 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
'maxconn': maxconn
}
elif packet_type == ResponsePacketType.system_read_memory:
address, data_len =\
unpack('<IB', payload[:5])
data_data = [ord(b) for b in payload[5:]]
address, data_len = unpack('<IB', payload[:5])
data_data = bytearray(payload[5:])
response = {
'address': address, 'data': data_data
}
Expand Down Expand Up @@ -443,22 +448,22 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
elif packet_type == ResponsePacketType.system_endpoint_rx:
result, data_len =\
unpack('<HB', payload[:3])
data_data = [ord(b) for b in payload[3:]]
data_data = bytearray(payload[3:])
response = {
'result': result, 'data': data_data
}
elif packet_type == ResponsePacketType.flash_ps_load:
result, value_len = unpack('<HB',
payload[:3])
value_data = [ord(b) for b in payload[3:]]
value_data = bytearray(payload[3:])
response = {
'result': result, 'value': value_data
}
elif packet_type == ResponsePacketType.attributes_read:
handle, offset, result, value_len = unpack(
'<HHHB', payload[:7]
)
value_data = [ord(b) for b in payload[7:]]
value_data = bytearray(payload[7:])
response = {
'handle': handle, 'offset': offset,
'result': result, 'value': value_data
Expand All @@ -467,7 +472,7 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
handle, result, value_len = unpack(
'<HHB', payload[:5]
)
value_data = [ord(b) for b in payload[5:]]
value_data = bytearray(payload[5:])
response = {
'handle': handle, 'result': result,
'value': value_data
Expand Down Expand Up @@ -507,7 +512,7 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
connection, map_len = unpack(
'<BB', payload[:2]
)
map_data = [ord(b) for b in payload[2:]]
map_data = bytearray(payload[2:])
response = {
'connection_handle': connection, 'map': map_data
}
Expand Down Expand Up @@ -560,7 +565,7 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
result, channel, data_len = unpack(
'<HBB', payload[:4]
)
data_data = [ord(b) for b in payload[4:]]
data_data = bytearray(payload[4:])
response = {
'result': result, 'channel': channel,
'data': data_data
Expand All @@ -569,7 +574,7 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
result, data_len = unpack(
'<HB', payload[:3]
)
data_data = [ord(b) for b in payload[3:]]
data_data = bytearray(payload[3:])
response = {
'result': result, 'data': data_data
}
Expand All @@ -582,16 +587,14 @@ def _decode_response_packet(self, packet_class, packet_command, payload,
# channel_map_len = unpack(
# '<B', payload[:1]
# )[0]
channel_map_data =\
[ord(b) for b in payload[1:]]
channel_map_data = bytearray(payload[1:])
response = {
'channel_map': channel_map_data
}
elif packet_type == ResponsePacketType.test_debug:
# output_len = unpack('<B',
# payload[:1])[0]
output_data =\
[ord(b) for b in payload[1:]]
output_data = bytearray(payload[1:])
response = {
'output': output_data
}
Expand All @@ -616,7 +619,7 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
}
elif packet_type == EventPacketType.system_debug:
data_len = unpack('<B', payload[:1])[0]
data_data = [ord(b) for b in payload[1:]]
data_data = bytearray(payload[1:])
response = {
'data': data_data
}
Expand All @@ -640,15 +643,15 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
key, value_len = unpack(
'<HB', payload[:3]
)
value_data = [ord(b) for b in payload[3:]]
value_data = bytearray(payload[3:])
response = {
'key': key, 'value': value_data
}
elif packet_type == EventPacketType.attributes_value:
connection, reason, handle, offset, value_len = unpack(
'<BBHHB', payload[:7]
)
value_data = [ord(b) for b in payload[7:]]
value_data = bytearray(payload[7:])
response = {
'connection_handle': connection, 'reason': reason,
'handle': handle, 'offset': offset,
Expand All @@ -668,8 +671,8 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
'handle': handle, 'flags': flags
}
elif packet_type == EventPacketType.connection_status:
data = unpack('<BB6sBHHHB', payload[:16])
address = [ord(b) for b in data[2]]
data = unpack('<BB6BBHHHB', payload[:16])
address = data[2:8]
response = {
'connection_handle': data[0], 'flags': data[1],
'address': address, 'address_type': data[3],
Expand All @@ -688,16 +691,15 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
connection, features_len = unpack(
'<BB', payload[:2]
)
features_data =\
[ord(b) for b in payload[2:]]
features_data = bytearray(payload[2:])
response = {
'connection_handle': connection, 'features': features_data
}
elif packet_type == EventPacketType.connection_raw_rx:
connection, data_len = unpack(
'<BB', payload[:2]
)
data_data = [ord(b) for b in payload[2:]]
data_data = bytearray(payload[2:])
response = {
'connection_handle': connection, 'data': data_data
}
Expand Down Expand Up @@ -727,14 +729,14 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
connection, start, end, uuid_len = unpack(
'<BHHB', payload[:6]
)
uuid_data = [ord(b) for b in payload[6:]]
uuid_data = bytearray(payload[6:])
response = {
'connection_handle': connection, 'start': start,
'end': end, 'uuid': uuid_data
}
elif packet_type == EventPacketType.attclient_attribute_found:
data = unpack('<BHHBB', payload[:7])
uuid_data = [ord(b) for b in payload[7:]]
uuid_data = bytearray(payload[7:])
response = {
'connection_handle': data[0], 'chrdecl': data[1],
'value': data[2], 'properties': data[3],
Expand All @@ -744,7 +746,7 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
connection, chrhandle, uuid_len = unpack(
'<BHB', payload[:4]
)
uuid_data = [ord(b) for b in payload[4:]]
uuid_data = bytearray(payload[4:])
response = {
'connection_handle': connection, 'chrhandle': chrhandle,
'uuid': uuid_data
Expand All @@ -753,7 +755,7 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
connection, atthandle, type, value_len = unpack(
'<BHBB', payload[:5]
)
value_data = [ord(b) for b in payload[5:]]
value_data = bytearray(payload[5:])
response = {
'connection_handle': connection, 'atthandle': atthandle,
'type': type, 'value': value_data
Expand All @@ -762,16 +764,15 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
connection, handles_len = unpack(
'<BB', payload[:2]
)
handles_data =\
[ord(b) for b in payload[2:]]
handles_data = bytearray(payload[2:])
response = {
'connection_handle': connection, 'handles': handles_data
}
elif packet_type == EventPacketType.sm_smp_data:
handle, packet, data_len = unpack(
'<BBB', payload[:3]
)
data_data = [ord(b) for b in payload[3:]]
data_data = bytearray(payload[3:])
response = {
'handle': handle, 'packet': packet,
'data': data_data
Expand Down Expand Up @@ -804,13 +805,13 @@ def _decode_event_packet(self, packet_class, packet_command, payload,
'keys': keys
}
elif packet_type == EventPacketType.gap_scan_response:
data = unpack('<bB6sBBB', payload[:11])
sender = [ord(b) for b in data[2]]
data_data = [ord(b) for b in payload[11:]]
data = unpack('<bB6BBBB', payload[:11])
sender = bytearray(data[2:8])
data_data = bytearray(payload[11:])
response = {
'rssi': data[0], 'packet_type': data[1],
'sender': sender, 'address_type': data[3],
'bond': data[4], 'data': data_data
'sender': sender, 'address_type': data[9],
'bond': data[10], 'data': data_data
}
elif packet_type == EventPacketType.gap_mode_changed:
discover, connect = unpack(
Expand Down Expand Up @@ -861,7 +862,7 @@ def decode_packet(self, packet):
packet_id, payload_length, packet_class, packet_command = packet[:4]
# TODO we are not parsing out the high bits of the payload length from
# the first byte
payload = b''.join(chr(i) for i in packet[4:])
payload = bytearray(packet[4:])
message_type = packet_id & 0x88
if message_type == 0:
return self._decode_response_packet(
Expand Down
Loading

0 comments on commit ad5767e

Please sign in to comment.