From caa6034e46b9de053498d88822b16392d79ce971 Mon Sep 17 00:00:00 2001 From: Santiago Carot-Nemesio Date: Tue, 27 Dec 2011 15:33:19 +0100 Subject: [PATCH] gatt-example: Use adapter driver to register GATT attributes GATT servers should register their attributes on each adapter when it is plugged instead of doing that when the plugins is loaded. This patch registers a new adapter driver to manage plug and unplug events in order to register attributes in each GATT served managed in each adapter. --- plugins/gatt-example.c | 98 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 19 deletions(-) diff --git a/plugins/gatt-example.c b/plugins/gatt-example.c index 6d9b6b8b6..4e8f36f90 100644 --- a/plugins/gatt-example.c +++ b/plugins/gatt-example.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "plugin.h" #include "hcid.h" @@ -57,7 +58,39 @@ #define FMT_KILOGRAM_UUID 0xA010 #define FMT_HANGING_UUID 0xA011 -static GSList *sdp_handles = NULL; +struct gatt_example_adapter { + struct btd_adapter *adapter; + GSList *sdp_handles; +}; + +static GSList *adapters = NULL; + +static void gatt_example_adapter_free(struct gatt_example_adapter *gadapter) +{ + while (gadapter->sdp_handles != NULL) { + uint32_t handle = GPOINTER_TO_UINT(gadapter->sdp_handles->data); + + attrib_free_sdp(handle); + gadapter->sdp_handles = g_slist_remove(gadapter->sdp_handles, + gadapter->sdp_handles->data); + } + + if (gadapter->adapter != NULL) + btd_adapter_unref(gadapter->adapter); + + g_free(gadapter); +} + +static gint adapter_cmp(gconstpointer a, gconstpointer b) +{ + const struct gatt_example_adapter *gatt_adapter = a; + const struct btd_adapter *adapter = b; + + if (gatt_adapter->adapter == adapter) + return 0; + + return -1; +} static uint8_t battery_state_read(struct attribute *a, gpointer user_data) { @@ -81,8 +114,8 @@ static gboolean register_battery_service(void) GATT_OPT_INVALID); } -static void register_termometer_service(const uint16_t manuf1[2], - const uint16_t manuf2[2]) +static void register_termometer_service(struct gatt_example_adapter *adapter, + const uint16_t manuf1[2], const uint16_t manuf2[2]) { const char *desc_out_temp = "Outside Temperature"; const char *desc_out_hum = "Outside Relative Humidity"; @@ -189,7 +222,7 @@ static void register_termometer_service(const uint16_t manuf1[2], /* Add an SDP record for the above service */ sdp_handle = attrib_create_sdp(start_handle, "Thermometer"); if (sdp_handle) - sdp_handles = g_slist_prepend(sdp_handles, + adapter->sdp_handles = g_slist_prepend(adapter->sdp_handles, GUINT_TO_POINTER(sdp_handle)); } @@ -352,7 +385,8 @@ static void register_vendor_service(uint16_t range[2]) range[1] = start_handle + svc_size - 1; } -static void register_weight_service(const uint16_t vendor[2]) +static void register_weight_service(struct gatt_example_adapter *adapter, + const uint16_t vendor[2]) { const char *desc_weight = "Rucksack Weight"; const uint128_t char_weight_uuid_btorder = { @@ -432,45 +466,71 @@ static void register_weight_service(const uint16_t vendor[2]) /* Add an SDP record for the above service */ sdp_handle = attrib_create_sdp(start_handle, "Weight Service"); if (sdp_handle) - sdp_handles = g_slist_prepend(sdp_handles, + adapter->sdp_handles = g_slist_prepend(adapter->sdp_handles, GUINT_TO_POINTER(sdp_handle)); } -static int gatt_example_init(void) +static int gatt_example_adapter_probe(struct btd_adapter *adapter) { uint16_t manuf1_range[2] = {0, 0}, manuf2_range[2] = {0, 0}; uint16_t vendor_range[2] = {0, 0}; + struct gatt_example_adapter *gadapter; - if (!main_opts.attrib_server) { - DBG("Attribute server is disabled"); - return -1; - } + gadapter = g_new0(struct gatt_example_adapter, 1); + gadapter->adapter = btd_adapter_ref(adapter); if (!register_battery_service()) { DBG("Battery service could not be registered"); + gatt_example_adapter_free(gadapter); return -EIO; } register_manuf1_service(manuf1_range); register_manuf2_service(manuf2_range); - register_termometer_service(manuf1_range, manuf2_range); + register_termometer_service(gadapter, manuf1_range, manuf2_range); register_vendor_service(vendor_range); - register_weight_service(vendor_range); + register_weight_service(gadapter, vendor_range); + + adapters = g_slist_append(adapters, gadapter); return 0; } -static void gatt_example_exit(void) +static void gatt_example_adapter_remove(struct btd_adapter *adapter) { - if (!main_opts.attrib_server) + struct gatt_example_adapter *gadapter; + GSList *l; + + l = g_slist_find_custom(adapters, adapter, adapter_cmp); + if (l == NULL) return; - while (sdp_handles) { - uint32_t handle = GPOINTER_TO_UINT(sdp_handles->data); + gadapter = l->data; + gatt_example_adapter_free(gadapter); +} - attrib_free_sdp(handle); - sdp_handles = g_slist_remove(sdp_handles, sdp_handles->data); +static struct btd_adapter_driver gatt_example_adapter_driver = { + .name = "gatt-example-adapter-driver", + .probe = gatt_example_adapter_probe, + .remove = gatt_example_adapter_remove, +}; + +static int gatt_example_init(void) +{ + if (!main_opts.attrib_server) { + DBG("Attribute server is disabled"); + return -ENOTSUP; } + + return btd_register_adapter_driver(&gatt_example_adapter_driver); +} + +static void gatt_example_exit(void) +{ + if (!main_opts.attrib_server) + return; + + btd_unregister_adapter_driver(&gatt_example_adapter_driver); } BLUETOOTH_PLUGIN_DEFINE(gatt_example, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW, -- 2.47.3