Each adapter use its own databa list to manage handlers so all operations should managed in adapters instead of using a global handler list. --- src/attrib-server.c | 67 ++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/attrib-server.c b/src/attrib-server.c index 5c0f9b4..402db3e 100644 --- a/src/attrib-server.c +++ b/src/attrib-server.c @@ -52,7 +52,6 @@ #include "attrib-server.h" -static GSList *database = NULL; static GSList *adapters = NULL; struct gatt_adapter { @@ -419,7 +418,7 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start, struct att_data_list *adl; struct attribute *a; struct group_elem *cur, *old = NULL; - GSList *l, *groups; + GSList *l, *groups, *database; uint16_t length, last_handle, last_size = 0; uint8_t status; int i; @@ -439,6 +438,7 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start, ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len); last_handle = end; + database = channel->gadapter->database; for (l = database, groups = NULL, cur = NULL; l; l = l->next) { a = l->data; @@ -530,7 +530,7 @@ static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start, uint8_t *pdu, int len) { struct att_data_list *adl; - GSList *l, *types; + GSList *l, *types, *database; struct attribute *a; uint16_t num, length; uint8_t status; @@ -540,6 +540,7 @@ static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start, return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start, ATT_ECODE_INVALID_HANDLE, pdu, len); + database = channel->gadapter->database; for (l = database, length = 0, types = NULL; l; l = l->next) { a = l->data; @@ -606,11 +607,12 @@ static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start, return length; } -static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len) +static int find_info(struct gatt_channel *channel, uint16_t start, uint16_t end, + uint8_t *pdu, int len) { struct attribute *a; struct att_data_list *adl; - GSList *l, *info; + GSList *l, *info, *database; uint8_t format, last_type = BT_UUID_UNSPEC; uint16_t length, num; int i; @@ -619,6 +621,7 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len) return enc_error_resp(ATT_OP_FIND_INFO_REQ, start, ATT_ECODE_INVALID_HANDLE, pdu, len); + database = channel->gadapter->database; for (l = database, info = NULL, num = 0; l; l = l->next) { a = l->data; @@ -678,12 +681,13 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len) return length; } -static int find_by_type(uint16_t start, uint16_t end, bt_uuid_t *uuid, - const uint8_t *value, int vlen, uint8_t *opdu, int mtu) +static int find_by_type(struct gatt_channel *channel, uint16_t start, + uint16_t end, bt_uuid_t *uuid, const uint8_t *value, + int vlen, uint8_t *opdu, int mtu) { struct attribute *a; struct att_range *range; - GSList *l, *matches; + GSList *l, *matches, *database; int len; if (start > end || start == 0x0000) @@ -691,6 +695,7 @@ static int find_by_type(uint16_t start, uint16_t end, bt_uuid_t *uuid, ATT_ECODE_INVALID_HANDLE, opdu, mtu); /* Searching first requested handle number */ + database = channel->gadapter->database; for (l = database, matches = NULL, range = NULL; l; l = l->next) { a = l->data; @@ -743,7 +748,8 @@ static uint16_t read_value(struct gatt_channel *channel, uint16_t handle, uint16_t cccval; guint h = handle; - l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp); + l = g_slist_find_custom(channel->gadapter->database, + GUINT_TO_POINTER(h), handle_cmp); if (!l) return enc_error_resp(ATT_OP_READ_REQ, handle, ATT_ECODE_INVALID_HANDLE, pdu, len); @@ -780,7 +786,8 @@ static uint16_t read_blob(struct gatt_channel *channel, uint16_t handle, uint16_t cccval; guint h = handle; - l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp); + l = g_slist_find_custom(channel->gadapter->database, + GUINT_TO_POINTER(h), handle_cmp); if (!l) return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle, ATT_ECODE_INVALID_HANDLE, pdu, len); @@ -822,7 +829,8 @@ static uint16_t write_value(struct gatt_channel *channel, uint16_t handle, GSList *l; guint h = handle; - l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp); + l = g_slist_find_custom(channel->gadapter->database, + GUINT_TO_POINTER(h), handle_cmp); if (!l) return enc_error_resp(ATT_OP_WRITE_REQ, handle, ATT_ECODE_INVALID_HANDLE, pdu, len); @@ -950,7 +958,7 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len, goto done; } - length = find_info(start, end, opdu, channel->mtu); + length = find_info(channel, start, end, opdu, channel->mtu); break; case ATT_OP_WRITE_REQ: length = dec_write_req(ipdu, len, &start, value, &vlen); @@ -976,7 +984,7 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len, goto done; } - length = find_by_type(start, end, &uuid, value, vlen, + length = find_by_type(channel, start, end, &uuid, value, vlen, opdu, channel->mtu); break; case ATT_OP_HANDLE_CNF: @@ -1253,8 +1261,6 @@ void btd_adapter_gatt_server_stop(struct btd_adapter *adapter) gadapter = l->data; adapters = g_slist_remove(adapters, gadapter); gatt_adapter_free(gadapter); - - g_slist_free_full(database, attrib_free); } uint32_t attrib_create_sdp(uint16_t handle, const char *name) @@ -1277,12 +1283,19 @@ void attrib_free_sdp(uint32_t sdp_handle) uint16_t attrib_db_find_avail(uint16_t nitems) { + struct gatt_adapter *gadapter; uint16_t handle; GSList *l; + DBG("Deprecated function!"); + g_assert(nitems > 0); - for (l = database, handle = 0; l; l = l->next) { + gadapter = get_default_gatt_adapter(); + if (gadapter == NULL) + return 0; + + for (l = gadapter->database, handle = 0; l; l = l->next) { struct attribute *a = l->data; if (handle && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 || @@ -1321,13 +1334,21 @@ struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs, int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value, int len, struct attribute **attr) { + struct gatt_adapter *gadapter; struct attribute *a; GSList *l; guint h = handle; + DBG("Deprecated function!"); + + gadapter = get_default_gatt_adapter(); + if (gadapter == NULL) + return -ENOENT; + DBG("handle=0x%04x", handle); - l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp); + l = g_slist_find_custom(gadapter->database, GUINT_TO_POINTER(h), + handle_cmp); if (!l) return -ENOENT; @@ -1351,18 +1372,26 @@ int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value, int attrib_db_del(uint16_t handle) { + struct gatt_adapter *gadapter; struct attribute *a; GSList *l; guint h = handle; + DBG("Deprecated function!"); + + gadapter = get_default_gatt_adapter(); + if (gadapter == NULL) + return -ENOENT; + DBG("handle=0x%04x", handle); - l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp); + l = g_slist_find_custom(gadapter->database, GUINT_TO_POINTER(h), + handle_cmp); if (!l) return -ENOENT; a = l->data; - database = g_slist_remove(database, a); + gadapter->database = g_slist_remove(gadapter->database, a); g_free(a->data); g_free(a); -- 1.7.8 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html