Skip to content

Commit f79e90c

Browse files
committed
gattlib-py: Added support for manufacturer data from GATT advertising
1 parent 35566d1 commit f79e90c

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

gattlib-py/gattlib/__init__.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ class GattlibAdvertisementData(Structure):
103103
("data", c_void_p),
104104
("data_length", c_size_t)]
105105

106+
# typedef struct {
107+
# uint16_t manufacturer_id;
108+
# uint8_t* data;
109+
# size_t data_size;
110+
# } gattlib_manufacturer_data_t;
111+
class GattlibManufacturerData(Structure):
112+
_fields_ = [("manufacturer_id", c_ushort),
113+
("data", c_void_p),
114+
("data_size", c_size_t)]
115+
106116

107117
# int gattlib_adapter_open(const char* adapter_name, gattlib_adapter_t** adapter);
108118
gattlib_adapter_open = gattlib.gattlib_adapter_open
@@ -212,13 +222,13 @@ class GattlibAdvertisementData(Structure):
212222
# gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
213223
# gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
214224
gattlib_get_advertisement_data = gattlib.gattlib_get_advertisement_data
215-
gattlib_get_advertisement_data.argtypes = [c_void_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(c_uint16), POINTER(c_void_p), POINTER(c_size_t)]
225+
gattlib_get_advertisement_data.argtypes = [c_void_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(POINTER(GattlibManufacturerData)), POINTER(c_size_t)]
216226

217227
# int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
218228
# gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_length,
219229
# gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
220230
gattlib_get_advertisement_data_from_mac = gattlib.gattlib_get_advertisement_data_from_mac
221-
gattlib_get_advertisement_data_from_mac.argtypes = [c_void_p, c_char_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(c_uint16), POINTER(c_void_p), POINTER(c_size_t)]
231+
gattlib_get_advertisement_data_from_mac.argtypes = [c_void_p, c_char_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(POINTER(GattlibManufacturerData)), POINTER(c_size_t)]
222232

223233
# int gattlib_mainloop_python(PyObject *handler, PyObject *user_data)
224234
gattlib_mainloop = gattlib.gattlib_mainloop_python

gattlib-py/gattlib/adapter.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from gattlib import *
1111
from .device import Device
12-
from .exception import handle_return, AdapterNotOpened
12+
from .exception import handle_return
1313
from .uuid import gattlib_uuid_to_int
1414

1515
GATTLIB_DISCOVER_FILTER_USE_UUID = (1 << 0)
@@ -238,18 +238,16 @@ def gattlib_get_advertisement_data_from_mac(self, mac_address):
238238

239239
_advertisement_data = POINTER(GattlibAdvertisementData)()
240240
_advertisement_data_count = c_size_t(0)
241-
_manufacturer_id = c_uint16(0)
242-
_manufacturer_data = c_void_p(None)
241+
_manufacturer_data = POINTER(GattlibManufacturerData)()
243242
_manufacturer_data_len = c_size_t(0)
244243

245244
ret = gattlib_get_advertisement_data_from_mac(self._adapter, mac_address,
246245
byref(_advertisement_data), byref(_advertisement_data_count),
247-
byref(_manufacturer_id),
248246
byref(_manufacturer_data), byref(_manufacturer_data_len))
249247
handle_return(ret)
250248

251249
advertisement_data = {}
252-
manufacturer_data = None
250+
manufacturer_data = {}
253251

254252
for i in range(0, _advertisement_data_count.value):
255253
service_data = _advertisement_data[i]
@@ -264,15 +262,21 @@ def gattlib_get_advertisement_data_from_mac(self, mac_address):
264262

265263
advertisement_data[uuid] = data
266264

267-
if _manufacturer_data_len.value > 0:
268-
pointer_type = POINTER(c_byte * _manufacturer_data_len.value)
269-
c_bytearray = cast(_manufacturer_data, pointer_type)
265+
for i in range(0, _manufacturer_data_len.value):
266+
_manufacturer_data = _manufacturer_data[i]
270267

