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);
3277 if (ret != OAL_STATUS_SUCCESS) {
3278 BT_ERR("ret: %d", ret);
3280 return BLUETOOTH_ERROR_INTERNAL;
3284 return BLUETOOTH_ERROR_NONE;
3287 int _bt_gatt_server_read_phy(bluetooth_device_address_t *address)
3289 struct gatt_client_info_t *conn_info = NULL;
3290 //int ret = OAL_STATUS_SUCCESS;
3293 BT_CHECK_PARAMETER(address, return);
3295 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3296 _bt_convert_addr_type_to_string(addr, address->addr);
3298 BT_INFO("Read PHY for the server: address:[%s]", addr);
3300 /* Check if remote GATT client is connected or not */
3301 conn_info = _bt_find_remote_gatt_client_info(addr);
3302 if (conn_info == NULL) {
3303 BT_ERR("GATT Client is not yet connected..");
3305 return BLUETOOTH_ERROR_NOT_CONNECTED;
3308 /* TODO: This code is commented as currently this API is not supported in OAL
3309 ret = gatts_read_phy(conn_info->connection_id);
3310 if (ret != OAL_STATUS_SUCCESS) {
3311 BT_ERR("ret: %d", ret);
3313 return BLUETOOTH_ERROR_INTERNAL;
3317 return BLUETOOTH_ERROR_NONE;
3320 int _bt_gatt_client_set_phy(bluetooth_device_address_t *device_address,
3321 int tx_phy, int rx_phy, int phy_options)
3323 struct gatt_server_info_t *conn_info = NULL;
3325 //int ret = OAL_STATUS_SUCCESS;
3327 BT_INFO("Setting Preferred PHY");
3328 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3329 _bt_convert_addr_type_to_string(addr, device_address->addr);
3331 /* Check if remote GATT server is connected or not */
3332 conn_info = _bt_find_remote_gatt_server_info(addr);
3333 if (conn_info == NULL) {
3334 BT_ERR("GATT Server is not yet connected...");
3336 return BLUETOOTH_ERROR_NOT_CONNECTED;
3339 /* TODO: This code is commented as currently this API is not supported in OAL
3340 ret = gattc_set_preferred_phy(conn_info->connection_id, tx_phy, rx_phy, phy_options);
3341 if (ret != OAL_STATUS_SUCCESS) {
3342 BT_ERR("ret: %d", ret);
3344 return BLUETOOTH_ERROR_INTERNAL;
3348 return BLUETOOTH_ERROR_NONE;
3351 int _bt_gatt_client_read_phy(bluetooth_device_address_t *address)
3353 struct gatt_server_info_t *conn_info = NULL;
3354 //int ret = OAL_STATUS_SUCCESS;
3357 BT_CHECK_PARAMETER(address, return);
3359 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3360 _bt_convert_addr_type_to_string(addr, address->addr);
3362 BT_INFO("Read PHY for the server: address:[%s]", addr);
3364 /* Check if remote GATT server is connected or not */
3365 conn_info = _bt_find_remote_gatt_server_info(addr);
3366 if (conn_info == NULL) {
3367 BT_ERR("GATT Server is not yet connected..");
3369 return BLUETOOTH_ERROR_NOT_CONNECTED;
3372 /* TODO: This code is commented as currently this API is not supported in OAL
3373 ret = gattc_read_phy(conn_info->connection_id);
3374 if (ret != OAL_STATUS_SUCCESS) {
3375 BT_ERR("ret: %d", ret);
3377 return BLUETOOTH_ERROR_INTERNAL;
3381 return BLUETOOTH_ERROR_NONE;
3384 int _bt_request_att_mtu(bluetooth_device_address_t *device_address,
3387 struct gatt_server_info_t *conn_info = NULL;
3389 int ret = OAL_STATUS_SUCCESS;
3391 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3392 _bt_convert_addr_type_to_string(addr, device_address->addr);
3394 /* Check if remote GATT Server is connected or not */
3395 conn_info = _bt_find_remote_gatt_server_info(addr);
3396 if (conn_info == NULL) {
3397 BT_ERR("GATT Server is not yet connected..");
3399 return BLUETOOTH_ERROR_NOT_CONNECTED;
3402 ret = gattc_configure_mtu(conn_info->connection_id, mtu);
3403 if (ret != OAL_STATUS_SUCCESS) {
3404 BT_ERR("ret: %d", ret);
3406 return _bt_convert_oal_status_to_bt_error(ret);
3410 return BLUETOOTH_ERROR_NONE;
3413 int _bt_get_att_mtu(bluetooth_device_address_t *address,
3416 BT_CHECK_PARAMETER(address, return);
3417 BT_CHECK_PARAMETER(mtu, return);
3418 struct gatt_client_info_t *client_info = NULL;
3419 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
3420 int ret = OAL_STATUS_SUCCESS;
3423 _bt_convert_addr_type_to_string(addr, address->addr);
3425 BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]", addr);
3427 client_info = _bt_find_remote_gatt_client_info(addr);
3429 BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
3430 client_info->addr, client_info->connection_id, client_info->instance_id);
3432 ret = gatts_get_att_mtu(client_info->connection_id, &stack_mtu);
3433 if (ret != OAL_STATUS_SUCCESS) {
3434 BT_ERR("ret: %d", ret);
3435 return _bt_convert_oal_status_to_bt_error(ret);
3438 struct gatt_server_info_t *server_info = NULL;
3439 BT_ERR("GATT Client [%s] is not yet connected..", addr);
3440 server_info = _bt_find_remote_gatt_server_info(addr);
3442 BT_INFO("GATT Server [%s] is connected, conn Id [%d] Client ID [%d]",
3443 server_info->addr, server_info->connection_id, server_info->client_id);
3445 ret = gattc_get_att_mtu(server_info->connection_id, &stack_mtu);
3446 if (ret != OAL_STATUS_SUCCESS) {
3447 BT_ERR("ret: %d", ret);
3448 return _bt_convert_oal_status_to_bt_error(ret);
3451 BT_ERR("GATT Server [%s] is not yet connected..", addr);
3452 return BLUETOOTH_ERROR_NOT_CONNECTED;
3456 BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
3457 *mtu = (unsigned int)stack_mtu;
3460 BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
3461 return BLUETOOTH_ERROR_NOT_CONNECTED;
3464 return BLUETOOTH_ERROR_NONE;
3467 /* GATT Client utility static functions */
3468 static bt_gatt_service_info_list_t *__bt_get_service_info_list(int conn_id)
3471 bt_gatt_service_info_list_t *info = NULL;
3473 for (l = list_gatt_info; l != NULL; l = g_slist_next(l)) {
3474 info = (bt_gatt_service_info_list_t *)l->data;
3478 if (info->conn_id == conn_id)
3485 static bt_gatt_service_info_t *__bt_find_matching_service(
3486 bt_gatt_service_info_list_t *svc_list, oal_gatt_srvc_id_t *svc)
3489 bt_gatt_service_info_t *info = NULL;
3491 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3492 info = (bt_gatt_service_info_t *)l->data;
3496 /* Match UUID and instance ID */
3497 if (!memcmp(&svc->id.uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3498 && (svc->id.inst_id == info->inst_id)) {
3505 static bt_gatt_char_info_t *__bt_find_matching_charc(
3506 bt_gatt_service_info_t *svc_info, oal_gatt_id_t *charc)
3509 bt_gatt_char_info_t *info = NULL;
3511 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3512 info = (bt_gatt_char_info_t *)l->data;
3516 /* Match UUID and instance ID */
3517 if (!memcmp(&charc->uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3518 && (charc->inst_id == info->inst_id)) {
3525 static bt_gatt_descriptor_info_t *__bt_find_matching_desc(
3526 bt_gatt_char_info_t *char_info, oal_gatt_id_t *desc)
3529 bt_gatt_descriptor_info_t *info = NULL;
3531 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3532 info = (bt_gatt_descriptor_info_t *)l->data;
3536 /* Match UUID and instance ID */
3537 if (!memcmp(&desc->uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3538 && (desc->inst_id == info->inst_id)) {
3545 static bt_gatt_service_info_t* __bt_find_removed_service(bt_gatt_service_info_list_t *svc_list)
3548 bt_gatt_service_info_t *info = NULL;
3550 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3551 info = (bt_gatt_service_info_t*)l->data;
3555 /* Service is marked a removed */
3556 if (info->is_removed == 1)
3562 static void __bt_remove_service_info_from_list(bt_gatt_service_info_t *svc_info)
3568 bt_gatt_char_info_t *charc = NULL;
3569 bt_gatt_included_service_info_t *incl = NULL;
3570 bt_gatt_descriptor_info_t *desc = NULL;
3572 /* Remove all Characteristic and Descriptors within characteristic */
3573 for (l = svc_info->chars; l != NULL;) {
3574 charc = (bt_gatt_char_info_t*)l->data;
3575 l = g_slist_next(l); /* Incase if l is removed, saving next to l */
3580 /* Inside Characteristic */
3581 for (l1 = charc->descs; l1 != NULL;) {
3583 desc = (bt_gatt_descriptor_info_t*)l1->data;
3584 l1 = g_slist_next(l1);
3589 /* Remove Descriptor */
3590 charc->descs = g_slist_remove(charc->descs, desc);
3593 /* Remove Characteristic */
3594 svc_info->chars = g_slist_remove(svc_info->chars, charc);
3598 /* Remove all Included Services */
3599 for (l2 = svc_info->included_svcs; l2 != NULL;) {
3600 incl = (bt_gatt_included_service_info_t*)l2->data;
3601 l2 = g_slist_next(l2); /* Incase if l is removed, saving next to l */
3606 /* Remove included service */
3607 svc_info->included_svcs = g_slist_remove(svc_info->included_svcs, incl);
3614 static void __bt_build_service_browse_info(int conn_id,
3615 bt_services_browse_info_t* info)
3618 bt_gatt_service_info_list_t *svc_info_list;
3619 bt_gatt_service_info_t *svc_info;
3621 service_uuid_t uuid;
3622 struct gatt_server_info_t *conn_info = NULL;
3624 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3626 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3627 if (conn_info == NULL) {
3628 BT_ERR("Cant find connection Information");
3632 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3634 svc_info_list = __bt_get_service_info_list(conn_id);
3638 info->count = g_slist_length(svc_info_list->services);
3639 BT_DBG("Total services present in the svc info list for this conn id [%d] is [%d]",
3640 conn_id, info->count);
3642 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
3643 svc_info = (bt_gatt_service_info_t*)l->data;
3644 if (svc_info == NULL)
3647 memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3648 _bt_uuid_to_string(&uuid, uuid_string);
3650 BT_INFO("[%d] %s [%s]", count, uuid_string, _bt_convert_uuid_to_string(uuid_string));
3652 /* Fill UUID of service */
3653 g_strlcpy(info->uuids[count], uuid_string,
3654 BLUETOOTH_UUID_STRING_MAX);
3656 /* Fill instance ID of service */
3657 info->inst_id[count] = svc_info->inst_id;
3659 /* Fill primary service or not info */
3660 info->primary[count] = svc_info->is_primary;
3662 /* Increment count of services browsed */
3667 static void __bt_build_char_browse_info(int conn_id,
3668 bt_gatt_service_info_t *svc_info,
3669 bt_char_browse_info_t* info)
3672 bt_gatt_char_info_t *char_info;
3673 service_uuid_t uuid;
3675 struct gatt_server_info_t *conn_info = NULL;
3677 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3679 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3680 if (conn_info == NULL) {
3681 BT_ERR("Cant find connection Information");
3685 /* Fill default data, this will be required even in case of failure */
3686 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3687 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3688 info->svc_inst_id = svc_info->inst_id;
3690 if (!svc_info->chars) {
3691 BT_ERR("No Chars browsed for address [%s]", conn_info->addr);
3695 info->count = g_slist_length(svc_info->chars);
3697 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3698 char_info = (bt_gatt_char_info_t*)l->data;
3699 if (char_info == NULL)
3702 memcpy(&uuid.uuid, &char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3703 _bt_uuid_to_string(&uuid, uuid_string);
3705 /* Fill UUID of characteristic */
3706 g_strlcpy(info->uuids[count], uuid_string,
3707 BLUETOOTH_UUID_STRING_MAX);
3709 /* Fill instance ID of characteristic */
3710 info->inst_id[count] = char_info->inst_id;
3712 /* Fill property of characteristic */
3713 info->props[count] = char_info->props;
3715 /* Increment count of services browsed */
3718 BT_DBG("Total characteristics browsed [%d]", count);
3721 static void __bt_build_descriptor_browse_info(int conn_id,
3722 bt_gatt_service_info_t *svc_info,
3723 bt_gatt_char_info_t *char_info,
3724 bt_descriptor_browse_info_t* info)
3727 bt_gatt_descriptor_info_t *desc_info;
3729 service_uuid_t uuid;
3730 struct gatt_server_info_t *conn_info = NULL;
3732 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3734 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3736 /* Fill default data, this will be required even in case of failure */
3737 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3738 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3739 info->svc_inst_id = svc_info->inst_id;
3740 memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3741 info->char_inst_id = char_info->inst_id;
3743 /* Fill property of the parent characteristic of this descriptor */
3744 info->char_props_map = char_info->props;
3746 info->count = g_slist_length(char_info->descs);
3748 if (!char_info->descs) {
3749 BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr + 12);
3753 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3754 desc_info = (bt_gatt_descriptor_info_t*)l->data;
3755 if (desc_info == NULL)
3758 memcpy(&uuid.uuid, &desc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3759 _bt_uuid_to_string(&uuid, uuid_string);
3761 /* Fill UUID of Descriptor */
3762 g_strlcpy(info->uuids[count], uuid_string,
3763 BLUETOOTH_UUID_STRING_MAX);
3765 /* Fill instance ID of Descriptor */
3766 info->inst_id[count] = desc_info->inst_id;
3769 /* Increment count of Descriptor browsed */
3773 BT_INFO("Total descriptors browsed [%d]", count);
3776 static void __bt_free_service_info(bt_gatt_service_info_t *svc)
3778 GSList *ll, *lll, *llll;
3779 bt_gatt_char_info_t *chr = NULL;
3780 bt_gatt_descriptor_info_t *desc = NULL;
3781 bt_gatt_included_service_info_t *incl_svc = NULL;
3783 BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id);
3784 /* Delete all chars and its descriptors */
3785 for (ll = svc->chars; ll != NULL; ) {
3786 chr = (bt_gatt_char_info_t *)ll->data;
3787 ll = g_slist_next(ll);
3791 for (lll = chr->descs; lll != NULL; ) {
3792 desc = (bt_gatt_descriptor_info_t *)lll->data;
3793 lll = g_slist_next(lll);
3796 chr->descs = g_slist_remove(chr->descs, desc);
3799 svc->chars = g_slist_remove(svc->chars, chr);
3803 /* Delete all included services */
3804 for (llll = svc->included_svcs; llll != NULL; ) {
3805 incl_svc = (bt_gatt_included_service_info_t *)llll->data;
3806 llll = g_slist_next(llll);
3807 if (incl_svc == NULL)
3809 svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc);
3814 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
3816 bt_gatt_service_info_list_t *svc_info_list = NULL;
3817 bt_gatt_service_info_t *svc = NULL;
3821 BT_ERR("conn_info is NULL");
3825 svc_info_list = __bt_get_service_info_list(conn_info->connection_id);
3826 if (!svc_info_list) {
3827 BT_INFO("Could not find Svc Info list for the connection ID [%d]",
3828 conn_info->connection_id);
3832 BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services));
3833 for (l = svc_info_list->services; l != NULL; ) {
3834 svc = (bt_gatt_service_info_t *)l->data;
3835 l = g_slist_next(l);
3839 __bt_free_service_info(svc);
3840 svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
3844 list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
3845 g_free(svc_info_list);
3848 int _bt_register_gatt_client_instance(const char *sender,
3849 bluetooth_device_address_t *address)
3851 int ret = OAL_STATUS_SUCCESS;
3852 char *uuid_string = NULL;
3857 /* App should ensure that it should not send */
3858 BT_INFO("Check on which instance GATT Client instance can be initialized....");
3859 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3860 if (numapps[k].is_initialized == 1) {
3861 BT_DBG("Instance ID [%d] is already in use..Check next slot",
3862 numapps[k].instance_id);
3865 BT_DBG("Time to register GATT client instancer..UUID to be used is [%s] slot [%d]",
3866 uuid_list[slot-1], slot);
3872 BT_ERR("No Slot if free for GATT Client registration..");
3873 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
3876 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3877 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
3878 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
3879 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
3881 /* Register GATT Client */
3882 ret = gattc_register(&uuid);
3883 if (ret != OAL_STATUS_SUCCESS) {
3884 BT_ERR("ret: %d", ret);
3885 g_free(uuid_string);
3886 return _bt_convert_oal_status_to_bt_error(ret);
3889 BT_DBG("GATT Client registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
3891 /* Return & wait for GATT Client Instance Initialization event */
3892 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
3893 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
3895 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
3896 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
3898 /* Address is saved here. When event comes, sender + address are matched for replying pending
3899 request. It is impossible for same sender to have requests with two same addresses */
3900 memcpy(&numapps[slot].address.addr, address->addr, sizeof(bluetooth_device_address_t));
3902 numapps[slot].is_initialized = TRUE; /* Set initialization to true here itself */
3904 g_free(uuid_string);
3905 return BLUETOOTH_ERROR_NONE;
3911 /* GATT client events */
3912 static void __bt_handle_client_instance_registered(event_gattc_register_t *data)
3914 bt_service_app_info_t *info = NULL;
3916 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3918 _bt_uuid_to_string(&(data->client_uuid), uuid_string);
3919 BT_INFO("Client ID is Initialized [%d] UUID initialized [%s]", data->client_if, uuid_string);
3921 /* Platform GATT client framwork does not use Default GATT client instance
3922 This GATT client instance is never deregistred in the lifetime of bt-service */
3923 if (g_strcmp0(uuid_string, DEFAULT_GATT_CLIENT_UUID) == 0) {
3924 BT_INFO("Default client Instance Registered");
3925 gatt_default_client = data->client_if;
3926 g_free(uuid_string);
3930 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3933 if (g_strcmp0(info->uuid, uuid_string) == 0) {
3934 BT_INFO("Found GATT client.. sender [%s] Slot [%d] occupied", info->sender, k);
3935 info->is_initialized = TRUE;
3936 info->client_id = data->client_if;
3937 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_CLIENT_REGISTER,
3938 (void*)info, sizeof(bt_service_app_info_t));
3942 g_free(uuid_string);
3945 static void __bt_handle_client_connected(event_gattc_conn_t *event_data)
3947 int result = BLUETOOTH_ERROR_NONE;
3948 struct gatt_server_info_t *conn_info = NULL;
3949 struct gatt_out_conn_info_t *out_conn_info = NULL;
3951 GVariant *param = NULL;
3953 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3954 _bt_convert_addr_type_to_string(address,
3955 (unsigned char *)event_data->address.addr);
3957 if (event_data->status != OAL_STATUS_SUCCESS)
3958 result = BLUETOOTH_ERROR_INTERNAL;
3960 /* DBUS Return fo BT_CONNECT_LE for all the apps */
3961 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
3962 BT_ADDRESS_STRING_SIZE);
3964 BT_INFO("Local GATT Client Connected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status[%d]",
3965 address, event_data->client_if, event_data->conn_id, event_data->status);
3967 if (result == BLUETOOTH_ERROR_NONE) {
3968 /* Check if device is already in connected list */
3969 conn_info = _bt_find_remote_gatt_server_info(address);
3972 /* Send event to BT-API */
3973 param = g_variant_new("(is)", result, address);
3974 _bt_send_event(BT_DEVICE_EVENT,
3975 BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED, /* Local device is GATT client */
3978 /* Save Connection info */
3979 conn_info = g_new0(struct gatt_server_info_t, 1);
3980 conn_info->addr = g_strdup(address);
3981 conn_info->client_id = event_data->client_if;
3982 #ifdef __INTEGRATE_GATT_INFO__
3983 conn_info->instance_id = -1;
3985 conn_info->connection_id = event_data->conn_id;
3986 gatt_server_info_list = g_slist_append(gatt_server_info_list, conn_info);
3987 BT_DBG("Total num of connected Remote GATT server devices [%d]",
3988 g_slist_length(gatt_server_info_list));
3991 BT_INFO("Do a Internal refresh");
3992 if (OAL_STATUS_SUCCESS != gattc_refresh(conn_info->client_id, &event_data->address))
3993 BT_ERR("GATT database refresh failed!!");
3995 BT_INFO("GATT database refresh Success!!");
3998 BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
4000 __bt_add_mtu_gatt_device(address);
4002 _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
4004 BT_ERR("GATT Client Connection failed!!");
4006 /* If outgoing connection Info is present, then remove it */
4007 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
4008 if (out_conn_info) {
4009 BT_ERR("Outgoing Client connect request was sent");
4010 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
4011 g_free(out_conn_info->addr);
4012 g_free(out_conn_info);
4014 _bt_restart_le_scan();
4019 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
4021 int result = BLUETOOTH_ERROR_NONE;
4022 struct gatt_server_info_t *conn_info = NULL;
4023 #ifndef __INTEGRATE_GATT_INFO__
4024 struct gatt_client_info_t *client_info = NULL;
4026 struct gatt_out_conn_info_t *out_conn_info = NULL;
4027 GVariant *param = NULL;
4029 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4030 _bt_convert_addr_type_to_string(address,
4031 (unsigned char *)event_data->address.addr);
4033 if (event_data->status != OAL_STATUS_SUCCESS)
4034 result = BLUETOOTH_ERROR_INTERNAL;
4036 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
4037 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
4038 result = BLUETOOTH_ERROR_INTERNAL;
4039 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
4040 address, BT_ADDRESS_STRING_SIZE);
4041 BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
4046 /* DBUS Return for BT_DISCONNECT_LE for all the apps */
4047 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE, address,
4048 BT_ADDRESS_STRING_SIZE);
4050 BT_INFO("Local GATT Client DisConnected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status [%d]",
4051 address + 12, event_data->client_if, event_data->conn_id, event_data->status);
4053 /* Remove Connection info */
4054 conn_info = _bt_find_remote_gatt_server_info(address);
4057 param = g_variant_new("(is)", result, address);
4058 /* Send event to application */
4059 _bt_send_event(BT_DEVICE_EVENT,
4060 BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED,
4063 BT_INFO("Remove GATT server info from List..");
4064 /* Remove all services from info list_gatt_info */
4065 __bt_cleanup_remote_services(conn_info);
4067 /* Remove info from List */
4068 gatt_server_info_list = g_slist_remove(gatt_server_info_list, conn_info);
4070 /* Remove all pending invocations from invocatin_list */
4071 BT_INFO("Clear all pending invocations");
4072 __bt_gatt_cleanup_invocation_on_gatt_disconnection(BLUETOOTH_ERROR_INTERNAL,
4073 address, BT_ADDRESS_STRING_SIZE);
4075 BT_INFO("Total num of connected GATT servers [%d]", g_slist_length(gatt_server_info_list));
4076 g_free(conn_info->addr);
4079 BT_INFO("Can not find conn info, already removed!");
4081 #ifndef __INTEGRATE_GATT_INFO__
4082 /* Remove client info */
4083 client_info = _bt_find_remote_gatt_client_info(address);
4085 BT_DBG("Remove GATT client info from list");
4086 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
4087 g_free(client_info->addr);
4088 g_free(client_info);
4092 __bt_remove_mtu_gatt_device(address);
4094 /* If outgoing connection Info is present, then remove it */
4095 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
4096 if (out_conn_info) {
4097 BT_ERR("Client Disconnected event, but outgoing connect request was sent");
4098 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
4099 g_free(out_conn_info->addr);
4100 g_free(out_conn_info);
4106 static void __bt_handle_client_service_search_result(
4107 event_gattc_service_result_t *event_data)
4109 /* Pre: status is never fail from OAL */
4111 /* Find service list from address */
4112 bt_gatt_service_info_list_t *svc_info_list;
4113 bt_gatt_service_info_t *svc_info;
4115 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4116 if (!svc_info_list) {
4117 BT_DBG("Service info list not present for connection ID %d, means first time browse", event_data->conn_status.conn_id);
4118 /* Means for this conn_id, no services are ever browsed, first time,
4119 create service info list for this conn_id */
4120 svc_info_list = g_malloc0(sizeof(bt_gatt_service_info_list_t));
4121 svc_info_list->conn_id = event_data->conn_status.conn_id;
4122 list_gatt_info = g_slist_append(list_gatt_info, svc_info_list);
4125 /* send list and current service's uuid and instance id to find it */
4126 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4127 /* If not found, check if service changed, if yes, means this is a new service added
4128 in remote GATT device, update uuid info in svc info list structure, to be used when
4129 search is completed */
4131 if (svc_info_list->info.is_changed) {
4132 BT_DBG("Service Changed indication already found for connection ID %d", event_data->conn_status.conn_id);
4133 memcpy(svc_info_list->info.uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4135 /* Create and add new service in service list */
4136 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4137 memcpy(svc_info->uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4138 svc_info->inst_id = event_data->srvc_id.id.inst_id;
4139 svc_info->is_primary = event_data->srvc_id.is_prmry;
4140 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4141 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_status.conn_id);
4143 /* If returned matching service info, then just update service_rmeoved value inside it to 0 */
4144 svc_info->is_removed = 0;
4148 static void __bt_handle_client_service_search_completed(
4149 event_gattc_conn_status_t *event_data)
4151 struct gatt_server_info_t *conn_info = NULL;
4152 bt_gatt_service_info_list_t *svc_info_list;
4153 bt_gatt_service_info_t *svc_info;
4154 bt_services_browse_info_t browse_info;
4155 unsigned char uuid_empty[BLUETOOTH_UUID_HEX_MAX_LEN];
4157 memset(&uuid_empty, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4158 memset(&browse_info, 0x00, sizeof(bt_services_browse_info_t));
4159 BT_INFO("Primary Services browsing completed status[%d] conn ID [%d]",
4160 event_data->status, event_data->conn_id);
4162 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4164 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4165 if (!svc_info_list) {
4166 BT_ERR("No services browsed ever for addr [%s]", conn_info->addr);
4168 /* Just build response and return ERROR */
4169 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4171 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4172 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4173 sizeof(bt_services_browse_info_t));
4177 /* If fail, then send event with error */
4178 if (event_data->status != OAL_STATUS_SUCCESS) {
4179 /* Just build response and return ERROR */
4180 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4182 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4183 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4184 sizeof(bt_services_browse_info_t));
4188 /* If success, then find service info list from address */
4190 /* If svc_changed == 1 and uuid valid, means a new service is added*/
4191 if (svc_info_list->info.is_changed && !memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4192 /* TODO: Send event -Service added with instance ID and UUID of newly added service */
4193 BT_INFO("new service added");
4195 BT_INFO("TODO new service added");
4198 /* If svc_changed == 1 and uuid invalid, then a service is removed */
4199 if (svc_info_list->info.is_changed && memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4200 /* Scan through the service info list to find service with is_removed = 1*/
4201 svc_info = __bt_find_removed_service(svc_info_list);
4203 /* TODO Send event - Service removed with instance ID and UUID of just rmeoved service */
4205 /* Remove that service info from service info list */
4206 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
4208 /* Delete that service completely from svc_info list*/
4209 __bt_remove_service_info_from_list(svc_info);
4213 /* Reset svc_changed = 0, and reset UUID = all 0's */
4214 svc_info_list->info.is_changed = 0;
4215 memset(&svc_info_list->info.uuid, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4217 /* Build Reply and send to service browse primary services request of pending apps */
4218 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4220 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4221 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4222 sizeof(bt_services_browse_info_t));
4226 static void __bt_handle_client_characteristic_search_result(
4227 event_gattc_characteristic_result_t *event_data)
4229 bt_gatt_service_info_list_t *svc_info_list;
4230 bt_gatt_service_info_t *svc_info;
4231 bt_gatt_char_info_t *char_info;
4232 bt_char_browse_info_t browse_info;
4234 memset(&browse_info, 0x00, sizeof(bt_char_browse_info_t));
4237 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4238 /* Find service info list from address */
4239 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4240 if (svc_info_list == NULL) {
4241 BT_ERR("svc_info_list is NULL");
4245 /* Find matching service info from svc info list */
4246 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4247 if (svc_info == NULL) {
4248 BT_ERR("svc_info is NULL");
4252 /* Find Matching char from service info in event */
4253 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4254 /* If not found, then add new characteristic and return */
4256 BT_DBG("Add new characteristic");
4257 char_info = g_malloc0(sizeof(bt_gatt_char_info_t));
4258 memcpy(char_info->uuid, event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4260 char_info->inst_id = event_data->char_id.inst_id;
4261 char_info->props = event_data->char_prop;
4262 svc_info->chars = g_slist_append(svc_info->chars, char_info);
4264 /* If found, then return */
4265 BT_DBG("update char property as Characteristic browsed is already present");
4266 char_info->props |= event_data->char_prop;
4269 /* If Not success: Means Charc browse is completed */
4270 /* Find char list from service in event */
4271 /* Find service list from address */
4272 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4273 if (svc_info_list == NULL) {
4274 BT_ERR("svc_info_list is NULL");
4278 /* Find service info from service in event */
4279 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4280 if (svc_info == NULL) {
4281 BT_ERR("svc_info is NULL");
4285 /* Build char list from service in event */
4286 __bt_build_char_browse_info(event_data->conn_status.conn_id,
4287 svc_info, &browse_info);
4289 /* Create response and return by sending event*/
4290 /* Build Reply and send to service browse All Included services request of pending apps */
4291 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4292 BT_GATT_GET_SERVICE_PROPERTIES,
4294 sizeof(bt_char_browse_info_t));
4298 static void __bt_handle_client_descriptor_search_result(
4299 event_gattc_descriptor_result_t *event_data)
4301 bt_gatt_service_info_list_t *svc_info_list;
4302 bt_gatt_service_info_t *svc_info;
4303 bt_gatt_char_info_t *char_info;
4304 bt_gatt_descriptor_info_t *desc_info;
4305 bt_descriptor_browse_info_t browse_info;
4307 BT_DBG("descriptor search result status [%d]", event_data->conn_status.status);
4309 memset(&browse_info, 0x00, sizeof(bt_descriptor_browse_info_t));
4312 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4313 /* Find service list from address */
4314 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4315 if (svc_info_list == NULL) {
4316 BT_ERR("svc_info_list is NULL");
4320 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4321 if (svc_info == NULL) {
4322 BT_ERR("svc_info is NULL");
4326 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4327 if (char_info == NULL) {
4328 BT_ERR("char_info is NULL");
4332 desc_info = __bt_find_matching_desc(char_info, &event_data->descr_id);
4333 /* If not found, add new descriptor and return */
4335 desc_info = g_malloc0(sizeof(bt_gatt_descriptor_info_t));
4336 memcpy(desc_info->uuid, event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4338 desc_info->inst_id = event_data->descr_id.inst_id;
4339 char_info->descs = g_slist_append(char_info->descs, desc_info);
4342 /* If found, then return */
4343 BT_DBG("Descriptor browsed is already presesnt");
4346 /* If Not success */
4347 /* Find service list from address */
4348 /* Find included service list from service in event */
4349 /* Create response and return by sending event*/
4350 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4351 if (svc_info_list == NULL) {
4352 BT_ERR("svc_info_list is NULL");
4356 /* Find service info from service in event */
4357 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4358 if (svc_info == NULL) {
4359 BT_ERR("svc_info is NULL");
4363 /* Find char info from char in event */
4364 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4365 if (char_info == NULL) {
4366 BT_ERR("char_info is NULL");
4370 /* Build descriptor list from char in event */
4371 __bt_build_descriptor_browse_info(event_data->conn_status.conn_id,
4372 svc_info, char_info, &browse_info);
4375 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4376 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
4378 sizeof(bt_descriptor_browse_info_t));
4382 static void __bt_handle_client_characteristic_read_data(
4383 event_gattc_read_data *event_data)
4385 int result = BLUETOOTH_ERROR_NONE;
4386 struct gatt_server_info_t *conn_info = NULL;
4387 bluetooth_gatt_client_char_prop_info_t read_info;
4389 /* Read Information data structures */
4390 GVariant *param = NULL;
4391 GVariant *data = NULL;
4392 GVariant *data_svc_uuid = NULL;
4393 GVariant *data_char_uuid = NULL;
4394 char *read_val = NULL;
4395 char *svc_uuid = NULL;
4396 char *char_uuid = NULL;
4399 //memset(&read_info, 0x00, sizeof(bt_gatt_handle_property_t));
4400 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4402 /* Extract Address from conn_id of event data */
4403 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4404 event_data->uuid_status.conn_status.conn_id);
4406 BT_INFO("Characteristic Read result from addr [%s] status [%d]",
4407 conn_info->addr, event_data->uuid_status.conn_status.status);
4409 /* Fill char in buffer */
4410 memcpy(&read_info.characteristic.uuid,
4411 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4412 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4414 /* Fill Service in buffer */
4415 memcpy(&read_info.svc.uuid,
4416 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4417 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4419 /* Fill remote device address */
4420 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4422 /* Fill data and reply to all apps waiting for Read result on the same characteristic
4423 Note: Even in case of failure, address, handles and result code should be returned */
4424 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4425 result = BLUETOOTH_ERROR_INTERNAL;
4427 if (event_data->data_len > 0) {
4429 // for (i = 0; i < event_data->data_len; i++)
4430 // BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4433 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4435 data = g_variant_new_from_data(
4436 G_VARIANT_TYPE_BYTESTRING,
4438 event_data->data_len,
4441 BT_ERR("Characteristic Read success, but no data!!!");
4443 data = g_variant_new_from_data(
4444 G_VARIANT_TYPE_BYTESTRING,
4451 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4453 data_svc_uuid = g_variant_new_from_data(
4454 G_VARIANT_TYPE_BYTESTRING,
4460 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4462 data_char_uuid = g_variant_new_from_data(
4463 G_VARIANT_TYPE_BYTESTRING,
4468 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4472 event_data->uuid_status.srvc_id.id.inst_id,
4475 event_data->uuid_status.char_id.inst_id,
4476 event_data->data_len,
4480 char *sender = NULL;
4481 __bt_gatt_get_pending_request_info(BT_GATT_READ_CHARACTERISTIC, &sender);
4482 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4483 BLUETOOTH_EVENT_GATT_READ_CHAR,
4486 /* Send DBUS return */
4487 __bt_gatt_handle_pending_request_info(result,
4488 BT_GATT_READ_CHARACTERISTIC,
4490 sizeof(bluetooth_gatt_client_char_prop_info_t));
4501 static void __bt_handle_client_descriptor_read_data(
4502 event_gattc_read_data *event_data)
4504 int result = BLUETOOTH_ERROR_NONE;
4505 struct gatt_server_info_t *conn_info = NULL;
4506 bluetooth_gatt_client_desc_prop_info_t read_info;
4508 /* Read Information data structures */
4509 GVariant *param = NULL;
4510 GVariant *data = NULL;
4511 GVariant *data_svc_uuid = NULL;
4512 GVariant *data_char_uuid = NULL;
4513 GVariant *data_desc_uuid = NULL;
4514 char *read_val = NULL;
4515 char *svc_uuid = NULL;
4516 char *char_uuid = NULL;
4517 char *desc_uuid = NULL;
4521 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4523 /* Extract Address from conn_id of event data */
4524 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4525 event_data->uuid_status.conn_status.conn_id);
4527 BT_DBG("Descriptor Read result from addr [%s] status [%d]",
4528 conn_info->addr, event_data->uuid_status.conn_status.status);
4530 /* Fill descriptor informations in buffer */
4531 memcpy(&read_info.descriptor.uuid,
4532 event_data->uuid_status.descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4533 read_info.descriptor.instance_id = event_data->uuid_status.descr_id.inst_id;
4535 /* Fill Characteristic informations in buffer */
4536 memcpy(&read_info.characteristic.uuid,
4537 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4538 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4540 /* Fill Service informations in buffer */
4541 memcpy(&read_info.svc.uuid,
4542 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4543 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4545 /* Fill remote device address */
4546 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4548 /* Fill data and reply to all apps waiting for Read result on the same characteristic */
4549 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4550 result = BLUETOOTH_ERROR_INTERNAL;
4552 if (event_data->data_len > 0) {
4554 for (i = 0; i < event_data->data_len; i++)
4555 BT_DBG("Data[%d] = [0x%x]", i, event_data->data[i]);
4558 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4560 data = g_variant_new_from_data(
4561 G_VARIANT_TYPE_BYTESTRING,
4563 event_data->data_len,
4566 BT_INFO("Descriptor Read success, but no data!!!");
4568 data = g_variant_new_from_data(
4569 G_VARIANT_TYPE_BYTESTRING,
4575 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4577 data_svc_uuid = g_variant_new_from_data(
4578 G_VARIANT_TYPE_BYTESTRING,
4584 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4586 data_char_uuid = g_variant_new_from_data(
4587 G_VARIANT_TYPE_BYTESTRING,
4593 desc_uuid = g_memdup2(&event_data->uuid_status.descr_id.uuid.uuid[0], uuid_len);
4595 data_desc_uuid = g_variant_new_from_data(
4596 G_VARIANT_TYPE_BYTESTRING,
4601 param = g_variant_new("(isn@ayin@ayin@ayin@ay)", result,
4605 event_data->uuid_status.srvc_id.id.inst_id,
4608 event_data->uuid_status.char_id.inst_id,
4611 event_data->uuid_status.descr_id.inst_id,
4612 event_data->data_len,
4616 char *sender = NULL;
4617 __bt_gatt_get_pending_request_info(BT_GATT_READ_DESCRIPTOR_VALUE, &sender);
4618 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4619 BLUETOOTH_EVENT_GATT_READ_DESC,
4623 /* Send DBUS return */
4624 __bt_gatt_handle_pending_request_info(result,
4625 BT_GATT_READ_DESCRIPTOR_VALUE,
4627 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4638 static void __bt_handle_client_characteristic_write_data(
4639 event_gattc_write_data *event_data)
4641 int result = BLUETOOTH_ERROR_NONE;
4642 struct gatt_server_info_t *conn_info = NULL;
4643 bluetooth_gatt_client_char_prop_info_t write_info;
4645 /* Read Information data structures */
4646 GVariant *param = NULL;
4647 GVariant *data_svc_uuid = NULL;
4648 GVariant *data_char_uuid = NULL;
4649 char *svc_uuid = NULL;
4650 char *char_uuid = NULL;
4653 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4655 /* Extract Address from conn_id of event data */
4656 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4657 event_data->conn_status.conn_id);
4659 BT_DBG("Characteristic Write callback from addr [%s] status [%d]",
4660 conn_info->addr, event_data->conn_status.status);
4662 /* Fill char in buffer */
4663 memcpy(&write_info.characteristic.uuid,
4664 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4665 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4667 /* Fill Service in buffer */
4668 memcpy(&write_info.svc.uuid,
4669 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4670 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4672 /* Fill remote device address */
4673 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4675 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4676 result = BLUETOOTH_ERROR_INTERNAL;
4682 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4684 data_svc_uuid = g_variant_new_from_data(
4685 G_VARIANT_TYPE_BYTESTRING,
4691 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4693 data_char_uuid = g_variant_new_from_data(
4694 G_VARIANT_TYPE_BYTESTRING,
4699 param = g_variant_new("(isn@ayin@ayi)", result,
4703 event_data->srvc_id.id.inst_id,
4706 event_data->char_id.inst_id);
4709 char *sender = NULL;
4710 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, &sender);
4711 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4712 BLUETOOTH_EVENT_GATT_WRITE_CHAR,
4722 /* Send DBUS return */
4723 __bt_gatt_handle_pending_request_info(result,
4724 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
4726 sizeof(bluetooth_gatt_client_char_prop_info_t));
4730 static void __bt_handle_client_descriptor_write_data(
4731 event_gattc_write_data *event_data)
4733 int result = BLUETOOTH_ERROR_NONE;
4734 struct gatt_server_info_t *conn_info = NULL;
4735 bluetooth_gatt_client_desc_prop_info_t write_info;
4737 /* Write Information data structures */
4738 GVariant *param = NULL;
4739 GVariant *data_svc_uuid = NULL;
4740 GVariant *data_char_uuid = NULL;
4741 GVariant *data_desc_uuid = NULL;
4742 char *svc_uuid = NULL;
4743 char *char_uuid = NULL;
4744 char *desc_uuid = NULL;
4747 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4749 /* Extract Address from conn_id of event data */
4750 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4751 event_data->conn_status.conn_id);
4753 if (NULL == conn_info) {
4754 BT_ERR("Failed to get the conn info for conn_id [%d]", event_data->conn_status.conn_id);
4758 BT_DBG("Descriptor Write callback from addr [%s] status [%d]",
4759 conn_info->addr, event_data->conn_status.status);
4761 /* Fill descriptor informations in buffer */
4762 memcpy(&write_info.descriptor.uuid,
4763 event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4764 write_info.descriptor.instance_id = event_data->descr_id.inst_id;
4766 /* Fill Characteristic informations in buffer */
4767 memcpy(&write_info.characteristic.uuid,
4768 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4769 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4771 /* Fill Service informations in buffer */
4772 memcpy(&write_info.svc.uuid,
4773 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4774 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4776 /* Fill remote device address */
4777 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4779 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4780 result = BLUETOOTH_ERROR_INTERNAL;
4786 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4788 data_svc_uuid = g_variant_new_from_data(
4789 G_VARIANT_TYPE_BYTESTRING,
4795 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4797 data_char_uuid = g_variant_new_from_data(
4798 G_VARIANT_TYPE_BYTESTRING,
4804 desc_uuid = g_memdup2(&event_data->descr_id.uuid.uuid[0], uuid_len);
4806 data_desc_uuid = g_variant_new_from_data(
4807 G_VARIANT_TYPE_BYTESTRING,
4812 param = g_variant_new("(isn@ayin@ayin@ayi)", result,
4816 event_data->srvc_id.id.inst_id,
4819 event_data->char_id.inst_id,
4822 event_data->descr_id.inst_id);
4825 char *sender = NULL;
4826 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_DESCRIPTOR_VALUE, &sender);
4827 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4828 BLUETOOTH_EVENT_GATT_WRITE_DESC,
4839 /* Send DBUS return */
4840 __bt_gatt_handle_pending_request_info(result,
4841 BT_GATT_WRITE_DESCRIPTOR_VALUE,
4843 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4846 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data)
4848 int result = BLUETOOTH_ERROR_INTERNAL;
4849 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4851 _bt_convert_addr_type_to_string(address, (unsigned char *)event_data->address.addr);
4853 /* DBUS Return with fail of pending BT_CONNECT_LE for all the apps */
4854 BT_INFO("Local GATT Client disconnected: Remote addr[%s] ", address + 12);
4856 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
4857 BT_ADDRESS_STRING_SIZE);
4861 static void __bt_handle_client_notification_registered(
4862 event_gattc_regdereg_notify_t *event_data,
4863 gboolean is_registered)
4865 int result = BLUETOOTH_ERROR_NONE;
4866 struct gatt_server_info_t *conn_info = NULL;
4867 bt_gatt_notif_reg_info_t notif_info;
4870 memset(¬if_info, 0x00, sizeof(bt_gatt_notif_reg_info_t));
4872 BT_INFO("Client Interface [%d] status [%d]",
4873 event_data->conn_id,
4874 event_data->status);
4876 /* Extract Address from conn_id of event data */
4877 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4879 BT_INFO("Connection Info is not present, return");
4882 BT_INFO("Notification Registered for addr [%s]", conn_info->addr);
4884 /* Fill svc informations in buffer */
4885 memcpy(¬if_info.svc_uuid,
4886 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4887 notif_info.svc_inst = event_data->srvc_id.id.inst_id;
4889 /* Fill char in buffer */
4890 memcpy(¬if_info.char_uuid,
4891 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4892 notif_info.char_inst = event_data->char_id.inst_id;
4894 /* Fill remote device address */
4895 _bt_convert_addr_string_to_type(notif_info.addr.addr, conn_info->addr);
4897 notif_info.is_registered = is_registered;
4899 if (event_data->status != OAL_STATUS_SUCCESS)
4900 result = BLUETOOTH_ERROR_INTERNAL;
4902 /* Send DBUS Return for BT_GATT_WATCH_CHARACTERISTIC */
4903 __bt_gatt_handle_pending_request_info(result,
4904 BT_GATT_WATCH_CHARACTERISTIC,
4906 sizeof(bt_gatt_notif_reg_info_t));
4909 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
4911 /* No status in this event from OAL */
4912 int result = BLUETOOTH_ERROR_NONE;
4914 /* Read Information data structures */
4915 GVariant *param = NULL;
4916 GVariant *data = NULL;
4917 GVariant *data_svc_uuid = NULL;
4918 GVariant *data_char_uuid = NULL;
4919 char *read_val = NULL;
4920 char *svc_uuid = NULL;
4921 char *char_uuid = NULL;
4927 BT_INFO("Notifcation of charc data changed");
4929 if (event_data->data_len > 0) {
4931 for (i = 0; i < event_data->data_len; i++)
4932 BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4935 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4936 _bt_convert_addr_type_to_string(addr,
4937 (unsigned char *)&(event_data->address.addr));
4940 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4942 data = g_variant_new_from_data(
4943 G_VARIANT_TYPE_BYTESTRING,
4945 event_data->data_len,
4948 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4950 data_svc_uuid = g_variant_new_from_data(
4951 G_VARIANT_TYPE_BYTESTRING,
4957 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4959 data_char_uuid = g_variant_new_from_data(
4960 G_VARIANT_TYPE_BYTESTRING,
4966 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4970 event_data->srvc_id.id.inst_id,
4973 event_data->char_id.inst_id,
4974 event_data->data_len,
4978 _bt_send_event(BT_GATT_CLIENT_EVENT,
4979 BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
4982 BT_ERR("No Data!!");
4995 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data)
4997 bt_gatt_service_info_list_t *svc_info_list;
4999 bt_gatt_service_info_t *svc_info;
5000 GVariant *param = NULL;
5001 char *address_str = NULL;
5002 char *uuid_str = NULL;
5004 #ifndef TIZEN_BLUEDROID_PORTING
5005 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
5006 if (svc_info_list == NULL) {
5007 BT_ERR("svc_info_list is NULL");
5011 if (event_data->change_type) {
5012 /* Add service UUID in list */
5013 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
5014 memcpy(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5015 svc_info->inst_id = event_data->inst_id;
5016 svc_info->is_primary = 1; // TODO: Need to check is_primary is required or not
5017 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
5018 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_id);
5020 /* Remove service UUID in list */
5021 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
5022 svc_info = (bt_gatt_service_info_t *)l->data;
5023 if (svc_info == NULL)
5026 if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
5027 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
5028 __bt_free_service_info(svc_info);
5035 address_str = g_malloc0(BT_ADDRESS_STRING_SIZE);
5036 uuid_str = g_malloc0(BT_UUID_STRING_MAX);
5037 _bt_convert_addr_type_to_string(address_str, event_data->address.addr);
5039 #ifndef TIZEN_BLUEDROID_PORTING
5040 _bt_uuid_to_string(&event_data->uuid, uuid_str);
5042 event_data->change_type = BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_RESYNC;
5045 param = g_variant_new("(iiss)", event_data->inst_id, event_data->change_type, address_str, uuid_str);
5047 _bt_send_event(BT_GATT_CLIENT_EVENT,
5048 BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED,
5050 g_free(address_str);
5054 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
5057 struct gatt_server_info_t *conn_info = NULL;
5058 gboolean connected = FALSE;
5060 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
5061 _bt_convert_addr_type_to_string(addr,
5062 (unsigned char *)&(address->addr));
5064 BT_DBG("Check GATT connection status of [%s]", addr);
5065 /* Check if device is already in connected list */
5066 conn_info = _bt_find_remote_gatt_server_info(addr);
5068 BT_DBG("Remote GATT Server device [%s] is Connected", conn_info->addr);
5071 struct gatt_client_info_t *client_info = NULL;
5073 BT_DBG("Remote GATT Server Device [%s] is not Connected", addr);
5075 /* Check if device is already in connected list */
5076 client_info = _bt_find_remote_gatt_client_info(addr);
5078 BT_DBG("Remote Client device [%s] is Connected", client_info->addr);
5081 BT_DBG("Remote GATT Client Device [%s] is not Connected", addr);
5089 void _bt_handle_invocation_context(int function_name, void *data)
5091 switch (function_name) {
5093 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_CONNECT_LE,
5094 (char *)data, BT_ADDRESS_STRING_SIZE);
5101 int _bt_connect_le_device(bluetooth_device_address_t *address,
5102 int auto_connect, int client_id)
5104 struct gatt_server_info_t *conn_info = NULL;
5105 struct gatt_out_conn_info_t *out_conn_info = NULL;
5107 invocation_info_t *req_info = NULL;
5108 int ret = OAL_STATUS_SUCCESS;
5110 char *remote_address = NULL;
5112 BT_CHECK_PARAMETER(address, return);
5114 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5115 _bt_convert_addr_type_to_string(addr, address->addr);
5116 BT_DBG("GATT Client connect request for address [%s] client instance [%d]",
5120 /* Check if Remote Device is already under connection progress */
5121 req_info = _bt_get_request_info_data_from_function_name(BT_CONNECT_LE);
5123 remote_address = (char*)req_info->user_data;
5124 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5125 BT_DBG("Already Connection ongoing for same remote GATT Server address [%s]", remote_address);
5126 /* Return and wait for events to be sent to all apps */
5128 return BLUETOOTH_ERROR_IN_PROGRESS;
5132 /* Check if remote GATT Server is connected or not */
5133 conn_info = _bt_find_remote_gatt_server_info(addr);
5135 BT_ERR("GATT Server is already connected..");
5137 return BLUETOOTH_ERROR_ALREADY_CONNECT;
5140 /* TODO Check Requirement of holding Advertisement before initiating LE connect */
5143 /* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
5144 if (client_id == 0) {
5145 /* GATT CLient connect request sent by an app without any client instance [0] */
5146 BT_DBG("Assign default GATT client id [%d]", gatt_default_client);
5147 client_id = gatt_default_client;
5150 BT_INFO("Connect using CLient ID [%d]", client_id);
5151 ret = gattc_connect(client_id, (bt_address_t*)(address), auto_connect);
5153 if (ret != OAL_STATUS_SUCCESS) {
5154 BT_ERR("gattc_connect is failed. ret: %d", ret);
5156 _bt_restart_le_scan();
5157 return _bt_convert_oal_status_to_bt_error(ret);
5160 /* Mark this as outgoing connection */
5161 out_conn_info = g_new0(struct gatt_out_conn_info_t, 1);
5162 out_conn_info->addr = g_strdup(addr);
5163 out_conn_info->client_id = client_id;
5164 BT_INFO("Added outgoing connection info addr[%s]", out_conn_info->addr + 12);
5165 outgoing_gatt_conn_list = g_slist_append(outgoing_gatt_conn_list, out_conn_info);
5168 return BLUETOOTH_ERROR_NONE;
5171 int _bt_gatt_get_primary_services(char *address)
5173 BT_CHECK_PARAMETER(address, return);
5174 struct gatt_server_info_t *conn_info = NULL;
5175 invocation_info_t *req_info = NULL;
5176 int ret = OAL_STATUS_SUCCESS;
5178 /* Check if any app is already browsing primary services on the same remote GATT Server */
5179 req_info = _bt_get_request_info_data(BT_GATT_GET_PRIMARY_SERVICES, address);
5181 BT_INFO("Already Primary Service Browsing ongoing for same rmeote GATT Server");
5182 /* Return and wait for events to be sent to all apps */
5183 return BLUETOOTH_ERROR_NONE;
5186 /* Check if remote GATT Server is connected or not */
5187 conn_info = _bt_find_remote_gatt_server_info(address);
5189 BT_ERR("GATT Server is not yet connected..");
5190 return BLUETOOTH_ERROR_NOT_CONNECTED;
5193 BT_INFO("Get all services. GATT Server [%s] is connected, conn Id [%d]",
5194 conn_info->addr + 12, conn_info->connection_id);
5196 /* Send Primary Service Browsing request to stack */
5197 ret = gattc_search_service(conn_info->connection_id, NULL);
5198 if (ret != OAL_STATUS_SUCCESS) {
5199 BT_ERR("ret: %d", ret);
5200 return _bt_convert_oal_status_to_bt_error(ret);
5202 return BLUETOOTH_ERROR_NONE;
5205 int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc)
5207 BT_CHECK_PARAMETER(svc, return);
5208 struct gatt_server_info_t *conn_info = NULL;
5209 invocation_info_t *req_info = NULL;
5210 bluetooth_gatt_client_svc_prop_info_t *prop;
5211 oal_gatt_srvc_id_t srvc_id;
5212 int ret = OAL_STATUS_SUCCESS;
5215 /* Check if any app is already browsing characteristics of the same service on the same remote GATT Server */
5216 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_SERVICE_PROPERTIES);
5218 prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
5219 if (prop && !memcmp(svc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t))
5220 && !memcmp(prop->svc.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
5221 && prop->svc.instance_id == svc->svc.instance_id) {
5222 BT_INFO("Already Properties browsing for Primary Service ongoing for same remote GATT Server");
5223 /* Return and wait for events to be sent to all apps */
5224 return BLUETOOTH_ERROR_NONE;
5228 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5229 _bt_convert_addr_type_to_string(addr, svc->device_address.addr);
5231 /* Check if remote GATT Server is connected or not */
5232 conn_info = _bt_find_remote_gatt_server_info(addr);
5234 BT_ERR("GATT Server is not yet connected..");
5236 return BLUETOOTH_ERROR_NOT_CONNECTED;
5239 BT_DBG("Get all charc. GATT Server [%s] is connected, conn Id [%d]",
5240 conn_info->addr, conn_info->connection_id);
5242 srvc_id.is_prmry = TRUE;
5243 srvc_id.id.inst_id = svc->svc.instance_id;
5244 memcpy(srvc_id.id.uuid.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5246 /* Search All Characteristic */
5247 ret = gattc_get_characteristic(conn_info->connection_id, &srvc_id, NULL);
5248 if (ret != OAL_STATUS_SUCCESS) {
5249 BT_ERR("ret: %d", ret);
5251 return _bt_convert_oal_status_to_bt_error(ret);
5254 return BLUETOOTH_ERROR_NONE;
5257 int _bt_gatt_get_all_characteristic_properties(
5258 bluetooth_gatt_client_char_prop_info_t *chr)
5260 struct gatt_server_info_t *conn_info = NULL;
5261 invocation_info_t *req_info = NULL;
5262 bluetooth_gatt_client_char_prop_info_t *prop;
5263 oal_gatt_srvc_id_t srvc_id;
5264 oal_gatt_id_t char_id;
5265 int ret = OAL_STATUS_SUCCESS;
5268 BT_CHECK_PARAMETER(chr, return);
5270 /* Check if any app is already browsing descriptors of the same char of
5271 particular service on the same remote GATT Server */
5272 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_CHARACTERISTIC_PROPERTIES);
5274 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5275 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5276 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5277 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5278 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5279 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5280 BT_INFO("Already Properties browsing for Characteristic ongoing for same remote GATT Server");
5281 /* Return and wait for events to be sent to all apps */
5282 return BLUETOOTH_ERROR_NONE;
5286 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5287 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5289 /* Check if remote GATT Server is connected or not */
5290 conn_info = _bt_find_remote_gatt_server_info(addr);
5292 BT_ERR("GATT Server is not yet connected..");
5294 return BLUETOOTH_ERROR_NOT_CONNECTED;
5297 BT_DBG("Get all desc. GATT Server [%s] is connected, conn Id [%d]",
5298 conn_info->addr, conn_info->connection_id);
5300 srvc_id.is_prmry = TRUE;
5301 srvc_id.id.inst_id = chr->svc.instance_id;
5302 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5304 char_id.inst_id = chr->characteristic.instance_id;
5305 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5307 /* Search All Descriptors */
5308 ret = gattc_get_descriptor(conn_info->connection_id, &srvc_id, &char_id, NULL);
5309 if (ret != OAL_STATUS_SUCCESS) {
5310 BT_ERR("ret: %d", ret);
5312 return _bt_convert_oal_status_to_bt_error(ret);
5315 return BLUETOOTH_ERROR_NONE;
5318 int _bt_gatt_read_characteristic_value(
5319 bluetooth_gatt_client_char_prop_info_t *chr)
5321 struct gatt_server_info_t *conn_info = NULL;
5322 invocation_info_t *req_info = NULL;
5323 bluetooth_gatt_client_char_prop_info_t *prop;
5324 oal_gatt_srvc_id_t srvc_id;
5325 oal_gatt_id_t char_id;
5326 int ret = OAL_STATUS_SUCCESS;
5329 BT_CHECK_PARAMETER(chr, return);
5331 /* Check if any app is already Reading characteristic of the same char of
5332 particular service on the same remote GATT Server */
5333 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_CHARACTERISTIC);
5335 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5336 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5337 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5338 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5339 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5340 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5341 BT_INFO("Already Characteristic value Read operation in progress for same remote GATT Server");
5342 /* Return and wait for events to be sent to all apps */
5343 return BLUETOOTH_ERROR_NONE;
5347 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5348 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5350 /* Check if remote GATT Server is connected or not */
5351 conn_info = _bt_find_remote_gatt_server_info(addr);
5353 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5354 conn_info->addr, conn_info->connection_id);
5356 BT_ERR("GATT Server is not yet connected..");
5358 return BLUETOOTH_ERROR_NOT_CONNECTED;
5361 srvc_id.is_prmry = TRUE;
5362 srvc_id.id.inst_id = chr->svc.instance_id;
5363 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5365 char_id.inst_id = chr->characteristic.instance_id;
5366 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5368 /* Search All Descriptors */
5369 ret = gattc_read_characteristic(conn_info->connection_id, &srvc_id, &char_id, OAL_GATT_AUTH_REQ_NONE);
5370 if (ret != OAL_STATUS_SUCCESS) {
5371 BT_ERR("ret: %d", ret);
5373 return _bt_convert_oal_status_to_bt_error(ret);
5376 return BLUETOOTH_ERROR_NONE;
5379 int _bt_gatt_read_descriptor_value(
5380 bluetooth_gatt_client_desc_prop_info_t *desc)
5382 struct gatt_server_info_t *conn_info = NULL;
5383 invocation_info_t *req_info = NULL;
5384 bluetooth_gatt_client_desc_prop_info_t *prop;
5385 oal_gatt_srvc_id_t srvc_id;
5386 oal_gatt_id_t char_id;
5387 oal_gatt_id_t desc_id;
5388 int ret = OAL_STATUS_SUCCESS;
5391 BT_CHECK_PARAMETER(desc, return);
5393 /* Check if any app is already Reading descriptors of the same char of
5394 particular service on the same remote GATT Server */
5395 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_DESCRIPTOR_VALUE);
5397 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5398 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5399 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5400 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5401 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5402 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5403 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5404 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5405 BT_INFO("Already Descriptor value Read operation in progress for same remote GATT Server");
5406 /* Return and wait for events to be sent to all apps */
5407 return BLUETOOTH_ERROR_NONE;
5411 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5412 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5414 /* Check if remote GATT Server is connected or not */
5415 conn_info = _bt_find_remote_gatt_server_info(addr);
5417 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5418 conn_info->addr, conn_info->connection_id);
5420 BT_ERR("GATT Server is not yet connected..");
5422 return BLUETOOTH_ERROR_NOT_CONNECTED;
5425 srvc_id.is_prmry = TRUE;
5426 srvc_id.id.inst_id = desc->svc.instance_id;
5427 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5429 char_id.inst_id = desc->characteristic.instance_id;
5430 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5432 desc_id.inst_id = desc->descriptor.instance_id;
5433 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5435 /* Search All Descriptors */
5436 ret = gattc_read_descriptor(conn_info->connection_id, &srvc_id, &char_id,
5437 &desc_id, OAL_GATT_AUTH_REQ_NONE);
5438 if (ret != OAL_STATUS_SUCCESS) {
5439 BT_ERR("ret: %d", ret);
5441 return _bt_convert_oal_status_to_bt_error(ret);
5444 return BLUETOOTH_ERROR_NONE;
5448 int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5450 struct gatt_server_info_t *conn_info = NULL;
5451 oal_gatt_srvc_id_t srvc_id;
5452 oal_gatt_id_t char_id;
5453 int ret = OAL_STATUS_SUCCESS;
5456 BT_CHECK_PARAMETER(chr, return);
5458 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5459 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5461 /* Check if remote GATT Server is connected or not */
5462 conn_info = _bt_find_remote_gatt_server_info(addr);
5464 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5465 conn_info->addr, conn_info->connection_id);
5467 BT_ERR("GATT Server is not yet connected..");
5469 return BLUETOOTH_ERROR_NOT_CONNECTED;
5472 srvc_id.is_prmry = TRUE;
5473 srvc_id.id.inst_id = chr->svc.instance_id;
5474 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5476 char_id.inst_id = chr->characteristic.instance_id;
5477 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5479 ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
5481 if (ret != OAL_STATUS_SUCCESS) {
5482 BT_ERR("ret: %d", ret);
5484 return _bt_convert_oal_status_to_bt_error(ret);
5486 BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
5488 return BLUETOOTH_ERROR_NONE;
5492 int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5495 struct gatt_server_info_t *conn_info = NULL;
5496 oal_gatt_srvc_id_t srvc_id;
5497 oal_gatt_id_t char_id;
5498 int ret = OAL_STATUS_SUCCESS;
5501 BT_CHECK_PARAMETER(chr, return);
5503 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5504 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5506 /* Check if remote GATT Server is connected or not */
5507 conn_info = _bt_find_remote_gatt_server_info(addr);
5509 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5510 conn_info->addr, conn_info->connection_id);
5512 BT_ERR("GATT Server is not yet connected..");
5514 return BLUETOOTH_ERROR_NOT_CONNECTED;
5517 srvc_id.is_prmry = TRUE;
5518 srvc_id.id.inst_id = chr->svc.instance_id;
5519 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5521 char_id.inst_id = chr->characteristic.instance_id;
5522 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5524 ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
5525 OAL_GATT_AUTH_REQ_NONE, fd, mtu);
5526 if (ret != OAL_STATUS_SUCCESS) {
5527 BT_ERR("ret: %d", ret);
5529 return _bt_convert_oal_status_to_bt_error(ret);
5531 BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
5533 return BLUETOOTH_ERROR_NONE;
5538 /* Write Characteristic */
5539 int _bt_gatt_write_characteristic_value_by_type(
5540 bluetooth_gatt_client_char_prop_info_t *chr,
5541 bluetooth_gatt_att_data_t *data,
5542 bluetooth_gatt_write_type_e write_type)
5544 struct gatt_server_info_t *conn_info = NULL;
5545 invocation_info_t *req_info = NULL;
5546 bluetooth_gatt_client_char_prop_info_t *prop;
5547 oal_gatt_srvc_id_t srvc_id;
5548 oal_gatt_id_t char_id;
5549 int ret = OAL_STATUS_SUCCESS;
5552 BT_CHECK_PARAMETER(chr, return);
5553 BT_CHECK_PARAMETER(data, return);
5555 /* Check if any app is already writing same char of
5556 particular service on the same remote GATT Server */
5557 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE);
5559 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5560 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5561 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5562 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5563 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5564 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5565 BT_INFO("Already Characteristic Write Value operation in progress for same remote GATT Server");
5566 /* Return and wait for events to be sent to all apps */
5567 return BLUETOOTH_ERROR_NONE;
5571 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5572 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5574 /* Check if remote GATT Server is connected or not */
5575 conn_info = _bt_find_remote_gatt_server_info(addr);
5577 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5578 conn_info->addr, conn_info->connection_id);
5580 BT_ERR("GATT Server is not yet connected..");
5582 return BLUETOOTH_ERROR_NOT_CONNECTED;
5585 srvc_id.is_prmry = TRUE;
5586 srvc_id.id.inst_id = chr->svc.instance_id;
5587 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5589 char_id.inst_id = chr->characteristic.instance_id;
5590 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5592 /* Write CHar value */
5593 ret = gattc_write_characteristic(conn_info->connection_id,
5595 (oal_gatt_write_type_t)write_type, data->length,
5596 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5597 if (ret != OAL_STATUS_SUCCESS) {
5598 BT_ERR("ret: %d", ret);
5600 return _bt_convert_oal_status_to_bt_error(ret);
5603 return BLUETOOTH_ERROR_NONE;
5606 /* Write Descriptor */
5607 int _bt_gatt_write_descriptor_value_by_type(
5608 bluetooth_gatt_client_desc_prop_info_t *desc,
5609 bluetooth_gatt_att_data_t *data,
5610 bluetooth_gatt_write_type_e write_type)
5612 struct gatt_server_info_t *conn_info = NULL;
5613 invocation_info_t *req_info = NULL;
5614 bluetooth_gatt_client_desc_prop_info_t *prop;
5615 oal_gatt_srvc_id_t srvc_id;
5616 oal_gatt_id_t char_id;
5617 oal_gatt_id_t desc_id;
5618 int ret = OAL_STATUS_SUCCESS;
5622 BT_CHECK_PARAMETER(desc, return);
5623 BT_CHECK_PARAMETER(data, return);
5627 /* Check if any app is already writing on same Descriptor of the same char of
5628 particular service on the same remote GATT Server */
5629 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_DESCRIPTOR_VALUE);
5631 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5632 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5633 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5634 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5635 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5636 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5637 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5638 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5639 BT_INFO("Already Descriptor value Write operation in progress for same remote GATT Server");
5640 /* Return and wait for events to be sent to all apps */
5641 return BLUETOOTH_ERROR_NONE;
5645 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5646 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5648 /* Check if remote GATT Server is connected or not */
5649 conn_info = _bt_find_remote_gatt_server_info(addr);
5651 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5652 conn_info->addr, conn_info->connection_id);
5654 BT_ERR("GATT Server is not yet connected..");
5656 return BLUETOOTH_ERROR_NOT_CONNECTED;
5659 srvc_id.is_prmry = TRUE;
5660 srvc_id.id.inst_id = desc->svc.instance_id;
5661 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5663 char_id.inst_id = desc->characteristic.instance_id;
5664 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5666 desc_id.inst_id = desc->descriptor.instance_id;
5667 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5670 BT_INFO("Connection ID [%d] write type [%d] data length [%d]", conn_info->connection_id, write_type, data->length);
5671 for (k = 0; k < data->length; k++)
5672 BT_INFO("Data[%d] [0x%x]", k, data->data[k]);
5674 ret = gattc_write_descriptor(conn_info->connection_id,
5675 &srvc_id, &char_id, &desc_id,
5676 (oal_gatt_write_type_t)write_type, data->length,
5677 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5678 if (ret != OAL_STATUS_SUCCESS) {
5679 BT_ERR("ret: %d", ret);
5681 return _bt_convert_oal_status_to_bt_error(ret);
5684 return BLUETOOTH_ERROR_NONE;
5687 int _bt_gatt_watch_characteristic(
5688 bluetooth_gatt_client_char_prop_info_t *chr,
5692 struct gatt_server_info_t *conn_info = NULL;
5693 oal_gatt_srvc_id_t srvc_id;
5694 oal_gatt_id_t char_id;
5695 int ret = OAL_STATUS_SUCCESS;
5698 BT_CHECK_PARAMETER(chr, return);
5700 BT_INFO("Client ID [%d] Is Notify [%d]", client_id, is_notify);
5702 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5703 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5705 /* Check if remote GATT Server is connected or not */
5706 conn_info = _bt_find_remote_gatt_server_info(addr);
5708 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5709 conn_info->addr, conn_info->connection_id);
5711 BT_ERR("GATT Server is not yet connected..");
5713 return BLUETOOTH_ERROR_NOT_CONNECTED;
5715 srvc_id.is_prmry = TRUE;
5716 srvc_id.id.inst_id = chr->svc.instance_id;
5717 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5719 char_id.inst_id = chr->characteristic.instance_id;
5720 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5722 /* Register or unregister Notification characteristic */
5724 ret = gattc_register_for_notification(conn_info->connection_id,
5725 (bt_address_t*)&(chr->device_address),
5726 &srvc_id, &char_id);
5728 ret = gattc_deregister_for_notification(conn_info->connection_id,
5729 (bt_address_t*)&(chr->device_address),
5730 &srvc_id, &char_id);
5732 BT_INFO("Result[%d]", ret);
5733 if (ret != OAL_STATUS_SUCCESS) {
5734 BT_ERR("ret: %d", ret);
5736 return _bt_convert_oal_status_to_bt_error(ret);
5739 return BLUETOOTH_ERROR_NONE;
5743 int _bt_disconnect_le_device(bluetooth_device_address_t *address,
5746 struct gatt_server_info_t *conn_info = NULL;
5747 struct gatt_client_info_t *rem_client_conn_info = NULL;
5748 invocation_info_t *req_info = NULL;
5749 int ret = OAL_STATUS_SUCCESS;
5751 char *remote_address = NULL;
5753 BT_CHECK_PARAMETER(address, return);
5755 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5756 _bt_convert_addr_type_to_string(addr, address->addr);
5757 BT_INFO("GATT Client Disconnect request for address [%s]", addr + 12);
5759 /* Check if Remote Device is already under connection progress */
5760 req_info = _bt_get_request_info_data_from_function_name(BT_DISCONNECT_LE);
5762 remote_address = (char*)req_info->user_data;
5763 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5764 BT_DBG("Already DisConnection ongoing for same remote GATT Server address [%s]", remote_address);
5765 /* Return success and wait for events to be sent to all apps */
5767 return BLUETOOTH_ERROR_IN_PROGRESS;
5770 /* Check if remote GATT Server is connected or not */
5771 conn_info = _bt_find_remote_gatt_server_info(addr);
5773 /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
5774 if (client_id == 0) {
5775 BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
5777 BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
5778 client_id = gatt_default_client;
5781 BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
5782 ret = gattc_disconnect(client_id, (bt_address_t*)(address),
5783 conn_info->connection_id);
5785 /* check if remote client is connected */
5786 rem_client_conn_info = _bt_find_remote_gatt_client_info(addr);
5788 if (!rem_client_conn_info || client_id != 0) {
5789 BT_ERR("GATT device is not connected..");
5791 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
5794 BT_INFO("Disconnect remote gatt client ");
5796 ret = gatts_disconnect(rem_client_conn_info->instance_id,
5797 (bt_address_t*)(address), rem_client_conn_info->connection_id);
5800 if (ret != OAL_STATUS_SUCCESS) {
5801 BT_ERR("ret: %d", ret);
5803 return _bt_convert_oal_status_to_bt_error(ret);
5806 return BLUETOOTH_ERROR_NONE;
5809 int _bt_gatt_watch_service_changed_indication(const char *sender,
5810 bluetooth_device_address_t *address,
5811 gboolean is_enabled)
5814 bt_service_app_info_t *info = NULL;
5816 BT_INFO("%s Servic changed Indication watcher for app [%s]",
5817 is_enabled ? "Enable":"Disable", sender);
5819 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5822 if (g_strcmp0(sender, info->sender) == 0 &&
5823 memcmp(info->address.addr, address->addr,
5824 sizeof(bluetooth_device_address_t)) == 0) {
5825 BT_DBG("Found GATT client App.. [%s], sender [%s]", info->uuid, info->sender);
5826 info->is_watcher_enabled = is_enabled;
5830 return BLUETOOTH_ERROR_NONE;
5833 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
5835 bt_service_app_info_t *info = NULL;
5838 BT_DBG("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
5840 /* Unregister CLient instance associated with address X. It is possible that another app still
5841 has client_id valid for same remote address */
5842 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5845 /* Exact matching of sender */
5846 if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) { /* Check for only valid GATT client Instance */
5847 numapps[k].client_id = -1;
5848 numapps[k].is_initialized = FALSE;
5849 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
5850 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
5851 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
5853 /* Its a GATT Client Instance */
5854 ret = gattc_deregister(client_id);
5855 if (ret != OAL_STATUS_SUCCESS) {
5856 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
5857 return _bt_convert_oal_status_to_bt_error(ret);
5859 return BLUETOOTH_ERROR_NONE;
5864 return BLUETOOTH_ERROR_NOT_FOUND;
5867 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data)
5869 int result = BLUETOOTH_ERROR_NONE;
5870 struct gatt_server_info_t *conn_info = NULL;
5871 GVariant *param = NULL;
5875 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
5876 if (conn_info == NULL) {
5877 BT_ERR("Cant find connection Information");
5881 BT_DBG("GATT Client: MTU Configured from addr [%s] status [%d] MTU size [%d]",
5882 conn_info->addr, event_data->status, event_data->mtu);
5884 if (event_data->status != OAL_STATUS_SUCCESS)
5885 result = BLUETOOTH_ERROR_INTERNAL;
5887 /* DBUS Return fo BT_REQ_ATT_MTU for all the apps */
5888 __bt_gatt_handle_pending_request_info(result, BT_REQ_ATT_MTU, conn_info->addr,
5889 BT_ADDRESS_STRING_SIZE);
5891 if (result == BLUETOOTH_ERROR_NONE) {
5892 mtu = event_data->mtu;
5893 param = g_variant_new("(isqy)",
5899 /* Send event to BT-API */
5900 _bt_send_event(BT_DEVICE_EVENT,
5901 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
5904 /* Update the MTU for current connection */
5905 __bt_update_mtu_gatt_device(conn_info->addr, event_data->mtu);
5909 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address)
5912 struct gatt_mtu_info_t *info = NULL;
5914 for (l = gatt_mtu_info_list; l != NULL; l = g_slist_next(l)) {
5915 info = (struct gatt_mtu_info_t*)l->data;
5919 if (!g_strcmp0(info->addr, address)) {
5920 BT_DBG("Remote GATT device found addr[%s]", info->addr);
5925 BT_DBG("Not found Remote GATT device addr[%s]", address);
5929 static void __bt_remove_mtu_gatt_device(char *address)
5931 struct gatt_mtu_info_t *dev_info = NULL;
5933 dev_info = __bt_find_mtu_gatt_device(address);
5936 BT_DBG("removing the gatt device from mtu list");
5937 gatt_mtu_info_list = g_slist_remove(gatt_mtu_info_list, dev_info);
5938 g_free(dev_info->addr);
5943 static void __bt_add_mtu_gatt_device(char *address)
5945 struct gatt_mtu_info_t *dev_info = NULL;
5947 dev_info = __bt_find_mtu_gatt_device(address);
5950 BT_DBG("adding the gatt device in mtu list");
5951 dev_info = g_new0(struct gatt_mtu_info_t, 1);
5952 dev_info->addr = g_strdup(address);
5953 dev_info->att_mtu = BT_DEFAULT_ATT_MTU;
5954 gatt_mtu_info_list = g_slist_append(gatt_mtu_info_list, dev_info);
5958 static void __bt_update_mtu_gatt_device(char *address, int mtu)
5960 struct gatt_mtu_info_t *dev_info = NULL;
5962 dev_info = __bt_find_mtu_gatt_device(address);
5965 dev_info->att_mtu = mtu;
5969 int _bt_gatt_get_data_batching_available_packets(
5970 guint *available_packets)
5972 int ret = OAL_STATUS_SUCCESS;
5974 BT_CHECK_PARAMETER(available_packets, return);
5976 ret = gatt_get_data_batching_available_packets(available_packets);
5977 if (ret != OAL_STATUS_SUCCESS) {
5978 BT_ERR("ret: %d", ret);
5979 return _bt_convert_oal_status_to_bt_error(ret);
5982 return BLUETOOTH_ERROR_NONE;
5985 int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address,
5986 int packet_threshold, int timeout)
5988 int ret = OAL_STATUS_SUCCESS;
5989 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5991 BT_CHECK_PARAMETER(address, return);
5993 _bt_convert_addr_type_to_string(remote_address, address->addr);
5994 BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]",
5995 remote_address, packet_threshold, timeout);
5997 ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout);
5999 if (ret != OAL_STATUS_SUCCESS) {
6000 BT_ERR("ret: %d", ret);
6001 return _bt_convert_oal_status_to_bt_error(ret);
6004 return BLUETOOTH_ERROR_NONE;
6007 int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address)
6009 int ret = OAL_STATUS_SUCCESS;
6010 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
6012 BT_CHECK_PARAMETER(address, return);
6014 _bt_convert_addr_type_to_string(remote_address, address->addr);
6015 BT_INFO("Disable GATT data batching. address[%s]", remote_address);
6017 ret = gatt_disable_data_batching((bt_address_t*)(address));
6019 if (ret != OAL_STATUS_SUCCESS) {
6020 BT_ERR("ret: %d", ret);
6021 return _bt_convert_oal_status_to_bt_error(ret);
6024 return BLUETOOTH_ERROR_NONE;