4 * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
6 * Contact: Anupam Roy (anupam.r@samsung.com)
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 #include "bt-service-common.h"
24 #include "bt-service-core-adapter.h"
25 #include "bt-service-event-receiver.h"
26 #include "bt-request-handler.h"
27 #include "bluetooth-api.h"
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
31 #include "bt-service-util.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
35 #include "bt-internal-types.h"
36 #include "bt-service-gatt.h"
37 #include "bt-service-gatt.h"
38 #include "bt-service-core-device.h"
39 #include "bt-service-core-adapter-le.h"
40 #include "bluetooth-gatt-client-api.h"
42 #include <oal-hardware.h>
43 #include <oal-manager.h>
44 #include <oal-event.h>
45 #include <oal-adapter-mgr.h>
46 #include <oal-device-mgr.h>
49 #define BT_GATT_TRANSPORT_LE 0
50 #define BT_GATT_TRANSPORT_BR_EDR 1
51 #define BT_GATT_TRANSPORT_LE_BR_EDR 2
52 #define BT_UUID_STRING_MAX 64
53 #define BT_SENDER_MAX_LENGTH 50
54 #define MAX_APPS_SUPPORTED 11 /* Slot 0 is not used */
55 #define BT_DEFAULT_ATT_MTU 23
57 #define UUID_MAX_LEN 50
59 #ifdef TIZEN_BLUEDROID_PORTING
68 bluetooth_gatt_att_request_type_e request_type;
69 int prep_request_count;
70 } bt_gatt_prep_write_data_t;
72 static GSList *g_pending_write_list = NULL;
75 #define BDADDR_ANY (&(bluetooth_device_address_t) {{0, 0, 0, 0, 0, 0} })
77 static char uuid_list[NUM_UUID][BT_UUID_STRING_MAX] = {"0000b00b-0000-0000-f065-080080fa49b5", /* Used by BLEAPP */
78 "0000b00b-1111-1111-0123-456789ab0cd2", /* Used by BLEAPP */
79 "0000b00b-2222-1111-0123-456789ab0cd2",
80 "0000b00b-3333-1111-0123-456789ab0cd2",
81 "0000b00b-4444-1111-0123-456789ab0cd2",
82 "0000b00b-5555-1111-0123-456789ab0cd2",
83 "0000b00b-6666-1111-0123-456789ab0cd2",
84 "0000b00b-7777-1111-0123-456789ab0cd2",
85 "0000b00b-8888-1111-0123-456789ab0cd2",
86 "0000b00b-9999-1111-0123-456789ab0cd2",
87 "0000b00b-aaaa-1111-0123-456789ab0cd2",
88 "0000b00b-bbbb-1111-0123-456789ab0cd2",
89 "0000b00b-cccc-1111-0123-456789ab0cd2",
90 "0000b00b-dddd-1111-0123-456789ab0cd2",
91 "0000b00b-eeee-1111-0123-456789ab0cd2",
92 "0000b00b-ffff-1111-0123-456789ab0cd2",
93 "0000b00c-0000-1111-0123-456789ab0cd2",
94 "0000b00c-1111-1111-0123-456789ab0cd2",
95 "0000b00c-2222-1111-0123-456789ab0cd2",
96 "0000b00c-3333-1111-0123-456789ab0cd2"};
98 /* Reserved GATT client Instance UUID. This is used only internally by bt-service */
99 #define DEFAULT_GATT_CLIENT_UUID "0000a00a-1111-1111-0123-456789abcdef"
101 static int gatt_default_client = -1;
104 gboolean is_registered;
105 bluetooth_device_address_t addr;
106 unsigned char svc_uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
108 unsigned char char_uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
110 } bt_gatt_notif_reg_info_t;
112 struct gatt_out_conn_info_t {
113 int client_id; /* This value unique identifies a GATT Client instance */
114 char *addr; /* Remote GATT Server address */
117 /* Linked List of outgoing gatt connection list
118 Note: This is valid only for local GATT client */
119 static GSList *outgoing_gatt_conn_list = NULL;
121 /* GATT Server Info(Local Client) List Structure */
122 struct gatt_server_info_t {
123 int connection_id; /* This value will uniquely identify a GATT client-server connection */
124 int client_id; /* This value unique identifies a GATT Client instance */
125 char *addr; /* Remote GATT Server address */
128 struct gatt_client_info_t {
129 int connection_id; /* This value will uniquely identify a GATT client-server connection */
130 int instance_id; /* This value unique identifies a GATT server instance */
131 char *addr; /* Remote GATT client address */
135 * Remove this feature if code is verified
136 * Remove gatt_client/server_info_t and use gatt_conn_info_t
137 * Remove gatt_client/server_info_list and use gatt_conn_info_list
139 //#define __INTEGRATE_GATT_INFO__ // TODO: this feature can be used if easy setup scenario is fully supported and the name need to be changed to avoid confusion with existing GATT flags
140 #ifndef __INTEGRATE_GATT_INFO__
141 /* Linked List of connected Remote GATT Servers */
142 static GSList *gatt_server_info_list = NULL;
143 /* Linked List of connected Remote GATT clients */
144 static GSList *gatt_client_info_list = NULL;
146 /* GATT Connection Info List Structure */
147 struct gatt_conn_info_t {
148 char *addr; /* Remote GATT address */
149 int connection_id; /* This value will uniquely identify a GATT client-server connection */
150 int client_id; /* This value unique identifies a GATT Client instance */
151 int instance_id; /* This value unique identifies a GATT Server instance */
154 /* Linked List of connected Remote GATT info */
155 static GSList *gatt_conn_info_list = NULL;
156 #define gatt_server_info_t gatt_conn_info_t
157 #define gatt_client_info_t gatt_conn_info_t
158 #define gatt_server_info_list gatt_conn_info_list
159 #define gatt_client_info_list gatt_conn_info_list
164 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN]; /* If any service added */
165 } bt_gatt_svc_changed_info_t;
170 // bluetooth_device_address_t address; /* Remote BLE Device Address */
171 GSList *services; /* List of all services of above remote device */
172 int count; /* Number of services browsed from remote device */
173 bt_gatt_svc_changed_info_t info;
174 } bt_gatt_service_info_list_t;
177 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
181 GSList *included_svcs;
182 gboolean is_removed; /* 0 => Service is added, 1=> removed */
183 } bt_gatt_service_info_t;
186 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
190 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
192 } bt_gatt_char_info_t;
195 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
198 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
199 } bt_gatt_descriptor_info_t;
202 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
204 } bt_gatt_included_service_info_t;
206 static GSList *list_gatt_info = NULL;
211 } bt_service_handle_uuid_info_t;
213 /* App Information structure */
216 char sender[BT_SENDER_MAX_LENGTH];
217 char uuid[BT_UUID_STRING_MAX];
220 bluetooth_advertising_data_t adv_data; /* Will store adv data for specific slot */
222 bluetooth_scan_resp_data_t scan_rsp; /* Will store scan rsp data for specific slot */
224 gboolean is_initialized;
225 GSList *service_handles;
226 GSList *service_handle_uuids; /* List of bt_service_handle_uuid_info_t */
227 int client_id; /* GATT Client instance ID */
228 bluetooth_device_address_t address; /* Remote BLE Device Address */
229 gboolean is_watcher_enabled;
230 } bt_service_app_info_t;
232 /* GATT Server Request Info Structure */
233 struct gatt_server_req_info {
234 int connection_id; /* This value will uniquely identify a GATT client-server connection */
235 int request_id; /* This is an unique transaction ID assigned against each request by stack */
236 int attribute_handle; /* GATT server attribute handle */
237 int offset; /* GATT server attribute offset on which request is invoked by GATT client */
238 bluetooth_gatt_att_request_type_e request_type; /* Read or Write request */
239 char *addr; /* Remote GATT client address */
242 /* GATT Indicate confirm result */
243 struct gatt_indicate_cfm_result_info_t {
244 int result; /* Result of event */
245 char *addr; /* Remote GATT client address */
246 int att_hdl; /* Characteristic Attribute handle */
247 int completed; /* 1 if last event, otheriwse 0 */
250 static char service_persistence[BT_UUID_STRING_SIZE + 1];
252 /* Request Search Utility method */
253 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
254 bluetooth_gatt_att_request_type_e req_type);
256 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
257 bluetooth_gatt_server_indication_params_t *param);
259 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info);
261 static void __bt_free_service_info(bt_gatt_service_info_t *service_info);
263 static int __bt_unregister_gatt_client_instance(int client_if);
265 static void __bt_service_reset_gatt_data(void);
267 static void __bt_handle_client_instance_registered(event_gattc_register_t *data);
268 static void __bt_handle_client_connected(event_gattc_conn_t *event_data);
269 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data);
270 static void __bt_handle_client_service_search_completed(event_gattc_conn_status_t *event_data);
271 static void __bt_handle_client_service_search_result(event_gattc_service_result_t *event_data);
272 static void __bt_handle_client_characteristic_search_result(
273 event_gattc_characteristic_result_t *event_data);
274 static void __bt_handle_client_descriptor_search_result(event_gattc_descriptor_result_t *event_data);
275 static void __bt_handle_client_characteristic_read_data(event_gattc_read_data *event_data);
276 static void __bt_handle_client_descriptor_read_data(event_gattc_read_data *event_data);
277 static void __bt_handle_client_characteristic_write_data(event_gattc_write_data *event_data);
278 static void __bt_handle_client_descriptor_write_data(event_gattc_write_data *event_data);
279 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data);
280 static void __bt_handle_client_notification_registered(event_gattc_regdereg_notify_t *event_data,
281 gboolean is_registered);
282 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data);
283 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data);
284 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data);
286 static int __bt_unregister_gatt_server_instance(int server_instance);
287 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info);
288 #ifdef TIZEN_BLUEDROID_PORTING
289 static void __bt_remove_all_prep_write_req(int conn_id);
293 struct gatt_mtu_info_t {
294 char *addr; /* Remote GATT Server address */
298 static GSList *gatt_mtu_info_list = NULL;
300 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address);
301 static void __bt_remove_mtu_gatt_device(char *address);
302 static void __bt_add_mtu_gatt_device(char *address);
303 static void __bt_update_mtu_gatt_device(char *address, int mtu);
305 /* Linked List of GATT requests from Remote GATT Clients */
306 static GSList *gatt_server_requests = NULL;
308 /* Number of clients to be notified to */
309 static int num_indicate_clients;
311 /* List of applications */
312 static bt_service_app_info_t numapps[MAX_APPS_SUPPORTED];
314 static void __bt_gatt_handle_pending_request_info(int result,
315 int service_function, void *data, unsigned int size);
317 static void __bt_handle_server_instance_registered(event_gatts_register_t *data);
319 static void __bt_gatt_event_handler(int event_type, gpointer event_data);
326 void _bt_check_adv_app_termination(const char *name)
328 bt_service_app_info_t *app = NULL;
330 int apps[MAX_APPS_SUPPORTED] = { 0, };
332 ret_if(NULL == name);
334 memset(&apps, -1, sizeof(apps));
336 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
339 /* Search for a app which has same sender and stop adv is running */
340 if (strcasecmp(app->sender, name) == 0 && app->is_initialized == TRUE) {
341 BT_DBG("numapps[%d] Match found, name: %s", k, name);
343 /* TODO 2: Need to manage app info as list, not array.
344 This loop always run for MAX count if any apps are terminated.
347 /* Save instances of all apps that need to be unregistered */
348 if (app->instance_id != -1) {
350 /* Unregister all service handles with stack */
351 __bt_remove_all_service_handles(app);
353 /* If Advertising is enabled, stop it */
354 if (app->adv_handle != 0) {
355 BT_INFO("Stop advertising on instance ID [%d]", app->instance_id);
356 /* Disable adv if running */
357 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
358 app->adv_handle, name);
359 _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE);
362 apps[app->instance_id] = BT_GATT_SERVER; /* App holds a GATT server Instance */
363 } else if (app->client_id != -1) {
365 apps[app->client_id] = BT_GATT_CLIENT; /* App holds a GATT client Instance */
370 /* Unregister all apps one by one */
371 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
372 if (apps[k] == BT_GATT_SERVER) {
373 BT_INFO("Unregister server app[%d]", k);
374 /* Unregister server instance */
375 __bt_unregister_gatt_server_instance(k);
376 } else if (apps[k] == BT_GATT_CLIENT) {
377 BT_INFO("Unregister client app[%d]", k);
378 /* Unregister client instance */
379 __bt_unregister_gatt_client_instance(k);
384 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
385 bluetooth_gatt_server_indication_params_t *param)
388 int ret = OAL_STATUS_SUCCESS;
389 int result = OAL_STATUS_INTERNAL_ERROR;
391 BT_INFO("Current total number of connected clients [%d]", g_slist_length(gatt_client_info_list));
392 for (l = gatt_client_info_list; l != NULL; l = l->next) {
393 struct gatt_client_info_t *info = l->data;
396 BT_INFO("GATT Remote client address [%s] connection Id [%d]", info->addr, info->connection_id);
398 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
399 info->connection_id, data->length,
400 param->need_confirmation, (char *)(&data->data[0]));
402 BT_INFO("Send Indication to GATT client [%s] result: [%d]", info->addr, ret);
403 if (ret == OAL_STATUS_SUCCESS) {
404 BT_INFO("Send Indication sent successfully to GATT client [%s]", info->addr);
406 num_indicate_clients++;
410 BT_INFO("Indication sending done for total number of clients [%d]", num_indicate_clients);
414 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
415 bluetooth_gatt_att_request_type_e req_type)
419 for (l = gatt_server_requests; l != NULL; l = l->next) {
420 struct gatt_server_req_info *req_info = l->data;
422 if (req_info && req_info->request_id == request_id && req_info->request_type == req_type) {
423 BT_DBG("GATT Server request info found Req ID [%d] handle [%d] conn ID [%d]",
424 req_info->request_id, req_info->attribute_handle, req_info->connection_id);
428 BT_ERR("Gatt Request not found");
432 static void __bt_gatt_server_release_request_info(const char *address)
435 struct gatt_server_req_info *req_info = NULL;
437 for (l = gatt_server_requests; l != NULL; l = g_slist_next(l)) {
439 if (req_info == NULL)
442 if (g_strcmp0(req_info->addr, address) == 0) {
443 BT_DBG("Remove unhandled req_info %s", address);
444 g_free(req_info->addr);
445 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
451 void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle)
455 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
456 if (numapps[k].is_initialized == 1 && numapps[k].instance_id == server_inst) {
457 *adv_handle = numapps[k].adv_handle;
463 char * _bt_gatt_get_default_gatt_client_uuid(void)
465 return g_strdup(DEFAULT_GATT_CLIENT_UUID);
469 static void __bt_register_default_gatt_client()
474 uuid_str = _bt_gatt_get_default_gatt_client_uuid();
475 _bt_string_to_uuid(uuid_str, (service_uuid_t*)&uuid);
477 BT_INFO("Register Default GATT client uuid [%s]", uuid_str);
479 if (OAL_STATUS_SUCCESS != gattc_register(&uuid)) /* for only Smart Control */
480 BT_ERR("gattc register failed");
485 static struct gatt_server_info_t *__bt_find_remote_gatt_server_info_from_conn_id(int conn_id)
488 struct gatt_server_info_t *info = NULL;
490 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
491 info = (struct gatt_server_info_t*)l->data;
495 if (info->connection_id == conn_id)
501 int _bt_gatt_init(void)
503 const char *stack_name = NULL;
508 result = gatt_enable();
509 if (result != OAL_STATUS_SUCCESS) {
510 BT_ERR("gatt Init failed");
511 return _bt_convert_oal_status_to_bt_error(result);
514 /* Register gatt event handler */
515 _bt_service_register_event_handler_callback(BT_GATT_MODULE, __bt_gatt_event_handler);
517 __bt_service_reset_gatt_data();
519 stack_name = oal_get_stack_name();
521 if (stack_name && g_strcmp0(stack_name, "bluez") == 0) {
522 /*In the platform, defacult gatt client should be registered */
523 __bt_register_default_gatt_client();
527 return BLUETOOTH_ERROR_NONE;
530 static void __bt_service_reset_gatt_data(void)
534 BT_INFO("Rest numapp");
537 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
538 numapps[k].is_initialized = 0;
539 numapps[k].instance_id = -1;
540 numapps[k].adv_handle = 0;
541 numapps[k].adv_instance = -1;
542 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
543 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
544 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
545 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
546 numapps[k].adv_data_len = 0;
547 numapps[k].scan_rsp_len = 0;
550 numapps[k].client_id = -1;
551 memset(numapps[k].address.addr, 0x00, BLUETOOTH_ADDRESS_LENGTH);
552 numapps[k].is_watcher_enabled = FALSE;
556 void _bt_gatt_deinit(void)
558 BT_INFO("GATT deinit");
560 /* Un-register the default gatt client before */
561 __bt_unregister_gatt_client_instance(gatt_default_client);
563 if (OAL_STATUS_SUCCESS != gatt_disable())
564 BT_ERR("gatt deinit failed");
566 /* Un-register gatt event handler */
567 _bt_service_unregister_event_handler_callback(BT_GATT_MODULE);
569 __bt_service_reset_gatt_data();
572 void _bt_update_adv_handle(const char *sender, int adv_handle)
575 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
576 bt_service_app_info_t *info = NULL;
578 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
580 /* Do not update client instance */
581 if (info->instance_id == -1)
583 /* Search for a app which has same sender and adv handle as 0 */
584 if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0)
585 info->adv_handle = adv_handle;
589 int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
592 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
593 bt_service_app_info_t *info = NULL;
595 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
597 /* Search for a app which has same sender and adv handle as 0
598 It is possible that same sender but different adv handle */
599 if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0) {
600 //info->adv_handle = adv_handle;
601 return info->instance_id;
607 int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot)
610 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
611 bt_service_app_info_t *info = NULL;
613 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
616 /* Exact matching of Adv handle + sender combination */
617 if (!g_strcmp0(info->sender, sender) && info->adv_handle == adv_handle)
618 return info->instance_id;
620 if (!g_strcmp0(info->sender, sender) && info->adv_handle == -1)
621 return info->instance_id;
627 char * _bt_get_sender_and_handle(int server_instance, int *adv_handle)
630 bt_service_app_info_t *info = NULL;
632 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
635 if (info->instance_id == server_instance && info->adv_handle != 0) {
636 *adv_handle = info->adv_handle;
637 BT_DBG("Server instance [%d] Adv handle [%d] Sender [%s]", server_instance, *adv_handle, info->sender);
638 return g_strdup(info->sender);
644 void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance)
648 bt_service_app_info_t *info = NULL;
649 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
652 if (info->instance_id == instance) {
653 memcpy(info->adv_data.data, &adv->data, len);
659 void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance)
663 bt_service_app_info_t *info = NULL;
664 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
667 if (info->instance_id == instance) {
668 memcpy(info->scan_rsp.data, &scan->data, len);
674 void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance)
677 bt_service_app_info_t *info = NULL;
679 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
682 if (info->instance_id == instance) {
683 memcpy(&adv->data, info->adv_data.data, info->adv_data_len);
684 *len = info->adv_data_len;
690 void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance)
694 bt_service_app_info_t *info = NULL;
696 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
699 if (info->instance_id == instance) {
700 memcpy(&scan->data, info->scan_rsp.data, info->scan_rsp_len);
701 *len = info->scan_rsp_len;
707 static gboolean __bt_check_service_uuid_registered(const char *service_uuid)
711 bt_service_app_info_t *info = NULL;
713 bt_service_handle_uuid_info_t *uuid_info = NULL;
715 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
718 for (l = info->service_handle_uuids; l != NULL; l = g_slist_next(l)) {
722 if (!g_strcmp0(uuid_info->service_uuid, service_uuid)) {
723 BT_INFO("Same Service UUID is registered");
732 static void __bt_remove_service_uuid(int service_handle)
736 bt_service_app_info_t *info = NULL;
738 bt_service_handle_uuid_info_t *uuid_info = NULL;
739 bool removed = false;
741 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
744 for (l = info->service_handle_uuids; l != NULL;) {
749 if (uuid_info->service_handle == service_handle) {
750 BT_INFO("Removed Service handle [%d] Service UUID [%s]",
751 uuid_info->service_handle, uuid_info->service_uuid);
752 info->service_handle_uuids = g_slist_remove(info->service_handle_uuids, uuid_info);
753 g_free(uuid_info->service_uuid);
765 static int __bt_unregister_gatt_client_instance(int client_if)
767 int ret = OAL_STATUS_SUCCESS;
770 BT_INFO("DeAllocate client instance ID [%d]", client_if);
772 /* Reset data: instance_id parameter could be either for GATT Server or for GATT client */
773 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
774 if (numapps[k].client_id == client_if) {
775 BT_INFO("This is a GATT client app, unregister: Slot [%d] vacant", k);
776 numapps[k].client_id = -1;
777 numapps[k].is_initialized = FALSE;
778 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
779 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
780 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
782 /* Its a GATT Client Instance */
783 ret = gattc_deregister(client_if);
784 if (ret != OAL_STATUS_SUCCESS) {
785 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
786 return _bt_convert_oal_status_to_bt_error(ret);
791 return BLUETOOTH_ERROR_NONE;
794 static int __bt_unregister_gatt_server_instance(int server_instance)
796 int ret = OAL_STATUS_SUCCESS;
799 /* Unregister the server instance */
800 ret = gatts_unregister(server_instance);
801 if (ret != OAL_STATUS_SUCCESS) {
802 BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret);
803 return _bt_convert_oal_status_to_bt_error(ret);
805 BT_INFO("DeAllocated server instance with stack successful..");
808 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
809 if (numapps[k].instance_id == server_instance) {
810 numapps[k].is_initialized = 0;
811 numapps[k].instance_id = -1;
812 numapps[k].adv_handle = 0;
813 numapps[k].adv_instance = -1;
814 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
815 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
816 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
817 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
818 numapps[k].adv_data_len = 0;
819 numapps[k].scan_rsp_len = 0;
823 BT_DBG("Going8 to reset numapp block num [%d]", k);
824 return BLUETOOTH_ERROR_NONE;
827 int _bt_gatt_server_set_service_persistence(const char *uuid)
829 int result = BLUETOOTH_ERROR_NONE;
832 retv_if(uuid == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
834 if (!strncasecmp(service_persistence, uuid, BT_UUID_STRING_SIZE)) {
835 result = BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
837 g_strlcpy(service_persistence, uuid, sizeof(service_persistence));
838 BT_DBG("Set service(%s) to be persisted not removed", uuid);
844 int _bt_gatt_server_unset_service_persistence(const char *uuid)
846 int result = BLUETOOTH_ERROR_NONE;
849 retv_if(uuid == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
851 if (!strncasecmp(service_persistence, uuid, BT_UUID_STRING_SIZE)) {
852 memset(service_persistence, 0, sizeof(service_persistence));
853 BT_DBG("Unset service persistence: %s", uuid);
855 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
861 char *_bt_gatt_server_get_service_persistence()
863 return service_persistence;
866 static gboolean __bt_gatt_server_is_service_persistence(int service_handle)
869 bt_service_app_info_t *info = NULL;
870 bt_service_handle_uuid_info_t *uuid_info = NULL;
872 for (int k = 1; k < MAX_APPS_SUPPORTED; k++) {
874 for (l = info->service_handle_uuids; l != NULL;) {
879 if (uuid_info->service_handle == service_handle) {
880 char *uuid = _bt_gatt_server_get_service_persistence();
881 if (!strcasecmp(uuid_info->service_uuid, uuid)) {
882 BT_DBG("service(%s) persisted by user. can't be removed", uuid);
892 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info)
896 int ret = OAL_STATUS_SUCCESS;
899 if (app_info == NULL)
902 count = g_slist_length(app_info->service_handles);
903 BT_INFO("Before handle removal: current count [%d]", count);
905 for (l = app_info->service_handles; l != NULL;) {
910 if (__bt_gatt_server_is_service_persistence(*handle))
913 BT_INFO("Server Handle to be Removed [%d] Instance ID [%d]", *handle, app_info->instance_id);
914 if (_bt_gatt_server_stop_service(app_info->sender, *handle, app_info->instance_id) != BLUETOOTH_ERROR_NONE)
917 ret = gatts_delete_service(app_info->instance_id, *handle);
918 if (ret != OAL_STATUS_SUCCESS) {
919 BT_ERR("ret: %d", ret);
922 app_info->service_handles = g_slist_remove(app_info->service_handles, handle);
923 /* Remove Service UUID from the list */
924 __bt_remove_service_uuid(*handle);
927 count = g_slist_length(app_info->service_handles);
928 BT_INFO("After deleting current count [%d]", count);
934 int _bt_unregister_server_instance(const char *sender, int adv_handle)
936 BT_INFO("Unregister Allocated server instance request Sender [%s] Adv handle [%d]", sender, adv_handle);
937 int result = BLUETOOTH_ERROR_NONE;
938 int apps[MAX_APPS_SUPPORTED];
941 bt_service_app_info_t *info = NULL;
943 memset(&apps, -1, sizeof(apps));
945 if (adv_handle == 0) {
946 BT_DBG("Its a direct GATT Server app request to unregister");
947 /* Unregister server instance for each app with same sender (case: GATT Server with multiple adv handle) */
949 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
952 /* Exact matching of sender */
953 if (!g_strcmp0(info->sender, sender)) {
954 BT_INFO("Unregister GATT server instance [%d]", info->instance_id);
955 /* Unregister all service handles with stack */
956 __bt_remove_all_service_handles(info);
958 /* Disable adv if running */
959 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
960 info->adv_handle, sender);
961 _bt_set_advertising(sender, info->adv_handle, FALSE, FALSE);
963 /* Save all instances which need to be unregistered */
964 apps[info->instance_id] = 1;
968 BT_DBG("Its an Internal unregister request by adv application");
969 server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
970 BT_DBG("Its an Internal unregister request by adv application: Adv disabled srv instance [%d]", server_instance);
971 if (server_instance == -1) {
972 BT_ERR("No allocated server instance to be removed");
973 return BLUETOOTH_ERROR_INVALID_PARAM;
976 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
978 if (info->instance_id == server_instance) {
979 if (info->service_handles == NULL) {
980 BT_INFO("There are no Service handles with this app, safe to unregister");
981 /* Unregister server instance only if this sender does not have any gatt services in it */
982 result = __bt_unregister_gatt_server_instance(server_instance);
984 info->adv_handle = 0;
985 memset(info->adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
986 info->adv_data_len = 0;
987 memset(info->scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
988 info->scan_rsp_len = 0;
995 /* Unregister all apps one by one */
996 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
998 BT_INFO("Unregister app[%d]", k);
999 /* Unregister server instance */
1000 __bt_unregister_gatt_server_instance(k);
1007 int _bt_register_server_instance(const char *sender, int adv_handle)
1009 int ret = OAL_STATUS_SUCCESS;
1010 char *uuid_string = NULL;
1015 BT_INFO("Check on which instance Server instance can be initialized....");
1016 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1017 if (numapps[k].is_initialized == 1 || strlen(numapps[k].uuid) > 0) {
1018 BT_DBG("Instance ID [%d] is already in use..Check next slot", numapps[k].instance_id);
1021 BT_DBG("Time to register GATT Server..UUID to be used is [%s] slot [%d]", uuid_list[slot-1], slot);
1027 BT_ERR("No Slot if free for GATT Server registration..");
1028 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
1031 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
1032 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
1033 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
1034 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
1036 /* Register GATT Server */
1037 ret = gatts_register(&uuid);
1038 if (ret != OAL_STATUS_SUCCESS) {
1039 BT_ERR("ret: %d", ret);
1040 g_free(uuid_string);
1041 return _bt_convert_oal_status_to_bt_error(ret);
1043 BT_DBG("GATT Server registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
1044 /* Return & wait for GATT Server Instance Initialization event */
1045 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
1046 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
1048 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
1049 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
1051 numapps[slot].is_initialized = 0; /* Set initialization from app registered callback */
1052 numapps[slot].adv_handle = adv_handle;
1054 g_free(uuid_string);
1055 return BLUETOOTH_ERROR_NONE;
1058 /* Event handlers */
1059 static void __bt_gatt_get_pending_request_info(int service_function,
1063 invocation_info_t *req_info = NULL;
1065 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1067 if (req_info == NULL)
1070 if (req_info->service_function == service_function) {
1071 *sender = req_info->sender;
1077 static void __bt_gatt_cleanup_invocation_on_gatt_disconnection(int result,
1078 void *data, unsigned int size)
1083 invocation_info_t *req_info = NULL;
1084 ret_if(data == NULL);
1085 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1087 for (l = _bt_get_invocation_list(); l != NULL; ) {
1089 l = g_slist_next(l);
1091 if (req_info == NULL)
1094 switch (req_info->service_function) {
1095 case BT_GATT_GET_PRIMARY_SERVICES: {
1096 if(!g_strcmp0((char*)req_info->user_data, (char*)data)){
1097 bt_services_browse_info_t param;
1098 memset(¶m, 0, sizeof(bt_services_browse_info_t));
1099 _bt_convert_addr_string_to_type(param.device_addr.addr, (char*)data);
1100 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1101 g_array_append_vals(out_param, ¶m, sizeof(bt_services_browse_info_t));
1102 _bt_service_method_return(req_info->context, out_param, result);
1103 BT_DBG("BT_GATT_GET_PRIMARY_SERVICES request cleared for address [%s]", (char*)data);
1104 _bt_free_info_from_invocation_list(req_info);
1105 g_array_free(out_param, TRUE);
1109 case BT_GATT_GET_SERVICE_PROPERTIES: {
1110 bluetooth_gatt_client_svc_prop_info_t *prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
1111 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1112 if (!g_strcmp0(addr, (char*)data)){
1113 bt_char_browse_info_t param;
1114 memset(¶m, 0, sizeof(bt_char_browse_info_t));
1115 _bt_convert_addr_string_to_type(param.device_addr.addr,addr);
1116 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1117 g_array_append_vals(out_param, ¶m, sizeof(bt_char_browse_info_t));
1118 _bt_service_method_return(req_info->context, out_param, result);
1119 BT_DBG("BT_GATT_GET_SERVICE_PROPERTIES request cleared for address [%s]", addr);
1120 _bt_free_info_from_invocation_list(req_info);
1121 g_array_free(out_param, TRUE);
1125 case BT_GATT_GET_CHARACTERISTIC_PROPERTIES: {
1126 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1127 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1128 if (!g_strcmp0(addr, (char*)data)){
1129 bt_descriptor_browse_info_t param;
1130 memset(¶m, 0, sizeof(bt_descriptor_browse_info_t));
1131 _bt_convert_addr_string_to_type(param.device_addr.addr, addr);
1132 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1133 g_array_append_vals(out_param, ¶m, sizeof(bt_descriptor_browse_info_t));
1134 _bt_service_method_return(req_info->context, out_param, result);
1135 BT_DBG("BT_GATT_GET_CHARACTERISTIC_PROPERTIES request cleared for address [%s]", addr);
1136 _bt_free_info_from_invocation_list(req_info);
1137 g_array_free(out_param, TRUE);
1141 case BT_GATT_WATCH_CHARACTERISTIC: {
1142 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1143 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1144 if (!g_strcmp0(addr, (char*)data)){
1145 bt_gatt_notif_reg_info_t param;
1146 memset(¶m, 0, sizeof(bt_gatt_notif_reg_info_t));
1147 _bt_convert_addr_string_to_type(param.addr.addr, addr);
1148 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1149 g_array_append_vals(out_param, ¶m, sizeof(bt_gatt_notif_reg_info_t));
1150 _bt_service_method_return(req_info->context, out_param, result);
1151 _bt_free_info_from_invocation_list(req_info);
1152 g_array_free(out_param, TRUE);
1156 case BT_GATT_READ_CHARACTERISTIC:
1157 case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: {
1158 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1159 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1160 if (!g_strcmp0(addr, (char*)data)){
1161 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1162 g_array_append_vals(out_param, prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
1163 _bt_service_method_return(req_info->context, out_param, result);
1164 BT_DBG("BT_GATT_READ/WRITE_CHARACTERISTIC request cleared for address [%s]", addr);
1165 _bt_free_info_from_invocation_list(req_info);
1166 g_array_free(out_param, TRUE);
1170 case BT_GATT_READ_DESCRIPTOR_VALUE:
1171 case BT_GATT_WRITE_DESCRIPTOR_VALUE: {
1172 bluetooth_gatt_client_desc_prop_info_t *prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
1173 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1174 if (!g_strcmp0(addr, (char*)data)){
1175 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1176 g_array_append_vals(out_param, prop, sizeof(bluetooth_gatt_client_desc_prop_info_t));
1177 _bt_service_method_return(req_info->context, out_param, result);
1178 BT_DBG("BT_GATT_READ/WRITE_DESCRIPTOR_VALUE request cleared for address [%s]", addr);
1179 _bt_free_info_from_invocation_list(req_info);
1180 g_array_free(out_param, TRUE);
1184 case BT_REQ_ATT_MTU: {
1185 char *temp_addr = (char*)req_info->user_data;
1186 bluetooth_device_address_t address;
1187 if (!g_strcmp0(temp_addr, (char*)data)) {
1188 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1189 _bt_convert_addr_string_to_type(address.addr, temp_addr);
1190 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1191 sizeof(bluetooth_device_address_t));
1192 _bt_service_method_return(req_info->context, out_param, result);
1193 _bt_free_info_from_invocation_list(req_info);
1194 g_array_free(out_param, TRUE);
1205 static void __bt_gatt_handle_pending_request_info(int result,
1206 int service_function, void *data, unsigned int size)
1210 invocation_info_t *req_info = NULL;
1211 ret_if(data == NULL);
1213 for (l = _bt_get_invocation_list(); l != NULL; ) {
1215 l = g_slist_next(l);
1216 if (req_info == NULL || req_info->service_function != service_function)
1219 switch (service_function) {
1221 case BT_GATT_SERVER_REGISTER: {
1222 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1224 if (!g_strcmp0(req_info->sender, param->sender)) {
1225 BT_DBG("GATT Server app found [%s]", req_info->sender);
1227 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1228 g_array_append_vals(out_param, ¶m->instance_id, sizeof(int));
1229 _bt_service_method_return(req_info->context, out_param, result);
1231 _bt_free_info_from_invocation_list(req_info);
1232 g_array_free(out_param, TRUE);
1236 case BT_GATT_SERVER_START_SERVICE:
1237 case BT_GATT_SERVER_DELETE_SERVICE: {
1238 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1240 int *saved_instance_id = (int*)req_info->user_data;
1241 if (!g_strcmp0(req_info->sender, param->sender) && param->instance_id == *saved_instance_id) {
1242 BT_DBG("GATT Server app found [%s] Instance ID [%d] Reply DBUS",
1243 req_info->sender, *saved_instance_id);
1245 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1246 g_array_append_vals(out_param, &saved_instance_id, sizeof(int));
1247 _bt_service_method_return(req_info->context, out_param, result);
1249 _bt_free_info_from_invocation_list(req_info);
1250 g_array_free(out_param, TRUE);
1254 case BT_GATT_SERVER_ADD_SERVICE:
1255 case BT_GATT_SERVER_ADD_DESCRIPTOR:
1256 case BT_GATT_SERVER_ADD_CHARACTERISTIC: {
1257 int *handle = (int*)data;
1258 BT_DBG("Characteristic added: Handle [%d]", *handle);
1259 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1261 g_array_append_vals(out_param, handle, sizeof(int));
1262 _bt_service_method_return(req_info->context, out_param, result);
1264 _bt_free_info_from_invocation_list(req_info);
1265 g_array_free(out_param, TRUE);
1270 case BT_DISCONNECT_LE: {
1271 char *addr = (char*)req_info->user_data;
1272 bluetooth_device_address_t address;
1274 if (!g_strcmp0(addr, (char*)data)) {
1275 BT_INFO("GATT Client connect-disconnect call pending for app [%s] addr [%s]",
1276 req_info->sender, addr + 12);
1277 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1278 _bt_convert_addr_string_to_type(address.addr, addr);
1280 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1281 sizeof(bluetooth_device_address_t));
1282 _bt_service_method_return(req_info->context, out_param, result);
1284 _bt_free_info_from_invocation_list(req_info);
1285 g_array_free(out_param, TRUE);
1289 case BT_GATT_CLIENT_REGISTER: {
1290 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1292 if (!g_strcmp0(req_info->sender, param->sender)) {
1293 BT_DBG("GATT Client app found [%s] created client ID [%d]",
1294 req_info->sender, param->client_id);
1296 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1297 g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1298 _bt_service_method_return(req_info->context, out_param, result);
1300 _bt_free_info_from_invocation_list(req_info);
1301 g_array_free(out_param, TRUE);
1305 case BT_GATT_GET_PRIMARY_SERVICES: {
1306 bt_services_browse_info_t *param = (bt_services_browse_info_t*)data;
1307 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1308 _bt_convert_addr_type_to_string(address,
1309 (unsigned char *)(¶m->device_addr.addr));
1311 /* Match address to determine same request */
1312 if (!g_strcmp0((char*)req_info->user_data, address)) {
1313 BT_DBG("GATT Client app found [%s] Remote address [%s]",
1314 req_info->sender, address);
1316 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1317 g_array_append_vals(out_param, param,
1318 sizeof(bt_services_browse_info_t));
1320 //g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1321 _bt_service_method_return(req_info->context, out_param, result);
1323 _bt_free_info_from_invocation_list(req_info);
1324 g_array_free(out_param, TRUE);
1329 case BT_GATT_GET_SERVICE_PROPERTIES: {
1330 bt_char_browse_info_t param;
1331 memcpy((void*)¶m, data, sizeof(bt_char_browse_info_t));
1332 //bt_char_browse_info_t *param = (bt_char_browse_info_t*)data;
1334 bluetooth_gatt_client_svc_prop_info_t *prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
1336 /* Match both address and service properties to determine same request */
1337 if (!memcmp(param.device_addr.addr,
1338 prop->device_address.addr,
1339 sizeof(bluetooth_device_address_t)) &&
1340 !memcmp(param.svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1341 param.svc_inst_id == prop->svc.instance_id) {
1342 BT_DBG("Returning Service properties");
1344 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1345 g_array_append_vals(out_param, ¶m, sizeof(bt_char_browse_info_t));
1346 _bt_service_method_return(req_info->context, out_param, result);
1348 _bt_free_info_from_invocation_list(req_info);
1349 g_array_free(out_param, TRUE);
1353 case BT_GATT_GET_CHARACTERISTIC_PROPERTIES: {
1354 bt_descriptor_browse_info_t *param = (bt_descriptor_browse_info_t*)data;
1356 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1358 /* Match both address, service properties &char properties to determine same request */
1359 if (!memcmp(param->device_addr.addr,
1360 prop->device_address.addr,
1361 sizeof(bluetooth_device_address_t)) &&
1362 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1363 param->svc_inst_id == prop->svc.instance_id &&
1364 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1365 param->char_inst_id == prop->characteristic.instance_id) {
1366 BT_DBG("Returning Characteristic properties");
1367 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1368 g_array_append_vals(out_param, param, sizeof(bt_descriptor_browse_info_t));
1369 _bt_service_method_return(req_info->context, out_param, result);
1371 _bt_free_info_from_invocation_list(req_info);
1372 g_array_free(out_param, TRUE);
1376 case BT_GATT_WATCH_CHARACTERISTIC: {
1377 bt_gatt_notif_reg_info_t *param = (bt_gatt_notif_reg_info_t*)data;
1378 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1380 /* Match both address, service properties &char properties to determine same request */
1381 if (!memcmp(param->addr.addr,
1382 prop->device_address.addr,
1383 sizeof(bluetooth_device_address_t)) &&
1384 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1385 param->svc_inst == prop->svc.instance_id &&
1386 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1387 param->char_inst == prop->characteristic.instance_id) {
1388 BT_INFO("Characteristic Watch Successful: Is registered [%d]",
1389 param->is_registered);
1390 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1391 g_array_append_vals(out_param, param, sizeof(bt_gatt_notif_reg_info_t));
1392 _bt_service_method_return(req_info->context, out_param, result);
1393 _bt_free_info_from_invocation_list(req_info);
1394 g_array_free(out_param, TRUE);
1398 case BT_GATT_READ_CHARACTERISTIC:
1399 case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: {
1400 bluetooth_gatt_client_char_prop_info_t *param = (bluetooth_gatt_client_char_prop_info_t*)data;
1402 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1403 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1404 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1406 if (!memcmp(param, prop, sizeof(bluetooth_gatt_client_char_prop_info_t))) {
1407 BT_DBG("Gatt Char read or write request matched for address [%s]", addr);
1408 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1409 g_array_append_vals(out_param, param, sizeof(bluetooth_gatt_client_char_prop_info_t));
1410 _bt_service_method_return(req_info->context, out_param, result);
1412 _bt_free_info_from_invocation_list(req_info);
1413 g_array_free(out_param, TRUE);
1418 case BT_GATT_READ_DESCRIPTOR_VALUE:
1419 case BT_GATT_WRITE_DESCRIPTOR_VALUE: {
1420 bluetooth_gatt_client_desc_prop_info_t *param = (bluetooth_gatt_client_desc_prop_info_t*)data;
1422 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1423 bluetooth_gatt_client_desc_prop_info_t *prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
1424 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1426 if (!memcmp(param, prop, sizeof(bluetooth_gatt_client_desc_prop_info_t))) {
1427 BT_DBG("Descriptor read or write request matched for address [%s]", addr);
1428 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1429 g_array_append_vals(out_param, param, sizeof(bluetooth_gatt_client_desc_prop_info_t));
1430 _bt_service_method_return(req_info->context, out_param, result);
1432 _bt_free_info_from_invocation_list(req_info);
1433 g_array_free(out_param, TRUE);
1438 case BT_REQ_ATT_MTU: {
1439 char *addr = (char*)req_info->user_data;
1440 bluetooth_device_address_t address;
1442 if (!g_strcmp0(addr, (char*)data)) {
1443 BT_DBG("GATT Client BT_REQ_ATT_MTU call pending for app [%s] addr [%s]",
1444 req_info->sender, addr);
1445 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1446 _bt_convert_addr_string_to_type(address.addr, addr);
1448 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1449 sizeof(bluetooth_device_address_t));
1450 _bt_service_method_return(req_info->context, out_param, result);
1452 _bt_free_info_from_invocation_list(req_info);
1453 g_array_free(out_param, TRUE);
1462 static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
1464 bt_service_app_info_t *info = NULL;
1466 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
1468 _bt_uuid_to_string(&(data->server_uuid), uuid_string);
1469 BT_INFO("Instance ID is Intialized [%d] UUID initialized [%s]", data->server_inst, uuid_string);
1471 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1472 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1475 if (g_strcmp0(info->uuid, uuid_string) == 0) {
1476 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1477 info->is_initialized = TRUE;
1478 info->instance_id = data->server_inst;
1479 info->adv_instance = data->server_inst;
1480 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_SERVER_REGISTER,
1481 (void*)info, sizeof(bt_service_app_info_t));
1485 g_free(uuid_string);
1488 static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
1490 int result = BLUETOOTH_ERROR_NONE;
1494 bt_service_app_info_t *info = NULL;
1497 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1498 _bt_uuid_to_string(&(event->gatt_srvc_id.id.uuid), uuid_str);
1499 BT_INFO("GATT Added Service UUID: [%s] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1500 uuid_str, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1502 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1503 result = BLUETOOTH_ERROR_INTERNAL;
1504 svc_handle = 0; /* Service handle set to 0 indicates.
1505 0 is reserved by BT SIG, cant be used by app*/
1507 svc_handle = event->gatt_srvc_stat.servic_hndl;
1509 BT_INFO("GATT Added Service Status [%d] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1510 event->gatt_srvc_stat.status, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1512 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1513 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1516 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1517 BT_INFO("numapps[%d] Found GATT Server.. UUID [%s], sender [%s]", k, info->uuid, info->sender);
1518 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_SERVICE,
1519 (int*)&svc_handle, sizeof(int));
1521 /* Add Service Handle */
1522 if (svc_handle > 0) {
1523 bt_service_handle_uuid_info_t *uuid_info;
1524 handle = g_malloc0(sizeof(int));
1525 *handle = svc_handle;
1526 numapps[k].service_handles = g_slist_append(numapps[k].service_handles, handle);
1527 count = g_slist_length(numapps[k].service_handles);
1528 BT_INFO("Added Service handle [%d] to list..current count [%d]", svc_handle, count);
1529 /* Add Service UUID to the list */
1530 uuid_info = g_malloc0(sizeof(bt_service_handle_uuid_info_t));
1531 uuid_info->service_handle = svc_handle;
1532 uuid_info->service_uuid = g_strdup(uuid_str);
1533 numapps[k].service_handle_uuids = g_slist_append(numapps[k].service_handle_uuids, uuid_info);
1542 static void __bt_handle_gatt_server_characteristic_added(event_gatts_srvc_charctr_t *event)
1544 int result = BLUETOOTH_ERROR_NONE;
1546 bt_service_app_info_t *info = NULL;
1548 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1550 BT_INFO("GATT Server Char added status [%d]", event->gatt_srvc_stat.status);
1551 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1552 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1553 BT_INFO("GATT Add characteristic Status: [%d]", event->gatt_srvc_stat.status);
1554 BT_INFO("GATT Service characteristic Handle: [%d]", event->charctr_hndl);
1556 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1557 result = BLUETOOTH_ERROR_INTERNAL;
1558 char_handle = 0; /* characteristic handle set to 0 indicates.
1559 0 is reserved by BT SIG, cant be used by app*/
1561 char_handle = event->charctr_hndl;
1564 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1565 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1568 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1569 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1570 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_CHARACTERISTIC,
1571 (int*)&char_handle, sizeof(int));
1577 _bt_uuid_to_string(&(event->charctr_uuid), uuid_str);
1578 BT_INFO("GATT Added Characteristic: UUID: [%s]", uuid_str);
1583 static void __bt_handle_gatt_server_descriptor_added(event_gatts_srvc_descr_t* event)
1585 int result = BLUETOOTH_ERROR_NONE;
1587 bt_service_app_info_t *info = NULL;
1589 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1591 BT_INFO("GATT Server Descriptor added status [%d]", event->gatt_srvc_stat.status);
1592 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1593 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1594 BT_INFO("GATT Add Descriptor Status: [%d]", event->gatt_srvc_stat.status);
1595 BT_INFO("GATT Service Descriptor Handle: [%d]", event->descrptr_hndl);
1597 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1598 result = BLUETOOTH_ERROR_INTERNAL;
1599 desc_handle = 0; /* Service handle set to 0 indicates.
1600 0 is reserved by BT SIG, cant be used by app*/
1602 desc_handle = event->descrptr_hndl;
1604 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1605 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1608 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1609 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1610 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_DESCRIPTOR,
1611 (int*)&desc_handle, sizeof(int));
1616 _bt_uuid_to_string(&(event->descrptr_uuid), uuid_str);
1617 BT_INFO("GATT Added Descriptor: UUID: [%s]", uuid_str);
1622 static void __bt_handle_gatt_server_service_started(event_gatts_srvc_t *event)
1624 bt_service_app_info_t *info = NULL;
1625 int result = BLUETOOTH_ERROR_NONE;
1627 BT_INFO("GATT Server Service Started..");
1630 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1631 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1632 BT_INFO("GATT Service Started Status: [%d]", event->status);
1634 if (event->status != OAL_STATUS_SUCCESS) {
1635 BT_ERR("GATT Server Service Start Failed Err: [%d]", event->status);
1636 result = BLUETOOTH_ERROR_INTERNAL;
1639 /* Check if the just registered Instance ID belongs to requester */
1640 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1643 if (info->instance_id == event->server_inst) {
1644 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1645 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_START_SERVICE,
1646 (void*)info, sizeof(bt_service_app_info_t));
1652 static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
1654 int result = BLUETOOTH_ERROR_NONE;
1655 bt_service_app_info_t *info = NULL;
1657 BT_INFO("GATT Server Service Stopped..");
1659 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1660 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1661 BT_INFO("GATT Service Stopped Status: [%d]", event->status);
1663 if (event->status != OAL_STATUS_SUCCESS) {
1664 BT_ERR("GATT Server Service Stop Failed Err: [%d]", event->status);
1665 result = BLUETOOTH_ERROR_INTERNAL;
1668 /* Check if the just registered Instance ID belongs to requester */
1669 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1672 if (info->instance_id == event->server_inst) {
1673 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1674 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_STOP_SERVICE,
1675 (void*)info, sizeof(bt_service_app_info_t));
1681 static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
1683 int result = BLUETOOTH_ERROR_NONE;
1684 bt_service_app_info_t *info = NULL;
1686 BT_INFO("GATT Server Service Deleted..");
1688 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1689 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1690 BT_INFO("GATT Service Deleted Status: [%d]", event->status);
1692 if (event->status != OAL_STATUS_SUCCESS) {
1693 BT_ERR("GATT Server Service Delete Failed Err: [%d]", event->status);
1694 result = BLUETOOTH_ERROR_INTERNAL;
1697 /* Check if the just registered Instance ID belongs to requester */
1698 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1701 if (info->instance_id == event->server_inst) {
1702 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1703 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_DELETE_SERVICE,
1704 (void*)info, sizeof(bt_service_app_info_t));
1710 static struct gatt_client_info_t *_bt_find_remote_gatt_client_info_with_inst_id(char *address, int instance_id)
1713 struct gatt_client_info_t *info = NULL;
1714 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1715 info = (struct gatt_client_info_t*)l->data;
1719 if (!g_strcmp0(info->addr, address)) {
1720 if (info->instance_id == instance_id) {
1721 BT_DBG("Remote GATT client found addr[%s] instance_id[%d]", info->addr, info->instance_id);
1729 struct gatt_client_info_t *_bt_find_remote_gatt_client_info(char *address)
1732 struct gatt_client_info_t *info = NULL;
1733 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1734 info = (struct gatt_client_info_t*)l->data;
1738 if (!g_strcmp0(info->addr, address)) {
1739 BT_DBG("Remote GATT client found addr[%s]", info->addr);
1746 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info_from_conn_id(int conn_id)
1749 struct gatt_client_info_t *info = NULL;
1751 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1752 info = (struct gatt_client_info_t*)l->data;
1756 if (info->connection_id == conn_id) {
1757 BT_INFO("Remote GATT client found addr[%s]", info->addr);
1764 struct gatt_server_info_t *_bt_find_remote_gatt_server_info(char *address)
1767 struct gatt_server_info_t *info = NULL;
1768 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
1769 info = (struct gatt_server_info_t*)l->data;
1773 if (!g_strcmp0(info->addr, address)) {
1774 BT_DBG("Remote GATT Server found addr[%s] connection_id %d", info->addr, info->connection_id);
1781 static struct gatt_out_conn_info_t* __bt_find_gatt_outgoing_conn_info(char *address)
1784 struct gatt_out_conn_info_t *info = NULL;
1785 for (l = outgoing_gatt_conn_list; l != NULL; l = g_slist_next(l)) {
1786 info = (struct gatt_out_conn_info_t*)l->data;
1790 if (!g_strcmp0(info->addr, address)) {
1791 BT_INFO("Outgoing connection info found addr[%s]", info->addr + 12);
1798 static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
1800 int result = BLUETOOTH_ERROR_NONE;
1801 struct gatt_client_info_t *client_info = NULL;
1802 #ifndef __INTEGRATE_GATT_INFO__
1803 struct gatt_server_info_t *server_info = NULL;
1805 bluetooth_device_address_t dev_addr;
1806 GVariant *param = NULL;
1809 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1811 memcpy(dev_addr.addr, event->address.addr, 6);
1813 /* REPLY dbus Context to application which called BT_CONNECT_LE. There is status
1815 _bt_convert_addr_type_to_string(address,
1816 (unsigned char *)dev_addr.addr);
1818 if (event->status != OAL_STATUS_SUCCESS)
1819 result = BLUETOOTH_ERROR_INTERNAL;
1821 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1822 address, BT_ADDRESS_STRING_SIZE);
1824 BT_INFO("GATT Server Connedted: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1825 address + 12, event->server_inst, event->conn_id);
1828 /* Check if device is already in connected list */
1829 client_info = _bt_find_remote_gatt_client_info(address);
1832 BT_DBG("Conn Info absent: But no need to Send Local GATT Server Connected event to apps");
1834 param = g_variant_new("(is)", result, address);
1836 /* Send event to application */
1837 _bt_send_event(BT_DEVICE_EVENT,
1838 BLUETOOTH_EVENT_GATT_SERVER_CONNECTED, /* Local device is GATT server */
1841 /* Save client connection info */
1842 client_info = g_new0(struct gatt_client_info_t, 1);
1843 client_info->addr = g_strdup(address);
1844 BT_INFO("Added GATT client addr[%s]", client_info->addr + 12);
1845 client_info->connection_id = event->conn_id;
1846 #ifdef __INTEGRATE_GATT_INFO__
1847 client_info->client_id = -1;
1849 client_info->instance_id = event->server_inst;
1850 gatt_client_info_list = g_slist_append(gatt_client_info_list, client_info);
1851 BT_INFO("Total num of connected Remote GATT Clients [%d]", g_slist_length(gatt_client_info_list));
1853 #ifndef __INTEGRATE_GATT_INFO__
1854 /* Save server connection info */
1855 server_info = g_new0(struct gatt_server_info_t, 1);
1856 server_info->addr = g_strdup(address);
1857 server_info->client_id = -1;
1858 BT_INFO("Added GATT server addr[%s]", server_info->addr + 12);
1859 server_info->connection_id = event->conn_id;
1860 gatt_server_info_list = g_slist_append(gatt_server_info_list, server_info);
1861 BT_INFO("Total num of connected Remote GATT Servers [%d]", g_slist_length(gatt_server_info_list));
1864 ret = gattc_add_connection_info((bt_address_t *)&dev_addr, event->conn_id, event->server_inst);
1865 if (ret != OAL_STATUS_SUCCESS) {
1866 BT_ERR("gattc register server instance failed");
1870 __bt_add_mtu_gatt_device(address);
1875 /* GATT Server Dis connected */
1876 static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *event)
1878 int result = BLUETOOTH_ERROR_NONE;
1879 struct gatt_client_info_t *client_info = NULL;
1880 #ifndef __INTEGRATE_GATT_INFO__
1881 struct gatt_server_info_t *server_info = NULL;
1883 bluetooth_device_address_t dev_addr;
1884 GVariant *param = NULL;
1885 char address[BT_ADDRESS_STRING_SIZE];
1887 memcpy(dev_addr.addr, event->address.addr, 6);
1889 /* REPLY dbus Context to application which called BT_DISCONNECT_LE. There is status
1891 _bt_convert_addr_type_to_string(address,
1892 (unsigned char *)dev_addr.addr);
1894 if (event->status != OAL_STATUS_SUCCESS)
1895 result = BLUETOOTH_ERROR_INTERNAL;
1897 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
1898 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
1899 result = BLUETOOTH_ERROR_INTERNAL;
1901 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1902 address, BT_ADDRESS_STRING_SIZE);
1904 BT_ERR("Failed to connect Local GATT Server Remote Client addr[%s]", address + 12);
1908 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE,
1909 address, BT_ADDRESS_STRING_SIZE);
1912 /* Remove previous invalid request info */
1913 __bt_gatt_server_release_request_info(address);
1915 BT_INFO("Local GATT Server DisConnected: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1916 address + 12, event->server_inst, event->conn_id);
1918 #ifdef TIZEN_BLUEDROID_PORTING
1919 __bt_remove_all_prep_write_req(event->conn_id);
1922 /* Remove Connection info */
1923 client_info = _bt_find_remote_gatt_client_info(address);
1925 BT_DBG("No need to Send Local GATT Server Disconnected event to apps, just remove remote client info");
1927 param = g_variant_new("(is)", result, address);
1928 /* Send event to application */
1929 _bt_send_event(BT_DEVICE_EVENT,
1930 BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED, /* Local device is GATT server */
1933 #ifndef __INTEGRATE_GATT_INFO__
1934 /* Remove server info from list */
1935 server_info = _bt_find_remote_gatt_server_info(address);
1937 gatt_server_info_list = g_slist_remove(gatt_server_info_list, server_info);
1939 /* Remove all services from info list_gatt_info */
1940 __bt_cleanup_remote_services(server_info);
1942 BT_INFO("Can not find conn info, already removed!");
1945 /* Remove all services from info list_gatt_info */
1946 __bt_cleanup_remote_services(client_info);
1949 /* Remove client info from List */
1950 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
1951 BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
1952 g_free(client_info->addr);
1953 g_free(client_info);
1956 __bt_remove_mtu_gatt_device(address);
1959 static void __bt_handle_gatt_server_acquire_write_requested(event_gatts_srvc_acquire_attr_t *event)
1961 GVariant *param = NULL;
1962 int result = BLUETOOTH_ERROR_NONE;
1963 struct gatt_server_req_info *req_info = NULL;
1964 bluetooth_device_address_t dev_addr;
1965 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1967 BT_INFO("GATT Server ACQUIRE Write Req");
1968 BT_DBG(" conn id %d, trans id %d, attr andle %d", event->attr_trans.conn_id,
1969 event->attr_trans.trans_id, event->attr_trans.attr_handle);
1971 //address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1972 memcpy(dev_addr.addr, event->address.addr, 6);
1974 req_info = g_new0(struct gatt_server_req_info, 1);
1975 req_info->request_id = event->attr_trans.trans_id;
1976 req_info->attribute_handle = event->attr_trans.attr_handle;
1977 req_info->connection_id = event->attr_trans.conn_id;
1978 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
1979 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
1981 _bt_convert_addr_type_to_string(address,
1982 (unsigned char *)dev_addr.addr);
1984 param = g_variant_new("(iiiiiis)", result,
1985 event->attr_trans.conn_id,
1986 event->attr_trans.trans_id,
1987 event->attr_trans.attr_handle,
1988 event->mtu, event->attr_trans.offset, address);
1989 BT_DBG("remote address : [%s]", address);
1991 _bt_send_event(BT_GATT_SERVER_EVENT,
1992 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
1997 static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_acquire_attr_t *event)
1999 GVariant *param = NULL;
2000 int result = BLUETOOTH_ERROR_NONE;
2001 struct gatt_server_req_info *req_info = NULL;
2002 bluetooth_device_address_t dev_addr;
2003 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2005 BT_INFO("GATT Server ACQUIRE Notify Req");
2006 BT_DBG("conn id %d, trans id %d, attr handle %d, req address %s",
2007 event->attr_trans.conn_id, event->attr_trans.trans_id,
2008 event->attr_trans.attr_handle, address);
2010 memcpy(dev_addr.addr, event->address.addr, 6);
2011 _bt_convert_addr_type_to_string(address,
2012 (unsigned char *)dev_addr.addr);
2013 BT_INFO("Remote address : [%s]", address);
2015 req_info = g_new0(struct gatt_server_req_info, 1);
2016 req_info->request_id = event->attr_trans.trans_id;
2017 req_info->attribute_handle = event->attr_trans.attr_handle;
2018 req_info->connection_id = event->attr_trans.conn_id;
2019 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
2020 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2022 param = g_variant_new("(iiiiiis)", result,
2023 event->attr_trans.conn_id,
2024 event->attr_trans.trans_id,
2025 event->attr_trans.attr_handle,
2026 event->mtu, event->attr_trans.offset,
2029 _bt_send_event(BT_GATT_SERVER_EVENT,
2030 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY,
2034 #ifdef TIZEN_BLUEDROID_PORTING
2035 static bt_gatt_prep_write_data_t* __bt_create_prep_write_data(event_gatts_srvc_write_attr_t *event)
2037 bluetooth_device_address_t dev_addr;
2039 bt_gatt_prep_write_data_t *prep_data = NULL;
2041 prep_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2042 prep_data->connection_id = event->attr_trans.conn_id;
2043 prep_data->request_id = event->attr_trans.trans_id;
2044 prep_data->handle = event->attr_trans.attr_handle;
2045 prep_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2046 memcpy(dev_addr.addr, event->address.addr, 6);
2047 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
2048 _bt_convert_addr_type_to_string(addr,
2049 (unsigned char *)dev_addr.addr);
2050 prep_data->device_address = addr;
2051 prep_data->offset = event->attr_trans.offset;
2052 prep_data->length = event->length;
2053 prep_data->value = g_memdup2(&event->value[0], event->length);
2058 static int __bt_gatt_server_send_long_write_response(bt_gatt_prep_write_data_t *prep_data, int resp_status, int auth_req)
2060 int ret = OAL_STATUS_SUCCESS;
2061 oal_gatt_response_t response;
2063 memset(&response, 0x00, sizeof(oal_gatt_response_t));
2065 BT_INFO("GATT Server Write Res Connection ID: [%d]", prep_data->connection_id);
2066 BT_INFO("GATT Server Write Res Transaction ID:[%d]", prep_data->request_id);
2067 BT_INFO("GATT Server Write Res Attribute Handle: [%d]", prep_data->handle);
2068 BT_INFO("GATT Server Write Res Attribute Offset: [%d]", prep_data->offset);
2069 BT_INFO("GATT Server Write Res value length [%d]", prep_data->length);
2071 response.handle = prep_data->handle;
2072 response.attr_value.auth_req = auth_req;
2073 response.attr_value.handle = prep_data->handle;
2074 response.attr_value.offset = prep_data->offset;
2075 response.attr_value.len = prep_data->length;
2076 memcpy(&response.attr_value.value, &prep_data->value[0], prep_data->length);
2078 ret = gatts_send_response(prep_data->connection_id, prep_data->request_id,
2079 resp_status, &response);
2083 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_request_id(int request_id)
2086 bt_gatt_prep_write_data_t *prep_data = NULL;
2088 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2089 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2090 if (prep_data && (prep_data->request_id == request_id) &&
2091 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
2092 BT_INFO("prep_data found for request id [%d]", request_id);
2096 BT_INFO("prep_data not found for request [%d]", request_id);
2100 static bt_gatt_prep_write_data_t* __bt_find_exec_write_req(int conn_id)
2103 bt_gatt_prep_write_data_t *prep_data = NULL;
2105 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2106 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2107 if (prep_data && (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE)
2108 && (prep_data->connection_id == conn_id)) {
2109 BT_INFO("Exec request found");
2113 BT_INFO("Exec request not found");
2117 static int __bt_get_prep_request_count(int conn_id)
2121 bt_gatt_prep_write_data_t *prep_data = NULL;
2123 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2124 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2125 if (prep_data && (prep_data->connection_id == conn_id) &&
2126 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE))
2132 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_handle(int conn_id, int handle)
2135 bt_gatt_prep_write_data_t *prep_data = NULL;
2136 bt_gatt_prep_write_data_t *last_prep_data = NULL;
2138 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2139 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2140 if (prep_data && (prep_data->connection_id == conn_id) && (prep_data->handle == handle)) {
2141 BT_INFO("prep_data entry found for handle [%d]", handle);
2142 last_prep_data = prep_data;
2146 if (!last_prep_data)
2147 BT_INFO("prep_data entry not found for handle [%d]", handle);
2149 return last_prep_data;
2152 static void __bt_gatt_server_send_prep_write_req(int conn_id)
2154 int result = BLUETOOTH_ERROR_NONE;
2156 bt_gatt_prep_write_data_t *prep_data = NULL;
2158 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2159 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2160 if (prep_data && (prep_data->connection_id == conn_id) &&
2161 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
2162 BT_INFO("sending prep_req, req_id=%d", prep_data->request_id);
2163 GVariant *data = NULL;
2164 GVariant *param = NULL;
2165 data = g_variant_new_from_data(
2166 G_VARIANT_TYPE_BYTESTRING,
2171 param = g_variant_new("(iiiiiibbsn@ay)", result,
2172 prep_data->connection_id,
2173 prep_data->request_id,
2179 prep_data->device_address,
2183 _bt_send_event(BT_GATT_SERVER_EVENT,
2184 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2190 static void __bt_remove_all_prep_write_req(int conn_id)
2193 bt_gatt_prep_write_data_t *prep_data = NULL;
2195 BT_INFO("Removing all req for conn_id %d", conn_id);
2196 for (l = g_pending_write_list; l != NULL;) {
2197 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2198 l = g_slist_next(l);
2199 if (prep_data && (prep_data->connection_id == conn_id)) {
2200 BT_INFO("Removing req for req_id %d", prep_data->request_id);
2201 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
2202 g_free(prep_data->value);
2203 g_free(prep_data->device_address);
2210 static bool __bt_update_prep_write_data(bt_gatt_prep_write_data_t *prep_data, int offset,
2211 int length, char *value)
2219 len = prep_data->length + length;
2220 val = g_realloc(prep_data->value, len);
2224 memcpy(val + prep_data->length, value, length);
2225 prep_data->value = val;
2226 prep_data->length = len;
2228 BT_INFO("updated prep_data->length %d, prep_data->req_id %d", prep_data->length, prep_data->request_id);
2232 static bool __bt_handle_gatt_server_prepare_write_response(int *res,
2233 bluetooth_gatt_server_response_params_t *param)
2235 bt_gatt_prep_write_data_t *prep_data = NULL;
2236 bt_gatt_prep_write_data_t *exec_data = NULL;
2238 int ret = OAL_STATUS_SUCCESS;
2240 /* Search for matching Request in prepare write List */
2241 prep_data = __bt_find_prep_write_data_from_request_id(param->request_id);
2246 conn_id = prep_data->connection_id;
2247 exec_data = __bt_find_exec_write_req(conn_id);
2250 BT_ERR("Oops, Something weird has happened!!!");
2251 *res = BLUETOOTH_ERROR_INTERNAL;
2252 __bt_remove_all_prep_write_req(conn_id);
2254 // remove pending write request from the list
2255 BT_INFO("Removing prending write request, request id = %d", prep_data->request_id);
2256 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
2257 g_free(prep_data->value);
2258 g_free(prep_data->device_address);
2261 exec_data->prep_request_count--;
2262 if (param->response_status || !exec_data->prep_request_count) {
2263 BT_INFO("Sending exec response with status = %d", param->response_status);
2264 ret = __bt_gatt_server_send_long_write_response(exec_data, param->response_status, param->auth_req);
2265 if (ret != OAL_STATUS_SUCCESS) {
2266 BT_ERR("ret: %d", ret);
2267 *res = BLUETOOTH_ERROR_INTERNAL;
2269 __bt_remove_all_prep_write_req(conn_id);
2275 static void __bt_handle_gatt_server_prepare_write_requested(event_gatts_srvc_write_attr_t *event)
2277 bt_gatt_prep_write_data_t *pdata = NULL;
2278 bt_gatt_prep_write_data_t *prep_data = NULL;
2280 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2282 prep_data = __bt_create_prep_write_data(event);
2284 /* Find if the req node for that attribute already exists */
2285 pdata = __bt_find_prep_write_data_from_handle(prep_data->connection_id, prep_data->handle);
2287 if (!pdata || (prep_data->offset != (pdata->length + pdata->offset))) {
2288 BT_INFO("prep_write_req node doestn't exist or data is not in continuation, offset=%d", prep_data->offset);
2290 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)pdata);
2291 BT_INFO("Send prep_write_response");
2292 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
2294 /* Update the data and offset in attribute node */
2295 if (!(__bt_update_prep_write_data(pdata, prep_data->offset, prep_data->length, prep_data->value))) {
2296 BT_ERR("prep_data couldnot be updated");
2297 resp_status = BLUETOOTH_ATT_ERROR_INSUFFICIENT_RESOURCES;
2299 BT_INFO("Send prep_write_response");
2300 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
2301 g_free(prep_data->device_address);
2302 g_free(prep_data->value);
2306 if (ret != OAL_STATUS_SUCCESS)
2307 BT_ERR("ret: %d", ret);
2311 static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
2314 bluetooth_device_address_t dev_addr;
2315 GVariant *param = NULL;
2316 int result = BLUETOOTH_ERROR_NONE;
2318 gboolean is_prepare_write;
2319 char *write_val = NULL;
2320 GVariant *data = NULL;
2322 struct gatt_server_req_info *req_info = NULL;
2323 BT_INFO("GATT Server Write Requested");
2325 memcpy(dev_addr.addr, event->address.addr, 6);
2327 BT_INFO("GATT Server Write Req Connection ID: [%d]", event->attr_trans.conn_id);
2328 BT_INFO("GATT Server Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
2329 BT_INFO("GATT Server Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
2330 BT_INFO("GATT Server Write Req Attribute Offset: [%d]", event->attr_trans.offset);
2331 BT_INFO("GATT Server Write Req value length [%d]", event->length);
2332 BT_INFO("GATT Server Write Req needs response: [%d]", event->need_rsp);
2333 BT_INFO("GATT Server Write Req Is Prep: [%d]", event->is_prep);
2335 #ifdef TIZEN_BLUEDROID_PORTING
2336 if (event->is_prep) {
2337 BT_INFO("receive prepare_write request");
2338 return __bt_handle_gatt_server_prepare_write_requested(event);
2342 need_resp = event->need_rsp;
2343 is_prepare_write = event->is_prep;
2345 if (event->length > 0)
2346 write_val = g_memdup2(&event->value[0], event->length);
2348 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2349 _bt_convert_addr_type_to_string(address,
2350 (unsigned char *)dev_addr.addr);
2352 BT_INFO("GATT Server Write Request from remote client [%s]", address);
2354 if (event->length > 0) {
2355 for (i = 0; i < event->length; i++)
2356 BT_DBG("Data[%d] = [0x%x]", i, event->value[i]);
2358 /* Save Write Request Info */
2359 req_info = g_new0(struct gatt_server_req_info, 1);
2360 req_info->request_id = event->attr_trans.trans_id;
2361 req_info->attribute_handle = event->attr_trans.attr_handle;
2362 req_info->connection_id = event->attr_trans.conn_id;
2363 req_info->addr = address;
2364 req_info->offset = event->attr_trans.offset;
2365 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2366 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2368 data = g_variant_new_from_data(
2369 G_VARIANT_TYPE_BYTESTRING,
2374 param = g_variant_new("(iiiiiibbsn@ay)", result,
2375 event->attr_trans.conn_id,
2376 event->attr_trans.trans_id,
2377 event->attr_trans.attr_handle,
2378 event->attr_trans.offset,
2386 _bt_send_event(BT_GATT_SERVER_EVENT,
2387 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2393 #ifdef TIZEN_BLUEDROID_PORTING
2394 static void __bt_handle_gatt_server_exec_write_requested(event_gatts_srvc_exec_write_attr_t *event)
2397 bluetooth_device_address_t dev_addr;
2399 bt_gatt_prep_write_data_t *exec_data = NULL;
2400 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2401 BT_INFO("GATT Server Execute Write Requested");
2403 memcpy(dev_addr.addr, event->address.addr, 6);
2404 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2405 _bt_convert_addr_type_to_string(address,
2406 (unsigned char *)dev_addr.addr);
2408 BT_INFO("GATT Server Exec Write Req Connection ID: [%d]", event->conn_id);
2409 BT_INFO("GATT Server Exec Write Req Transaction ID:[%d]", event->trans_id);
2410 BT_INFO("GATT Server Exec Write Req Exec Write: [%d]", event->exec_write);
2412 // prepare exec response data
2413 exec_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2414 exec_data->connection_id = event->conn_id;
2415 exec_data->request_id = event->trans_id;
2416 exec_data->device_address = address;
2417 exec_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE;
2418 exec_data->prep_request_count = __bt_get_prep_request_count(exec_data->connection_id);
2420 if ((exec_data->prep_request_count != 1) || !event->exec_write) {
2421 if (!event->exec_write) {
2422 BT_INFO("Cancelling all prepared writes, removing all pending entries");
2423 __bt_remove_all_prep_write_req(event->conn_id);
2424 } else if (exec_data->prep_request_count > 1) {
2425 /* TODO: Handle reliable-write session */
2426 BT_INFO("This may be reliable write session. Not yet supported!!!, prep_request_count =%d",
2427 exec_data->prep_request_count);
2428 resp_status = BLUETOOTH_ATT_ERROR_REQUEST_NOT_SUPPORTED;
2429 __bt_remove_all_prep_write_req(event->conn_id);
2432 BT_INFO("Send exec response");
2433 // Made response and send it.
2434 ret = __bt_gatt_server_send_long_write_response(exec_data, resp_status, 0);
2435 if (ret != OAL_STATUS_SUCCESS)
2436 BT_ERR("ret: %d", ret);
2438 g_free(exec_data->device_address);
2443 BT_INFO("Write all pending prepared values");
2444 __bt_gatt_server_send_prep_write_req(exec_data->connection_id);
2446 // Add exec request in the queue.
2447 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)exec_data);
2451 static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t *event)
2453 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2454 bluetooth_device_address_t dev_addr;
2455 int result = BLUETOOTH_ERROR_NONE;
2456 struct gatt_server_req_info *req_info = NULL;
2457 GVariant *param = NULL;
2460 memcpy(dev_addr.addr, event->address.addr, 6);
2461 _bt_convert_addr_type_to_string(address,
2462 (unsigned char *)dev_addr.addr);
2464 BT_DBG("conn_id %d, trans id %d, attr handle %d, offset %d, is_long %d, addr %s",
2465 event->attr_trans.conn_id, event->attr_trans.trans_id,
2466 event->attr_trans.attr_handle, event->attr_trans.offset,
2467 event->is_long, address);
2469 is_long = event->is_long;
2471 /* Save Read Request Info */
2472 req_info = g_new0(struct gatt_server_req_info, 1);
2473 req_info->request_id = event->attr_trans.trans_id;
2474 req_info->attribute_handle = event->attr_trans.attr_handle;
2475 req_info->connection_id = event->attr_trans.conn_id;
2476 req_info->addr = address;
2477 req_info->offset = event->attr_trans.offset;
2478 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_READ;
2479 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2481 /* Send event to BT-API */
2482 param = g_variant_new("(iiiiibs)", result,
2483 event->attr_trans.conn_id,
2484 event->attr_trans.trans_id,
2485 event->attr_trans.attr_handle,
2486 event->attr_trans.offset,
2490 _bt_send_event(BT_GATT_SERVER_EVENT,
2491 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
2495 static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
2497 bluetooth_device_address_t dev_addr;
2498 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2499 int cur_connected_clients;
2500 static int recvd = 0;
2501 gboolean completed = 0;
2502 GVariant *param = NULL;
2504 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2505 incase of any issues, check with OAL */
2506 int result = BLUETOOTH_ERROR_NONE;
2508 memcpy(dev_addr.addr, event->address.addr, 6);
2509 _bt_convert_addr_type_to_string(address,
2510 (unsigned char *)dev_addr.addr);
2512 BT_INFO("Indication sent to GATT client [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d]",
2513 address, event->conn_id, event->trans_id, event->attr_handle);
2516 cur_connected_clients = g_slist_length(gatt_client_info_list);
2517 BT_INFO("Number of connected clients during sending Indication [%d] & current connected count [%d]",
2518 num_indicate_clients, cur_connected_clients);
2521 if (recvd == num_indicate_clients) {
2522 BT_INFO("Gatt indication confirm event for last GATT client.. [%s]", address);
2523 completed = 1; /* Last event */
2524 recvd = 0; /* Reset */
2525 num_indicate_clients = 0;
2528 param = g_variant_new("(isib)",
2534 /* Send event to BT-API */
2535 _bt_send_event(BT_GATT_SERVER_EVENT,
2536 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
2539 BT_INFO("Received Indication confirm for client number [%d]", recvd);
2543 /* Tizen Platform Specific */
2544 static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *event)
2546 bluetooth_device_address_t dev_addr;
2547 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2548 GVariant *param = NULL;
2551 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2552 incase of any issues, check with OAL */
2553 int result = BLUETOOTH_ERROR_NONE;
2555 memcpy(dev_addr.addr, event->address.addr, 6);
2556 _bt_convert_addr_type_to_string(address,
2557 (unsigned char *)dev_addr.addr);
2559 BT_INFO("notification_changed [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d] Notify[%d]",
2560 address, event->conn_id, event->trans_id, event->attr_handle, event->notify);
2562 /* Set Notifcation status */
2563 notify = event->notify;
2565 param = g_variant_new("(isib)",
2571 /* Send event to BT-API */
2572 _bt_send_event(BT_GATT_SERVER_EVENT,
2573 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
2579 static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
2581 int result = BLUETOOTH_ERROR_NONE;
2582 struct gatt_client_info_t *conn_info = NULL;
2583 GVariant *param = NULL;
2586 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2587 if (conn_info == NULL) {
2588 BT_ERR("Cant find connection Information");
2591 BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
2592 conn_info->addr, event->mtu_size);
2594 __bt_update_mtu_gatt_device(conn_info->addr, event->mtu_size);
2596 param = g_variant_new("(isqy)",
2602 /* Send event to BT-API */
2603 _bt_send_event(BT_GATT_SERVER_EVENT,
2604 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
2608 static void __bt_handle_gatt_phy_updated_event(event_gatts_phy_updated_t *event)
2610 int result = BLUETOOTH_ERROR_NONE;
2611 struct gatt_client_info_t *conn_info = NULL;
2612 GVariant *param = NULL;
2614 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2615 if (conn_info == NULL) {
2616 BT_ERR("Can't find connection Information");
2620 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2621 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2623 param = g_variant_new("(isiii)",
2630 /* Send event to BT-API */
2631 _bt_send_event(BT_GATT_SERVER_EVENT,
2632 BLUETOOTH_EVENT_GATT_SERVER_PHY_UPDATED,
2636 static void __bt_handle_gatt_phy_read_event(event_gatts_phy_read_t *event)
2638 int result = BLUETOOTH_ERROR_NONE;
2639 struct gatt_client_info_t *conn_info = NULL;
2640 GVariant *param = NULL;
2642 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2643 if (conn_info == NULL) {
2644 BT_ERR("Cant find connection Information");
2648 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2649 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2651 param = g_variant_new("(isiii)",
2658 /* Send event to BT-API */
2659 _bt_send_event(BT_GATT_SERVER_EVENT,
2660 BLUETOOTH_EVENT_GATT_SERVER_PHY_READ,
2664 static void __bt_handle_gatt_client_phy_updated_event(event_gattc_phy_updated_t *event)
2666 int result = BLUETOOTH_ERROR_NONE;
2667 struct gatt_server_info_t *conn_info = NULL;
2668 GVariant *param = NULL;
2670 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event->conn_id);
2671 if (conn_info == NULL) {
2672 BT_ERR("Cant find connection Information");
2676 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2677 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2679 param = g_variant_new("(isiii)",
2686 /* Send event to BT-API */
2687 _bt_send_event(BT_GATT_CLIENT_EVENT,
2688 BLUETOOTH_EVENT_GATT_CLIENT_PHY_UPDATED,
2692 static void __bt_handle_gatt_client_phy_read_event(event_gattc_phy_read_t *event)
2694 int result = BLUETOOTH_ERROR_NONE;
2695 struct gatt_server_info_t *conn_info = NULL;
2696 GVariant *param = NULL;
2698 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event->conn_id);
2699 if (conn_info == NULL) {
2700 BT_ERR("Cant find connection Information");
2704 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2705 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2707 param = g_variant_new("(isiii)",
2714 /* Send event to BT-API */
2715 _bt_send_event(BT_GATT_CLIENT_EVENT,
2716 BLUETOOTH_EVENT_GATT_CLIENT_PHY_READ,
2720 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
2722 switch (event_type) {
2723 case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
2724 BT_INFO("OAL Event: Server Instance Registered");
2725 /* GATT Server Registered event is handled in MAIN thread context */
2726 __bt_handle_server_instance_registered((event_gatts_register_t *)event_data);
2729 case OAL_EVENT_GATTS_SERVICE_ADDED: {
2730 BT_INFO("OAL Event: GATT Service added");
2731 __bt_handle_gatt_server_service_added((event_gatts_srvc_prm_t *)event_data);
2734 case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
2735 BT_INFO("OAL Event: GATT characteristic added");
2736 __bt_handle_gatt_server_characteristic_added((event_gatts_srvc_charctr_t *)event_data);
2739 case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
2740 BT_INFO("OAL Event: GATT descriptor added");
2741 __bt_handle_gatt_server_descriptor_added((event_gatts_srvc_descr_t *)event_data);
2744 case OAL_EVENT_GATTS_SERVICE_STARTED: {
2745 BT_INFO("OAL Event: GATT Service started");
2746 __bt_handle_gatt_server_service_started((event_gatts_srvc_t *)event_data);
2749 case OAL_EVENT_GATTS_SERVICE_STOPED: {
2750 BT_INFO("OAL Event: GATT Service stopped");
2751 __bt_handle_gatt_server_service_stopped((event_gatts_srvc_t *)event_data);
2754 case OAL_EVENT_GATTS_SERVICE_DELETED: {
2755 BT_INFO("OAL Event: GATT Service deleted");
2756 __bt_handle_gatt_server_service_deleted((event_gatts_srvc_t *) event_data);
2759 case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
2760 BT_INFO("OAL Event: GATT Server Connected");
2761 __bt_handle_gatt_server_connection_state((event_gatts_conn_t *)event_data);
2764 case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
2765 BT_INFO("OAL Event: GATT Server Disconnected");
2766 __bt_handle_gatt_server_disconnection_state((event_gatts_conn_t *)event_data);
2769 case OAL_EVENT_GATTS_REQUEST_READ: {
2770 BT_DBG("OAL Event: GATT Server Read Request");
2771 __bt_handle_gatt_server_read_requested((event_gatts_srvc_read_attr_t *)event_data);
2774 case OAL_EVENT_GATTS_REQUEST_WRITE: {
2775 BT_DBG("OAL Event: GATT Server Write Request");
2776 __bt_handle_gatt_server_write_requested((event_gatts_srvc_write_attr_t *)event_data);
2779 #ifdef TIZEN_BLUEDROID_PORTING
2780 case OAL_EVENT_GATTS_EXEC_REQUEST_WRITE: {
2781 BT_INFO("OAL Event: GATT Server Exec Write Request");
2782 __bt_handle_gatt_server_exec_write_requested((event_gatts_srvc_exec_write_attr_t *)event_data);
2786 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE: {
2787 BT_INFO("OAL Event: GATT Server Acquire Write Request");
2788 __bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2791 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
2792 BT_INFO("OAL Event: GATT ServerAcquire Notify Request");
2793 __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2796 case OAL_EVENT_GATTS_IND_CONFIRM: {
2797 BT_INFO("OAL Event: GATT Server Indication confirmed");
2798 __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
2801 case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
2802 BT_INFO("OAL Event: GATT Server DisConnected");
2803 __bt_handle_gatt_server_notification_changed((event_gatts_notif_t *)event_data);
2806 case OAL_EVENT_GATTS_MTU_CHANGED: {
2807 BT_INFO("OAL Event: GATT Server MTU changed event callback");
2808 __bt_handle_gatt_mtu_changed_event((event_gatts_mtu_changed_t *)event_data);
2811 case OAL_EVENT_GATTS_PHY_UPDATED: {
2812 BT_INFO("OAL Event: GATT Server PHY Updated event callback");
2813 __bt_handle_gatt_phy_updated_event((event_gatts_phy_updated_t *)event_data);
2816 case OAL_EVENT_GATTS_PHY_READ: {
2817 BT_INFO("OAL Event: GATT Server PHY Read event callback");
2818 __bt_handle_gatt_phy_read_event((event_gatts_phy_read_t *)event_data);
2821 case OAL_EVENT_GATTC_PHY_UPDATED: {
2822 BT_INFO("OAL Event: GATT Client PHY Updated event callback");
2823 __bt_handle_gatt_client_phy_updated_event((event_gattc_phy_updated_t *)event_data);
2826 case OAL_EVENT_GATTC_PHY_READ: {
2827 BT_INFO("OAL Event: GATT Client PHY Read event callback");
2828 __bt_handle_gatt_client_phy_read_event((event_gattc_phy_read_t *)event_data);
2831 case OAL_EVENT_GATTC_REGISTRATION: {
2832 BT_INFO("OAL Event: GATT Client instance Registered");
2833 __bt_handle_client_instance_registered((event_gattc_register_t *) event_data);
2836 case OAL_EVENT_GATTC_CONNECTION_COMPLETED: {
2837 BT_INFO("OAL Event: GATT Client Connected");
2838 __bt_handle_client_connected((event_gattc_conn_t *) event_data);
2841 case OAL_EVENT_GATTC_DISCONNECTION_COMPLETED: {
2842 BT_INFO("OAL Event: GATT Client DisConnected");
2843 __bt_handle_client_disconnected((event_gattc_conn_t *) event_data);
2846 case OAL_EVENT_GATTC_SERVICE_SEARCH_RESULT: {
2847 BT_DBG("OAL Event: GATT Client Service Search Result");
2848 __bt_handle_client_service_search_result((event_gattc_service_result_t *) event_data);
2851 case OAL_EVENT_GATTC_SERVICE_SEARCH_DONE: {
2852 BT_INFO("OAL Event: GATT Client Service Completed");
2853 __bt_handle_client_service_search_completed((event_gattc_conn_status_t *) event_data);
2856 case OAL_EVENT_GATTC_CHARAC_SERACH_RESULT: {
2857 BT_DBG("OAL Event: GATT Client Characteristic Search Result");
2858 __bt_handle_client_characteristic_search_result((event_gattc_characteristic_result_t *) event_data);
2861 case OAL_EVENT_GATTC_DESC_SERACH_RESULT: {
2862 BT_DBG("OAL Event: GATT Client Descriptor Search Result");
2863 __bt_handle_client_descriptor_search_result((event_gattc_descriptor_result_t *) event_data);
2866 case OAL_EVENT_GATTC_READ_CHARAC: {
2867 BT_DBG("OAL Event: GATT Client Characteristic Read Data");
2868 __bt_handle_client_characteristic_read_data((event_gattc_read_data *) event_data);
2871 case OAL_EVENT_GATTC_READ_DESCR: {
2872 BT_DBG("OAL Event: GATT Client Descriptor Read Data");
2873 __bt_handle_client_descriptor_read_data((event_gattc_read_data *) event_data);
2876 case OAL_EVENT_GATTC_WRITE_CHARAC: {
2877 BT_DBG("OAL Event: GATT Client Characteristic Write Data");
2878 __bt_handle_client_characteristic_write_data((event_gattc_write_data *) event_data);
2881 case OAL_EVENT_GATTC_WRITE_DESCR: {
2882 BT_DBG("OAL Event: GATT Client Descriptor Write Data");
2883 __bt_handle_client_descriptor_write_data((event_gattc_write_data *) event_data);
2886 case OAL_EVENT_DEVICE_LE_DISCONNECTED: {
2887 BT_INFO("OAL Event: LE device disconnected");
2888 __bt_hanlde_le_device_disconnection((event_dev_conn_status_t *)event_data);
2891 case OAL_EVENT_GATTC_NOTIFICATION_REGISTERED: {
2892 BT_INFO("OAL Event: GATT Client Notification Registered");
2893 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, TRUE);
2896 case OAL_EVENT_GATTC_NOTIFICATION_DEREGISTERED: {
2897 BT_INFO("OAL Event: GATT Client Notification Registered");
2898 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, FALSE);
2901 case OAL_EVENT_GATTC_NOTIFY_DATA: {
2902 BT_DBG("OAL Event: GATT Client Notification Data");
2903 __bt_handle_client_notification_data((event_gattc_notify_data *) event_data);
2906 case OAL_EVENT_GATTC_SERVICE_CHANGED_IND: {
2907 BT_INFO("OAL Event: GATT Client service changed indication");
2908 __bt_handle_client_service_changed_ind((event_gattc_service_changed_data *)event_data);
2911 case OAL_EVENT_GATTC_MTU_EXCHANGE_COMPLETED: {
2912 BT_INFO("OAL Event: GATT Client MTU Exchange Complete");
2913 __bt_handle_client_mtu_exchange_completed((event_gattc_mtu_configured_t *) event_data);
2917 BT_DBG("Unhandled OAL event = 0x%x", event_type);
2922 int _bt_gatt_server_add_service(char *sender, int service_type,
2923 int num_handles, char *svc_uuid, int instance_id)
2925 BT_CHECK_PARAMETER(svc_uuid, return);
2926 BT_CHECK_PARAMETER(sender, return);
2927 int ret = OAL_STATUS_SUCCESS;
2929 oal_gatt_srvc_id_t svc_data;
2931 svc_data.is_prmry = service_type;
2932 svc_data.id.inst_id = instance_id;
2934 /* Check Service UUID duplication */
2935 if (__bt_check_service_uuid_registered(svc_uuid))
2936 return BLUETOOTH_ERROR_INTERNAL;
2938 BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id);
2939 _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid);
2941 ret = gatts_add_service(instance_id, &svc_data, num_handles);
2942 if (ret != OAL_STATUS_SUCCESS) {
2943 BT_ERR("ret: %d", ret);
2944 return _bt_convert_oal_status_to_bt_error(ret);
2947 return BLUETOOTH_ERROR_NONE;
2951 int _bt_gatt_server_add_included_service(char *sender, int instance_id,
2952 int service_handle, int included_svc_handle)
2954 BT_CHECK_PARAMETER(sender, return);
2955 int ret = OAL_STATUS_SUCCESS;
2957 ret = gatts_add_included_services(instance_id, service_handle, included_svc_handle);
2958 if (ret != OAL_STATUS_SUCCESS) {
2959 BT_ERR("ret: %d", ret);
2960 return _bt_convert_oal_status_to_bt_error(ret);
2962 return BLUETOOTH_ERROR_NONE;
2965 int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
2966 bluetooth_gatt_server_attribute_params_t *param)
2968 BT_CHECK_PARAMETER(char_uuid, return);
2969 BT_CHECK_PARAMETER(sender, return);
2970 BT_CHECK_PARAMETER(param, return);
2971 int ret = OAL_STATUS_SUCCESS;
2973 oal_uuid_t uuid = {{0} };
2975 BT_INFO("Char UUID [%s] Instance ID [%d]", char_uuid, param->instance_id);
2976 _bt_string_to_uuid(char_uuid, (service_uuid_t*)&uuid);
2978 BT_INFO("Char permission From API [0x%x]", param->permissions);
2980 ret = gatts_add_characteristics(param->instance_id, param->service_handle, &uuid,
2981 param->properties, (int)param->permissions);
2982 if (ret != OAL_STATUS_SUCCESS) {
2983 BT_ERR("ret: %d", ret);
2984 return _bt_convert_oal_status_to_bt_error(ret);
2986 return BLUETOOTH_ERROR_NONE;
2989 int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
2990 bt_gatt_permission_t *param, int service_handle, int instance_id)
2992 BT_CHECK_PARAMETER(desc_uuid, return);
2993 BT_CHECK_PARAMETER(sender, return);
2994 BT_CHECK_PARAMETER(param, return);
2995 int ret = OAL_STATUS_SUCCESS;
2997 oal_uuid_t uuid = {{0} };
2999 BT_INFO("Descriptor UUID [%s] Instance ID [%d] Service handle [%d]",
3000 desc_uuid, service_handle, instance_id);
3002 _bt_string_to_uuid(desc_uuid, (service_uuid_t*)&uuid);
3004 BT_INFO("Descriptor permission From API [0x%x]", *param);
3005 ret = gatts_add_descriptor(instance_id, service_handle, &uuid, (int)*param);
3007 if (ret != OAL_STATUS_SUCCESS) {
3008 BT_ERR("ret: %d", ret);
3009 return _bt_convert_oal_status_to_bt_error(ret);
3011 return BLUETOOTH_ERROR_NONE;
3014 int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id)
3016 BT_CHECK_PARAMETER(sender, return);
3017 int ret = OAL_STATUS_SUCCESS;
3019 ret = gatts_start_service(instance_id, service_handle, BT_GATT_TRANSPORT_LE);
3020 if (ret != OAL_STATUS_SUCCESS) {
3021 BT_ERR("ret: %d", ret);
3022 return _bt_convert_oal_status_to_bt_error(ret);
3024 return BLUETOOTH_ERROR_NONE;
3027 int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id)
3029 BT_CHECK_PARAMETER(sender, return);
3030 int ret = OAL_STATUS_SUCCESS;
3032 ret = gatts_stop_service(instance_id, service_handle);
3033 if (ret != OAL_STATUS_SUCCESS) {
3034 BT_ERR("ret: %d", ret);
3035 return _bt_convert_oal_status_to_bt_error(ret);
3037 return BLUETOOTH_ERROR_NONE;
3040 int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id)
3042 BT_CHECK_PARAMETER(sender, return);
3043 int ret = OAL_STATUS_SUCCESS;
3047 bt_service_app_info_t *info = NULL;
3049 if (__bt_gatt_server_is_service_persistence(service_handle))
3050 return BLUETOOTH_ERROR_INTERNAL;
3052 ret = gatts_delete_service(instance_id, service_handle);
3053 if (ret != OAL_STATUS_SUCCESS) {
3054 BT_ERR("ret: %d", ret);
3055 return _bt_convert_oal_status_to_bt_error(ret);
3058 /* Remove the Service Handle */
3059 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3061 if (info->instance_id == instance_id) {
3062 for (l = info->service_handles; l != NULL; ) {
3064 l = g_slist_next(l);
3065 if (handle && *handle == service_handle) {
3066 BT_INFO("Remove Service handle [%d]", *handle);
3067 info->service_handles = g_slist_remove(info->service_handles, handle);
3068 /* Remove Service UUID from the list */
3069 __bt_remove_service_uuid(*handle);
3078 return BLUETOOTH_ERROR_NONE;
3081 int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
3082 bluetooth_gatt_server_response_params_t *param)
3084 BT_CHECK_PARAMETER(sender, return);
3085 BT_CHECK_PARAMETER(data, return);
3086 BT_CHECK_PARAMETER(param, return);
3087 struct gatt_server_req_info *req_info = NULL;
3088 int ret = OAL_STATUS_SUCCESS;
3089 #ifdef TIZEN_BLUEDROID_PORTING
3090 int res = BLUETOOTH_ERROR_NONE;
3092 oal_gatt_response_t response;
3094 BT_INFO("GATT Server Response: Req Type [%d] req_id [%d] status [%d] auth_req [%d] offset[%d] data len[%d]",
3095 param->req_type, param->request_id,
3096 param->response_status, param->auth_req,
3097 data->offset, data->length);
3099 #ifdef TIZEN_BLUEDROID_PORTING
3100 if (__bt_handle_gatt_server_prepare_write_response(&res, param))
3104 /* Search for matching Request in List */
3105 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
3107 BT_ERR("GATT Server Req Info not found for current response..return Error");
3108 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
3111 memset(&response, 0x00, sizeof(oal_gatt_response_t));
3113 response.handle = req_info->attribute_handle;
3114 response.attr_value.auth_req = param->auth_req;
3115 response.attr_value.handle = req_info->attribute_handle;
3116 response.attr_value.offset = data->offset;
3117 response.attr_value.len = data->length;
3118 memcpy(&response.attr_value.value, &data->data, data->length);
3121 ret = gatts_send_response(req_info->connection_id, param->request_id,
3122 param->response_status, &response);
3124 if (ret != OAL_STATUS_SUCCESS) {
3125 BT_ERR("ret: %d", ret);
3126 return _bt_convert_oal_status_to_bt_error(ret);
3129 /* Remove GATT server request from list */
3130 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
3131 g_free(req_info->addr);
3133 return BLUETOOTH_ERROR_NONE;
3136 int _bt_gatt_server_acquire_send_response(char *sender, bluetooth_gatt_server_acquire_response_params_t *param , void *fd_list)
3138 BT_CHECK_PARAMETER(sender, return);
3139 BT_CHECK_PARAMETER(param, return);
3140 struct gatt_server_req_info *req_info = NULL;
3141 int ret = OAL_STATUS_SUCCESS;
3144 BT_INFO("GATT acquire Server Response: Req Type [%d] req_id [%d] fd [%d] mtu[%d]",
3145 param->req_type, param->request_id,
3149 /* Search for matching Request in List */
3150 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
3152 BT_ERR("GATT acquire Server Req Info not found for current response..return Error");
3153 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
3156 ret = gatt_send_response_acquire(req_info->connection_id, param->request_id, 0, param->fd, param->mtu, fd_list);
3158 if (ret != OAL_STATUS_SUCCESS) {
3159 BT_ERR("ret: %d", ret);
3160 return _bt_convert_oal_status_to_bt_error(ret);
3163 /* Remove GATT server request from list */
3164 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
3165 g_free(req_info->addr);
3167 return BLUETOOTH_ERROR_NONE;
3172 int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
3173 bluetooth_gatt_att_data_t *data,
3174 bluetooth_gatt_server_indication_params_t *param)
3176 BT_CHECK_PARAMETER(sender, return);
3177 BT_CHECK_PARAMETER(data, return);
3178 BT_CHECK_PARAMETER(param, return);
3180 gboolean all_send = FALSE;
3181 int ret = OAL_STATUS_SUCCESS;
3182 struct gatt_client_info_t *conn;
3184 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3185 _bt_convert_addr_type_to_string(address, dev_addr->addr);
3187 if (memcmp(dev_addr->addr, BDADDR_ANY, 6) == 0) {
3188 BT_INFO("GATT Server: Send Indication to all connected GATT clients..");
3191 BT_INFO("GATT Server: Send Indication to connected GATT client addr [%s]", address);
3194 /* Attempt to send Notification/Indication to all Connected GATT clients */
3196 ret = __bt_gatt_send_indication_to_all_connected_clients(data, param);
3197 if (ret != OAL_STATUS_SUCCESS) {
3198 BT_ERR("ret: %d", ret);
3200 return _bt_convert_oal_status_to_bt_error(ret);
3204 conn = _bt_find_remote_gatt_client_info_with_inst_id(address, param->instance_id);
3206 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
3207 conn->connection_id, data->length,
3208 param->need_confirmation, (char *)(&data->data[0]));
3210 if (ret != OAL_STATUS_SUCCESS) {
3211 BT_ERR("ret: %d", ret);
3212 BT_INFO("Indication failed to send to Remote GATT Client [%s]", address);
3214 return _bt_convert_oal_status_to_bt_error(ret);
3216 BT_INFO("Indication sent to Remote GATT Client [%s] wait for Notification completed event from OAL", address);
3218 num_indicate_clients = 1;
3219 return BLUETOOTH_ERROR_NONE;
3221 BT_ERR("Remote GATT client [%s] is not connected..Cant send Indication!!", address);
3223 return BLUETOOTH_ERROR_NOT_CONNECTED;
3226 return BLUETOOTH_ERROR_NONE;
3229 int _bt_gatt_server_update_attribute_value(char *sender, int instance_id,
3230 bluetooth_gatt_server_update_value_t *param)
3232 BT_CHECK_PARAMETER(sender, return);
3233 BT_CHECK_PARAMETER(param, return);
3234 int ret = OAL_STATUS_SUCCESS;
3236 oal_gatt_value_t value;
3237 BT_DBG("GATT Server Update value: Instance ID [%d] attr handle [%d] Value len [%d]",
3238 instance_id, param->attribute_handle, param->length);
3240 memset(&value, 0x00, sizeof(oal_gatt_value_t));
3242 value.handle = param->attribute_handle;
3243 value.len = param->length;
3244 memcpy(&value.value, ¶m->data.data, param->length);
3246 ret = gatts_update_att_value(instance_id, &value);
3248 if (ret != OAL_STATUS_SUCCESS) {
3249 BT_ERR("ret: %d", ret);
3250 return _bt_convert_oal_status_to_bt_error(ret);
3253 return BLUETOOTH_ERROR_NONE;
3256 int _bt_gatt_server_set_phy(bluetooth_device_address_t *device_address,
3257 int tx_phy, int rx_phy, int phy_options)
3259 struct gatt_client_info_t *conn_info = NULL;
3261 int ret = OAL_STATUS_SUCCESS;
3263 BT_INFO("Setting Preferred PHY");
3264 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3265 _bt_convert_addr_type_to_string(addr, device_address->addr);
3267 /* Check if remote GATT Client is connected or not */
3268 conn_info = _bt_find_remote_gatt_client_info(addr);
3269 if (conn_info == NULL) {
3270 BT_ERR("GATT Client is not yet connected...");
3272 return BLUETOOTH_ERROR_NOT_CONNECTED;
3275 // TODO: This code is commented as currently this API is not supported in OAL
3276 //ret = gatts_set_preferred_phy(conn_info->connection_id, tx_phy, rx_phy, phy_options);
3278 if (ret != OAL_STATUS_SUCCESS) {
3279 BT_ERR("ret: %d", ret);
3281 return BLUETOOTH_ERROR_INTERNAL;
3285 return BLUETOOTH_ERROR_NONE;
3288 int _bt_gatt_server_read_phy(bluetooth_device_address_t *address)
3290 struct gatt_client_info_t *conn_info = NULL;
3291 int ret = OAL_STATUS_SUCCESS;
3294 BT_CHECK_PARAMETER(address, return);
3296 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3297 _bt_convert_addr_type_to_string(addr, address->addr);
3299 BT_INFO("Read PHY for the server: address:[%s]", addr);
3301 /* Check if remote GATT client is connected or not */
3302 conn_info = _bt_find_remote_gatt_client_info(addr);
3303 if (conn_info == NULL) {
3304 BT_ERR("GATT Client is not yet connected..");
3306 return BLUETOOTH_ERROR_NOT_CONNECTED;
3309 // TODO: This code is commented as currently this API is not supported in OAL
3310 //ret = gatts_read_phy(conn_info->connection_id);
3312 if (ret != OAL_STATUS_SUCCESS) {
3313 BT_ERR("ret: %d", ret);
3315 return BLUETOOTH_ERROR_INTERNAL;
3319 return BLUETOOTH_ERROR_NONE;
3322 int _bt_gatt_client_set_phy(bluetooth_device_address_t *device_address,
3323 int tx_phy, int rx_phy, int phy_options)
3325 struct gatt_server_info_t *conn_info = NULL;
3327 int ret = OAL_STATUS_SUCCESS;
3329 BT_INFO("Setting Preferred PHY");
3330 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3331 _bt_convert_addr_type_to_string(addr, device_address->addr);
3333 /* Check if remote GATT server is connected or not */
3334 conn_info = _bt_find_remote_gatt_server_info(addr);
3335 if (conn_info == NULL) {
3336 BT_ERR("GATT Server is not yet connected...");
3338 return BLUETOOTH_ERROR_NOT_CONNECTED;
3341 // TODO: This code is commented as currently this API is not supported in OAL
3342 //ret = gattc_set_preferred_phy(conn_info->connection_id, tx_phy, rx_phy, phy_options);
3344 if (ret != OAL_STATUS_SUCCESS) {
3345 BT_ERR("ret: %d", ret);
3347 return BLUETOOTH_ERROR_INTERNAL;
3351 return BLUETOOTH_ERROR_NONE;
3354 int _bt_gatt_client_read_phy(bluetooth_device_address_t *address)
3356 struct gatt_server_info_t *conn_info = NULL;
3357 int ret = OAL_STATUS_SUCCESS;
3360 BT_CHECK_PARAMETER(address, return);
3362 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3363 _bt_convert_addr_type_to_string(addr, address->addr);
3365 BT_INFO("Read PHY for the server: address:[%s]", addr);
3367 /* Check if remote GATT server is connected or not */
3368 conn_info = _bt_find_remote_gatt_server_info(addr);
3369 if (conn_info == NULL) {
3370 BT_ERR("GATT Server is not yet connected..");
3372 return BLUETOOTH_ERROR_NOT_CONNECTED;
3375 // TODO: This code is commented as currently this API is not supported in OAL
3376 //ret = gattc_read_phy(conn_info->connection_id);
3378 if (ret != OAL_STATUS_SUCCESS) {
3379 BT_ERR("ret: %d", ret);
3381 return BLUETOOTH_ERROR_INTERNAL;
3385 return BLUETOOTH_ERROR_NONE;
3388 int _bt_request_att_mtu(bluetooth_device_address_t *device_address,
3391 struct gatt_server_info_t *conn_info = NULL;
3393 int ret = OAL_STATUS_SUCCESS;
3395 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3396 _bt_convert_addr_type_to_string(addr, device_address->addr);
3398 /* Check if remote GATT Server is connected or not */
3399 conn_info = _bt_find_remote_gatt_server_info(addr);
3400 if (conn_info == NULL) {
3401 BT_ERR("GATT Server is not yet connected..");
3403 return BLUETOOTH_ERROR_NOT_CONNECTED;
3406 ret = gattc_configure_mtu(conn_info->connection_id, mtu);
3407 if (ret != OAL_STATUS_SUCCESS) {
3408 BT_ERR("ret: %d", ret);
3410 return _bt_convert_oal_status_to_bt_error(ret);
3414 return BLUETOOTH_ERROR_NONE;
3417 int _bt_get_att_mtu(bluetooth_device_address_t *address,
3420 BT_CHECK_PARAMETER(address, return);
3421 BT_CHECK_PARAMETER(mtu, return);
3422 struct gatt_client_info_t *client_info = NULL;
3423 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
3424 int ret = OAL_STATUS_SUCCESS;
3427 _bt_convert_addr_type_to_string(addr, address->addr);
3429 BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]", addr);
3431 client_info = _bt_find_remote_gatt_client_info(addr);
3433 BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
3434 client_info->addr, client_info->connection_id, client_info->instance_id);
3436 ret = gatts_get_att_mtu(client_info->connection_id, &stack_mtu);
3437 if (ret != OAL_STATUS_SUCCESS) {
3438 BT_ERR("ret: %d", ret);
3439 return _bt_convert_oal_status_to_bt_error(ret);
3442 struct gatt_server_info_t *server_info = NULL;
3443 BT_ERR("GATT Client [%s] is not yet connected..", addr);
3444 server_info = _bt_find_remote_gatt_server_info(addr);
3446 BT_INFO("GATT Server [%s] is connected, conn Id [%d] Client ID [%d]",
3447 server_info->addr, server_info->connection_id, server_info->client_id);
3449 ret = gattc_get_att_mtu(server_info->connection_id, &stack_mtu);
3450 if (ret != OAL_STATUS_SUCCESS) {
3451 BT_ERR("ret: %d", ret);
3452 return _bt_convert_oal_status_to_bt_error(ret);
3455 BT_ERR("GATT Server [%s] is not yet connected..", addr);
3456 return BLUETOOTH_ERROR_NOT_CONNECTED;
3460 BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
3461 *mtu = (unsigned int)stack_mtu;
3464 BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
3465 return BLUETOOTH_ERROR_NOT_CONNECTED;
3468 return BLUETOOTH_ERROR_NONE;
3471 /* GATT Client utility static functions */
3472 static bt_gatt_service_info_list_t *__bt_get_service_info_list(int conn_id)
3475 bt_gatt_service_info_list_t *info = NULL;
3477 for (l = list_gatt_info; l != NULL; l = g_slist_next(l)) {
3478 info = (bt_gatt_service_info_list_t *)l->data;
3482 if (info->conn_id == conn_id)
3489 static bt_gatt_service_info_t *__bt_find_matching_service(
3490 bt_gatt_service_info_list_t *svc_list, oal_gatt_srvc_id_t *svc)
3493 bt_gatt_service_info_t *info = NULL;
3495 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3496 info = (bt_gatt_service_info_t *)l->data;
3500 /* Match UUID and instance ID */
3501 if (!memcmp(&svc->id.uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3502 && (svc->id.inst_id == info->inst_id)) {
3509 static bt_gatt_char_info_t *__bt_find_matching_charc(
3510 bt_gatt_service_info_t *svc_info, oal_gatt_id_t *charc)
3513 bt_gatt_char_info_t *info = NULL;
3515 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3516 info = (bt_gatt_char_info_t *)l->data;
3520 /* Match UUID and instance ID */
3521 if (!memcmp(&charc->uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3522 && (charc->inst_id == info->inst_id)) {
3529 static bt_gatt_descriptor_info_t *__bt_find_matching_desc(
3530 bt_gatt_char_info_t *char_info, oal_gatt_id_t *desc)
3533 bt_gatt_descriptor_info_t *info = NULL;
3535 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3536 info = (bt_gatt_descriptor_info_t *)l->data;
3540 /* Match UUID and instance ID */
3541 if (!memcmp(&desc->uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3542 && (desc->inst_id == info->inst_id)) {
3549 static bt_gatt_service_info_t* __bt_find_removed_service(bt_gatt_service_info_list_t *svc_list)
3552 bt_gatt_service_info_t *info = NULL;
3554 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3555 info = (bt_gatt_service_info_t*)l->data;
3559 /* Service is marked a removed */
3560 if (info->is_removed == 1)
3566 static void __bt_remove_service_info_from_list(bt_gatt_service_info_t *svc_info)
3572 bt_gatt_char_info_t *charc = NULL;
3573 bt_gatt_included_service_info_t *incl = NULL;
3574 bt_gatt_descriptor_info_t *desc = NULL;
3576 /* Remove all Characteristic and Descriptors within characteristic */
3577 for (l = svc_info->chars; l != NULL;) {
3578 charc = (bt_gatt_char_info_t*)l->data;
3579 l = g_slist_next(l); /* Incase if l is removed, saving next to l */
3584 /* Inside Characteristic */
3585 for (l1 = charc->descs; l1 != NULL;) {
3587 desc = (bt_gatt_descriptor_info_t*)l1->data;
3588 l1 = g_slist_next(l1);
3593 /* Remove Descriptor */
3594 charc->descs = g_slist_remove(charc->descs, desc);
3597 /* Remove Characteristic */
3598 svc_info->chars = g_slist_remove(svc_info->chars, charc);
3602 /* Remove all Included Services */
3603 for (l2 = svc_info->included_svcs; l2 != NULL;) {
3604 incl = (bt_gatt_included_service_info_t*)l2->data;
3605 l2 = g_slist_next(l2); /* Incase if l is removed, saving next to l */
3610 /* Remove included service */
3611 svc_info->included_svcs = g_slist_remove(svc_info->included_svcs, incl);
3618 static void __bt_build_service_browse_info(int conn_id,
3619 bt_services_browse_info_t* info)
3622 bt_gatt_service_info_list_t *svc_info_list;
3623 bt_gatt_service_info_t *svc_info;
3625 service_uuid_t uuid;
3626 struct gatt_server_info_t *conn_info = NULL;
3628 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3630 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3631 if (conn_info == NULL) {
3632 BT_ERR("Cant find connection Information");
3636 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3638 svc_info_list = __bt_get_service_info_list(conn_id);
3642 info->count = g_slist_length(svc_info_list->services);
3643 BT_DBG("Total services present in the svc info list for this conn id [%d] is [%d]",
3644 conn_id, info->count);
3646 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
3647 svc_info = (bt_gatt_service_info_t*)l->data;
3648 if (svc_info == NULL)
3651 memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3652 _bt_uuid_to_string(&uuid, uuid_string);
3654 BT_INFO("[%d] %s [%s]", count, uuid_string, _bt_convert_uuid_to_string(uuid_string));
3656 /* Fill UUID of service */
3657 g_strlcpy(info->uuids[count], uuid_string,
3658 BLUETOOTH_UUID_STRING_MAX);
3660 /* Fill instance ID of service */
3661 info->inst_id[count] = svc_info->inst_id;
3663 /* Fill primary service or not info */
3664 info->primary[count] = svc_info->is_primary;
3666 /* Increment count of services browsed */
3671 static void __bt_build_char_browse_info(int conn_id,
3672 bt_gatt_service_info_t *svc_info,
3673 bt_char_browse_info_t* info)
3676 bt_gatt_char_info_t *char_info;
3677 service_uuid_t uuid;
3679 struct gatt_server_info_t *conn_info = NULL;
3681 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3683 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3684 if (conn_info == NULL) {
3685 BT_ERR("Cant find connection Information");
3689 /* Fill default data, this will be required even in case of failure */
3690 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3691 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3692 info->svc_inst_id = svc_info->inst_id;
3694 if (!svc_info->chars) {
3695 BT_ERR("No Chars browsed for address [%s]", conn_info->addr);
3699 info->count = g_slist_length(svc_info->chars);
3701 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3702 char_info = (bt_gatt_char_info_t*)l->data;
3703 if (char_info == NULL)
3706 memcpy(&uuid.uuid, &char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3707 _bt_uuid_to_string(&uuid, uuid_string);
3709 /* Fill UUID of characteristic */
3710 g_strlcpy(info->uuids[count], uuid_string,
3711 BLUETOOTH_UUID_STRING_MAX);
3713 /* Fill instance ID of characteristic */
3714 info->inst_id[count] = char_info->inst_id;
3716 /* Fill property of characteristic */
3717 info->props[count] = char_info->props;
3719 /* Increment count of services browsed */
3722 BT_DBG("Total characteristics browsed [%d]", count);
3725 static void __bt_build_descriptor_browse_info(int conn_id,
3726 bt_gatt_service_info_t *svc_info,
3727 bt_gatt_char_info_t *char_info,
3728 bt_descriptor_browse_info_t* info)
3731 bt_gatt_descriptor_info_t *desc_info;
3733 service_uuid_t uuid;
3734 struct gatt_server_info_t *conn_info = NULL;
3736 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3738 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3740 /* Fill default data, this will be required even in case of failure */
3741 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3742 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3743 info->svc_inst_id = svc_info->inst_id;
3744 memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3745 info->char_inst_id = char_info->inst_id;
3747 /* Fill property of the parent characteristic of this descriptor */
3748 info->char_props_map = char_info->props;
3750 info->count = g_slist_length(char_info->descs);
3752 if (!char_info->descs) {
3753 BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr + 12);
3757 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3758 desc_info = (bt_gatt_descriptor_info_t*)l->data;
3759 if (desc_info == NULL)
3762 memcpy(&uuid.uuid, &desc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3763 _bt_uuid_to_string(&uuid, uuid_string);
3765 /* Fill UUID of Descriptor */
3766 g_strlcpy(info->uuids[count], uuid_string,
3767 BLUETOOTH_UUID_STRING_MAX);
3769 /* Fill instance ID of Descriptor */
3770 info->inst_id[count] = desc_info->inst_id;
3773 /* Increment count of Descriptor browsed */
3777 BT_INFO("Total descriptors browsed [%d]", count);
3780 static void __bt_free_service_info(bt_gatt_service_info_t *svc)
3782 GSList *ll, *lll, *llll;
3783 bt_gatt_char_info_t *chr = NULL;
3784 bt_gatt_descriptor_info_t *desc = NULL;
3785 bt_gatt_included_service_info_t *incl_svc = NULL;
3787 BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id);
3788 /* Delete all chars and its descriptors */
3789 for (ll = svc->chars; ll != NULL; ) {
3790 chr = (bt_gatt_char_info_t *)ll->data;
3791 ll = g_slist_next(ll);
3795 for (lll = chr->descs; lll != NULL; ) {
3796 desc = (bt_gatt_descriptor_info_t *)lll->data;
3797 lll = g_slist_next(lll);
3800 chr->descs = g_slist_remove(chr->descs, desc);
3803 svc->chars = g_slist_remove(svc->chars, chr);
3807 /* Delete all included services */
3808 for (llll = svc->included_svcs; llll != NULL; ) {
3809 incl_svc = (bt_gatt_included_service_info_t *)llll->data;
3810 llll = g_slist_next(llll);
3811 if (incl_svc == NULL)
3813 svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc);
3818 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
3820 bt_gatt_service_info_list_t *svc_info_list = NULL;
3821 bt_gatt_service_info_t *svc = NULL;
3825 BT_ERR("conn_info is NULL");
3829 svc_info_list = __bt_get_service_info_list(conn_info->connection_id);
3830 if (!svc_info_list) {
3831 BT_INFO("Could not find Svc Info list for the connection ID [%d]",
3832 conn_info->connection_id);
3836 BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services));
3837 for (l = svc_info_list->services; l != NULL; ) {
3838 svc = (bt_gatt_service_info_t *)l->data;
3839 l = g_slist_next(l);
3843 __bt_free_service_info(svc);
3844 svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
3848 list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
3849 g_free(svc_info_list);
3852 int _bt_register_gatt_client_instance(const char *sender,
3853 bluetooth_device_address_t *address)
3855 int ret = OAL_STATUS_SUCCESS;
3856 char *uuid_string = NULL;
3861 /* App should ensure that it should not send */
3862 BT_INFO("Check on which instance GATT Client instance can be initialized....");
3863 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3864 if (numapps[k].is_initialized == 1) {
3865 BT_DBG("Instance ID [%d] is already in use..Check next slot",
3866 numapps[k].instance_id);
3869 BT_DBG("Time to register GATT client instancer..UUID to be used is [%s] slot [%d]",
3870 uuid_list[slot-1], slot);
3876 BT_ERR("No Slot if free for GATT Client registration..");
3877 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
3880 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3881 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
3882 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
3883 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
3885 /* Register GATT Client */
3886 ret = gattc_register(&uuid);
3887 if (ret != OAL_STATUS_SUCCESS) {
3888 BT_ERR("ret: %d", ret);
3889 g_free(uuid_string);
3890 return _bt_convert_oal_status_to_bt_error(ret);
3893 BT_DBG("GATT Client registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
3895 /* Return & wait for GATT Client Instance Initialization event */
3896 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
3897 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
3899 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
3900 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
3902 /* Address is saved here. When event comes, sender + address are matched for replying pending
3903 request. It is impossible for same sender to have requests with two same addresses */
3904 memcpy(&numapps[slot].address.addr, address->addr, sizeof(bluetooth_device_address_t));
3906 numapps[slot].is_initialized = TRUE; /* Set initialization to true here itself */
3908 g_free(uuid_string);
3909 return BLUETOOTH_ERROR_NONE;
3915 /* GATT client events */
3916 static void __bt_handle_client_instance_registered(event_gattc_register_t *data)
3918 bt_service_app_info_t *info = NULL;
3920 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3922 _bt_uuid_to_string(&(data->client_uuid), uuid_string);
3923 BT_INFO("Client ID is Initialized [%d] UUID initialized [%s]", data->client_if, uuid_string);
3925 /* Platform GATT client framwork does not use Default GATT client instance
3926 This GATT client instance is never deregistred in the lifetime of bt-service */
3927 if (g_strcmp0(uuid_string, DEFAULT_GATT_CLIENT_UUID) == 0) {
3928 BT_INFO("Default client Instance Registered");
3929 gatt_default_client = data->client_if;
3930 g_free(uuid_string);
3934 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3937 if (g_strcmp0(info->uuid, uuid_string) == 0) {
3938 BT_INFO("Found GATT client.. sender [%s] Slot [%d] occupied", info->sender, k);
3939 info->is_initialized = TRUE;
3940 info->client_id = data->client_if;
3941 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_CLIENT_REGISTER,
3942 (void*)info, sizeof(bt_service_app_info_t));
3946 g_free(uuid_string);
3949 static void __bt_handle_client_connected(event_gattc_conn_t *event_data)
3951 int result = BLUETOOTH_ERROR_NONE;
3952 struct gatt_server_info_t *conn_info = NULL;
3953 struct gatt_out_conn_info_t *out_conn_info = NULL;
3955 GVariant *param = NULL;
3957 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3958 _bt_convert_addr_type_to_string(address,
3959 (unsigned char *)event_data->address.addr);
3961 if (event_data->status != OAL_STATUS_SUCCESS)
3962 result = BLUETOOTH_ERROR_INTERNAL;
3964 /* DBUS Return fo BT_CONNECT_LE for all the apps */
3965 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
3966 BT_ADDRESS_STRING_SIZE);
3968 BT_INFO("Local GATT Client Connected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status[%d]",
3969 address, event_data->client_if, event_data->conn_id, event_data->status);
3971 if (result == BLUETOOTH_ERROR_NONE) {
3972 /* Check if device is already in connected list */
3973 conn_info = _bt_find_remote_gatt_server_info(address);
3976 /* Send event to BT-API */
3977 param = g_variant_new("(is)", result, address);
3978 _bt_send_event(BT_DEVICE_EVENT,
3979 BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED, /* Local device is GATT client */
3982 /* Save Connection info */
3983 conn_info = g_new0(struct gatt_server_info_t, 1);
3984 conn_info->addr = g_strdup(address);
3985 conn_info->client_id = event_data->client_if;
3986 #ifdef __INTEGRATE_GATT_INFO__
3987 conn_info->instance_id = -1;
3989 conn_info->connection_id = event_data->conn_id;
3990 gatt_server_info_list = g_slist_append(gatt_server_info_list, conn_info);
3991 BT_DBG("Total num of connected Remote GATT server devices [%d]",
3992 g_slist_length(gatt_server_info_list));
3995 BT_INFO("Do a Internal refresh");
3996 if (OAL_STATUS_SUCCESS != gattc_refresh(conn_info->client_id, &event_data->address))
3997 BT_ERR("GATT database refresh failed!!");
3999 BT_INFO("GATT database refresh Success!!");
4002 BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
4004 __bt_add_mtu_gatt_device(address);
4006 _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
4008 BT_ERR("GATT Client Connection failed!!");
4010 /* If outgoing connection Info is present, then remove it */
4011 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
4012 if (out_conn_info) {
4013 BT_ERR("Outgoing Client connect request was sent");
4014 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
4015 g_free(out_conn_info->addr);
4016 g_free(out_conn_info);
4018 _bt_restart_le_scan();
4023 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
4025 int result = BLUETOOTH_ERROR_NONE;
4026 struct gatt_server_info_t *conn_info = NULL;
4027 #ifndef __INTEGRATE_GATT_INFO__
4028 struct gatt_client_info_t *client_info = NULL;
4030 struct gatt_out_conn_info_t *out_conn_info = NULL;
4031 GVariant *param = NULL;
4033 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4034 _bt_convert_addr_type_to_string(address,
4035 (unsigned char *)event_data->address.addr);
4037 if (event_data->status != OAL_STATUS_SUCCESS)
4038 result = BLUETOOTH_ERROR_INTERNAL;
4040 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
4041 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
4042 result = BLUETOOTH_ERROR_INTERNAL;
4043 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
4044 address, BT_ADDRESS_STRING_SIZE);
4045 BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
4050 /* DBUS Return for BT_DISCONNECT_LE for all the apps */
4051 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE, address,
4052 BT_ADDRESS_STRING_SIZE);
4054 BT_INFO("Local GATT Client DisConnected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status [%d]",
4055 address + 12, event_data->client_if, event_data->conn_id, event_data->status);
4057 /* Remove Connection info */
4058 conn_info = _bt_find_remote_gatt_server_info(address);
4061 param = g_variant_new("(is)", result, address);
4062 /* Send event to application */
4063 _bt_send_event(BT_DEVICE_EVENT,
4064 BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED,
4067 BT_INFO("Remove GATT server info from List..");
4068 /* Remove all services from info list_gatt_info */
4069 __bt_cleanup_remote_services(conn_info);
4071 /* Remove info from List */
4072 gatt_server_info_list = g_slist_remove(gatt_server_info_list, conn_info);
4074 /* Remove all pending invocations from invocatin_list */
4075 BT_INFO("Clear all pending invocations");
4076 __bt_gatt_cleanup_invocation_on_gatt_disconnection(BLUETOOTH_ERROR_INTERNAL,
4077 address, BT_ADDRESS_STRING_SIZE);
4079 BT_INFO("Total num of connected GATT servers [%d]", g_slist_length(gatt_server_info_list));
4080 g_free(conn_info->addr);
4083 BT_INFO("Can not find conn info, already removed!");
4085 #ifndef __INTEGRATE_GATT_INFO__
4086 /* Remove client info */
4087 client_info = _bt_find_remote_gatt_client_info(address);
4089 BT_DBG("Remove GATT client info from list");
4090 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
4091 g_free(client_info->addr);
4092 g_free(client_info);
4096 __bt_remove_mtu_gatt_device(address);
4098 /* If outgoing connection Info is present, then remove it */
4099 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
4100 if (out_conn_info) {
4101 BT_ERR("Client Disconnected event, but outgoing connect request was sent");
4102 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
4103 g_free(out_conn_info->addr);
4104 g_free(out_conn_info);
4110 static void __bt_handle_client_service_search_result(
4111 event_gattc_service_result_t *event_data)
4113 /* Pre: status is never fail from OAL */
4115 /* Find service list from address */
4116 bt_gatt_service_info_list_t *svc_info_list;
4117 bt_gatt_service_info_t *svc_info;
4119 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4120 if (!svc_info_list) {
4121 BT_DBG("Service info list not present for connection ID %d, means first time browse", event_data->conn_status.conn_id);
4122 /* Means for this conn_id, no services are ever browsed, first time,
4123 create service info list for this conn_id */
4124 svc_info_list = g_malloc0(sizeof(bt_gatt_service_info_list_t));
4125 svc_info_list->conn_id = event_data->conn_status.conn_id;
4126 list_gatt_info = g_slist_append(list_gatt_info, svc_info_list);
4129 /* send list and current service's uuid and instance id to find it */
4130 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4131 /* If not found, check if service changed, if yes, means this is a new service added
4132 in remote GATT device, update uuid info in svc info list structure, to be used when
4133 search is completed */
4135 if (svc_info_list->info.is_changed) {
4136 BT_DBG("Service Changed indication already found for connection ID %d", event_data->conn_status.conn_id);
4137 memcpy(svc_info_list->info.uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4139 /* Create and add new service in service list */
4140 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4141 memcpy(svc_info->uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4142 svc_info->inst_id = event_data->srvc_id.id.inst_id;
4143 svc_info->is_primary = event_data->srvc_id.is_prmry;
4144 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4145 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_status.conn_id);
4147 /* If returned matching service info, then just update service_rmeoved value inside it to 0 */
4148 svc_info->is_removed = 0;
4152 static void __bt_handle_client_service_search_completed(
4153 event_gattc_conn_status_t *event_data)
4155 struct gatt_server_info_t *conn_info = NULL;
4156 bt_gatt_service_info_list_t *svc_info_list;
4157 bt_gatt_service_info_t *svc_info;
4158 bt_services_browse_info_t browse_info;
4159 unsigned char uuid_empty[BLUETOOTH_UUID_HEX_MAX_LEN];
4161 memset(&uuid_empty, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4162 memset(&browse_info, 0x00, sizeof(bt_services_browse_info_t));
4163 BT_INFO("Primary Services browsing completed status[%d] conn ID [%d]",
4164 event_data->status, event_data->conn_id);
4166 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4168 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4169 if (!svc_info_list) {
4170 BT_ERR("No services browsed ever for addr [%s]", conn_info->addr);
4172 /* Just build response and return ERROR */
4173 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4175 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4176 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4177 sizeof(bt_services_browse_info_t));
4181 /* If fail, then send event with error */
4182 if (event_data->status != OAL_STATUS_SUCCESS) {
4183 /* Just build response and return ERROR */
4184 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4186 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4187 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4188 sizeof(bt_services_browse_info_t));
4192 /* If success, then find service info list from address */
4194 /* If svc_changed == 1 and uuid valid, means a new service is added*/
4195 if (svc_info_list->info.is_changed && !memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4196 /* TODO: Send event -Service added with instance ID and UUID of newly added service */
4197 BT_INFO("new service added");
4199 BT_INFO("TODO new service added");
4202 /* If svc_changed == 1 and uuid invalid, then a service is removed */
4203 if (svc_info_list->info.is_changed && memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4204 /* Scan through the service info list to find service with is_removed = 1*/
4205 svc_info = __bt_find_removed_service(svc_info_list);
4207 /* TODO Send event - Service removed with instance ID and UUID of just rmeoved service */
4209 /* Remove that service info from service info list */
4210 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
4212 /* Delete that service completely from svc_info list*/
4213 __bt_remove_service_info_from_list(svc_info);
4217 /* Reset svc_changed = 0, and reset UUID = all 0's */
4218 svc_info_list->info.is_changed = 0;
4219 memset(&svc_info_list->info.uuid, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4221 /* Build Reply and send to service browse primary services request of pending apps */
4222 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4224 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4225 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4226 sizeof(bt_services_browse_info_t));
4230 static void __bt_handle_client_characteristic_search_result(
4231 event_gattc_characteristic_result_t *event_data)
4233 bt_gatt_service_info_list_t *svc_info_list;
4234 bt_gatt_service_info_t *svc_info;
4235 bt_gatt_char_info_t *char_info;
4236 bt_char_browse_info_t browse_info;
4238 memset(&browse_info, 0x00, sizeof(bt_char_browse_info_t));
4241 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4242 /* Find service info list from address */
4243 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4244 if (svc_info_list == NULL) {
4245 BT_ERR("svc_info_list is NULL");
4249 /* Find matching service info from svc info list */
4250 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4251 if (svc_info == NULL) {
4252 BT_ERR("svc_info is NULL");
4256 /* Find Matching char from service info in event */
4257 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4258 /* If not found, then add new characteristic and return */
4260 BT_DBG("Add new characteristic");
4261 char_info = g_malloc0(sizeof(bt_gatt_char_info_t));
4262 memcpy(char_info->uuid, event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4264 char_info->inst_id = event_data->char_id.inst_id;
4265 char_info->props = event_data->char_prop;
4266 svc_info->chars = g_slist_append(svc_info->chars, char_info);
4268 /* If found, then return */
4269 BT_DBG("update char property as Characteristic browsed is already present");
4270 char_info->props |= event_data->char_prop;
4273 /* If Not success: Means Charc browse is completed */
4274 /* Find char list from service in event */
4275 /* Find service list from address */
4276 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4277 if (svc_info_list == NULL) {
4278 BT_ERR("svc_info_list is NULL");
4282 /* Find service info from service in event */
4283 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4284 if (svc_info == NULL) {
4285 BT_ERR("svc_info is NULL");
4289 /* Build char list from service in event */
4290 __bt_build_char_browse_info(event_data->conn_status.conn_id,
4291 svc_info, &browse_info);
4293 /* Create response and return by sending event*/
4294 /* Build Reply and send to service browse All Included services request of pending apps */
4295 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4296 BT_GATT_GET_SERVICE_PROPERTIES,
4298 sizeof(bt_char_browse_info_t));
4302 static void __bt_handle_client_descriptor_search_result(
4303 event_gattc_descriptor_result_t *event_data)
4305 bt_gatt_service_info_list_t *svc_info_list;
4306 bt_gatt_service_info_t *svc_info;
4307 bt_gatt_char_info_t *char_info;
4308 bt_gatt_descriptor_info_t *desc_info;
4309 bt_descriptor_browse_info_t browse_info;
4311 BT_DBG("descriptor search result status [%d]", event_data->conn_status.status);
4313 memset(&browse_info, 0x00, sizeof(bt_descriptor_browse_info_t));
4316 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4317 /* Find service list from address */
4318 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4319 if (svc_info_list == NULL) {
4320 BT_ERR("svc_info_list is NULL");
4324 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4325 if (svc_info == NULL) {
4326 BT_ERR("svc_info is NULL");
4330 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4331 if (char_info == NULL) {
4332 BT_ERR("char_info is NULL");
4336 desc_info = __bt_find_matching_desc(char_info, &event_data->descr_id);
4337 /* If not found, add new descriptor and return */
4339 desc_info = g_malloc0(sizeof(bt_gatt_descriptor_info_t));
4340 memcpy(desc_info->uuid, event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4342 desc_info->inst_id = event_data->descr_id.inst_id;
4343 char_info->descs = g_slist_append(char_info->descs, desc_info);
4346 /* If found, then return */
4347 BT_DBG("Descriptor browsed is already presesnt");
4350 /* If Not success */
4351 /* Find service list from address */
4352 /* Find included service list from service in event */
4353 /* Create response and return by sending event*/
4354 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4355 if (svc_info_list == NULL) {
4356 BT_ERR("svc_info_list is NULL");
4360 /* Find service info from service in event */
4361 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4362 if (svc_info == NULL) {
4363 BT_ERR("svc_info is NULL");
4367 /* Find char info from char in event */
4368 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4369 if (char_info == NULL) {
4370 BT_ERR("char_info is NULL");
4374 /* Build descriptor list from char in event */
4375 __bt_build_descriptor_browse_info(event_data->conn_status.conn_id,
4376 svc_info, char_info, &browse_info);
4379 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4380 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
4382 sizeof(bt_descriptor_browse_info_t));
4386 static void __bt_handle_client_characteristic_read_data(
4387 event_gattc_read_data *event_data)
4389 int result = BLUETOOTH_ERROR_NONE;
4390 struct gatt_server_info_t *conn_info = NULL;
4391 bluetooth_gatt_client_char_prop_info_t read_info;
4393 /* Read Information data structures */
4394 GVariant *param = NULL;
4395 GVariant *data = NULL;
4396 GVariant *data_svc_uuid = NULL;
4397 GVariant *data_char_uuid = NULL;
4398 char *read_val = NULL;
4399 char *svc_uuid = NULL;
4400 char *char_uuid = NULL;
4403 //memset(&read_info, 0x00, sizeof(bt_gatt_handle_property_t));
4404 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4406 /* Extract Address from conn_id of event data */
4407 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4408 event_data->uuid_status.conn_status.conn_id);
4410 BT_INFO("Characteristic Read result from addr [%s] status [%d]",
4411 conn_info->addr, event_data->uuid_status.conn_status.status);
4413 /* Fill char in buffer */
4414 memcpy(&read_info.characteristic.uuid,
4415 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4416 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4418 /* Fill Service in buffer */
4419 memcpy(&read_info.svc.uuid,
4420 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4421 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4423 /* Fill remote device address */
4424 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4426 /* Fill data and reply to all apps waiting for Read result on the same characteristic
4427 Note: Even in case of failure, address, handles and result code should be returned */
4428 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4429 result = BLUETOOTH_ERROR_INTERNAL;
4431 if (event_data->data_len > 0) {
4433 // for (i = 0; i < event_data->data_len; i++)
4434 // BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4437 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4439 data = g_variant_new_from_data(
4440 G_VARIANT_TYPE_BYTESTRING,
4442 event_data->data_len,
4445 BT_ERR("Characteristic Read success, but no data!!!");
4447 data = g_variant_new_from_data(
4448 G_VARIANT_TYPE_BYTESTRING,
4455 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4457 data_svc_uuid = g_variant_new_from_data(
4458 G_VARIANT_TYPE_BYTESTRING,
4464 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4466 data_char_uuid = g_variant_new_from_data(
4467 G_VARIANT_TYPE_BYTESTRING,
4472 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4476 event_data->uuid_status.srvc_id.id.inst_id,
4479 event_data->uuid_status.char_id.inst_id,
4480 event_data->data_len,
4484 char *sender = NULL;
4485 __bt_gatt_get_pending_request_info(BT_GATT_READ_CHARACTERISTIC, &sender);
4486 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4487 BLUETOOTH_EVENT_GATT_READ_CHAR,
4490 /* Send DBUS return */
4491 __bt_gatt_handle_pending_request_info(result,
4492 BT_GATT_READ_CHARACTERISTIC,
4494 sizeof(bluetooth_gatt_client_char_prop_info_t));
4505 static void __bt_handle_client_descriptor_read_data(
4506 event_gattc_read_data *event_data)
4508 int result = BLUETOOTH_ERROR_NONE;
4509 struct gatt_server_info_t *conn_info = NULL;
4510 bluetooth_gatt_client_desc_prop_info_t read_info;
4512 /* Read Information data structures */
4513 GVariant *param = NULL;
4514 GVariant *data = NULL;
4515 GVariant *data_svc_uuid = NULL;
4516 GVariant *data_char_uuid = NULL;
4517 GVariant *data_desc_uuid = NULL;
4518 char *read_val = NULL;
4519 char *svc_uuid = NULL;
4520 char *char_uuid = NULL;
4521 char *desc_uuid = NULL;
4525 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4527 /* Extract Address from conn_id of event data */
4528 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4529 event_data->uuid_status.conn_status.conn_id);
4531 BT_DBG("Descriptor Read result from addr [%s] status [%d]",
4532 conn_info->addr, event_data->uuid_status.conn_status.status);
4534 /* Fill descriptor informations in buffer */
4535 memcpy(&read_info.descriptor.uuid,
4536 event_data->uuid_status.descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4537 read_info.descriptor.instance_id = event_data->uuid_status.descr_id.inst_id;
4539 /* Fill Characteristic informations in buffer */
4540 memcpy(&read_info.characteristic.uuid,
4541 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4542 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4544 /* Fill Service informations in buffer */
4545 memcpy(&read_info.svc.uuid,
4546 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4547 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4549 /* Fill remote device address */
4550 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4552 /* Fill data and reply to all apps waiting for Read result on the same characteristic */
4553 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4554 result = BLUETOOTH_ERROR_INTERNAL;
4556 if (event_data->data_len > 0) {
4558 for (i = 0; i < event_data->data_len; i++)
4559 BT_DBG("Data[%d] = [0x%x]", i, event_data->data[i]);
4562 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4564 data = g_variant_new_from_data(
4565 G_VARIANT_TYPE_BYTESTRING,
4567 event_data->data_len,
4570 BT_INFO("Descriptor Read success, but no data!!!");
4572 data = g_variant_new_from_data(
4573 G_VARIANT_TYPE_BYTESTRING,
4579 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4581 data_svc_uuid = g_variant_new_from_data(
4582 G_VARIANT_TYPE_BYTESTRING,
4588 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4590 data_char_uuid = g_variant_new_from_data(
4591 G_VARIANT_TYPE_BYTESTRING,
4597 desc_uuid = g_memdup2(&event_data->uuid_status.descr_id.uuid.uuid[0], uuid_len);
4599 data_desc_uuid = g_variant_new_from_data(
4600 G_VARIANT_TYPE_BYTESTRING,
4605 param = g_variant_new("(isn@ayin@ayin@ayin@ay)", result,
4609 event_data->uuid_status.srvc_id.id.inst_id,
4612 event_data->uuid_status.char_id.inst_id,
4615 event_data->uuid_status.descr_id.inst_id,
4616 event_data->data_len,
4620 char *sender = NULL;
4621 __bt_gatt_get_pending_request_info(BT_GATT_READ_DESCRIPTOR_VALUE, &sender);
4622 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4623 BLUETOOTH_EVENT_GATT_READ_DESC,
4627 /* Send DBUS return */
4628 __bt_gatt_handle_pending_request_info(result,
4629 BT_GATT_READ_DESCRIPTOR_VALUE,
4631 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4642 static void __bt_handle_client_characteristic_write_data(
4643 event_gattc_write_data *event_data)
4645 int result = BLUETOOTH_ERROR_NONE;
4646 struct gatt_server_info_t *conn_info = NULL;
4647 bluetooth_gatt_client_char_prop_info_t write_info;
4649 /* Read Information data structures */
4650 GVariant *param = NULL;
4651 GVariant *data_svc_uuid = NULL;
4652 GVariant *data_char_uuid = NULL;
4653 char *svc_uuid = NULL;
4654 char *char_uuid = NULL;
4657 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4659 /* Extract Address from conn_id of event data */
4660 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4661 event_data->conn_status.conn_id);
4663 BT_DBG("Characteristic Write callback from addr [%s] status [%d]",
4664 conn_info->addr, event_data->conn_status.status);
4666 /* Fill char in buffer */
4667 memcpy(&write_info.characteristic.uuid,
4668 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4669 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4671 /* Fill Service in buffer */
4672 memcpy(&write_info.svc.uuid,
4673 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4674 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4676 /* Fill remote device address */
4677 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4679 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4680 result = BLUETOOTH_ERROR_INTERNAL;
4686 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4688 data_svc_uuid = g_variant_new_from_data(
4689 G_VARIANT_TYPE_BYTESTRING,
4695 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4697 data_char_uuid = g_variant_new_from_data(
4698 G_VARIANT_TYPE_BYTESTRING,
4703 param = g_variant_new("(isn@ayin@ayi)", result,
4707 event_data->srvc_id.id.inst_id,
4710 event_data->char_id.inst_id);
4713 char *sender = NULL;
4714 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, &sender);
4715 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4716 BLUETOOTH_EVENT_GATT_WRITE_CHAR,
4726 /* Send DBUS return */
4727 __bt_gatt_handle_pending_request_info(result,
4728 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
4730 sizeof(bluetooth_gatt_client_char_prop_info_t));
4734 static void __bt_handle_client_descriptor_write_data(
4735 event_gattc_write_data *event_data)
4737 int result = BLUETOOTH_ERROR_NONE;
4738 struct gatt_server_info_t *conn_info = NULL;
4739 bluetooth_gatt_client_desc_prop_info_t write_info;
4741 /* Write Information data structures */
4742 GVariant *param = NULL;
4743 GVariant *data_svc_uuid = NULL;
4744 GVariant *data_char_uuid = NULL;
4745 GVariant *data_desc_uuid = NULL;
4746 char *svc_uuid = NULL;
4747 char *char_uuid = NULL;
4748 char *desc_uuid = NULL;
4751 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4753 /* Extract Address from conn_id of event data */
4754 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4755 event_data->conn_status.conn_id);
4757 if (NULL == conn_info) {
4758 BT_ERR("Failed to get the conn info for conn_id [%d]", event_data->conn_status.conn_id);
4762 BT_DBG("Descriptor Write callback from addr [%s] status [%d]",
4763 conn_info->addr, event_data->conn_status.status);
4765 /* Fill descriptor informations in buffer */
4766 memcpy(&write_info.descriptor.uuid,
4767 event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4768 write_info.descriptor.instance_id = event_data->descr_id.inst_id;
4770 /* Fill Characteristic informations in buffer */
4771 memcpy(&write_info.characteristic.uuid,
4772 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4773 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4775 /* Fill Service informations in buffer */
4776 memcpy(&write_info.svc.uuid,
4777 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4778 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4780 /* Fill remote device address */
4781 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4783 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4784 result = BLUETOOTH_ERROR_INTERNAL;
4790 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4792 data_svc_uuid = g_variant_new_from_data(
4793 G_VARIANT_TYPE_BYTESTRING,
4799 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4801 data_char_uuid = g_variant_new_from_data(
4802 G_VARIANT_TYPE_BYTESTRING,
4808 desc_uuid = g_memdup2(&event_data->descr_id.uuid.uuid[0], uuid_len);
4810 data_desc_uuid = g_variant_new_from_data(
4811 G_VARIANT_TYPE_BYTESTRING,
4816 param = g_variant_new("(isn@ayin@ayin@ayi)", result,
4820 event_data->srvc_id.id.inst_id,
4823 event_data->char_id.inst_id,
4826 event_data->descr_id.inst_id);
4829 char *sender = NULL;
4830 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_DESCRIPTOR_VALUE, &sender);
4831 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4832 BLUETOOTH_EVENT_GATT_WRITE_DESC,
4843 /* Send DBUS return */
4844 __bt_gatt_handle_pending_request_info(result,
4845 BT_GATT_WRITE_DESCRIPTOR_VALUE,
4847 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4850 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data)
4852 int result = BLUETOOTH_ERROR_INTERNAL;
4853 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4855 _bt_convert_addr_type_to_string(address, (unsigned char *)event_data->address.addr);
4857 /* DBUS Return with fail of pending BT_CONNECT_LE for all the apps */
4858 BT_INFO("Local GATT Client disconnected: Remote addr[%s] ", address + 12);
4860 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
4861 BT_ADDRESS_STRING_SIZE);
4865 static void __bt_handle_client_notification_registered(
4866 event_gattc_regdereg_notify_t *event_data,
4867 gboolean is_registered)
4869 int result = BLUETOOTH_ERROR_NONE;
4870 struct gatt_server_info_t *conn_info = NULL;
4871 bt_gatt_notif_reg_info_t notif_info;
4874 memset(¬if_info, 0x00, sizeof(bt_gatt_notif_reg_info_t));
4876 BT_INFO("Client Interface [%d] status [%d]",
4877 event_data->conn_id,
4878 event_data->status);
4880 /* Extract Address from conn_id of event data */
4881 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4883 BT_INFO("Connection Info is not present, return");
4886 BT_INFO("Notification Registered for addr [%s]", conn_info->addr);
4888 /* Fill svc informations in buffer */
4889 memcpy(¬if_info.svc_uuid,
4890 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4891 notif_info.svc_inst = event_data->srvc_id.id.inst_id;
4893 /* Fill char in buffer */
4894 memcpy(¬if_info.char_uuid,
4895 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4896 notif_info.char_inst = event_data->char_id.inst_id;
4898 /* Fill remote device address */
4899 _bt_convert_addr_string_to_type(notif_info.addr.addr, conn_info->addr);
4901 notif_info.is_registered = is_registered;
4903 if (event_data->status != OAL_STATUS_SUCCESS)
4904 result = BLUETOOTH_ERROR_INTERNAL;
4906 /* Send DBUS Return for BT_GATT_WATCH_CHARACTERISTIC */
4907 __bt_gatt_handle_pending_request_info(result,
4908 BT_GATT_WATCH_CHARACTERISTIC,
4910 sizeof(bt_gatt_notif_reg_info_t));
4913 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
4915 /* No status in this event from OAL */
4916 int result = BLUETOOTH_ERROR_NONE;
4918 /* Read Information data structures */
4919 GVariant *param = NULL;
4920 GVariant *data = NULL;
4921 GVariant *data_svc_uuid = NULL;
4922 GVariant *data_char_uuid = NULL;
4923 char *read_val = NULL;
4924 char *svc_uuid = NULL;
4925 char *char_uuid = NULL;
4931 BT_INFO("Notifcation of charc data changed");
4933 if (event_data->data_len > 0) {
4935 for (i = 0; i < event_data->data_len; i++)
4936 BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4939 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4940 _bt_convert_addr_type_to_string(addr,
4941 (unsigned char *)&(event_data->address.addr));
4944 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4946 data = g_variant_new_from_data(
4947 G_VARIANT_TYPE_BYTESTRING,
4949 event_data->data_len,
4952 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4954 data_svc_uuid = g_variant_new_from_data(
4955 G_VARIANT_TYPE_BYTESTRING,
4961 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4963 data_char_uuid = g_variant_new_from_data(
4964 G_VARIANT_TYPE_BYTESTRING,
4970 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4974 event_data->srvc_id.id.inst_id,
4977 event_data->char_id.inst_id,
4978 event_data->data_len,
4982 _bt_send_event(BT_GATT_CLIENT_EVENT,
4983 BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
4986 BT_ERR("No Data!!");
4999 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data)
5001 bt_gatt_service_info_list_t *svc_info_list;
5003 bt_gatt_service_info_t *svc_info;
5004 GVariant *param = NULL;
5005 char *address_str = NULL;
5006 char *uuid_str = NULL;
5008 #ifndef TIZEN_BLUEDROID_PORTING
5009 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
5010 if (svc_info_list == NULL) {
5011 BT_ERR("svc_info_list is NULL");
5015 if (event_data->change_type) {
5016 /* Add service UUID in list */
5017 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
5018 memcpy(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5019 svc_info->inst_id = event_data->inst_id;
5020 svc_info->is_primary = 1; // TODO: Need to check is_primary is required or not
5021 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
5022 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_id);
5024 /* Remove service UUID in list */
5025 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
5026 svc_info = (bt_gatt_service_info_t *)l->data;
5027 if (svc_info == NULL)
5030 if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
5031 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
5032 __bt_free_service_info(svc_info);
5039 address_str = g_malloc0(BT_ADDRESS_STRING_SIZE);
5040 uuid_str = g_malloc0(BT_UUID_STRING_MAX);
5041 _bt_convert_addr_type_to_string(address_str, event_data->address.addr);
5043 #ifndef TIZEN_BLUEDROID_PORTING
5044 _bt_uuid_to_string(&event_data->uuid, uuid_str);
5046 event_data->change_type = BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_RESYNC;
5049 param = g_variant_new("(iiss)", event_data->inst_id, event_data->change_type, address_str, uuid_str);
5051 _bt_send_event(BT_GATT_CLIENT_EVENT,
5052 BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED,
5054 g_free(address_str);
5058 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
5061 struct gatt_server_info_t *conn_info = NULL;
5062 gboolean connected = FALSE;
5064 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
5065 _bt_convert_addr_type_to_string(addr,
5066 (unsigned char *)&(address->addr));
5068 BT_DBG("Check GATT connection status of [%s]", addr);
5069 /* Check if device is already in connected list */
5070 conn_info = _bt_find_remote_gatt_server_info(addr);
5072 BT_DBG("Remote GATT Server device [%s] is Connected", conn_info->addr);
5075 struct gatt_client_info_t *client_info = NULL;
5077 BT_DBG("Remote GATT Server Device [%s] is not Connected", addr);
5079 /* Check if device is already in connected list */
5080 client_info = _bt_find_remote_gatt_client_info(addr);
5082 BT_DBG("Remote Client device [%s] is Connected", client_info->addr);
5085 BT_DBG("Remote GATT Client Device [%s] is not Connected", addr);
5093 void _bt_handle_invocation_context(int function_name, void *data)
5095 switch (function_name) {
5097 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_CONNECT_LE,
5098 (char *)data, BT_ADDRESS_STRING_SIZE);
5105 int _bt_connect_le_device(bluetooth_device_address_t *address,
5106 int auto_connect, int client_id)
5108 struct gatt_server_info_t *conn_info = NULL;
5109 struct gatt_out_conn_info_t *out_conn_info = NULL;
5111 invocation_info_t *req_info = NULL;
5112 int ret = OAL_STATUS_SUCCESS;
5114 char *remote_address = NULL;
5116 BT_CHECK_PARAMETER(address, return);
5118 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5119 _bt_convert_addr_type_to_string(addr, address->addr);
5120 BT_DBG("GATT Client connect request for address [%s] client instance [%d]",
5124 /* Check if Remote Device is already under connection progress */
5125 req_info = _bt_get_request_info_data_from_function_name(BT_CONNECT_LE);
5127 remote_address = (char*)req_info->user_data;
5128 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5129 BT_DBG("Already Connection ongoing for same remote GATT Server address [%s]", remote_address);
5130 /* Return and wait for events to be sent to all apps */
5132 return BLUETOOTH_ERROR_IN_PROGRESS;
5136 /* Check if remote GATT Server is connected or not */
5137 conn_info = _bt_find_remote_gatt_server_info(addr);
5139 BT_ERR("GATT Server is already connected..");
5141 return BLUETOOTH_ERROR_ALREADY_CONNECT;
5144 /* TODO Check Requirement of holding Advertisement before initiating LE connect */
5147 /* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
5148 if (client_id == 0) {
5149 /* GATT CLient connect request sent by an app without any client instance [0] */
5150 BT_DBG("Assign default GATT client id [%d]", gatt_default_client);
5151 client_id = gatt_default_client;
5154 BT_INFO("Connect using CLient ID [%d]", client_id);
5155 ret = gattc_connect(client_id, (bt_address_t*)(address), auto_connect);
5157 if (ret != OAL_STATUS_SUCCESS) {
5158 BT_ERR("gattc_connect is failed. ret: %d", ret);
5160 _bt_restart_le_scan();
5161 return _bt_convert_oal_status_to_bt_error(ret);
5164 /* Mark this as outgoing connection */
5165 out_conn_info = g_new0(struct gatt_out_conn_info_t, 1);
5166 out_conn_info->addr = g_strdup(addr);
5167 out_conn_info->client_id = client_id;
5168 BT_INFO("Added outgoing connection info addr[%s]", out_conn_info->addr + 12);
5169 outgoing_gatt_conn_list = g_slist_append(outgoing_gatt_conn_list, out_conn_info);
5172 return BLUETOOTH_ERROR_NONE;
5175 int _bt_gatt_get_primary_services(char *address)
5177 BT_CHECK_PARAMETER(address, return);
5178 struct gatt_server_info_t *conn_info = NULL;
5179 invocation_info_t *req_info = NULL;
5180 int ret = OAL_STATUS_SUCCESS;
5182 /* Check if any app is already browsing primary services on the same remote GATT Server */
5183 req_info = _bt_get_request_info_data(BT_GATT_GET_PRIMARY_SERVICES, address);
5185 BT_INFO("Already Primary Service Browsing ongoing for same rmeote GATT Server");
5186 /* Return and wait for events to be sent to all apps */
5187 return BLUETOOTH_ERROR_NONE;
5190 /* Check if remote GATT Server is connected or not */
5191 conn_info = _bt_find_remote_gatt_server_info(address);
5193 BT_ERR("GATT Server is not yet connected..");
5194 return BLUETOOTH_ERROR_NOT_CONNECTED;
5197 BT_INFO("Get all services. GATT Server [%s] is connected, conn Id [%d]",
5198 conn_info->addr + 12, conn_info->connection_id);
5200 /* Send Primary Service Browsing request to stack */
5201 ret = gattc_search_service(conn_info->connection_id, NULL);
5202 if (ret != OAL_STATUS_SUCCESS) {
5203 BT_ERR("ret: %d", ret);
5204 return _bt_convert_oal_status_to_bt_error(ret);
5206 return BLUETOOTH_ERROR_NONE;
5209 int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc)
5211 BT_CHECK_PARAMETER(svc, return);
5212 struct gatt_server_info_t *conn_info = NULL;
5213 invocation_info_t *req_info = NULL;
5214 bluetooth_gatt_client_svc_prop_info_t *prop;
5215 oal_gatt_srvc_id_t srvc_id;
5216 int ret = OAL_STATUS_SUCCESS;
5219 /* Check if any app is already browsing characteristics of the same service on the same remote GATT Server */
5220 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_SERVICE_PROPERTIES);
5222 prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
5223 if (prop && !memcmp(svc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t))
5224 && !memcmp(prop->svc.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
5225 && prop->svc.instance_id == svc->svc.instance_id) {
5226 BT_INFO("Already Properties browsing for Primary Service ongoing for same remote GATT Server");
5227 /* Return and wait for events to be sent to all apps */
5228 return BLUETOOTH_ERROR_NONE;
5232 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5233 _bt_convert_addr_type_to_string(addr, svc->device_address.addr);
5235 /* Check if remote GATT Server is connected or not */
5236 conn_info = _bt_find_remote_gatt_server_info(addr);
5238 BT_ERR("GATT Server is not yet connected..");
5240 return BLUETOOTH_ERROR_NOT_CONNECTED;
5243 BT_DBG("Get all charc. GATT Server [%s] is connected, conn Id [%d]",
5244 conn_info->addr, conn_info->connection_id);
5246 srvc_id.is_prmry = TRUE;
5247 srvc_id.id.inst_id = svc->svc.instance_id;
5248 memcpy(srvc_id.id.uuid.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5250 /* Search All Characteristic */
5251 ret = gattc_get_characteristic(conn_info->connection_id, &srvc_id, NULL);
5252 if (ret != OAL_STATUS_SUCCESS) {
5253 BT_ERR("ret: %d", ret);
5255 return _bt_convert_oal_status_to_bt_error(ret);
5258 return BLUETOOTH_ERROR_NONE;
5261 int _bt_gatt_get_all_characteristic_properties(
5262 bluetooth_gatt_client_char_prop_info_t *chr)
5264 struct gatt_server_info_t *conn_info = NULL;
5265 invocation_info_t *req_info = NULL;
5266 bluetooth_gatt_client_char_prop_info_t *prop;
5267 oal_gatt_srvc_id_t srvc_id;
5268 oal_gatt_id_t char_id;
5269 int ret = OAL_STATUS_SUCCESS;
5272 BT_CHECK_PARAMETER(chr, return);
5274 /* Check if any app is already browsing descriptors of the same char of
5275 particular service on the same remote GATT Server */
5276 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_CHARACTERISTIC_PROPERTIES);
5278 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5279 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5280 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5281 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5282 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5283 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5284 BT_INFO("Already Properties browsing for Characteristic ongoing for same remote GATT Server");
5285 /* Return and wait for events to be sent to all apps */
5286 return BLUETOOTH_ERROR_NONE;
5290 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5291 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5293 /* Check if remote GATT Server is connected or not */
5294 conn_info = _bt_find_remote_gatt_server_info(addr);
5296 BT_ERR("GATT Server is not yet connected..");
5298 return BLUETOOTH_ERROR_NOT_CONNECTED;
5301 BT_DBG("Get all desc. GATT Server [%s] is connected, conn Id [%d]",
5302 conn_info->addr, conn_info->connection_id);
5304 srvc_id.is_prmry = TRUE;
5305 srvc_id.id.inst_id = chr->svc.instance_id;
5306 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5308 char_id.inst_id = chr->characteristic.instance_id;
5309 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5311 /* Search All Descriptors */
5312 ret = gattc_get_descriptor(conn_info->connection_id, &srvc_id, &char_id, NULL);
5313 if (ret != OAL_STATUS_SUCCESS) {
5314 BT_ERR("ret: %d", ret);
5316 return _bt_convert_oal_status_to_bt_error(ret);
5319 return BLUETOOTH_ERROR_NONE;
5322 int _bt_gatt_read_characteristic_value(
5323 bluetooth_gatt_client_char_prop_info_t *chr)
5325 struct gatt_server_info_t *conn_info = NULL;
5326 invocation_info_t *req_info = NULL;
5327 bluetooth_gatt_client_char_prop_info_t *prop;
5328 oal_gatt_srvc_id_t srvc_id;
5329 oal_gatt_id_t char_id;
5330 int ret = OAL_STATUS_SUCCESS;
5333 BT_CHECK_PARAMETER(chr, return);
5335 /* Check if any app is already Reading characteristic of the same char of
5336 particular service on the same remote GATT Server */
5337 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_CHARACTERISTIC);
5339 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5340 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5341 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5342 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5343 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5344 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5345 BT_INFO("Already Characteristic value Read operation in progress for same remote GATT Server");
5346 /* Return and wait for events to be sent to all apps */
5347 return BLUETOOTH_ERROR_NONE;
5351 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5352 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5354 /* Check if remote GATT Server is connected or not */
5355 conn_info = _bt_find_remote_gatt_server_info(addr);
5357 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5358 conn_info->addr, conn_info->connection_id);
5360 BT_ERR("GATT Server is not yet connected..");
5362 return BLUETOOTH_ERROR_NOT_CONNECTED;
5365 srvc_id.is_prmry = TRUE;
5366 srvc_id.id.inst_id = chr->svc.instance_id;
5367 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5369 char_id.inst_id = chr->characteristic.instance_id;
5370 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5372 /* Search All Descriptors */
5373 ret = gattc_read_characteristic(conn_info->connection_id, &srvc_id, &char_id, OAL_GATT_AUTH_REQ_NONE);
5374 if (ret != OAL_STATUS_SUCCESS) {
5375 BT_ERR("ret: %d", ret);
5377 return _bt_convert_oal_status_to_bt_error(ret);
5380 return BLUETOOTH_ERROR_NONE;
5383 int _bt_gatt_read_descriptor_value(
5384 bluetooth_gatt_client_desc_prop_info_t *desc)
5386 struct gatt_server_info_t *conn_info = NULL;
5387 invocation_info_t *req_info = NULL;
5388 bluetooth_gatt_client_desc_prop_info_t *prop;
5389 oal_gatt_srvc_id_t srvc_id;
5390 oal_gatt_id_t char_id;
5391 oal_gatt_id_t desc_id;
5392 int ret = OAL_STATUS_SUCCESS;
5395 BT_CHECK_PARAMETER(desc, return);
5397 /* Check if any app is already Reading descriptors of the same char of
5398 particular service on the same remote GATT Server */
5399 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_DESCRIPTOR_VALUE);
5401 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5402 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5403 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5404 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5405 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5406 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5407 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5408 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5409 BT_INFO("Already Descriptor value Read operation in progress for same remote GATT Server");
5410 /* Return and wait for events to be sent to all apps */
5411 return BLUETOOTH_ERROR_NONE;
5415 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5416 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5418 /* Check if remote GATT Server is connected or not */
5419 conn_info = _bt_find_remote_gatt_server_info(addr);
5421 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5422 conn_info->addr, conn_info->connection_id);
5424 BT_ERR("GATT Server is not yet connected..");
5426 return BLUETOOTH_ERROR_NOT_CONNECTED;
5429 srvc_id.is_prmry = TRUE;
5430 srvc_id.id.inst_id = desc->svc.instance_id;
5431 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5433 char_id.inst_id = desc->characteristic.instance_id;
5434 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5436 desc_id.inst_id = desc->descriptor.instance_id;
5437 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5439 /* Search All Descriptors */
5440 ret = gattc_read_descriptor(conn_info->connection_id, &srvc_id, &char_id,
5441 &desc_id, OAL_GATT_AUTH_REQ_NONE);
5442 if (ret != OAL_STATUS_SUCCESS) {
5443 BT_ERR("ret: %d", ret);
5445 return _bt_convert_oal_status_to_bt_error(ret);
5448 return BLUETOOTH_ERROR_NONE;
5452 int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5454 struct gatt_server_info_t *conn_info = NULL;
5455 oal_gatt_srvc_id_t srvc_id;
5456 oal_gatt_id_t char_id;
5457 int ret = OAL_STATUS_SUCCESS;
5460 BT_CHECK_PARAMETER(chr, return);
5462 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5463 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5465 /* Check if remote GATT Server is connected or not */
5466 conn_info = _bt_find_remote_gatt_server_info(addr);
5468 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5469 conn_info->addr, conn_info->connection_id);
5471 BT_ERR("GATT Server is not yet connected..");
5473 return BLUETOOTH_ERROR_NOT_CONNECTED;
5476 srvc_id.is_prmry = TRUE;
5477 srvc_id.id.inst_id = chr->svc.instance_id;
5478 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5480 char_id.inst_id = chr->characteristic.instance_id;
5481 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5483 ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
5485 if (ret != OAL_STATUS_SUCCESS) {
5486 BT_ERR("ret: %d", ret);
5488 return _bt_convert_oal_status_to_bt_error(ret);
5490 BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
5492 return BLUETOOTH_ERROR_NONE;
5496 int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5499 struct gatt_server_info_t *conn_info = NULL;
5500 oal_gatt_srvc_id_t srvc_id;
5501 oal_gatt_id_t char_id;
5502 int ret = OAL_STATUS_SUCCESS;
5505 BT_CHECK_PARAMETER(chr, return);
5507 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5508 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5510 /* Check if remote GATT Server is connected or not */
5511 conn_info = _bt_find_remote_gatt_server_info(addr);
5513 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5514 conn_info->addr, conn_info->connection_id);
5516 BT_ERR("GATT Server is not yet connected..");
5518 return BLUETOOTH_ERROR_NOT_CONNECTED;
5521 srvc_id.is_prmry = TRUE;
5522 srvc_id.id.inst_id = chr->svc.instance_id;
5523 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5525 char_id.inst_id = chr->characteristic.instance_id;
5526 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5528 ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
5529 OAL_GATT_AUTH_REQ_NONE, fd, mtu);
5530 if (ret != OAL_STATUS_SUCCESS) {
5531 BT_ERR("ret: %d", ret);
5533 return _bt_convert_oal_status_to_bt_error(ret);
5535 BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
5537 return BLUETOOTH_ERROR_NONE;
5542 /* Write Characteristic */
5543 int _bt_gatt_write_characteristic_value_by_type(
5544 bluetooth_gatt_client_char_prop_info_t *chr,
5545 bluetooth_gatt_att_data_t *data,
5546 bluetooth_gatt_write_type_e write_type)
5548 struct gatt_server_info_t *conn_info = NULL;
5549 invocation_info_t *req_info = NULL;
5550 bluetooth_gatt_client_char_prop_info_t *prop;
5551 oal_gatt_srvc_id_t srvc_id;
5552 oal_gatt_id_t char_id;
5553 int ret = OAL_STATUS_SUCCESS;
5556 BT_CHECK_PARAMETER(chr, return);
5557 BT_CHECK_PARAMETER(data, return);
5559 /* Check if any app is already writing same char of
5560 particular service on the same remote GATT Server */
5561 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE);
5563 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5564 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5565 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5566 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5567 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5568 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5569 BT_INFO("Already Characteristic Write Value operation in progress for same remote GATT Server");
5570 /* Return and wait for events to be sent to all apps */
5571 return BLUETOOTH_ERROR_NONE;
5575 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5576 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5578 /* Check if remote GATT Server is connected or not */
5579 conn_info = _bt_find_remote_gatt_server_info(addr);
5581 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5582 conn_info->addr, conn_info->connection_id);
5584 BT_ERR("GATT Server is not yet connected..");
5586 return BLUETOOTH_ERROR_NOT_CONNECTED;
5589 srvc_id.is_prmry = TRUE;
5590 srvc_id.id.inst_id = chr->svc.instance_id;
5591 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5593 char_id.inst_id = chr->characteristic.instance_id;
5594 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5596 /* Write CHar value */
5597 ret = gattc_write_characteristic(conn_info->connection_id,
5599 (oal_gatt_write_type_t)write_type, data->length,
5600 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5601 if (ret != OAL_STATUS_SUCCESS) {
5602 BT_ERR("ret: %d", ret);
5604 return _bt_convert_oal_status_to_bt_error(ret);
5607 return BLUETOOTH_ERROR_NONE;
5610 /* Write Descriptor */
5611 int _bt_gatt_write_descriptor_value_by_type(
5612 bluetooth_gatt_client_desc_prop_info_t *desc,
5613 bluetooth_gatt_att_data_t *data,
5614 bluetooth_gatt_write_type_e write_type)
5616 struct gatt_server_info_t *conn_info = NULL;
5617 invocation_info_t *req_info = NULL;
5618 bluetooth_gatt_client_desc_prop_info_t *prop;
5619 oal_gatt_srvc_id_t srvc_id;
5620 oal_gatt_id_t char_id;
5621 oal_gatt_id_t desc_id;
5622 int ret = OAL_STATUS_SUCCESS;
5626 BT_CHECK_PARAMETER(desc, return);
5627 BT_CHECK_PARAMETER(data, return);
5631 /* Check if any app is already writing on same Descriptor of the same char of
5632 particular service on the same remote GATT Server */
5633 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_DESCRIPTOR_VALUE);
5635 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5636 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5637 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5638 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5639 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5640 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5641 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5642 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5643 BT_INFO("Already Descriptor value Write operation in progress for same remote GATT Server");
5644 /* Return and wait for events to be sent to all apps */
5645 return BLUETOOTH_ERROR_NONE;
5649 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5650 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5652 /* Check if remote GATT Server is connected or not */
5653 conn_info = _bt_find_remote_gatt_server_info(addr);
5655 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5656 conn_info->addr, conn_info->connection_id);
5658 BT_ERR("GATT Server is not yet connected..");
5660 return BLUETOOTH_ERROR_NOT_CONNECTED;
5663 srvc_id.is_prmry = TRUE;
5664 srvc_id.id.inst_id = desc->svc.instance_id;
5665 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5667 char_id.inst_id = desc->characteristic.instance_id;
5668 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5670 desc_id.inst_id = desc->descriptor.instance_id;
5671 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5674 BT_INFO("Connection ID [%d] write type [%d] data length [%d]", conn_info->connection_id, write_type, data->length);
5675 for (k = 0; k < data->length; k++)
5676 BT_INFO("Data[%d] [0x%x]", k, data->data[k]);
5678 ret = gattc_write_descriptor(conn_info->connection_id,
5679 &srvc_id, &char_id, &desc_id,
5680 (oal_gatt_write_type_t)write_type, data->length,
5681 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5682 if (ret != OAL_STATUS_SUCCESS) {
5683 BT_ERR("ret: %d", ret);
5685 return _bt_convert_oal_status_to_bt_error(ret);
5688 return BLUETOOTH_ERROR_NONE;
5691 int _bt_gatt_watch_characteristic(
5692 bluetooth_gatt_client_char_prop_info_t *chr,
5696 struct gatt_server_info_t *conn_info = NULL;
5697 oal_gatt_srvc_id_t srvc_id;
5698 oal_gatt_id_t char_id;
5699 int ret = OAL_STATUS_SUCCESS;
5702 BT_CHECK_PARAMETER(chr, return);
5704 BT_INFO("Client ID [%d] Is Notify [%d]", client_id, is_notify);
5706 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5707 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5709 /* Check if remote GATT Server is connected or not */
5710 conn_info = _bt_find_remote_gatt_server_info(addr);
5712 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5713 conn_info->addr, conn_info->connection_id);
5715 BT_ERR("GATT Server is not yet connected..");
5717 return BLUETOOTH_ERROR_NOT_CONNECTED;
5719 srvc_id.is_prmry = TRUE;
5720 srvc_id.id.inst_id = chr->svc.instance_id;
5721 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5723 char_id.inst_id = chr->characteristic.instance_id;
5724 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5726 /* Register or unregister Notification characteristic */
5728 ret = gattc_register_for_notification(conn_info->connection_id,
5729 (bt_address_t*)&(chr->device_address),
5730 &srvc_id, &char_id);
5732 ret = gattc_deregister_for_notification(conn_info->connection_id,
5733 (bt_address_t*)&(chr->device_address),
5734 &srvc_id, &char_id);
5736 BT_INFO("Result[%d]", ret);
5737 if (ret != OAL_STATUS_SUCCESS) {
5738 BT_ERR("ret: %d", ret);
5740 return _bt_convert_oal_status_to_bt_error(ret);
5743 return BLUETOOTH_ERROR_NONE;
5747 int _bt_disconnect_le_device(bluetooth_device_address_t *address,
5750 struct gatt_server_info_t *conn_info = NULL;
5751 struct gatt_client_info_t *rem_client_conn_info = NULL;
5752 invocation_info_t *req_info = NULL;
5753 int ret = OAL_STATUS_SUCCESS;
5755 char *remote_address = NULL;
5757 BT_CHECK_PARAMETER(address, return);
5759 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5760 _bt_convert_addr_type_to_string(addr, address->addr);
5761 BT_INFO("GATT Client Disconnect request for address [%s]", addr + 12);
5763 /* Check if Remote Device is already under connection progress */
5764 req_info = _bt_get_request_info_data_from_function_name(BT_DISCONNECT_LE);
5766 remote_address = (char*)req_info->user_data;
5767 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5768 BT_DBG("Already DisConnection ongoing for same remote GATT Server address [%s]", remote_address);
5769 /* Return success and wait for events to be sent to all apps */
5771 return BLUETOOTH_ERROR_IN_PROGRESS;
5774 /* Check if remote GATT Server is connected or not */
5775 conn_info = _bt_find_remote_gatt_server_info(addr);
5777 /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
5778 if (client_id == 0) {
5779 BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
5781 BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
5782 client_id = gatt_default_client;
5785 BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
5786 ret = gattc_disconnect(client_id, (bt_address_t*)(address),
5787 conn_info->connection_id);
5789 /* check if remote client is connected */
5790 rem_client_conn_info = _bt_find_remote_gatt_client_info(addr);
5792 if (!rem_client_conn_info || client_id != 0) {
5793 BT_ERR("GATT device is not connected..");
5795 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
5798 BT_INFO("Disconnect remote gatt client ");
5800 ret = gatts_disconnect(rem_client_conn_info->instance_id,
5801 (bt_address_t*)(address), rem_client_conn_info->connection_id);
5804 if (ret != OAL_STATUS_SUCCESS) {
5805 BT_ERR("ret: %d", ret);
5807 return _bt_convert_oal_status_to_bt_error(ret);
5810 return BLUETOOTH_ERROR_NONE;
5813 int _bt_gatt_watch_service_changed_indication(const char *sender,
5814 bluetooth_device_address_t *address,
5815 gboolean is_enabled)
5818 bt_service_app_info_t *info = NULL;
5820 BT_INFO("%s Servic changed Indication watcher for app [%s]",
5821 is_enabled ? "Enable":"Disable", sender);
5823 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5826 if (g_strcmp0(sender, info->sender) == 0 &&
5827 memcmp(info->address.addr, address->addr,
5828 sizeof(bluetooth_device_address_t)) == 0) {
5829 BT_DBG("Found GATT client App.. [%s], sender [%s]", info->uuid, info->sender);
5830 info->is_watcher_enabled = is_enabled;
5834 return BLUETOOTH_ERROR_NONE;
5837 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
5839 bt_service_app_info_t *info = NULL;
5842 BT_DBG("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
5844 /* Unregister CLient instance associated with address X. It is possible that another app still
5845 has client_id valid for same remote address */
5846 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5849 /* Exact matching of sender */
5850 if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) { /* Check for only valid GATT client Instance */
5851 numapps[k].client_id = -1;
5852 numapps[k].is_initialized = FALSE;
5853 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
5854 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
5855 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
5857 /* Its a GATT Client Instance */
5858 ret = gattc_deregister(client_id);
5859 if (ret != OAL_STATUS_SUCCESS) {
5860 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
5861 return _bt_convert_oal_status_to_bt_error(ret);
5863 return BLUETOOTH_ERROR_NONE;
5868 return BLUETOOTH_ERROR_NOT_FOUND;
5871 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data)
5873 int result = BLUETOOTH_ERROR_NONE;
5874 struct gatt_server_info_t *conn_info = NULL;
5875 GVariant *param = NULL;
5879 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
5880 if (conn_info == NULL) {
5881 BT_ERR("Cant find connection Information");
5885 BT_DBG("GATT Client: MTU Configured from addr [%s] status [%d] MTU size [%d]",
5886 conn_info->addr, event_data->status, event_data->mtu);
5888 if (event_data->status != OAL_STATUS_SUCCESS)
5889 result = BLUETOOTH_ERROR_INTERNAL;
5891 /* DBUS Return fo BT_REQ_ATT_MTU for all the apps */
5892 __bt_gatt_handle_pending_request_info(result, BT_REQ_ATT_MTU, conn_info->addr,
5893 BT_ADDRESS_STRING_SIZE);
5895 if (result == BLUETOOTH_ERROR_NONE) {
5896 mtu = event_data->mtu;
5897 param = g_variant_new("(isqy)",
5903 /* Send event to BT-API */
5904 _bt_send_event(BT_DEVICE_EVENT,
5905 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
5908 /* Update the MTU for current connection */
5909 __bt_update_mtu_gatt_device(conn_info->addr, event_data->mtu);
5913 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address)
5916 struct gatt_mtu_info_t *info = NULL;
5918 for (l = gatt_mtu_info_list; l != NULL; l = g_slist_next(l)) {
5919 info = (struct gatt_mtu_info_t*)l->data;
5923 if (!g_strcmp0(info->addr, address)) {
5924 BT_DBG("Remote GATT device found addr[%s]", info->addr);
5929 BT_DBG("Not found Remote GATT device addr[%s]", address);
5933 static void __bt_remove_mtu_gatt_device(char *address)
5935 struct gatt_mtu_info_t *dev_info = NULL;
5937 dev_info = __bt_find_mtu_gatt_device(address);
5940 BT_DBG("removing the gatt device from mtu list");
5941 gatt_mtu_info_list = g_slist_remove(gatt_mtu_info_list, dev_info);
5942 g_free(dev_info->addr);
5947 static void __bt_add_mtu_gatt_device(char *address)
5949 struct gatt_mtu_info_t *dev_info = NULL;
5951 dev_info = __bt_find_mtu_gatt_device(address);
5954 BT_DBG("adding the gatt device in mtu list");
5955 dev_info = g_new0(struct gatt_mtu_info_t, 1);
5956 dev_info->addr = g_strdup(address);
5957 dev_info->att_mtu = BT_DEFAULT_ATT_MTU;
5958 gatt_mtu_info_list = g_slist_append(gatt_mtu_info_list, dev_info);
5962 static void __bt_update_mtu_gatt_device(char *address, int mtu)
5964 struct gatt_mtu_info_t *dev_info = NULL;
5966 dev_info = __bt_find_mtu_gatt_device(address);
5969 dev_info->att_mtu = mtu;
5973 int _bt_gatt_get_data_batching_available_packets(
5974 guint *available_packets)
5976 int ret = OAL_STATUS_SUCCESS;
5978 BT_CHECK_PARAMETER(available_packets, return);
5980 ret = gatt_get_data_batching_available_packets(available_packets);
5981 if (ret != OAL_STATUS_SUCCESS) {
5982 BT_ERR("ret: %d", ret);
5983 return _bt_convert_oal_status_to_bt_error(ret);
5986 return BLUETOOTH_ERROR_NONE;
5989 int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address,
5990 int packet_threshold, int timeout)
5992 int ret = OAL_STATUS_SUCCESS;
5993 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5995 BT_CHECK_PARAMETER(address, return);
5997 _bt_convert_addr_type_to_string(remote_address, address->addr);
5998 BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]",
5999 remote_address, packet_threshold, timeout);
6001 ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout);
6003 if (ret != OAL_STATUS_SUCCESS) {
6004 BT_ERR("ret: %d", ret);
6005 return _bt_convert_oal_status_to_bt_error(ret);
6008 return BLUETOOTH_ERROR_NONE;
6011 int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address)
6013 int ret = OAL_STATUS_SUCCESS;
6014 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
6016 BT_CHECK_PARAMETER(address, return);
6018 _bt_convert_addr_type_to_string(remote_address, address->addr);
6019 BT_INFO("Disable GATT data batching. address[%s]", remote_address);
6021 ret = gatt_disable_data_batching((bt_address_t*)(address));
6023 if (ret != OAL_STATUS_SUCCESS) {
6024 BT_ERR("ret: %d", ret);
6025 return _bt_convert_oal_status_to_bt_error(ret);
6028 return BLUETOOTH_ERROR_NONE;