271-
manufacturer_data = bytearray(_manufacturer_data_len.value)
272-
for i in range(_manufacturer_data_len.value):
273-
manufacturer_data[i] = c_bytearray.contents[i] & 0xFF
268+
pointer_type = POINTER(c_byte * _manufacturer_data.data_size.value)
269+
c_bytearray = cast(_manufacturer_data.data, pointer_type)
270+
271+
data = bytearray(_manufacturer_data.data_size.value)
272+
for j in range(_manufacturer_data.data_size.value):
273+
data[j] = c_bytearray.contents[j] & 0xFF
274+
275+
manufacturer_data[_manufacturer_data.manufacturer_id] = data
276+
277+
gattlib_free_mem(_manufacturer_data.data)
274278

275279
gattlib_free_mem(_advertisement_data)
276280
gattlib_free_mem(_manufacturer_data)
277281

278-
return advertisement_data, _manufacturer_id.value, manufacturer_data
282+
return advertisement_data, manufacturer_data

gattlib-py/gattlib/device.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,25 +182,22 @@ def discover(self):
182182
def get_advertisement_data(self):
183183
_advertisement_data = POINTER(GattlibAdvertisementData)()
184184
_advertisement_data_count = c_size_t(0)
185-
_manufacturer_id = c_uint16(0)
186-
_manufacturer_data = c_void_p(None)
185+
_manufacturer_data = POINTER(GattlibManufacturerData)()
187186
_manufacturer_data_len = c_size_t(0)
188187

189188
if self._connection is None:
190189
ret = gattlib_get_advertisement_data_from_mac(self._adapter._adapter, self._addr,
191190
byref(_advertisement_data), byref(_advertisement_data_count),
192-
byref(_manufacturer_id),
193191
byref(_manufacturer_data), byref(_manufacturer_data_len))
194192
else:
195193
ret = gattlib_get_advertisement_data(self._connection,
196194
byref(_advertisement_data), byref(_advertisement_data_count),
197-
byref(_manufacturer_id),
198195
byref(_manufacturer_data), byref(_manufacturer_data_len))
199196

200197
handle_return(ret)
201198

202199
advertisement_data = {}
203-
manufacturer_data = None
200+
manufacturer_data = {}
204201

205202
for i in range(0, _advertisement_data_count.value):
206203
service_data = _advertisement_data[i]
@@ -215,18 +212,24 @@ def get_advertisement_data(self):
215212

216213
advertisement_data[uuid] = data
217214

218-
if _manufacturer_data_len.value > 0:
219-
pointer_type = POINTER(c_byte * _manufacturer_data_len.value)
220-
c_bytearray = cast(_manufacturer_data, pointer_type)
215+
for i in range(0, _manufacturer_data_len.value):
216+
_manufacturer_data = _manufacturer_data[i]
221217

222-
manufacturer_data = bytearray(_manufacturer_data_len.value)
223-
for i in range(_manufacturer_data_len.value):
224-
manufacturer_data[i] = c_bytearray.contents[i] & 0xFF
218+
pointer_type = POINTER(c_byte * _manufacturer_data.data_size.value)
219+
c_bytearray = cast(_manufacturer_data.data, pointer_type)
220+
221+
data = bytearray(_manufacturer_data.data_size.value)
222+
for j in range(_manufacturer_data.data_size.value):
223+
data[j] = c_bytearray.contents[j] & 0xFF
224+
225+
manufacturer_data[_manufacturer_data.manufacturer_id] = data
226+
227+
gattlib_free_mem(_manufacturer_data.data)
225228

226229
gattlib_free_mem(_advertisement_data)
227230
gattlib_free_mem(_manufacturer_data)
228231

229-
return advertisement_data, _manufacturer_id.value, manufacturer_data
232+
return advertisement_data, manufacturer_data
230233

231234
@property
232235
def services(self):

0 commit comments

Comments
 (0)