From facd6cb007f9542678f7c68f9d5efca7648acc91 Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Mon, 12 Oct 2020 11:42:59 +0530 Subject: [PATCH] GATT: Refactor Sever Indication logic This patch handles following:- - Use socket for multicast indication & fallback to DBUS for unicast indication. - Send Remote Client address from HAL to FRWK when indication is enabled by remote client. Change-Id: Idacecd5a28afab1b22b9588f092ed75ea95d9070 Signed-off-by: Anupam Roy --- bt-api/bt-gatt-service.c | 31 ++++++++++++++++++++++------ bt-oal/bluez_hal/inc/bt-hal-msg.h | 1 + bt-oal/bluez_hal/src/bt-hal-gatt-server.c | 33 ++++++++++++++++++++++-------- bt-oal/bluez_hal/src/bt-hal-gatt.c | 2 +- bt-oal/hardware/bt_gatt_server.h | 2 +- bt-oal/oal-gatt.c | 5 +++-- bt-service/services/gatt/bt-service-gatt.c | 2 +- include/bluetooth-gatt-server-api.h | 1 + 8 files changed, 57 insertions(+), 20 deletions(-) diff --git a/bt-api/bt-gatt-service.c b/bt-api/bt-gatt-service.c index c65bf82..60c58ff 100644 --- a/bt-api/bt-gatt-service.c +++ b/bt-api/bt-gatt-service.c @@ -343,18 +343,27 @@ static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info( static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id); static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info); -static int bluetooth_get_characteristic_fd(int att_handle , char *path) +static int bluetooth_get_characteristic_fd(int att_handle , char *address) { GSList *l; - BT_DBG("request found path [%s] att_handle [ %d]", path, att_handle); + BT_DBG("Find FD for address [%s] att_handle [ %d]", address, att_handle); + + /* Check for NULL address */ + if (g_strcmp0(address, "00:00:00:00:00:00") != 0) { + BT_INFO("Unicast address: Use DBUS send indication"); + return -1; + } + for (l = gatt_characteristic_server_notify_list; l != NULL; l = l->next) { bluetooth_gatt_acquire_notify_info_t *info = l->data; - if (info->att_hand == att_handle) + if (info->att_hand == att_handle) { + BT_INFO("ATT handle Matched: AquireNotify Set: Remote addr[%s]", info->address); return info->write_fd; + } } - return -1; + return -2; } static bluetooth_gatt_acquire_notify_info_t * bluetooth_get_characteristic_info_from_path(int att_handle) @@ -2911,12 +2920,18 @@ BT_EXPORT_API int bluetooth_gatt_server_send_indication(bluetooth_device_address g_array_append_vals(in_param3, addr_hex, sizeof(bluetooth_device_address_t)); _bt_convert_addr_type_to_string(addr, addr_hex->addr); + BT_INFO("Send Indication to address [%s]", addr); fd = bluetooth_get_characteristic_fd(param->atrribute_handle, addr); if (fd > -1) { + BT_INFO("Send Multicast"); result = bluetooth_gatt_write_characteristics_value_to_fd_(fd, att_value->data, att_value->length, NULL); param->fd = fd; - } else { + } else if (fd == -2) { + BT_ERR("Acquire Notify FD not found for charatcristic handle"); + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + return BLUETOOTH_ERROR_INVALID_PARAM; + } else if (fd == -1) { result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_SEND_INDICATION, in_param1, in_param2, in_param3, in_param4, &out_param); } @@ -3226,13 +3241,17 @@ void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters, chr_info = bluetooth_get_characteristic_info_from_path(att_han); if (!chr_info) { + BT_INFO("char info not found for ATT handle [%u]", att_han); chr_info = g_malloc0(sizeof(bluetooth_gatt_acquire_notify_info_t)); chr_info->write_fd = fd; chr_info->att_hand = att_han; + memcpy(chr_info->address, address, BLUETOOTH_ADDRESS_STRING_LENGTH); gatt_characteristic_server_notify_list = g_slist_append(gatt_characteristic_server_notify_list, chr_info); - } else + } else { + BT_INFO("Already AcquireNotify Set for this attribute handle by remote Client [%s]", chr_info->address); chr_info->write_fd = fd; + } channel = g_io_channel_unix_new(fd); chr_info->io_channel = channel; diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index cd9c440..0d1199f 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -772,6 +772,7 @@ struct hal_ev_gatt_server_acquire_notify { int32_t conn_id; int32_t char_handl; char *path; + uint8_t bdaddr[6]; } __attribute__((packed)); #define HAL_EV_GATT_CLIENT_NOTIFY_CHANGED_VALUE 0XCB diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c index 59f91e4..6336fbf 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c @@ -1490,12 +1490,15 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, uint16_t mtu = 512; int char_hdl = -1; + char *dev_path = NULL; + char *link = NULL; struct hal_ev_gatt_server_acquire_notify ev; struct gatt_service_info *svc_info = NULL; struct gatt_client_info_t *conn_info = NULL; struct gatt_req_info *req_info = NULL; + char addr[BT_HAL_ADDRESS_STRING_SIZE]; - DBG("AcquireNotify : Application path %s, sender %s", object_path, sender); + INFO("AcquireNotify : Application path %s, sender %s", object_path, sender); GVariantIter* iter; g_variant_get(parameters, "(a{sv})", &iter); @@ -1504,12 +1507,28 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { if (g_strcmp0(key, "MTU") == 0) g_variant_get(value, "q", &mtu); + else if (g_strcmp0(key, "link") == 0) + g_variant_get(value, "s", &link); + else if (g_strcmp0(key, "device") == 0) + g_variant_get(value, "o", &dev_path); } DBG("MTU = %u", mtu); + INFO("Dev Path %s LINK = %s, MTU = %u", dev_path, link, mtu); + _bt_hal_convert_device_path_to_address(dev_path, addr); + INFO("Remote address %s", addr); + g_free(link); + g_free(dev_path); svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl); + /* Check if device is already in connected list */ + conn_info = __bt_find_remote_gatt_client_info(addr); + if (conn_info == NULL) { + ERR("Client info not found\n"); + g_variant_iter_free(iter); + goto done; + } if (svc_info == NULL) { ERR("svc_info info not found\n"); g_variant_iter_free(iter); @@ -1520,26 +1539,22 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, req_info = g_new0(struct gatt_req_info, 1); req_info->attr_path = g_strdup(object_path); req_info->svc_path = g_strdup(svc_info->serv_path); - req_info->request_id = 33; + req_info->request_id = -1; req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY; req_info->offset = mtu; req_info->context = invocation; - conn_info = g_new0(struct gatt_client_info_t, 1); - conn_info->addr = g_strdup(object_path); INFO("AcquireNotify : Added GATT client path[%s]", conn_info->addr); - conn_info->connection_id = 33; - conn_info->instance_id = 33; /* Append request info in list of requests for the particular connection */ conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info); - gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info); /* Send HAL event */ memset(&ev, 0, sizeof(ev)); - ev.conn_id = 33; + ev.conn_id = conn_info->connection_id; ev.char_handl = char_hdl; ev.mtu = mtu; - ev.trans_id = 33; + ev.trans_id = req_info->request_id; + _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr); event_cb(HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES, (void *)&ev, sizeof(ev)); g_variant_iter_free(iter); diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt.c b/bt-oal/bluez_hal/src/bt-hal-gatt.c index 5371784..0ec2253 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt.c @@ -267,7 +267,7 @@ static void __bt_hal_handle_gatt_server_acquire_notify_requested(void *buf, uint DBG("acquire notify requested event recived"); if (bt_gatt_callbacks->server->request_acquire_notify_cb) - bt_gatt_callbacks->server->request_acquire_notify_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl); + bt_gatt_callbacks->server->request_acquire_notify_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl, (bt_bdaddr_t *)ev->bdaddr); } static void __bt_hal_handle_gatt_server_indicate_confirmed(void *buf, uint16_t len) diff --git a/bt-oal/hardware/bt_gatt_server.h b/bt-oal/hardware/bt_gatt_server.h index 73df96c..ef7a190 100644 --- a/bt-oal/hardware/bt_gatt_server.h +++ b/bt-oal/hardware/bt_gatt_server.h @@ -138,7 +138,7 @@ typedef void (*request_acquire_write_callback)(int mtu, int conn_id, int trans_i int attr_handle, bt_bdaddr_t *bda); typedef void (*request_acquire_notify_callback)(int fd, int conn_id, int trans_id, - int attr_handle); + int attr_handle, bt_bdaddr_t *bd); /** Callback invoked when a previously prepared write is to be executed */ diff --git a/bt-oal/oal-gatt.c b/bt-oal/oal-gatt.c index ab6cc88..905f9ba 100644 --- a/bt-oal/oal-gatt.c +++ b/bt-oal/oal-gatt.c @@ -144,7 +144,7 @@ static void cb_gatts_request_write(int conn_id, int trans_id, bt_bdaddr_t *bda, static void cb_gatts_response_confirmation(int status, int handle); static void cb_gatts_acquire_write(int fd, int conn_id, int trans_id, int attr_handle, bt_bdaddr_t*); -static void cb_gatts_acquire_notify(int fd, int conn_id, int trans_id, int attr_handle); +static void cb_gatts_acquire_notify(int fd, int conn_id, int trans_id, int attr_handle, bt_bdaddr_t*); static void cb_indication_confirmation(int conn_id, int trans_id, int attr_handle, bt_bdaddr_t *bda); static void cb_gatts_connection(int conn_id, int server_if, int connected, bt_bdaddr_t *bda); @@ -1274,7 +1274,7 @@ static void cb_gatts_acquire_write(int mtu, int conn_id, int trans_id, int attr_ send_event(OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE, event, sizeof(event_gatts_srvc_acquire_attr_t)); } -static void cb_gatts_acquire_notify(int mtu, int conn_id, int trans_id, int attr_handle) +static void cb_gatts_acquire_notify(int mtu, int conn_id, int trans_id, int attr_handle, bt_bdaddr_t *bda) { BT_INFO("BTGATT SERVER REQUEST ACQUIRE NOTIFY conn_id:%d", conn_id); @@ -1284,6 +1284,7 @@ static void cb_gatts_acquire_notify(int mtu, int conn_id, int trans_id, int attr event->attr_trans.conn_id = conn_id; event->attr_trans.trans_id = trans_id; event->mtu = mtu; + memcpy(event->address.addr, bda->address, BT_ADDRESS_BYTES_NUM); send_event(OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY, event, sizeof(event_gatts_srvc_acquire_attr_t)); diff --git a/bt-service/services/gatt/bt-service-gatt.c b/bt-service/services/gatt/bt-service-gatt.c index f4d73e8..9944e26 100644 --- a/bt-service/services/gatt/bt-service-gatt.c +++ b/bt-service/services/gatt/bt-service-gatt.c @@ -1682,7 +1682,7 @@ static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_ac memcpy(dev_addr.addr, event->address.addr, 6); _bt_convert_addr_type_to_string(address, (unsigned char *)dev_addr.addr); - BT_DBG("remote address : [%s]", address); + BT_INFO("Remote address : [%s]", address); req_info = g_new0(struct gatt_server_req_info, 1); req_info->request_id = event->attr_trans.trans_id; diff --git a/include/bluetooth-gatt-server-api.h b/include/bluetooth-gatt-server-api.h index 08068b5..e997afa 100644 --- a/include/bluetooth-gatt-server-api.h +++ b/include/bluetooth-gatt-server-api.h @@ -184,6 +184,7 @@ typedef struct { void *io_channel; guint watch_id; char *path ; + char address[BLUETOOTH_ADDRESS_STRING_LENGTH]; } bluetooth_gatt_acquire_notify_info_t; /** -- 2.7.4