xref: /btstack/platform/daemon/binding/python/btstack/btstack_types.py (revision 6ccd8248590f666db07dd7add13fecb4f5664fb5)
1#!/usr/bin/env python3
2
3import struct
4
5BLUETOOTH_BASE_UUID = bytes ([ 0x00, 0x00, 0x00, 0x00,   0x00, 0x00,  0x10, 0x00,   0x80, 0x00,  0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB ]);
6
7def hex_string(bytes):
8    return " ".join([('%02x' % a) for a in bytes])
9
10def unpack24(data):
11    (upper, ) = struct.unpack("<H", data[1:])
12    return data[0] | (upper << 8)
13
14class BD_ADDR(object):
15    # addr stored in big endian
16    def __init__(self, addr):
17        if isinstance(addr, str):
18            parts = addr.split(':')
19            if len(parts) != 6:
20                return
21            # list comprehension
22            self.addr = bytes([int(a,16) for a in parts])
23        elif isinstance(addr, bytes):
24            self.addr = addr
25        elif isinstance(addr, bytearray):
26            self.addr = addr
27        else:
28            print('cannot use for bdaddr, len %u' % len(addr))
29            print(addr)
30
31    def get_bytes(self):
32        data = bytearray(self.addr)
33        data.reverse()
34        return data
35
36    def __repr__(self):
37        return ":".join([('%02x' % a) for a in self.addr])
38
39class BT_UUID(object):
40    # uuid stored in big endian
41
42    def __init__(self, uuid):
43        global BLUETOOTH_BASE_UUID
44        if isinstance(uuid,bytes):
45            self.uuid = uuid
46        if isinstance(uuid,int):
47            self.uuid = struct.pack(">I", uuid) + BLUETOOTH_BASE_UUID[4:]
48        if isinstance(uuid,str):
49            parts = uuid.split('-')
50            if len(parts) != 5:
51                return
52            # list comprehension
53            self.uuid = bytes([int(a,16) for a in uuid.replace('-','')])
54
55    def get_uuid32(self):
56        global BLUETOOTH_BASE_UUID
57        result = 0
58        if self.uuid[4:] == BLUETOOTH_BASE_UUID[4:]:
59            (result,) = struct.unpack(">I", self.uuid[:4])
60        return result
61
62    def get_bytes(self):
63        data = bytearray(self.uuid)
64        data.reverse()
65        return data
66
67    def __repr__(self):
68        return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
69                self.uuid[0], self.uuid[1], self.uuid[2], self.uuid[3],   self.uuid[4],  self.uuid[5],  self.uuid[6],  self.uuid[7],
70                self.uuid[8], self.uuid[9], self.uuid[10], self.uuid[11], self.uuid[12], self.uuid[13], self.uuid[14], self.uuid[15]);
71
72
73class GATTCharacteristic(object):
74
75    # uint16_t start_handle;
76    # uint16_t value_handle;
77    # uint16_t end_handle;
78    # uint16_t properties;
79    # uint8_t  uuid128[16];
80
81    def __init__(self, data):
82        self.data = data
83
84    def get_bytes(self):
85        return self.data
86
87    def get_start_handle(self):
88        (result, ) = struct.unpack('<H', self.data[0:2])
89        return result
90
91    def get_value_handle(self):
92        (result, ) = struct.unpack('<H', self.data[2:4])
93        return result
94
95    def get_ned_handle(self):
96        (result, ) = struct.unpack('<H', self.data[4:6])
97        return result
98
99    def get_properties(self):
100        (result, ) = struct.unpack('<H', self.data[6:8])
101        return result
102
103    def get_uuid(self):
104        return BT_UUID(self.data[8:])
105
106    def __repr__(self):
107        return "GATTCharacteristic [start_handle={start_handle}, value_handle={value_handle}, end_handle={end_handle}, get_uuid={uuid}]".format(
108            start_handle=self.get_start_handle(), value_handle=self.get_value_handle(), end_handle=self.get_end_handle(), uuid=self.get_uuid())
109
110
111
112class GATTCharacteristicDescriptor(object):
113
114    # uint16_t handle;
115    # uint8_t  uuid128[16];
116
117    def __init__(self, data):
118        self.data = data
119
120    def get_bytes(self):
121        return self.data
122
123    def get_handle(self):
124        (result, ) = struct.unpack('<H', self.data[0:2])
125        return result
126
127    def get_uuid(self):
128        return BT_UUID(self.data[2:])
129
130    def __repr__(self):
131        return "GATTCharacteristicDescriptor [handle={handle}, get_uuid={uuid}]".format(
132            handle=self.get_handle(), uuid=self.get_uuid())
133
134
135class GATTService(object):
136
137    # uint16_t start_group_handle;
138    # uint16_t end_group_handle;
139    # uint8_t  uuid128[16];
140
141    def __init__(self, data):
142        self.data = data
143
144    def get_bytes(self):
145        return self.data
146
147    def get_start_group_handle(self):
148        (result, ) = struct.unpack('<H', self.data[0:2])
149        return result
150
151    def get_end_group_handle(self):
152        (result, ) = struct.unpack('<H', self.data[2:4])
153        return result
154
155    def get_uuid(self):
156        return BT_UUID(self.data[4:])
157
158    def __repr__(self):
159        return "GattService [start_group_handle={start_group_handle}, [end_group_handle={end_group_handle}, get_uuid={uuid}]".format(
160            start_group_handle=self.get_start_group_handle(), end_group_handle=self.get_end_group_handle(), uuid=self.get_uuid())
161
162
163class Packet(object):
164
165    HCI_COMMAND_PACKET = 1;
166    HCI_EVENT_PACKET   = 4;
167    L2CAP_DATA_PACKET  = 6;
168    RFCOMM_DATA_PACKET = 7;
169
170    def __init__(self, packet_type, channel, payload):
171        self.packet_type = packet_type
172        self.channel = channel
173        self.payload = payload
174
175    def get_packet_type(self):
176        return self.packet_type
177
178    def get_channel(self):
179        return self.channel
180
181    def get_payload(self):
182        return self.payload
183
184    def __repr__(self):
185        return "Packet type {packet_type}, channel {channel}, payload {payload}".format(packet_type={self.get_packet_type()},
186            channel={self.get_channel()}, payload=hex_string(self.get_payload()))
187
188
189class Event(Packet):
190
191    def __init__(self, payload):
192        self.packet_type = Packet.HCI_COMMAND_PACKET
193        self.channel = 0
194        self.payload = payload
195
196    def get_event_type(self):
197        return self.payload[0]
198
199    def __repr__(self):
200        return "Event type {event_type}, payload {payload}".format(event_type={self.get_event_type()},
201         payload=hex_string(self.get_payload()))
202
203
204class BTstackEventState(Packet):
205
206    def __init__(self, payload):
207        self.packet_type = Packet.HCI_COMMAND_PACKET
208        self.channel = 0
209        self.payload = payload
210
211    def get_state(self):
212        return self.payload[2]
213
214