gattlib: Introduce gattlib_adapter_scan_enable_with_filter()

pull/116/head
Olivier Martin 2019-07-09 14:03:06 +02:00 committed by Olivier Martin
parent eca8415fd6
commit 2ae549f9d6
6 changed files with 169 additions and 5 deletions

View File

@ -210,6 +210,12 @@ int gattlib_adapter_scan_enable(void* adapter, gattlib_discovered_device_t disco
return GATTLIB_SUCCESS;
}
int gattlib_adapter_scan_enable_with_filter(void *adapter, uuid_t **uuid_list, int16_t rssi_threshold, uint32_t enabled_filters,
gattlib_discovered_device_t discovered_device_cb, int timeout)
{
return GATTLIB_NOT_SUPPORTED;
}
int gattlib_adapter_scan_disable(void* adapter) {
int device_desc = *(int*)adapter;

View File

@ -549,6 +549,13 @@ int get_handle_from_uuid(gatt_connection_t* connection, const uuid_t* uuid, uint
return -1;
}
int gattlib_get_rssi(gatt_connection_t *connection, int16_t *rssi) {
int gattlib_get_rssi(gatt_connection_t *connection, int16_t *rssi)
{
return GATTLIB_NOT_SUPPORTED;
}
int gattlib_get_advertisement_data(gatt_connection_t *connection, gattlib_advertisement_data_t **advertisement_data,
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
{
return GATTLIB_NOT_SUPPORTED;
}

View File

@ -172,12 +172,45 @@ on_interface_proxy_properties_changed (GDBusObjectManagerClient *device_manager,
device_manager_on_device1_signal(g_dbus_proxy_get_object_path(interface_proxy), user_data);
}
int gattlib_adapter_scan_enable(void* adapter, gattlib_discovered_device_t discovered_device_cb, int timeout) {
int gattlib_adapter_scan_enable_with_filter(void *adapter, uuid_t **uuid_list, int16_t rssi_threshold, uint32_t enabled_filters,
gattlib_discovered_device_t discovered_device_cb, int timeout)
{
GDBusObjectManager *device_manager;
GError *error = NULL;
int ret = GATTLIB_SUCCESS;
int added_signal_id, changed_signal_id;
GSList *discovered_devices = NULL;
GVariantBuilder arg_properties_builder;
g_variant_builder_init(&arg_properties_builder, G_VARIANT_TYPE("a{sv}"));
if (enabled_filters & GATTLIB_DISCOVER_FILTER_USE_UUID) {
char uuid_str[MAX_LEN_UUID_STR + 1];
GVariantBuilder list_uuid_builder;
g_variant_builder_init(&list_uuid_builder, G_VARIANT_TYPE ("as"));
for (uuid_t **uuid_ptr = uuid_list; *uuid_ptr != NULL; uuid_ptr++) {
gattlib_uuid_to_string(*uuid_ptr, uuid_str, sizeof(uuid_str));
g_variant_builder_add(&list_uuid_builder, "s", uuid_str);
}
g_variant_builder_add(&arg_properties_builder, "{sv}", "UUIDs", g_variant_builder_end(&list_uuid_builder));
}
if (enabled_filters & GATTLIB_DISCOVER_FILTER_USE_RSSI) {
GVariant *rssi_variant = g_variant_new_int16(rssi_threshold);
g_variant_builder_add(&arg_properties_builder, "{sv}", "RSSI", rssi_variant);
g_variant_unref(rssi_variant);
}
org_bluez_adapter1_call_set_discovery_filter_sync((OrgBluezAdapter1*)adapter,
g_variant_builder_end(&arg_properties_builder), NULL, &error);
if (error) {
fprintf(stderr, "Failed to set discovery filter: %s\n", error->message);
g_error_free(error);
return GATTLIB_ERROR_DBUS;
}
org_bluez_adapter1_call_start_discovery_sync((OrgBluezAdapter1*)adapter, NULL, &error);
if (error) {
@ -247,6 +280,14 @@ DISABLE_SCAN:
return ret;
}
int gattlib_adapter_scan_enable(void* adapter, gattlib_discovered_device_t discovered_device_cb, int timeout)
{
return gattlib_adapter_scan_enable_with_filter(adapter,
NULL, 0 /* RSSI Threshold */,
GATTLIB_DISCOVER_FILTER_USE_NONE,
discovered_device_cb, timeout);
}
int gattlib_adapter_scan_disable(void* adapter) {
GError *error = NULL;
@ -1556,3 +1597,11 @@ int gattlib_get_rssi(gatt_connection_t *connection, int16_t *rssi) {
return GATTLIB_SUCCESS;
}
int gattlib_get_advertisement_data(gatt_connection_t *connection, gattlib_advertisement_data_t **advertisement_data,
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
{
//gattlib_context_t* conn_context = connection->context;
return GATTLIB_NOT_SUPPORTED;
}

View File

@ -57,6 +57,11 @@ gattlib_adapter_open.argtypes = [c_char_p, POINTER(c_void_p)]
# typedef void (*gattlib_discovered_device_t)(const char* addr, const char* name)
gattlib_discovered_device_type = CFUNCTYPE(None, c_char_p, c_char_p)
# int gattlib_adapter_scan_enable_with_filter(void *adapter, uuid_t **uuid_list, int16_t rssi_threshold, uint32_t enabled_filters,
# gattlib_discovered_device_t discovered_device_cb, int timeout)
gattlib_adapter_scan_enable_with_filter = gattlib.gattlib_adapter_scan_enable_with_filter
gattlib_adapter_scan_enable_with_filter.argtypes = [c_void_p, POINTER(POINTER(GattlibUuid)), c_int16, c_uint32, gattlib_discovered_device_type, c_int]
# int gattlib_discover_primary(gatt_connection_t* connection, gattlib_primary_service_t** services, int* services_count);
gattlib_discover_primary = gattlib.gattlib_discover_primary
gattlib_discover_primary.argtypes = [c_void_p, POINTER(POINTER(GattlibPrimaryService)), POINTER(c_int)]

View File

@ -2,7 +2,12 @@ from gattlib import *
from .device import Device
from .exception import handle_return
GATTLIB_DISCOVER_FILTER_USE_UUID = (1 << 0)
GATTLIB_DISCOVER_FILTER_USE_RSSI = (1 << 1)
class Adapter:
def __init__(self, name=c_char_p(None)):
self._name = name
self._adapter = c_void_p(None)
@ -13,7 +18,7 @@ class Adapter:
@staticmethod
def list():
#TODO: Add support
# TODO: Add support
return []
def open(self):
@ -26,11 +31,37 @@ class Adapter:
device = Device(self, addr, name)
self.on_discovered_device_callback(device)
def scan_enable(self, on_discovered_device_callback, timeout):
def scan_enable(self, on_discovered_device_callback, timeout, uuids=None, rssi_threshold=None):
assert on_discovered_device_callback != None
self.on_discovered_device_callback = on_discovered_device_callback
ret = gattlib.gattlib_adapter_scan_enable(self._adapter, gattlib_discovered_device_type(self.on_discovered_device), timeout)
enabled_filters = 0
uuid_list = None
rssi = 0
if uuids is not None:
enabled_filters |= GATTLIB_DISCOVER_FILTER_USE_UUID
# We add 1 to make sure the array finishes with a NULL pointer
uuid_list = (POINTER(GattlibUuid) * (len(uuids) + 1))()
index = 0
for uuid in uuids:
gattlib_uuid = GattlibUuid()
uuid_ascii = uuid.encode("utf-8")
ret = gattlib.gattlib_string_to_uuid(uuid_ascii, len(uuid_ascii), byref(gattlib_uuid))
handle_return(ret)
uuid_list[index] = cast(byref(gattlib_uuid), POINTER(GattlibUuid))
index += 1
if rssi_threshold is not None:
enabled_filters |= GATTLIB_DISCOVER_FILTER_USE_RSSI
rssi = int(rssi_threshold)
ret = gattlib_adapter_scan_enable_with_filter(self._adapter,
uuid_list, rssi, enabled_filters,
gattlib_discovered_device_type(self.on_discovered_device), timeout)
handle_return(ret)
def scan_disable(self):

View File

@ -89,6 +89,10 @@ extern "C" {
GATTLIB_CONNECTION_OPTIONS_LEGACY_BDADDR_LE_RANDOM | \
GATTLIB_CONNECTION_OPTIONS_LEGACY_BT_SEC_LOW
#define GATTLIB_DISCOVER_FILTER_USE_NONE 0
#define GATTLIB_DISCOVER_FILTER_USE_UUID (1 << 0)
#define GATTLIB_DISCOVER_FILTER_USE_RSSI (1 << 1)
typedef struct _gatt_connection_t gatt_connection_t;
typedef void (*gattlib_event_handler_t)(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data);
@ -117,10 +121,56 @@ typedef void* (*gatt_read_cb_t)(const void *buffer, size_t buffer_len);
* @brief Open Bluetooth adapter
*
* @param adapter_name With value NULL, the default adapter will be selected.
* @param adapter is the context of the newly opened adapter
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_adapter_open(const char* adapter_name, void** adapter);
/**
* @brief Enable Bluetooth scanning on a given adapter
*
* @param adapter is the context of the newly opened adapter
* @param discovered_device_cb is the function callback called for each new Bluetooth device discovered
* @param timeout defines the duration of the Bluetooth scanning
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_adapter_scan_enable(void* adapter, gattlib_discovered_device_t discovered_device_cb, int timeout);
/**
* @brief Enable Bluetooth scanning on a given adapter
*
* @param adapter is the context of the newly opened adapter
* @param uuid_list is a NULL-terminated list of UUIDs to filter. The rule only applies to advertised UUID.
* Returned devices would match any of the UUIDs of the list.
* @param rssi_threshold is the imposed RSSI threshold for the returned devices.
* @param filter defines the parameters to use for filtering. There are selected by using the macros
* GATTLIB_DISCOVER_FILTER_USE_UUID and GATTLIB_DISCOVER_FILTER_USE_RSSI.
* @param discovered_device_cb is the function callback called for each new Bluetooth device discovered
* @param timeout defines the duration of the Bluetooth scanning
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_adapter_scan_enable_with_filter(void *adapter, uuid_t **uuid_list, int16_t rssi_threshold, uint32_t enabled_filters,
gattlib_discovered_device_t discovered_device_cb, int timeout);
/**
* @brief Disable Bluetooth scanning on a given adapter
*
* @param adapter is the context of the newly opened adapter
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_adapter_scan_disable(void* adapter);
/**
* @brief Close Bluetooth adapter context
*
* @param adapter is the context of the newly opened adapter
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_adapter_close(void* adapter);
/**
@ -168,6 +218,12 @@ typedef struct {
uuid_t uuid;
} gattlib_descriptor_t;
typedef struct {
uuid_t uuid;
uint8_t* data;
size_t data_length;
} gattlib_advertisement_data_t;
/**
* @brief Function to discover GATT Services
*
@ -278,6 +334,16 @@ void gattlib_register_indication(gatt_connection_t* connection, gattlib_event_ha
*/
int gattlib_get_rssi(gatt_connection_t *connection, int16_t *rssi);
/**
* @brief Function to retrieve Advertisement Data of the GATT connection
*
* @param connection Active GATT connection
*
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
*/
int gattlib_get_advertisement_data(gatt_connection_t *connection, gattlib_advertisement_data_t **advertisement_data,
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size);
int gattlib_uuid_to_string(const uuid_t *uuid, char *str, size_t n);
int gattlib_string_to_uuid(const char *str, size_t n, uuid_t *uuid);
int gattlib_uuid_cmp(const uuid_t *uuid1, const uuid_t *uuid2);