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 /* Linked List of connected Remote GATT Servers */
129 static GSList *gatt_server_info_list = NULL;
133 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN]; /* If any service added */
134 } bt_gatt_svc_changed_info_t;
139 // bluetooth_device_address_t address; /* Remote BLE Device Address */
140 GSList *services; /* List of all services of above remote device */
141 int count; /* Number of services browsed from remote device */
142 bt_gatt_svc_changed_info_t info;
143 } bt_gatt_service_info_list_t;
146 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
150 GSList *included_svcs;
151 gboolean is_removed; /* 0 => Service is added, 1=> removed */
152 } bt_gatt_service_info_t;
155 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
159 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
161 } bt_gatt_char_info_t;
164 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
167 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
168 } bt_gatt_descriptor_info_t;
171 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
173 } bt_gatt_included_service_info_t;
175 static GSList *list_gatt_info = NULL;
180 } bt_service_handle_uuid_info_t;
182 /* App Information structure */
185 char sender[BT_SENDER_MAX_LENGTH];
186 char uuid[BT_UUID_STRING_MAX];
189 bluetooth_advertising_data_t adv_data; /* Will store adv data for specific slot */
191 bluetooth_scan_resp_data_t scan_rsp; /* Will store scan rsp data for specific slot */
193 gboolean is_initialized;
194 GSList *service_handles;
195 GSList *service_handle_uuids; /* List of bt_service_handle_uuid_info_t */
196 int client_id; /* GATT Client instance ID */
197 bluetooth_device_address_t address; /* Remote BLE Device Address */
198 gboolean is_watcher_enabled;
199 } bt_service_app_info_t;
201 /* GATT Server Request Info Structure */
202 struct gatt_server_req_info {
203 int connection_id; /* This value will uniquely identify a GATT client-server connection */
204 int request_id; /* This is an unique transaction ID assigned against each request by stack */
205 int attribute_handle; /* GATT server attribute handle */
206 int offset; /* GATT server attribute offset on which request is invoked by GATT client */
207 bluetooth_gatt_att_request_type_e request_type; /* Read or Write request */
208 char *addr; /* Remote GATT client address */
211 /* GATT Client Info List Structure */
212 struct gatt_client_info_t {
213 int connection_id; /* This value will uniquely identify a GATT client-server connection */
214 int instance_id; /* This value unique identifies a GATT server instance */
215 char *addr; /* Remote GATT client address */
218 /* GATT Indicate confirm result */
219 struct gatt_indicate_cfm_result_info_t {
220 int result; /* Result of event */
221 char *addr; /* Remote GATT client address */
222 int att_hdl; /* Characteristic Attribute handle */
223 int completed; /* 1 if last event, otheriwse 0 */
226 static char service_persistence[BT_UUID_STRING_SIZE + 1];
228 /* Request Search Utility method */
229 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
230 bluetooth_gatt_att_request_type_e req_type);
232 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
233 bluetooth_gatt_server_indication_params_t *param);
235 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info);
237 static void __bt_free_service_info(bt_gatt_service_info_t *service_info);
239 static int __bt_unregister_gatt_client_instance(int client_if);
241 static void __bt_service_reset_gatt_data(void);
243 static void __bt_handle_client_instance_registered(event_gattc_register_t *data);
244 static void __bt_handle_client_connected(event_gattc_conn_t *event_data);
245 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data);
246 static void __bt_handle_client_service_search_completed(event_gattc_conn_status_t *event_data);
247 static void __bt_handle_client_service_search_result(event_gattc_service_result_t *event_data);
248 static void __bt_handle_client_characteristic_search_result(
249 event_gattc_characteristic_result_t *event_data);
250 static void __bt_handle_client_descriptor_search_result(event_gattc_descriptor_result_t *event_data);
251 static void __bt_handle_client_characteristic_read_data(event_gattc_read_data *event_data);
252 static void __bt_handle_client_descriptor_read_data(event_gattc_read_data *event_data);
253 static void __bt_handle_client_characteristic_write_data(event_gattc_write_data *event_data);
254 static void __bt_handle_client_descriptor_write_data(event_gattc_write_data *event_data);
255 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data);
256 static void __bt_handle_client_notification_registered(event_gattc_regdereg_notify_t *event_data,
257 gboolean is_registered);
258 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data);
259 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data);
260 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data);
262 static int __bt_unregister_gatt_server_instance(int server_instance);
263 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info);
264 #ifdef TIZEN_BLUEDROID_PORTING
265 static void __bt_remove_all_prep_write_req(int conn_id);
269 struct gatt_mtu_info_t {
270 char *addr; /* Remote GATT Server address */
274 static GSList *gatt_mtu_info_list = NULL;
276 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address);
277 static void __bt_remove_mtu_gatt_device(char *address);
278 static void __bt_add_mtu_gatt_device(char *address);
279 static void __bt_update_mtu_gatt_device(char *address, int mtu);
281 /* Linked List of GATT requests from Remote GATT Clients */
282 static GSList *gatt_server_requests = NULL;
284 /* Linked List of connected Remote GATT clients */
285 static GSList *gatt_client_info_list = NULL;
287 /* Number of clients to be notified to */
288 static int num_indicate_clients;
290 /* List of applications */
291 static bt_service_app_info_t numapps[MAX_APPS_SUPPORTED];
293 static void __bt_gatt_handle_pending_request_info(int result,
294 int service_function, void *data, unsigned int size);
296 static void __bt_handle_server_instance_registered(event_gatts_register_t *data);
298 static void __bt_gatt_event_handler(int event_type, gpointer event_data);
305 void _bt_check_adv_app_termination(const char *name)
307 bt_service_app_info_t *app = NULL;
309 int apps[MAX_APPS_SUPPORTED] = { 0, };
311 ret_if(NULL == name);
313 memset(&apps, -1, sizeof(apps));
315 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
318 /* Search for a app which has same sender and stop adv is running */
319 if (strcasecmp(app->sender, name) == 0 && app->is_initialized == TRUE) {
320 BT_INFO("numapps[%d] Match found, name: %s", k, name);
322 /* TODO 2: Need to manage app info as list, not array.
323 This loop always run for MAX count if any apps are terminated.
326 /* Save instances of all apps that need to be unregistered */
327 if (app->instance_id != -1) {
329 /* Unregister all service handles with stack */
330 __bt_remove_all_service_handles(app);
332 /* If Advertising is enabled, stop it */
333 if (app->adv_handle != 0) {
334 BT_INFO("Stop advertising on instance ID [%d]", app->instance_id);
335 /* Disable adv if running */
336 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
337 app->adv_handle, name);
338 _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE);
341 apps[app->instance_id] = BT_GATT_SERVER; /* App holds a GATT server Instance */
342 } else if (app->client_id != -1) {
344 apps[app->client_id] = BT_GATT_CLIENT; /* App holds a GATT client Instance */
349 /* Unregister all apps one by one */
350 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
351 if (apps[k] == BT_GATT_SERVER) {
352 BT_INFO("Unregister server app[%d]", k);
353 /* Unregister server instance */
354 __bt_unregister_gatt_server_instance(k);
355 } else if (apps[k] == BT_GATT_CLIENT) {
356 BT_INFO("Unregister client app[%d]", k);
357 /* Unregister client instance */
358 __bt_unregister_gatt_client_instance(k);
363 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
364 bluetooth_gatt_server_indication_params_t *param)
367 int ret = OAL_STATUS_SUCCESS;
368 int result = OAL_STATUS_INTERNAL_ERROR;
370 BT_INFO("Current total number of connected clients [%d]", g_slist_length(gatt_client_info_list));
371 for (l = gatt_client_info_list; l != NULL; l = l->next) {
372 struct gatt_client_info_t *info = l->data;
375 BT_INFO("GATT Remote client address [%s] connection Id [%d]", info->addr, info->connection_id);
377 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
378 info->connection_id, data->length,
379 param->need_confirmation, (char *)(&data->data[0]));
381 BT_INFO("Send Indication to GATT client [%s] result: [%d]", info->addr, ret);
382 if (ret == OAL_STATUS_SUCCESS) {
383 BT_INFO("Send Indication sent successfully to GATT client [%s]", info->addr);
385 num_indicate_clients++;
389 BT_INFO("Indication sending done for total number of clients [%d]", num_indicate_clients);
393 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
394 bluetooth_gatt_att_request_type_e req_type)
398 for (l = gatt_server_requests; l != NULL; l = l->next) {
399 struct gatt_server_req_info *req_info = l->data;
401 if (req_info && req_info->request_id == request_id && req_info->request_type == req_type) {
402 BT_DBG("GATT Server request info found Req ID [%d] handle [%d] conn ID [%d]",
403 req_info->request_id, req_info->attribute_handle, req_info->connection_id);
407 BT_ERR("Gatt Request not found");
411 static void __bt_gatt_server_release_request_info(const char *address)
414 struct gatt_server_req_info *req_info = NULL;
416 for (l = gatt_server_requests; l != NULL; l = g_slist_next(l)) {
418 if (req_info == NULL)
421 if (g_strcmp0(req_info->addr, address) == 0) {
422 BT_DBG("Remove unhandled req_info %s", address);
423 g_free(req_info->addr);
424 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
430 void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle)
434 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
435 if (numapps[k].is_initialized == 1 && numapps[k].instance_id == server_inst) {
436 *adv_handle = numapps[k].adv_handle;
442 char * _bt_gatt_get_default_gatt_client_uuid(void)
444 return g_strdup(DEFAULT_GATT_CLIENT_UUID);
448 static void __bt_register_default_gatt_client()
453 uuid_str = _bt_gatt_get_default_gatt_client_uuid();
454 _bt_string_to_uuid(uuid_str, (service_uuid_t*)&uuid);
456 BT_INFO("Register Default GATT client uuid [%s]", uuid_str);
458 if (OAL_STATUS_SUCCESS != gattc_register(&uuid)) /* for only Smart Control */
459 BT_ERR("gattc register failed");
464 static struct gatt_server_info_t *__bt_find_remote_gatt_server_info_from_conn_id(int conn_id)
467 struct gatt_server_info_t *info = NULL;
469 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
470 info = (struct gatt_server_info_t*)l->data;
474 if (info->connection_id == conn_id)
480 int _bt_gatt_init(void)
482 const char *stack_name = NULL;
487 result = gatt_enable();
488 if (result != OAL_STATUS_SUCCESS) {
489 BT_ERR("gatt Init failed");
490 return _bt_convert_oal_status_to_bt_error(result);
493 /* Register gatt event handler */
494 _bt_service_register_event_handler_callback(BT_GATT_MODULE, __bt_gatt_event_handler);
496 __bt_service_reset_gatt_data();
498 stack_name = oal_get_stack_name();
500 if (stack_name && g_strcmp0(stack_name, "bluez") == 0) {
501 /*In the platform, defacult gatt client should be registered */
502 __bt_register_default_gatt_client();
506 return BLUETOOTH_ERROR_NONE;
509 static void __bt_service_reset_gatt_data(void)
513 BT_INFO("Rest numapp");
516 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
517 numapps[k].is_initialized = 0;
518 numapps[k].instance_id = -1;
519 numapps[k].adv_handle = 0;
520 numapps[k].adv_instance = -1;
521 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
522 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
523 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
524 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
525 numapps[k].adv_data_len = 0;
526 numapps[k].scan_rsp_len = 0;
529 numapps[k].client_id = -1;
530 memset(numapps[k].address.addr, 0x00, BLUETOOTH_ADDRESS_LENGTH);
531 numapps[k].is_watcher_enabled = FALSE;
535 void _bt_gatt_deinit(void)
537 BT_INFO("GATT deinit");
539 /* Un-register the default gatt client before */
540 __bt_unregister_gatt_client_instance(gatt_default_client);
542 if (OAL_STATUS_SUCCESS != gatt_disable())
543 BT_ERR("gatt deinit failed");
545 /* Un-register gatt event handler */
546 _bt_service_unregister_event_handler_callback(BT_GATT_MODULE);
548 __bt_service_reset_gatt_data();
551 /* NOTE: Not sure this function is really needed or not */
552 void _bt_update_adv_handle(const char *sender, int instance_id, int adv_handle)
555 BT_DBG("Sender [%s] Instance Id [%d] Adv handle [%d]", sender, instance_id, adv_handle);
556 bt_service_app_info_t *info = NULL;
558 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
560 /* Do not update client instance */
561 if (info->instance_id == -1)
563 /* Search for a app which has same sender and adv handle as 0 */
564 if (!g_strcmp0(info->sender, sender) && info->instance_id == instance_id && info->adv_handle == 0)
565 info->adv_handle = adv_handle;
569 int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
572 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
573 bt_service_app_info_t *info = NULL;
575 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
577 /* Search for a app which has same sender and adv handle as 0
578 It is possible that same sender but different adv handle */
579 if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0) {
580 //info->adv_handle = adv_handle;
581 return info->instance_id;
587 int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot)
590 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
591 bt_service_app_info_t *info = NULL;
593 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
596 /* Exact matching of Adv handle + sender combination */
597 if (!g_strcmp0(info->sender, sender) && info->adv_handle == adv_handle)
598 return info->instance_id;
600 if (!g_strcmp0(info->sender, sender) && info->adv_handle == -1)
601 return info->instance_id;
607 char * _bt_get_sender_and_handle(int server_instance, int *adv_handle)
610 bt_service_app_info_t *info = NULL;
612 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
615 if (info->instance_id == server_instance && info->adv_handle != 0) {
616 *adv_handle = info->adv_handle;
617 BT_DBG("Server instance [%d] Adv handle [%d] Sender [%s]", server_instance, *adv_handle, info->sender);
618 return g_strdup(info->sender);
624 void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance)
628 bt_service_app_info_t *info = NULL;
629 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
632 if (info->instance_id == instance) {
633 memcpy(info->adv_data.data, &adv->data, len);
639 void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance)
643 bt_service_app_info_t *info = NULL;
644 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
647 if (info->instance_id == instance) {
648 memcpy(info->scan_rsp.data, &scan->data, len);
654 void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance)
657 bt_service_app_info_t *info = NULL;
659 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
662 if (info->instance_id == instance) {
663 memcpy(&adv->data, info->adv_data.data, info->adv_data_len);
664 *len = info->adv_data_len;
670 void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance)
674 bt_service_app_info_t *info = NULL;
676 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
679 if (info->instance_id == instance) {
680 memcpy(&scan->data, info->scan_rsp.data, info->scan_rsp_len);
681 *len = info->scan_rsp_len;
687 static gboolean __bt_check_service_uuid_registered(const char *service_uuid)
691 bt_service_app_info_t *info = NULL;
693 bt_service_handle_uuid_info_t *uuid_info = NULL;
695 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
698 for (l = info->service_handle_uuids; l != NULL; l = g_slist_next(l)) {
702 if (!g_strcmp0(uuid_info->service_uuid, service_uuid)) {
703 BT_INFO("Same Service UUID is registered");
712 static void __bt_remove_service_uuid(int service_handle)
716 bt_service_app_info_t *info = NULL;
718 bt_service_handle_uuid_info_t *uuid_info = NULL;
719 bool removed = false;
721 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
724 for (l = info->service_handle_uuids; l != NULL;) {
729 if (uuid_info->service_handle == service_handle) {
730 BT_INFO("Removed Service handle [%d] Service UUID [%s]",
731 uuid_info->service_handle, uuid_info->service_uuid);
732 info->service_handle_uuids = g_slist_remove(info->service_handle_uuids, uuid_info);
733 g_free(uuid_info->service_uuid);
745 static int __bt_unregister_gatt_client_instance(int client_if)
747 int ret = OAL_STATUS_SUCCESS;
750 BT_INFO("DeAllocate client instance ID [%d]", client_if);
752 /* Reset data: instance_id parameter could be either for GATT Server or for GATT client */
753 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
754 if (numapps[k].client_id == client_if) {
755 BT_INFO("This is a GATT client app, unregister: Slot [%d] vacant", k);
756 numapps[k].client_id = -1;
757 numapps[k].is_initialized = FALSE;
758 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
759 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
760 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
762 /* Its a GATT Client Instance */
763 ret = gattc_deregister(client_if);
764 if (ret != OAL_STATUS_SUCCESS) {
765 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
766 return _bt_convert_oal_status_to_bt_error(ret);
771 return BLUETOOTH_ERROR_NONE;
774 static int __bt_unregister_gatt_server_instance(int server_instance)
776 int ret = OAL_STATUS_SUCCESS;
779 /* Unregister the server instance */
780 ret = gatts_unregister(server_instance);
781 if (ret != OAL_STATUS_SUCCESS) {
782 BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret);
783 return _bt_convert_oal_status_to_bt_error(ret);
785 BT_INFO("DeAllocated server instance with stack successful..");
788 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
789 if (numapps[k].instance_id == server_instance) {
790 numapps[k].is_initialized = 0;
791 numapps[k].instance_id = -1;
792 numapps[k].adv_handle = 0;
793 numapps[k].adv_instance = -1;
794 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
795 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
796 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
797 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
798 numapps[k].adv_data_len = 0;
799 numapps[k].scan_rsp_len = 0;
803 BT_DBG("Going8 to reset numapp block num [%d]", k);
804 return BLUETOOTH_ERROR_NONE;
807 int _bt_gatt_server_set_service_persistence(const char *uuid)
809 int result = BLUETOOTH_ERROR_NONE;
812 retv_if(uuid == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
814 if (!strncasecmp(service_persistence, uuid, BT_UUID_STRING_SIZE)) {
815 result = BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
817 g_strlcpy(service_persistence, uuid, sizeof(service_persistence));
818 BT_DBG("Set service(%s) to be persisted not removed", uuid);
824 int _bt_gatt_server_unset_service_persistence(const char *uuid)
826 int result = BLUETOOTH_ERROR_NONE;
829 retv_if(uuid == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
831 if (!strncasecmp(service_persistence, uuid, BT_UUID_STRING_SIZE)) {
832 memset(service_persistence, 0, sizeof(service_persistence));
833 BT_DBG("Unset service persistence: %s", uuid);
835 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
841 char *_bt_gatt_server_get_service_persistence()
843 return service_persistence;
846 static gboolean __bt_gatt_server_is_service_persistence(int service_handle)
849 bt_service_app_info_t *info = NULL;
850 bt_service_handle_uuid_info_t *uuid_info = NULL;
852 for (int k = 1; k < MAX_APPS_SUPPORTED; k++) {
854 for (l = info->service_handle_uuids; l != NULL;) {
859 if (uuid_info->service_handle == service_handle) {
860 char *uuid = _bt_gatt_server_get_service_persistence();
861 if (!strcasecmp(uuid_info->service_uuid, uuid)) {
862 BT_DBG("service(%s) persisted by user. can't be removed", uuid);
872 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info)
876 int ret = OAL_STATUS_SUCCESS;
879 if (app_info == NULL)
882 count = g_slist_length(app_info->service_handles);
883 BT_INFO("Before handle removal: current count [%d]", count);
885 for (l = app_info->service_handles; l != NULL;) {
890 if (__bt_gatt_server_is_service_persistence(*handle))
893 BT_INFO("Server Handle to be Removed [%d] Instance ID [%d]", *handle, app_info->instance_id);
894 if (_bt_gatt_server_stop_service(app_info->sender, *handle, app_info->instance_id) != BLUETOOTH_ERROR_NONE)
897 ret = gatts_delete_service(app_info->instance_id, *handle);
898 if (ret != OAL_STATUS_SUCCESS) {
899 BT_ERR("ret: %d", ret);
902 app_info->service_handles = g_slist_remove(app_info->service_handles, handle);
903 /* Remove Service UUID from the list */
904 __bt_remove_service_uuid(*handle);
907 count = g_slist_length(app_info->service_handles);
908 BT_INFO("After deleting current count [%d]", count);
914 int _bt_unregister_server_instance(const char *sender, int adv_handle)
916 BT_INFO("Unregister Allocated server instance request Sender [%s] Adv handle [%d]", sender, adv_handle);
917 int result = BLUETOOTH_ERROR_NONE;
918 int apps[MAX_APPS_SUPPORTED];
921 bt_service_app_info_t *info = NULL;
923 memset(&apps, -1, sizeof(apps));
925 if (adv_handle == 0) {
926 BT_DBG("Its a direct GATT Server app request to unregister");
927 /* Unregister server instance for each app with same sender (case: GATT Server with multiple adv handle) */
929 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
932 /* Exact matching of sender */
933 if (!g_strcmp0(info->sender, sender)) {
934 BT_INFO("Unregister GATT server instance [%d]", info->instance_id);
935 /* Unregister all service handles with stack */
936 __bt_remove_all_service_handles(info);
938 /* Disable adv if running */
939 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
940 info->adv_handle, sender);
941 _bt_set_advertising(sender, info->adv_handle, FALSE, FALSE);
943 /* Save all instances which need to be unregistered */
944 apps[info->instance_id] = 1;
948 BT_DBG("Its an Internal unregister request by adv application");
949 server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
950 BT_DBG("Its an Internal unregister request by adv application: Adv disabled srv instance [%d]", server_instance);
951 if (server_instance == -1) {
952 BT_ERR("No allocated server instance to be removed");
953 return BLUETOOTH_ERROR_INVALID_PARAM;
956 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
958 if (info->instance_id == server_instance) {
959 if (info->service_handles == NULL) {
960 BT_INFO("There are no Service handles with this app, safe to unregister");
961 /* Unregister server instance only if this sender does not have any gatt services in it */
962 result = __bt_unregister_gatt_server_instance(server_instance);
964 info->adv_handle = 0;
965 memset(info->adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
966 info->adv_data_len = 0;
967 memset(info->scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
968 info->scan_rsp_len = 0;
975 /* Unregister all apps one by one */
976 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
978 BT_INFO("Unregister app[%d]", k);
979 /* Unregister server instance */
980 __bt_unregister_gatt_server_instance(k);
987 int _bt_register_server_instance(const char *sender, int adv_handle)
989 int ret = OAL_STATUS_SUCCESS;
990 char *uuid_string = NULL;
995 BT_INFO("Check on which instance Server instance can be initialized....");
996 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
997 if (numapps[k].is_initialized == 1 || strlen(numapps[k].uuid) > 0) {
998 BT_DBG("Instance ID [%d] is already in use..Check next slot", numapps[k].instance_id);
1001 BT_DBG("Time to register GATT Server..UUID to be used is [%s] slot [%d]", uuid_list[slot-1], slot);
1007 BT_ERR("No Slot if free for GATT Server registration..");
1008 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
1011 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
1012 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
1013 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
1014 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
1016 /* Register GATT Server */
1017 ret = gatts_register(&uuid);
1018 if (ret != OAL_STATUS_SUCCESS) {
1019 BT_ERR("ret: %d", ret);
1020 g_free(uuid_string);
1021 return _bt_convert_oal_status_to_bt_error(ret);
1023 BT_DBG("GATT Server registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
1024 /* Return & wait for GATT Server Instance Initialization event */
1025 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
1026 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
1028 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
1029 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
1031 numapps[slot].is_initialized = 0; /* Set initialization from app registered callback */
1032 numapps[slot].adv_handle = adv_handle;
1034 g_free(uuid_string);
1035 return BLUETOOTH_ERROR_NONE;
1038 /* Event handlers */
1039 static void __bt_gatt_get_pending_request_info(int service_function,
1043 invocation_info_t *req_info = NULL;
1045 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1047 if (req_info == NULL)
1050 if (req_info->service_function == service_function) {
1051 *sender = req_info->sender;
1057 static void __bt_gatt_cleanup_invocation_on_gatt_disconnection(int result,
1058 void *data, unsigned int size)
1063 invocation_info_t *req_info = NULL;
1064 ret_if(data == NULL);
1065 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1067 for (l = _bt_get_invocation_list(); l != NULL; ) {
1069 l = g_slist_next(l);
1071 if (req_info == NULL)
1074 switch (req_info->service_function) {
1075 case BT_GATT_GET_PRIMARY_SERVICES: {
1076 if(!g_strcmp0((char*)req_info->user_data, (char*)data)){
1077 bt_services_browse_info_t param;
1078 memset(¶m, 0, sizeof(bt_services_browse_info_t));
1079 _bt_convert_addr_string_to_type(param.device_addr.addr, (char*)data);
1080 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1081 g_array_append_vals(out_param, ¶m, sizeof(bt_services_browse_info_t));
1082 _bt_service_method_return(req_info->context, out_param, result);
1083 BT_DBG("BT_GATT_GET_PRIMARY_SERVICES request cleared for address [%s]", (char*)data);
1084 _bt_free_info_from_invocation_list(req_info);
1085 g_array_free(out_param, TRUE);
1089 case BT_GATT_GET_SERVICE_PROPERTIES: {
1090 bluetooth_gatt_client_svc_prop_info_t *prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
1091 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1092 if (!g_strcmp0(addr, (char*)data)){
1093 bt_char_browse_info_t param;
1094 memset(¶m, 0, sizeof(bt_char_browse_info_t));
1095 _bt_convert_addr_string_to_type(param.device_addr.addr,addr);
1096 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1097 g_array_append_vals(out_param, ¶m, sizeof(bt_char_browse_info_t));
1098 _bt_service_method_return(req_info->context, out_param, result);
1099 BT_DBG("BT_GATT_GET_SERVICE_PROPERTIES request cleared for address [%s]", addr);
1100 _bt_free_info_from_invocation_list(req_info);
1101 g_array_free(out_param, TRUE);
1105 case BT_GATT_GET_CHARACTERISTIC_PROPERTIES: {
1106 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1107 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1108 if (!g_strcmp0(addr, (char*)data)){
1109 bt_descriptor_browse_info_t param;
1110 memset(¶m, 0, sizeof(bt_descriptor_browse_info_t));
1111 _bt_convert_addr_string_to_type(param.device_addr.addr, addr);
1112 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1113 g_array_append_vals(out_param, ¶m, sizeof(bt_descriptor_browse_info_t));
1114 _bt_service_method_return(req_info->context, out_param, result);
1115 BT_DBG("BT_GATT_GET_CHARACTERISTIC_PROPERTIES request cleared for address [%s]", addr);
1116 _bt_free_info_from_invocation_list(req_info);
1117 g_array_free(out_param, TRUE);
1121 case BT_GATT_WATCH_CHARACTERISTIC: {
1122 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1123 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1124 if (!g_strcmp0(addr, (char*)data)){
1125 bt_gatt_notif_reg_info_t param;
1126 memset(¶m, 0, sizeof(bt_gatt_notif_reg_info_t));
1127 _bt_convert_addr_string_to_type(param.addr.addr, addr);
1128 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1129 g_array_append_vals(out_param, ¶m, sizeof(bt_gatt_notif_reg_info_t));
1130 _bt_service_method_return(req_info->context, out_param, result);
1131 _bt_free_info_from_invocation_list(req_info);
1132 g_array_free(out_param, TRUE);
1136 case BT_GATT_READ_CHARACTERISTIC:
1137 case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: {
1138 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1139 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1140 if (!g_strcmp0(addr, (char*)data)){
1141 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1142 g_array_append_vals(out_param, prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
1143 _bt_service_method_return(req_info->context, out_param, result);
1144 BT_DBG("BT_GATT_READ/WRITE_CHARACTERISTIC request cleared for address [%s]", addr);
1145 _bt_free_info_from_invocation_list(req_info);
1146 g_array_free(out_param, TRUE);
1150 case BT_GATT_READ_DESCRIPTOR_VALUE:
1151 case BT_GATT_WRITE_DESCRIPTOR_VALUE: {
1152 bluetooth_gatt_client_desc_prop_info_t *prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
1153 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1154 if (!g_strcmp0(addr, (char*)data)){
1155 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1156 g_array_append_vals(out_param, prop, sizeof(bluetooth_gatt_client_desc_prop_info_t));
1157 _bt_service_method_return(req_info->context, out_param, result);
1158 BT_DBG("BT_GATT_READ/WRITE_DESCRIPTOR_VALUE request cleared for address [%s]", addr);
1159 _bt_free_info_from_invocation_list(req_info);
1160 g_array_free(out_param, TRUE);
1164 case BT_REQ_ATT_MTU: {
1165 char *temp_addr = (char*)req_info->user_data;
1166 bluetooth_device_address_t address;
1167 if (!g_strcmp0(temp_addr, (char*)data)) {
1168 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1169 _bt_convert_addr_string_to_type(address.addr, temp_addr);
1170 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1171 sizeof(bluetooth_device_address_t));
1172 _bt_service_method_return(req_info->context, out_param, result);
1173 _bt_free_info_from_invocation_list(req_info);
1174 g_array_free(out_param, TRUE);
1185 static void __bt_gatt_handle_pending_request_info(int result,
1186 int service_function, void *data, unsigned int size)
1190 invocation_info_t *req_info = NULL;
1191 ret_if(data == NULL);
1193 for (l = _bt_get_invocation_list(); l != NULL; ) {
1195 l = g_slist_next(l);
1196 if (req_info == NULL || req_info->service_function != service_function)
1199 switch (service_function) {
1201 case BT_GATT_SERVER_REGISTER: {
1202 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1204 if (!g_strcmp0(req_info->sender, param->sender)) {
1205 BT_DBG("GATT Server app found [%s]", req_info->sender);
1207 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1208 g_array_append_vals(out_param, ¶m->instance_id, sizeof(int));
1209 _bt_service_method_return(req_info->context, out_param, result);
1211 _bt_free_info_from_invocation_list(req_info);
1212 g_array_free(out_param, TRUE);
1216 case BT_GATT_SERVER_START_SERVICE:
1217 case BT_GATT_SERVER_DELETE_SERVICE: {
1218 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1220 int *saved_instance_id = (int*)req_info->user_data;
1221 if (!g_strcmp0(req_info->sender, param->sender) && param->instance_id == *saved_instance_id) {
1222 BT_DBG("GATT Server app found [%s] Instance ID [%d] Reply DBUS",
1223 req_info->sender, *saved_instance_id);
1225 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1226 g_array_append_vals(out_param, &saved_instance_id, sizeof(int));
1227 _bt_service_method_return(req_info->context, out_param, result);
1229 _bt_free_info_from_invocation_list(req_info);
1230 g_array_free(out_param, TRUE);
1234 case BT_GATT_SERVER_ADD_SERVICE:
1235 case BT_GATT_SERVER_ADD_DESCRIPTOR:
1236 case BT_GATT_SERVER_ADD_CHARACTERISTIC: {
1237 int *handle = (int*)data;
1238 BT_DBG("Characteristic added: Handle [%d]", *handle);
1239 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1241 g_array_append_vals(out_param, handle, sizeof(int));
1242 _bt_service_method_return(req_info->context, out_param, result);
1244 _bt_free_info_from_invocation_list(req_info);
1245 g_array_free(out_param, TRUE);
1250 case BT_DISCONNECT_LE: {
1251 char *addr = (char*)req_info->user_data;
1252 bluetooth_device_address_t address;
1254 if (!g_strcmp0(addr, (char*)data)) {
1255 BT_INFO("GATT Client connect-disconnect call pending for app [%s] addr [%s]",
1256 req_info->sender, addr + 12);
1257 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1258 _bt_convert_addr_string_to_type(address.addr, addr);
1260 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1261 sizeof(bluetooth_device_address_t));
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);
1269 case BT_GATT_CLIENT_REGISTER: {
1270 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1272 if (!g_strcmp0(req_info->sender, param->sender)) {
1273 BT_DBG("GATT Client app found [%s] created client ID [%d]",
1274 req_info->sender, param->client_id);
1276 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1277 g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1278 _bt_service_method_return(req_info->context, out_param, result);
1280 _bt_free_info_from_invocation_list(req_info);
1281 g_array_free(out_param, TRUE);
1285 case BT_GATT_GET_PRIMARY_SERVICES: {
1286 bt_services_browse_info_t *param = (bt_services_browse_info_t*)data;
1287 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1288 _bt_convert_addr_type_to_string(address,
1289 (unsigned char *)(¶m->device_addr.addr));
1291 /* Match address to determine same request */
1292 if (!g_strcmp0((char*)req_info->user_data, address)) {
1293 BT_DBG("GATT Client app found [%s] Remote address [%s]",
1294 req_info->sender, address);
1296 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1297 g_array_append_vals(out_param, param,
1298 sizeof(bt_services_browse_info_t));
1300 //g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1301 _bt_service_method_return(req_info->context, out_param, result);
1303 _bt_free_info_from_invocation_list(req_info);
1304 g_array_free(out_param, TRUE);
1309 case BT_GATT_GET_SERVICE_PROPERTIES: {
1310 bt_char_browse_info_t param;
1311 memcpy((void*)¶m, data, sizeof(bt_char_browse_info_t));
1312 //bt_char_browse_info_t *param = (bt_char_browse_info_t*)data;
1314 bluetooth_gatt_client_svc_prop_info_t *prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
1316 /* Match both address and service properties to determine same request */
1317 if (!memcmp(param.device_addr.addr,
1318 prop->device_address.addr,
1319 sizeof(bluetooth_device_address_t)) &&
1320 !memcmp(param.svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1321 param.svc_inst_id == prop->svc.instance_id) {
1322 BT_DBG("Returning Service properties");
1324 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1325 g_array_append_vals(out_param, ¶m, sizeof(bt_char_browse_info_t));
1326 _bt_service_method_return(req_info->context, out_param, result);
1328 _bt_free_info_from_invocation_list(req_info);
1329 g_array_free(out_param, TRUE);
1333 case BT_GATT_GET_CHARACTERISTIC_PROPERTIES: {
1334 bt_descriptor_browse_info_t *param = (bt_descriptor_browse_info_t*)data;
1336 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1338 /* Match both address, service properties &char properties to determine same request */
1339 if (!memcmp(param->device_addr.addr,
1340 prop->device_address.addr,
1341 sizeof(bluetooth_device_address_t)) &&
1342 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1343 param->svc_inst_id == prop->svc.instance_id &&
1344 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1345 param->char_inst_id == prop->characteristic.instance_id) {
1346 BT_DBG("Returning Characteristic properties");
1347 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1348 g_array_append_vals(out_param, param, sizeof(bt_descriptor_browse_info_t));
1349 _bt_service_method_return(req_info->context, out_param, result);
1351 _bt_free_info_from_invocation_list(req_info);
1352 g_array_free(out_param, TRUE);
1356 case BT_GATT_WATCH_CHARACTERISTIC: {
1357 bt_gatt_notif_reg_info_t *param = (bt_gatt_notif_reg_info_t*)data;
1358 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1360 /* Match both address, service properties &char properties to determine same request */
1361 if (!memcmp(param->addr.addr,
1362 prop->device_address.addr,
1363 sizeof(bluetooth_device_address_t)) &&
1364 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1365 param->svc_inst == prop->svc.instance_id &&
1366 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1367 param->char_inst == prop->characteristic.instance_id) {
1368 BT_INFO("Characteristic Watch Successful: Is registered [%d]",
1369 param->is_registered);
1370 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1371 g_array_append_vals(out_param, param, sizeof(bt_gatt_notif_reg_info_t));
1372 _bt_service_method_return(req_info->context, out_param, result);
1373 _bt_free_info_from_invocation_list(req_info);
1374 g_array_free(out_param, TRUE);
1378 case BT_GATT_READ_CHARACTERISTIC:
1379 case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: {
1380 bluetooth_gatt_client_char_prop_info_t *param = (bluetooth_gatt_client_char_prop_info_t*)data;
1382 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1383 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1384 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1386 if (!memcmp(param, prop, sizeof(bluetooth_gatt_client_char_prop_info_t))) {
1387 BT_DBG("Gatt Char read or write request matched for address [%s]", addr);
1388 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1389 g_array_append_vals(out_param, param, sizeof(bluetooth_gatt_client_char_prop_info_t));
1390 _bt_service_method_return(req_info->context, out_param, result);
1392 _bt_free_info_from_invocation_list(req_info);
1393 g_array_free(out_param, TRUE);
1398 case BT_GATT_READ_DESCRIPTOR_VALUE:
1399 case BT_GATT_WRITE_DESCRIPTOR_VALUE: {
1400 bluetooth_gatt_client_desc_prop_info_t *param = (bluetooth_gatt_client_desc_prop_info_t*)data;
1402 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1403 bluetooth_gatt_client_desc_prop_info_t *prop = (bluetooth_gatt_client_desc_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_desc_prop_info_t))) {
1407 BT_DBG("Descriptor 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_desc_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_REQ_ATT_MTU: {
1419 char *addr = (char*)req_info->user_data;
1420 bluetooth_device_address_t address;
1422 if (!g_strcmp0(addr, (char*)data)) {
1423 BT_DBG("GATT Client BT_REQ_ATT_MTU call pending for app [%s] addr [%s]",
1424 req_info->sender, addr);
1425 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1426 _bt_convert_addr_string_to_type(address.addr, addr);
1428 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1429 sizeof(bluetooth_device_address_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);
1442 static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
1444 bt_service_app_info_t *info = NULL;
1446 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
1448 _bt_uuid_to_string(&(data->server_uuid), uuid_string);
1449 BT_INFO("Instance ID is Intialized [%d] UUID initialized [%s]", data->server_inst, uuid_string);
1451 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1452 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1455 if (g_strcmp0(info->uuid, uuid_string) == 0) {
1456 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1457 info->is_initialized = TRUE;
1458 info->instance_id = data->server_inst;
1459 info->adv_instance = data->server_inst;
1460 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_SERVER_REGISTER,
1461 (void*)info, sizeof(bt_service_app_info_t));
1465 g_free(uuid_string);
1468 static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
1470 int result = BLUETOOTH_ERROR_NONE;
1474 bt_service_app_info_t *info = NULL;
1477 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1478 _bt_uuid_to_string(&(event->gatt_srvc_id.id.uuid), uuid_str);
1479 BT_INFO("GATT Added Service UUID: [%s] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1480 uuid_str, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1482 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1483 result = BLUETOOTH_ERROR_INTERNAL;
1484 svc_handle = 0; /* Service handle set to 0 indicates.
1485 0 is reserved by BT SIG, cant be used by app*/
1487 svc_handle = event->gatt_srvc_stat.servic_hndl;
1489 BT_INFO("GATT Added Service Status [%d] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1490 event->gatt_srvc_stat.status, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1492 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1493 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1496 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1497 BT_INFO("numapps[%d] Found GATT Server.. UUID [%s], sender [%s]", k, info->uuid, info->sender);
1498 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_SERVICE,
1499 (int*)&svc_handle, sizeof(int));
1501 /* Add Service Handle */
1502 if (svc_handle > 0) {
1503 bt_service_handle_uuid_info_t *uuid_info;
1504 handle = g_malloc0(sizeof(int));
1505 *handle = svc_handle;
1506 numapps[k].service_handles = g_slist_append(numapps[k].service_handles, handle);
1507 count = g_slist_length(numapps[k].service_handles);
1508 BT_INFO("Added Service handle [%d] to list..current count [%d]", svc_handle, count);
1509 /* Add Service UUID to the list */
1510 uuid_info = g_malloc0(sizeof(bt_service_handle_uuid_info_t));
1511 uuid_info->service_handle = svc_handle;
1512 uuid_info->service_uuid = g_strdup(uuid_str);
1513 numapps[k].service_handle_uuids = g_slist_append(numapps[k].service_handle_uuids, uuid_info);
1522 static void __bt_handle_gatt_server_characteristic_added(event_gatts_srvc_charctr_t *event)
1524 int result = BLUETOOTH_ERROR_NONE;
1526 bt_service_app_info_t *info = NULL;
1528 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1530 BT_INFO("GATT Server Char added status [%d]", event->gatt_srvc_stat.status);
1531 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1532 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1533 BT_INFO("GATT Add characteristic Status: [%d]", event->gatt_srvc_stat.status);
1534 BT_INFO("GATT Service characteristic Handle: [%d]", event->charctr_hndl);
1536 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1537 result = BLUETOOTH_ERROR_INTERNAL;
1538 char_handle = 0; /* characteristic handle set to 0 indicates.
1539 0 is reserved by BT SIG, cant be used by app*/
1541 char_handle = event->charctr_hndl;
1544 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1545 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1548 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1549 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1550 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_CHARACTERISTIC,
1551 (int*)&char_handle, sizeof(int));
1557 _bt_uuid_to_string(&(event->charctr_uuid), uuid_str);
1558 BT_INFO("GATT Added Characteristic: UUID: [%s]", uuid_str);
1563 static void __bt_handle_gatt_server_descriptor_added(event_gatts_srvc_descr_t* event)
1565 int result = BLUETOOTH_ERROR_NONE;
1567 bt_service_app_info_t *info = NULL;
1569 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1571 BT_INFO("GATT Server Descriptor added status [%d]", event->gatt_srvc_stat.status);
1572 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1573 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1574 BT_INFO("GATT Add Descriptor Status: [%d]", event->gatt_srvc_stat.status);
1575 BT_INFO("GATT Service Descriptor Handle: [%d]", event->descrptr_hndl);
1577 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1578 result = BLUETOOTH_ERROR_INTERNAL;
1579 desc_handle = 0; /* Service handle set to 0 indicates.
1580 0 is reserved by BT SIG, cant be used by app*/
1582 desc_handle = event->descrptr_hndl;
1584 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1585 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1588 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1589 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1590 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_DESCRIPTOR,
1591 (int*)&desc_handle, sizeof(int));
1596 _bt_uuid_to_string(&(event->descrptr_uuid), uuid_str);
1597 BT_INFO("GATT Added Descriptor: UUID: [%s]", uuid_str);
1602 static void __bt_handle_gatt_server_service_started(event_gatts_srvc_t *event)
1604 bt_service_app_info_t *info = NULL;
1605 int result = BLUETOOTH_ERROR_NONE;
1607 BT_INFO("GATT Server Service Started..");
1610 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1611 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1612 BT_INFO("GATT Service Started Status: [%d]", event->status);
1614 if (event->status != OAL_STATUS_SUCCESS) {
1615 BT_ERR("GATT Server Service Start Failed Err: [%d]", event->status);
1616 result = BLUETOOTH_ERROR_INTERNAL;
1619 /* Check if the just registered Instance ID belongs to requester */
1620 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1623 if (info->instance_id == event->server_inst) {
1624 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1625 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_START_SERVICE,
1626 (void*)info, sizeof(bt_service_app_info_t));
1632 static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
1634 int result = BLUETOOTH_ERROR_NONE;
1635 bt_service_app_info_t *info = NULL;
1637 BT_INFO("GATT Server Service Stopped..");
1639 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1640 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1641 BT_INFO("GATT Service Stopped Status: [%d]", event->status);
1643 if (event->status != OAL_STATUS_SUCCESS) {
1644 BT_ERR("GATT Server Service Stop Failed Err: [%d]", event->status);
1645 result = BLUETOOTH_ERROR_INTERNAL;
1648 /* Check if the just registered Instance ID belongs to requester */
1649 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1652 if (info->instance_id == event->server_inst) {
1653 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1654 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_STOP_SERVICE,
1655 (void*)info, sizeof(bt_service_app_info_t));
1661 static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
1663 int result = BLUETOOTH_ERROR_NONE;
1664 bt_service_app_info_t *info = NULL;
1666 BT_INFO("GATT Server Service Deleted..");
1668 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1669 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1670 BT_INFO("GATT Service Deleted Status: [%d]", event->status);
1672 if (event->status != OAL_STATUS_SUCCESS) {
1673 BT_ERR("GATT Server Service Delete Failed Err: [%d]", event->status);
1674 result = BLUETOOTH_ERROR_INTERNAL;
1677 /* Check if the just registered Instance ID belongs to requester */
1678 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1681 if (info->instance_id == event->server_inst) {
1682 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1683 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_DELETE_SERVICE,
1684 (void*)info, sizeof(bt_service_app_info_t));
1690 #ifdef TIZEN_BLUEDROID_PORTING
1691 static struct gatt_client_info_t *_bt_find_remote_gatt_client_info_with_inst_id(char *address, int instance_id)
1694 struct gatt_client_info_t *info = NULL;
1695 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1696 info = (struct gatt_client_info_t*)l->data;
1700 if (!g_strcmp0(info->addr, address)) {
1701 if (info->instance_id == instance_id) {
1702 BT_DBG("Remote GATT client found addr[%s] instance_id[%d]", info->addr, info->instance_id);
1711 struct gatt_client_info_t *_bt_find_remote_gatt_client_info(char *address)
1714 struct gatt_client_info_t *info = NULL;
1715 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1716 info = (struct gatt_client_info_t*)l->data;
1720 if (!g_strcmp0(info->addr, address)) {
1721 BT_DBG("Remote GATT client found addr[%s]", info->addr);
1728 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info_from_conn_id(int conn_id)
1731 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 (info->connection_id == conn_id) {
1739 BT_INFO("Remote GATT client found addr[%s]", info->addr);
1746 struct gatt_server_info_t *_bt_find_remote_gatt_server_info(char *address)
1749 struct gatt_server_info_t *info = NULL;
1750 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
1751 info = (struct gatt_server_info_t*)l->data;
1755 if (!g_strcmp0(info->addr, address)) {
1756 BT_DBG("Remote GATT Server found addr[%s] connection_id %d", info->addr, info->connection_id);
1763 static struct gatt_out_conn_info_t* __bt_find_gatt_outgoing_conn_info(char *address)
1766 struct gatt_out_conn_info_t *info = NULL;
1767 for (l = outgoing_gatt_conn_list; l != NULL; l = g_slist_next(l)) {
1768 info = (struct gatt_out_conn_info_t*)l->data;
1772 if (!g_strcmp0(info->addr, address)) {
1773 BT_INFO("Outgoing connection info found addr[%s]", info->addr + 12);
1780 static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
1782 int result = BLUETOOTH_ERROR_NONE;
1783 struct gatt_client_info_t *client_info = NULL;
1784 bluetooth_device_address_t dev_addr;
1785 GVariant *param = NULL;
1787 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1789 memcpy(dev_addr.addr, event->address.addr, 6);
1791 /* REPLY dbus Context to application which called BT_CONNECT_LE. There is status
1793 _bt_convert_addr_type_to_string(address,
1794 (unsigned char *)dev_addr.addr);
1796 if (event->status != OAL_STATUS_SUCCESS)
1797 result = BLUETOOTH_ERROR_INTERNAL;
1799 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1800 address, BT_ADDRESS_STRING_SIZE);
1802 BT_INFO("GATT Server Connedted: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1803 address + 12, event->server_inst, event->conn_id);
1806 /* Check if device is already in connected list */
1807 client_info = _bt_find_remote_gatt_client_info(address);
1810 BT_DBG("Conn Info absent: But no need to Send Local GATT Server Connected event to apps");
1812 param = g_variant_new("(is)", result, address);
1814 /* Send event to application */
1815 _bt_send_event(BT_DEVICE_EVENT,
1816 BLUETOOTH_EVENT_GATT_SERVER_CONNECTED, /* Local device is GATT server */
1819 /* Save client connection info */
1820 client_info = g_new0(struct gatt_client_info_t, 1);
1821 client_info->addr = g_strdup(address);
1822 BT_INFO("Added GATT client addr[%s]", client_info->addr + 12);
1823 client_info->connection_id = event->conn_id;
1824 client_info->instance_id = event->server_inst;
1825 gatt_client_info_list = g_slist_append(gatt_client_info_list, client_info);
1826 BT_INFO("Total num of connected Remote GATT Clients [%d]", g_slist_length(gatt_client_info_list));
1828 /* Below is for iOS GM support, currently not needed */
1829 if (TIZEN_PROFILE_WEARABLE) {
1830 struct gatt_server_info_t *server_info = NULL;
1833 /* Save server connection info */
1834 server_info = g_new0(struct gatt_server_info_t, 1);
1835 server_info->addr = g_strdup(address);
1836 server_info->client_id = -1;
1837 BT_INFO("Added GATT server addr[%s]", server_info->addr + 12);
1838 server_info->connection_id = event->conn_id;
1839 gatt_server_info_list = g_slist_append(gatt_server_info_list, server_info);
1840 BT_INFO("Total num of connected Remote GATT Servers [%d]", g_slist_length(gatt_server_info_list));
1842 ret = gattc_add_connection_info((bt_address_t *)&dev_addr, event->conn_id, event->server_inst);
1843 if (ret != OAL_STATUS_SUCCESS) {
1844 BT_ERR("gattc register server instance failed");
1849 __bt_add_mtu_gatt_device(address);
1854 /* GATT Server Dis connected */
1855 static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *event)
1857 int result = BLUETOOTH_ERROR_NONE;
1858 struct gatt_client_info_t *client_info = NULL;
1859 bluetooth_device_address_t dev_addr;
1860 GVariant *param = NULL;
1861 char address[BT_ADDRESS_STRING_SIZE];
1863 memcpy(dev_addr.addr, event->address.addr, 6);
1865 /* REPLY dbus Context to application which called BT_DISCONNECT_LE. There is status
1867 _bt_convert_addr_type_to_string(address,
1868 (unsigned char *)dev_addr.addr);
1870 if (event->status != OAL_STATUS_SUCCESS)
1871 result = BLUETOOTH_ERROR_INTERNAL;
1873 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
1874 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
1875 result = BLUETOOTH_ERROR_INTERNAL;
1877 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1878 address, BT_ADDRESS_STRING_SIZE);
1880 BT_ERR("Failed to connect Local GATT Server Remote Client addr[%s]", address + 12);
1884 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE,
1885 address, BT_ADDRESS_STRING_SIZE);
1888 /* Remove previous invalid request info */
1889 __bt_gatt_server_release_request_info(address);
1891 BT_INFO("Local GATT Server DisConnected: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1892 address + 12, event->server_inst, event->conn_id);
1894 #ifdef TIZEN_BLUEDROID_PORTING
1895 __bt_remove_all_prep_write_req(event->conn_id);
1898 /* Remove Connection info */
1899 client_info = _bt_find_remote_gatt_client_info(address);
1901 BT_DBG("No need to Send Local GATT Server Disconnected event to apps, just remove remote client info");
1903 param = g_variant_new("(is)", result, address);
1904 /* Send event to application */
1905 _bt_send_event(BT_DEVICE_EVENT,
1906 BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED, /* Local device is GATT server */
1909 /* Below is for iOS GM support, currently not needed */
1910 if (TIZEN_PROFILE_WEARABLE) {
1911 struct gatt_server_info_t *server_info = NULL;
1913 /* Remove server info from list */
1914 server_info = _bt_find_remote_gatt_server_info(address);
1916 gatt_server_info_list = g_slist_remove(gatt_server_info_list, server_info);
1918 /* Remove all services from info list_gatt_info */
1919 __bt_cleanup_remote_services(server_info);
1921 BT_INFO("Can not find conn info, already removed!");
1925 /* Remove client info from List */
1926 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
1927 BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
1928 g_free(client_info->addr);
1929 g_free(client_info);
1932 __bt_remove_mtu_gatt_device(address);
1935 static void __bt_handle_gatt_server_acquire_write_requested(event_gatts_srvc_acquire_attr_t *event)
1937 GVariant *param = NULL;
1938 int result = BLUETOOTH_ERROR_NONE;
1939 struct gatt_server_req_info *req_info = NULL;
1940 bluetooth_device_address_t dev_addr;
1941 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1943 BT_INFO("GATT Server ACQUIRE Write Req");
1944 BT_DBG(" conn id %d, trans id %d, attr andle %d", event->attr_trans.conn_id,
1945 event->attr_trans.trans_id, event->attr_trans.attr_handle);
1947 //address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1948 memcpy(dev_addr.addr, event->address.addr, 6);
1950 req_info = g_new0(struct gatt_server_req_info, 1);
1951 req_info->request_id = event->attr_trans.trans_id;
1952 req_info->attribute_handle = event->attr_trans.attr_handle;
1953 req_info->connection_id = event->attr_trans.conn_id;
1954 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
1955 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
1957 _bt_convert_addr_type_to_string(address,
1958 (unsigned char *)dev_addr.addr);
1960 param = g_variant_new("(iiiiiis)", result,
1961 event->attr_trans.conn_id,
1962 event->attr_trans.trans_id,
1963 event->attr_trans.attr_handle,
1964 event->mtu, event->attr_trans.offset, address);
1965 BT_DBG("remote address : [%s]", address);
1967 _bt_send_event(BT_GATT_SERVER_EVENT,
1968 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
1973 static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_acquire_attr_t *event)
1975 GVariant *param = NULL;
1976 int result = BLUETOOTH_ERROR_NONE;
1977 struct gatt_server_req_info *req_info = NULL;
1978 bluetooth_device_address_t dev_addr;
1979 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1981 BT_INFO("GATT Server ACQUIRE Notify Req");
1982 BT_DBG("conn id %d, trans id %d, attr handle %d, req address %s",
1983 event->attr_trans.conn_id, event->attr_trans.trans_id,
1984 event->attr_trans.attr_handle, address);
1986 memcpy(dev_addr.addr, event->address.addr, 6);
1987 _bt_convert_addr_type_to_string(address,
1988 (unsigned char *)dev_addr.addr);
1989 BT_INFO("Remote address : [%s]", address);
1991 req_info = g_new0(struct gatt_server_req_info, 1);
1992 req_info->request_id = event->attr_trans.trans_id;
1993 req_info->attribute_handle = event->attr_trans.attr_handle;
1994 req_info->connection_id = event->attr_trans.conn_id;
1995 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
1996 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
1998 param = g_variant_new("(iiiiiis)", result,
1999 event->attr_trans.conn_id,
2000 event->attr_trans.trans_id,
2001 event->attr_trans.attr_handle,
2002 event->mtu, event->attr_trans.offset,
2005 _bt_send_event(BT_GATT_SERVER_EVENT,
2006 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY,
2010 #ifdef TIZEN_BLUEDROID_PORTING
2011 static bt_gatt_prep_write_data_t* __bt_create_prep_write_data(event_gatts_srvc_write_attr_t *event)
2013 bluetooth_device_address_t dev_addr;
2015 bt_gatt_prep_write_data_t *prep_data = NULL;
2017 prep_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2018 prep_data->connection_id = event->attr_trans.conn_id;
2019 prep_data->request_id = event->attr_trans.trans_id;
2020 prep_data->handle = event->attr_trans.attr_handle;
2021 prep_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2022 memcpy(dev_addr.addr, event->address.addr, 6);
2023 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
2024 _bt_convert_addr_type_to_string(addr,
2025 (unsigned char *)dev_addr.addr);
2026 prep_data->device_address = addr;
2027 prep_data->offset = event->attr_trans.offset;
2028 prep_data->length = event->length;
2029 prep_data->value = g_memdup2(&event->value[0], event->length);
2034 static int __bt_gatt_server_send_long_write_response(bt_gatt_prep_write_data_t *prep_data, int resp_status, int auth_req)
2036 int ret = OAL_STATUS_SUCCESS;
2037 oal_gatt_response_t response;
2039 memset(&response, 0x00, sizeof(oal_gatt_response_t));
2041 BT_INFO("GATT Server Write Res Connection ID: [%d]", prep_data->connection_id);
2042 BT_INFO("GATT Server Write Res Transaction ID:[%d]", prep_data->request_id);
2043 BT_INFO("GATT Server Write Res Attribute Handle: [%d]", prep_data->handle);
2044 BT_INFO("GATT Server Write Res Attribute Offset: [%d]", prep_data->offset);
2045 BT_INFO("GATT Server Write Res value length [%d]", prep_data->length);
2047 response.handle = prep_data->handle;
2048 response.attr_value.auth_req = auth_req;
2049 response.attr_value.handle = prep_data->handle;
2050 response.attr_value.offset = prep_data->offset;
2051 response.attr_value.len = prep_data->length;
2052 memcpy(&response.attr_value.value, &prep_data->value[0], prep_data->length);
2054 ret = gatts_send_response(prep_data->connection_id, prep_data->request_id,
2055 resp_status, &response);
2059 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_request_id(int request_id)
2062 bt_gatt_prep_write_data_t *prep_data = NULL;
2064 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2065 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2066 if (prep_data && (prep_data->request_id == request_id) &&
2067 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
2068 BT_INFO("prep_data found for request id [%d]", request_id);
2072 BT_INFO("prep_data not found for request [%d]", request_id);
2076 static bt_gatt_prep_write_data_t* __bt_find_exec_write_req(int conn_id)
2079 bt_gatt_prep_write_data_t *prep_data = NULL;
2081 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2082 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2083 if (prep_data && (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE)
2084 && (prep_data->connection_id == conn_id)) {
2085 BT_INFO("Exec request found");
2089 BT_INFO("Exec request not found");
2093 static int __bt_get_prep_request_count(int conn_id)
2097 bt_gatt_prep_write_data_t *prep_data = NULL;
2099 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2100 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2101 if (prep_data && (prep_data->connection_id == conn_id) &&
2102 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE))
2108 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_handle(int conn_id, int handle)
2111 bt_gatt_prep_write_data_t *prep_data = NULL;
2112 bt_gatt_prep_write_data_t *last_prep_data = NULL;
2114 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2115 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2116 if (prep_data && (prep_data->connection_id == conn_id) && (prep_data->handle == handle)) {
2117 BT_INFO("prep_data entry found for handle [%d]", handle);
2118 last_prep_data = prep_data;
2122 if (!last_prep_data)
2123 BT_INFO("prep_data entry not found for handle [%d]", handle);
2125 return last_prep_data;
2128 static void __bt_gatt_server_send_prep_write_req(int conn_id)
2130 int result = BLUETOOTH_ERROR_NONE;
2132 bt_gatt_prep_write_data_t *prep_data = NULL;
2134 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
2135 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2136 if (prep_data && (prep_data->connection_id == conn_id) &&
2137 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
2138 BT_INFO("sending prep_req, req_id=%d", prep_data->request_id);
2139 GVariant *data = NULL;
2140 GVariant *param = NULL;
2141 data = g_variant_new_from_data(
2142 G_VARIANT_TYPE_BYTESTRING,
2147 param = g_variant_new("(iiiiiibbsn@ay)", result,
2148 prep_data->connection_id,
2149 prep_data->request_id,
2155 prep_data->device_address,
2159 _bt_send_event(BT_GATT_SERVER_EVENT,
2160 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2166 static void __bt_remove_all_prep_write_req(int conn_id)
2169 bt_gatt_prep_write_data_t *prep_data = NULL;
2171 BT_INFO("Removing all req for conn_id %d", conn_id);
2172 for (l = g_pending_write_list; l != NULL;) {
2173 prep_data = (bt_gatt_prep_write_data_t*)l->data;
2174 l = g_slist_next(l);
2175 if (prep_data && (prep_data->connection_id == conn_id)) {
2176 BT_INFO("Removing req for req_id %d", prep_data->request_id);
2177 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
2178 g_free(prep_data->value);
2179 g_free(prep_data->device_address);
2186 static bool __bt_update_prep_write_data(bt_gatt_prep_write_data_t *prep_data, int offset,
2187 int length, char *value)
2195 len = prep_data->length + length;
2196 val = g_realloc(prep_data->value, len);
2200 memcpy(val + prep_data->length, value, length);
2201 prep_data->value = val;
2202 prep_data->length = len;
2204 BT_INFO("updated prep_data->length %d, prep_data->req_id %d", prep_data->length, prep_data->request_id);
2208 static bool __bt_handle_gatt_server_prepare_write_response(int *res,
2209 bluetooth_gatt_server_response_params_t *param)
2211 bt_gatt_prep_write_data_t *prep_data = NULL;
2212 bt_gatt_prep_write_data_t *exec_data = NULL;
2214 int ret = OAL_STATUS_SUCCESS;
2216 /* Search for matching Request in prepare write List */
2217 prep_data = __bt_find_prep_write_data_from_request_id(param->request_id);
2222 conn_id = prep_data->connection_id;
2223 exec_data = __bt_find_exec_write_req(conn_id);
2226 BT_ERR("Oops, Something weird has happened!!!");
2227 *res = BLUETOOTH_ERROR_INTERNAL;
2228 __bt_remove_all_prep_write_req(conn_id);
2230 // remove pending write request from the list
2231 BT_INFO("Removing prending write request, request id = %d", prep_data->request_id);
2232 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
2233 g_free(prep_data->value);
2234 g_free(prep_data->device_address);
2237 exec_data->prep_request_count--;
2238 if (param->response_status || !exec_data->prep_request_count) {
2239 BT_INFO("Sending exec response with status = %d", param->response_status);
2240 ret = __bt_gatt_server_send_long_write_response(exec_data, param->response_status, param->auth_req);
2241 if (ret != OAL_STATUS_SUCCESS) {
2242 BT_ERR("ret: %d", ret);
2243 *res = BLUETOOTH_ERROR_INTERNAL;
2245 __bt_remove_all_prep_write_req(conn_id);
2251 static void __bt_handle_gatt_server_prepare_write_requested(event_gatts_srvc_write_attr_t *event)
2253 bt_gatt_prep_write_data_t *pdata = NULL;
2254 bt_gatt_prep_write_data_t *prep_data = NULL;
2256 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2258 prep_data = __bt_create_prep_write_data(event);
2260 /* Find if the req node for that attribute already exists */
2261 pdata = __bt_find_prep_write_data_from_handle(prep_data->connection_id, prep_data->handle);
2263 if (!pdata || (prep_data->offset != (pdata->length + pdata->offset))) {
2264 BT_INFO("prep_write_req node doestn't exist or data is not in continuation, offset=%d", prep_data->offset);
2266 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)pdata);
2267 BT_INFO("Send prep_write_response");
2268 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
2270 /* Update the data and offset in attribute node */
2271 if (!(__bt_update_prep_write_data(pdata, prep_data->offset, prep_data->length, prep_data->value))) {
2272 BT_ERR("prep_data couldnot be updated");
2273 resp_status = BLUETOOTH_ATT_ERROR_INSUFFICIENT_RESOURCES;
2275 BT_INFO("Send prep_write_response");
2276 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
2277 g_free(prep_data->device_address);
2278 g_free(prep_data->value);
2282 if (ret != OAL_STATUS_SUCCESS)
2283 BT_ERR("ret: %d", ret);
2287 static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
2290 bluetooth_device_address_t dev_addr;
2291 GVariant *param = NULL;
2292 int result = BLUETOOTH_ERROR_NONE;
2294 gboolean is_prepare_write;
2295 char *write_val = NULL;
2296 GVariant *data = NULL;
2298 struct gatt_server_req_info *req_info = NULL;
2299 BT_INFO("GATT Server Write Requested");
2301 memcpy(dev_addr.addr, event->address.addr, 6);
2303 BT_INFO("GATT Server Write Req Connection ID: [%d]", event->attr_trans.conn_id);
2304 BT_INFO("GATT Server Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
2305 BT_INFO("GATT Server Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
2306 BT_INFO("GATT Server Write Req Attribute Offset: [%d]", event->attr_trans.offset);
2307 BT_INFO("GATT Server Write Req value length [%d]", event->length);
2308 BT_INFO("GATT Server Write Req needs response: [%d]", event->need_rsp);
2309 BT_INFO("GATT Server Write Req Is Prep: [%d]", event->is_prep);
2311 #ifdef TIZEN_BLUEDROID_PORTING
2312 if (event->is_prep) {
2313 BT_INFO("receive prepare_write request");
2314 return __bt_handle_gatt_server_prepare_write_requested(event);
2318 need_resp = event->need_rsp;
2319 is_prepare_write = event->is_prep;
2321 if (event->length > 0)
2322 write_val = g_memdup2(&event->value[0], event->length);
2324 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2325 _bt_convert_addr_type_to_string(address,
2326 (unsigned char *)dev_addr.addr);
2328 BT_INFO("GATT Server Write Request from remote client [%s]", address);
2330 if (event->length > 0) {
2331 for (i = 0; i < event->length; i++)
2332 BT_DBG("Data[%d] = [0x%x]", i, event->value[i]);
2334 /* Save Write Request Info */
2335 req_info = g_new0(struct gatt_server_req_info, 1);
2336 req_info->request_id = event->attr_trans.trans_id;
2337 req_info->attribute_handle = event->attr_trans.attr_handle;
2338 req_info->connection_id = event->attr_trans.conn_id;
2339 req_info->addr = address;
2340 req_info->offset = event->attr_trans.offset;
2341 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2342 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2344 data = g_variant_new_from_data(
2345 G_VARIANT_TYPE_BYTESTRING,
2350 param = g_variant_new("(iiiiiibbsn@ay)", result,
2351 event->attr_trans.conn_id,
2352 event->attr_trans.trans_id,
2353 event->attr_trans.attr_handle,
2354 event->attr_trans.offset,
2362 _bt_send_event(BT_GATT_SERVER_EVENT,
2363 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2369 #ifdef TIZEN_BLUEDROID_PORTING
2370 static void __bt_handle_gatt_server_exec_write_requested(event_gatts_srvc_exec_write_attr_t *event)
2373 bluetooth_device_address_t dev_addr;
2375 bt_gatt_prep_write_data_t *exec_data = NULL;
2376 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2377 BT_INFO("GATT Server Execute Write Requested");
2379 memcpy(dev_addr.addr, event->address.addr, 6);
2380 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2381 _bt_convert_addr_type_to_string(address,
2382 (unsigned char *)dev_addr.addr);
2384 BT_INFO("GATT Server Exec Write Req Connection ID: [%d]", event->conn_id);
2385 BT_INFO("GATT Server Exec Write Req Transaction ID:[%d]", event->trans_id);
2386 BT_INFO("GATT Server Exec Write Req Exec Write: [%d]", event->exec_write);
2388 // prepare exec response data
2389 exec_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2390 exec_data->connection_id = event->conn_id;
2391 exec_data->request_id = event->trans_id;
2392 exec_data->device_address = address;
2393 exec_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE;
2394 exec_data->prep_request_count = __bt_get_prep_request_count(exec_data->connection_id);
2396 if ((exec_data->prep_request_count != 1) || !event->exec_write) {
2397 if (!event->exec_write) {
2398 BT_INFO("Cancelling all prepared writes, removing all pending entries");
2399 __bt_remove_all_prep_write_req(event->conn_id);
2400 } else if (exec_data->prep_request_count > 1) {
2401 /* TODO: Handle reliable-write session */
2402 BT_INFO("This may be reliable write session. Not yet supported!!!, prep_request_count =%d",
2403 exec_data->prep_request_count);
2404 resp_status = BLUETOOTH_ATT_ERROR_REQUEST_NOT_SUPPORTED;
2405 __bt_remove_all_prep_write_req(event->conn_id);
2408 BT_INFO("Send exec response");
2409 // Made response and send it.
2410 ret = __bt_gatt_server_send_long_write_response(exec_data, resp_status, 0);
2411 if (ret != OAL_STATUS_SUCCESS)
2412 BT_ERR("ret: %d", ret);
2414 g_free(exec_data->device_address);
2419 BT_INFO("Write all pending prepared values");
2420 __bt_gatt_server_send_prep_write_req(exec_data->connection_id);
2422 // Add exec request in the queue.
2423 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)exec_data);
2427 static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t *event)
2429 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2430 bluetooth_device_address_t dev_addr;
2431 int result = BLUETOOTH_ERROR_NONE;
2432 struct gatt_server_req_info *req_info = NULL;
2433 GVariant *param = NULL;
2436 memcpy(dev_addr.addr, event->address.addr, 6);
2437 _bt_convert_addr_type_to_string(address,
2438 (unsigned char *)dev_addr.addr);
2440 BT_DBG("conn_id %d, trans id %d, attr handle %d, offset %d, is_long %d, addr %s",
2441 event->attr_trans.conn_id, event->attr_trans.trans_id,
2442 event->attr_trans.attr_handle, event->attr_trans.offset,
2443 event->is_long, address);
2445 is_long = event->is_long;
2447 /* Save Read Request Info */
2448 req_info = g_new0(struct gatt_server_req_info, 1);
2449 req_info->request_id = event->attr_trans.trans_id;
2450 req_info->attribute_handle = event->attr_trans.attr_handle;
2451 req_info->connection_id = event->attr_trans.conn_id;
2452 req_info->addr = address;
2453 req_info->offset = event->attr_trans.offset;
2454 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_READ;
2455 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2457 /* Send event to BT-API */
2458 param = g_variant_new("(iiiiibs)", result,
2459 event->attr_trans.conn_id,
2460 event->attr_trans.trans_id,
2461 event->attr_trans.attr_handle,
2462 event->attr_trans.offset,
2466 _bt_send_event(BT_GATT_SERVER_EVENT,
2467 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
2471 static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
2473 bluetooth_device_address_t dev_addr;
2474 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2475 int cur_connected_clients;
2476 static int recvd = 0;
2477 gboolean completed = 0;
2478 GVariant *param = NULL;
2480 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2481 incase of any issues, check with OAL */
2482 int result = BLUETOOTH_ERROR_NONE;
2484 memcpy(dev_addr.addr, event->address.addr, 6);
2485 _bt_convert_addr_type_to_string(address,
2486 (unsigned char *)dev_addr.addr);
2488 BT_INFO("Indication sent to GATT client [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d]",
2489 address, event->conn_id, event->trans_id, event->attr_handle);
2492 cur_connected_clients = g_slist_length(gatt_client_info_list);
2493 BT_INFO("Number of connected clients during sending Indication [%d] & current connected count [%d]",
2494 num_indicate_clients, cur_connected_clients);
2497 if (recvd == num_indicate_clients) {
2498 BT_INFO("Gatt indication confirm event for last GATT client.. [%s]", address);
2499 completed = 1; /* Last event */
2500 recvd = 0; /* Reset */
2501 num_indicate_clients = 0;
2504 param = g_variant_new("(isib)",
2510 /* Send event to BT-API */
2511 _bt_send_event(BT_GATT_SERVER_EVENT,
2512 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
2515 BT_INFO("Received Indication confirm for client number [%d]", recvd);
2519 /* Tizen Platform Specific */
2520 static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *event)
2522 bluetooth_device_address_t dev_addr;
2523 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2524 GVariant *param = NULL;
2527 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2528 incase of any issues, check with OAL */
2529 int result = BLUETOOTH_ERROR_NONE;
2531 memcpy(dev_addr.addr, event->address.addr, 6);
2532 _bt_convert_addr_type_to_string(address,
2533 (unsigned char *)dev_addr.addr);
2535 BT_INFO("notification_changed [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d] Notify[%d]",
2536 address, event->conn_id, event->trans_id, event->attr_handle, event->notify);
2538 /* Set Notifcation status */
2539 notify = event->notify;
2541 param = g_variant_new("(isib)",
2547 /* Send event to BT-API */
2548 _bt_send_event(BT_GATT_SERVER_EVENT,
2549 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
2555 static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
2557 int result = BLUETOOTH_ERROR_NONE;
2558 struct gatt_client_info_t *conn_info = NULL;
2559 GVariant *param = NULL;
2562 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2563 if (conn_info == NULL) {
2564 BT_ERR("Cant find connection Information");
2567 BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
2568 conn_info->addr, event->mtu_size);
2570 __bt_update_mtu_gatt_device(conn_info->addr, event->mtu_size);
2572 param = g_variant_new("(isqy)",
2578 /* Send event to BT-API */
2579 _bt_send_event(BT_GATT_SERVER_EVENT,
2580 BLUETOOTH_EVENT_GATT_SERVER_ATT_MTU_CHANGED,
2584 static void __bt_handle_gatt_phy_updated_event(event_gatts_phy_updated_t *event)
2586 int result = BLUETOOTH_ERROR_NONE;
2587 struct gatt_client_info_t *conn_info = NULL;
2588 GVariant *param = NULL;
2590 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2591 if (conn_info == NULL) {
2592 BT_ERR("Can't find connection Information");
2596 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2597 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2599 param = g_variant_new("(isiii)",
2606 /* Send event to BT-API */
2607 _bt_send_event(BT_GATT_SERVER_EVENT,
2608 BLUETOOTH_EVENT_GATT_SERVER_PHY_UPDATED,
2612 static void __bt_handle_gatt_phy_read_event(event_gatts_phy_read_t *event)
2614 int result = BLUETOOTH_ERROR_NONE;
2615 struct gatt_client_info_t *conn_info = NULL;
2616 GVariant *param = NULL;
2618 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2619 if (conn_info == NULL) {
2620 BT_ERR("Cant find connection Information");
2624 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2625 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2627 param = g_variant_new("(isiii)",
2634 /* Send event to BT-API */
2635 _bt_send_event(BT_GATT_SERVER_EVENT,
2636 BLUETOOTH_EVENT_GATT_SERVER_PHY_READ,
2640 static void __bt_handle_gatt_client_phy_updated_event(event_gattc_phy_updated_t *event)
2642 int result = BLUETOOTH_ERROR_NONE;
2643 struct gatt_server_info_t *conn_info = NULL;
2644 GVariant *param = NULL;
2646 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event->conn_id);
2647 if (conn_info == NULL) {
2648 BT_ERR("Cant find connection Information");
2652 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2653 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2655 param = g_variant_new("(isiii)",
2662 /* Send event to BT-API */
2663 _bt_send_event(BT_GATT_CLIENT_EVENT,
2664 BLUETOOTH_EVENT_GATT_CLIENT_PHY_UPDATED,
2668 static void __bt_handle_gatt_client_phy_read_event(event_gattc_phy_read_t *event)
2670 int result = BLUETOOTH_ERROR_NONE;
2671 struct gatt_server_info_t *conn_info = NULL;
2672 GVariant *param = NULL;
2674 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event->conn_id);
2675 if (conn_info == NULL) {
2676 BT_ERR("Cant find connection Information");
2680 BT_INFO("Got connection Info GATT client:[%s] TX_PHY:[%d], RX_PHY:[%d], Status:[%d]",
2681 conn_info->addr, event->tx_phy, event->rx_phy, event->status);
2683 param = g_variant_new("(isiii)",
2690 /* Send event to BT-API */
2691 _bt_send_event(BT_GATT_CLIENT_EVENT,
2692 BLUETOOTH_EVENT_GATT_CLIENT_PHY_READ,
2696 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
2698 switch (event_type) {
2699 case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
2700 BT_INFO("OAL Event: Server Instance Registered");
2701 /* GATT Server Registered event is handled in MAIN thread context */
2702 __bt_handle_server_instance_registered((event_gatts_register_t *)event_data);
2705 case OAL_EVENT_GATTS_SERVICE_ADDED: {
2706 BT_INFO("OAL Event: GATT Service added");
2707 __bt_handle_gatt_server_service_added((event_gatts_srvc_prm_t *)event_data);
2710 case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
2711 BT_INFO("OAL Event: GATT characteristic added");
2712 __bt_handle_gatt_server_characteristic_added((event_gatts_srvc_charctr_t *)event_data);
2715 case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
2716 BT_INFO("OAL Event: GATT descriptor added");
2717 __bt_handle_gatt_server_descriptor_added((event_gatts_srvc_descr_t *)event_data);
2720 case OAL_EVENT_GATTS_SERVICE_STARTED: {
2721 BT_INFO("OAL Event: GATT Service started");
2722 __bt_handle_gatt_server_service_started((event_gatts_srvc_t *)event_data);
2725 case OAL_EVENT_GATTS_SERVICE_STOPED: {
2726 BT_INFO("OAL Event: GATT Service stopped");
2727 __bt_handle_gatt_server_service_stopped((event_gatts_srvc_t *)event_data);
2730 case OAL_EVENT_GATTS_SERVICE_DELETED: {
2731 BT_INFO("OAL Event: GATT Service deleted");
2732 __bt_handle_gatt_server_service_deleted((event_gatts_srvc_t *) event_data);
2735 case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
2736 BT_INFO("OAL Event: GATT Server Connected");
2737 __bt_handle_gatt_server_connection_state((event_gatts_conn_t *)event_data);
2740 case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
2741 BT_INFO("OAL Event: GATT Server Disconnected");
2742 __bt_handle_gatt_server_disconnection_state((event_gatts_conn_t *)event_data);
2745 case OAL_EVENT_GATTS_REQUEST_READ: {
2746 BT_DBG("OAL Event: GATT Server Read Request");
2747 __bt_handle_gatt_server_read_requested((event_gatts_srvc_read_attr_t *)event_data);
2750 case OAL_EVENT_GATTS_REQUEST_WRITE: {
2751 BT_DBG("OAL Event: GATT Server Write Request");
2752 __bt_handle_gatt_server_write_requested((event_gatts_srvc_write_attr_t *)event_data);
2755 #ifdef TIZEN_BLUEDROID_PORTING
2756 case OAL_EVENT_GATTS_EXEC_REQUEST_WRITE: {
2757 BT_INFO("OAL Event: GATT Server Exec Write Request");
2758 __bt_handle_gatt_server_exec_write_requested((event_gatts_srvc_exec_write_attr_t *)event_data);
2762 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE: {
2763 BT_INFO("OAL Event: GATT Server Acquire Write Request");
2764 __bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2767 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
2768 BT_INFO("OAL Event: GATT ServerAcquire Notify Request");
2769 __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2772 case OAL_EVENT_GATTS_IND_CONFIRM: {
2773 BT_INFO("OAL Event: GATT Server Indication confirmed");
2774 __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
2777 case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
2778 BT_INFO("OAL Event: GATT Server DisConnected");
2779 __bt_handle_gatt_server_notification_changed((event_gatts_notif_t *)event_data);
2782 case OAL_EVENT_GATTS_MTU_CHANGED: {
2783 BT_INFO("OAL Event: GATT Server MTU changed event callback");
2784 __bt_handle_gatt_mtu_changed_event((event_gatts_mtu_changed_t *)event_data);
2787 case OAL_EVENT_GATTS_PHY_UPDATED: {
2788 BT_INFO("OAL Event: GATT Server PHY Updated event callback");
2789 __bt_handle_gatt_phy_updated_event((event_gatts_phy_updated_t *)event_data);
2792 case OAL_EVENT_GATTS_PHY_READ: {
2793 BT_INFO("OAL Event: GATT Server PHY Read event callback");
2794 __bt_handle_gatt_phy_read_event((event_gatts_phy_read_t *)event_data);
2797 case OAL_EVENT_GATTC_PHY_UPDATED: {
2798 BT_INFO("OAL Event: GATT Client PHY Updated event callback");
2799 __bt_handle_gatt_client_phy_updated_event((event_gattc_phy_updated_t *)event_data);
2802 case OAL_EVENT_GATTC_PHY_READ: {
2803 BT_INFO("OAL Event: GATT Client PHY Read event callback");
2804 __bt_handle_gatt_client_phy_read_event((event_gattc_phy_read_t *)event_data);
2807 case OAL_EVENT_GATTC_REGISTRATION: {
2808 BT_INFO("OAL Event: GATT Client instance Registered");
2809 __bt_handle_client_instance_registered((event_gattc_register_t *) event_data);
2812 case OAL_EVENT_GATTC_CONNECTION_COMPLETED: {
2813 BT_INFO("OAL Event: GATT Client Connected");
2814 __bt_handle_client_connected((event_gattc_conn_t *) event_data);
2817 case OAL_EVENT_GATTC_DISCONNECTION_COMPLETED: {
2818 BT_INFO("OAL Event: GATT Client DisConnected");
2819 __bt_handle_client_disconnected((event_gattc_conn_t *) event_data);
2822 case OAL_EVENT_GATTC_SERVICE_SEARCH_RESULT: {
2823 BT_DBG("OAL Event: GATT Client Service Search Result");
2824 __bt_handle_client_service_search_result((event_gattc_service_result_t *) event_data);
2827 case OAL_EVENT_GATTC_SERVICE_SEARCH_DONE: {
2828 BT_INFO("OAL Event: GATT Client Service Completed");
2829 __bt_handle_client_service_search_completed((event_gattc_conn_status_t *) event_data);
2832 case OAL_EVENT_GATTC_CHARAC_SERACH_RESULT: {
2833 BT_DBG("OAL Event: GATT Client Characteristic Search Result");
2834 __bt_handle_client_characteristic_search_result((event_gattc_characteristic_result_t *) event_data);
2837 case OAL_EVENT_GATTC_DESC_SERACH_RESULT: {
2838 BT_DBG("OAL Event: GATT Client Descriptor Search Result");
2839 __bt_handle_client_descriptor_search_result((event_gattc_descriptor_result_t *) event_data);
2842 case OAL_EVENT_GATTC_READ_CHARAC: {
2843 BT_DBG("OAL Event: GATT Client Characteristic Read Data");
2844 __bt_handle_client_characteristic_read_data((event_gattc_read_data *) event_data);
2847 case OAL_EVENT_GATTC_READ_DESCR: {
2848 BT_DBG("OAL Event: GATT Client Descriptor Read Data");
2849 __bt_handle_client_descriptor_read_data((event_gattc_read_data *) event_data);
2852 case OAL_EVENT_GATTC_WRITE_CHARAC: {
2853 BT_DBG("OAL Event: GATT Client Characteristic Write Data");
2854 __bt_handle_client_characteristic_write_data((event_gattc_write_data *) event_data);
2857 case OAL_EVENT_GATTC_WRITE_DESCR: {
2858 BT_DBG("OAL Event: GATT Client Descriptor Write Data");
2859 __bt_handle_client_descriptor_write_data((event_gattc_write_data *) event_data);
2862 case OAL_EVENT_DEVICE_LE_DISCONNECTED: {
2863 BT_INFO("OAL Event: LE device disconnected");
2864 __bt_hanlde_le_device_disconnection((event_dev_conn_status_t *)event_data);
2867 case OAL_EVENT_GATTC_NOTIFICATION_REGISTERED: {
2868 BT_INFO("OAL Event: GATT Client Notification Registered");
2869 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, TRUE);
2872 case OAL_EVENT_GATTC_NOTIFICATION_DEREGISTERED: {
2873 BT_INFO("OAL Event: GATT Client Notification Registered");
2874 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, FALSE);
2877 case OAL_EVENT_GATTC_NOTIFY_DATA: {
2878 BT_DBG("OAL Event: GATT Client Notification Data");
2879 __bt_handle_client_notification_data((event_gattc_notify_data *) event_data);
2882 case OAL_EVENT_GATTC_SERVICE_CHANGED_IND: {
2883 BT_INFO("OAL Event: GATT Client service changed indication");
2884 __bt_handle_client_service_changed_ind((event_gattc_service_changed_data *)event_data);
2887 case OAL_EVENT_GATTC_MTU_EXCHANGE_COMPLETED: {
2888 BT_INFO("OAL Event: GATT Client MTU Exchange Complete");
2889 __bt_handle_client_mtu_exchange_completed((event_gattc_mtu_configured_t *) event_data);
2893 BT_DBG("Unhandled OAL event = 0x%x", event_type);
2898 int _bt_gatt_server_add_service(char *sender, int service_type,
2899 int num_handles, char *svc_uuid, int instance_id)
2901 BT_CHECK_PARAMETER(svc_uuid, return);
2902 BT_CHECK_PARAMETER(sender, return);
2903 int ret = OAL_STATUS_SUCCESS;
2905 oal_gatt_srvc_id_t svc_data;
2907 svc_data.is_prmry = service_type;
2908 svc_data.id.inst_id = instance_id;
2910 /* Check Service UUID duplication */
2911 if (__bt_check_service_uuid_registered(svc_uuid))
2912 return BLUETOOTH_ERROR_INTERNAL;
2914 BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id);
2915 _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid);
2917 ret = gatts_add_service(instance_id, &svc_data, num_handles);
2918 if (ret != OAL_STATUS_SUCCESS) {
2919 BT_ERR("ret: %d", ret);
2920 return _bt_convert_oal_status_to_bt_error(ret);
2923 return BLUETOOTH_ERROR_NONE;
2927 int _bt_gatt_server_add_included_service(char *sender, int instance_id,
2928 int service_handle, int included_svc_handle)
2930 BT_CHECK_PARAMETER(sender, return);
2931 int ret = OAL_STATUS_SUCCESS;
2933 ret = gatts_add_included_services(instance_id, service_handle, included_svc_handle);
2934 if (ret != OAL_STATUS_SUCCESS) {
2935 BT_ERR("ret: %d", ret);
2936 return _bt_convert_oal_status_to_bt_error(ret);
2938 return BLUETOOTH_ERROR_NONE;
2941 int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
2942 bluetooth_gatt_server_attribute_params_t *param)
2944 BT_CHECK_PARAMETER(char_uuid, return);
2945 BT_CHECK_PARAMETER(sender, return);
2946 BT_CHECK_PARAMETER(param, return);
2947 int ret = OAL_STATUS_SUCCESS;
2949 oal_uuid_t uuid = {{0} };
2951 BT_INFO("Char UUID [%s] Instance ID [%d]", char_uuid, param->instance_id);
2952 _bt_string_to_uuid(char_uuid, (service_uuid_t*)&uuid);
2954 BT_INFO("Char permission From API [0x%x]", param->permissions);
2956 ret = gatts_add_characteristics(param->instance_id, param->service_handle, &uuid,
2957 param->properties, (int)param->permissions);
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_descriptor(char *sender, char *desc_uuid,
2966 bt_gatt_permission_t *param, int service_handle, int instance_id)
2968 BT_CHECK_PARAMETER(desc_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("Descriptor UUID [%s] Instance ID [%d] Service handle [%d]",
2976 desc_uuid, service_handle, instance_id);
2978 _bt_string_to_uuid(desc_uuid, (service_uuid_t*)&uuid);
2980 BT_INFO("Descriptor permission From API [0x%x]", *param);
2981 ret = gatts_add_descriptor(instance_id, service_handle, &uuid, (int)*param);
2983 if (ret != OAL_STATUS_SUCCESS) {
2984 BT_ERR("ret: %d", ret);
2985 return _bt_convert_oal_status_to_bt_error(ret);
2987 return BLUETOOTH_ERROR_NONE;
2990 int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id)
2992 BT_CHECK_PARAMETER(sender, return);
2993 int ret = OAL_STATUS_SUCCESS;
2995 ret = gatts_start_service(instance_id, service_handle, BT_GATT_TRANSPORT_LE);
2996 if (ret != OAL_STATUS_SUCCESS) {
2997 BT_ERR("ret: %d", ret);
2998 return _bt_convert_oal_status_to_bt_error(ret);
3000 return BLUETOOTH_ERROR_NONE;
3003 int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id)
3005 BT_CHECK_PARAMETER(sender, return);
3006 int ret = OAL_STATUS_SUCCESS;
3008 ret = gatts_stop_service(instance_id, service_handle);
3009 if (ret != OAL_STATUS_SUCCESS) {
3010 BT_ERR("ret: %d", ret);
3011 return _bt_convert_oal_status_to_bt_error(ret);
3013 return BLUETOOTH_ERROR_NONE;
3016 int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id)
3018 BT_CHECK_PARAMETER(sender, return);
3019 int ret = OAL_STATUS_SUCCESS;
3023 bt_service_app_info_t *info = NULL;
3025 if (__bt_gatt_server_is_service_persistence(service_handle))
3026 return BLUETOOTH_ERROR_INTERNAL;
3028 ret = gatts_delete_service(instance_id, service_handle);
3029 if (ret != OAL_STATUS_SUCCESS) {
3030 BT_ERR("ret: %d", ret);
3031 return _bt_convert_oal_status_to_bt_error(ret);
3034 /* Remove the Service Handle */
3035 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3037 if (info->instance_id == instance_id) {
3038 for (l = info->service_handles; l != NULL; ) {
3040 l = g_slist_next(l);
3041 if (handle && *handle == service_handle) {
3042 BT_INFO("Remove Service handle [%d]", *handle);
3043 info->service_handles = g_slist_remove(info->service_handles, handle);
3044 /* Remove Service UUID from the list */
3045 __bt_remove_service_uuid(*handle);
3054 return BLUETOOTH_ERROR_NONE;
3057 int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
3058 bluetooth_gatt_server_response_params_t *param)
3060 BT_CHECK_PARAMETER(sender, return);
3061 BT_CHECK_PARAMETER(data, return);
3062 BT_CHECK_PARAMETER(param, return);
3063 struct gatt_server_req_info *req_info = NULL;
3064 int ret = OAL_STATUS_SUCCESS;
3065 #ifdef TIZEN_BLUEDROID_PORTING
3066 int res = BLUETOOTH_ERROR_NONE;
3068 oal_gatt_response_t response;
3070 BT_INFO("GATT Server Response: Req Type [%d] req_id [%d] status [%d] auth_req [%d] offset[%d] data len[%d]",
3071 param->req_type, param->request_id,
3072 param->response_status, param->auth_req,
3073 data->offset, data->length);
3075 #ifdef TIZEN_BLUEDROID_PORTING
3076 if (__bt_handle_gatt_server_prepare_write_response(&res, param))
3080 /* Search for matching Request in List */
3081 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
3083 BT_ERR("GATT Server Req Info not found for current response..return Error");
3084 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
3087 memset(&response, 0x00, sizeof(oal_gatt_response_t));
3089 response.handle = req_info->attribute_handle;
3090 response.attr_value.auth_req = param->auth_req;
3091 response.attr_value.handle = req_info->attribute_handle;
3092 response.attr_value.offset = data->offset;
3093 response.attr_value.len = data->length;
3094 memcpy(&response.attr_value.value, &data->data, data->length);
3097 ret = gatts_send_response(req_info->connection_id, param->request_id,
3098 param->response_status, &response);
3100 if (ret != OAL_STATUS_SUCCESS) {
3101 BT_ERR("ret: %d", ret);
3102 return _bt_convert_oal_status_to_bt_error(ret);
3105 /* Remove GATT server request from list */
3106 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
3107 g_free(req_info->addr);
3109 return BLUETOOTH_ERROR_NONE;
3112 int _bt_gatt_server_acquire_send_response(char *sender, bluetooth_gatt_server_acquire_response_params_t *param , void *fd_list)
3114 BT_CHECK_PARAMETER(sender, return);
3115 BT_CHECK_PARAMETER(param, return);
3116 struct gatt_server_req_info *req_info = NULL;
3117 int ret = OAL_STATUS_SUCCESS;
3120 BT_INFO("GATT acquire Server Response: Req Type [%d] req_id [%d] fd [%d] mtu[%d]",
3121 param->req_type, param->request_id,
3125 /* Search for matching Request in List */
3126 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
3128 BT_ERR("GATT acquire Server Req Info not found for current response..return Error");
3129 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
3132 ret = gatt_send_response_acquire(req_info->connection_id, param->request_id, 0, param->fd, param->mtu, fd_list);
3134 if (ret != OAL_STATUS_SUCCESS) {
3135 BT_ERR("ret: %d", ret);
3136 return _bt_convert_oal_status_to_bt_error(ret);
3139 /* Remove GATT server request from list */
3140 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
3141 g_free(req_info->addr);
3143 return BLUETOOTH_ERROR_NONE;
3148 int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
3149 bluetooth_gatt_att_data_t *data,
3150 bluetooth_gatt_server_indication_params_t *param)
3152 BT_CHECK_PARAMETER(sender, return);
3153 BT_CHECK_PARAMETER(data, return);
3154 BT_CHECK_PARAMETER(param, return);
3156 gboolean all_send = FALSE;
3157 int ret = OAL_STATUS_SUCCESS;
3158 struct gatt_client_info_t *conn;
3160 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3161 _bt_convert_addr_type_to_string(address, dev_addr->addr);
3163 if (memcmp(dev_addr->addr, BDADDR_ANY, 6) == 0) {
3164 BT_INFO("GATT Server: Send Indication to all connected GATT clients..");
3167 BT_INFO("GATT Server: Send Indication to connected GATT client addr [%s]", address);
3170 /* Attempt to send Notification/Indication to all Connected GATT clients */
3172 ret = __bt_gatt_send_indication_to_all_connected_clients(data, param);
3173 if (ret != OAL_STATUS_SUCCESS) {
3174 BT_ERR("ret: %d", ret);
3176 return _bt_convert_oal_status_to_bt_error(ret);
3180 #ifdef TIZEN_BLUEDROID_PORTING
3181 conn = _bt_find_remote_gatt_client_info_with_inst_id(address, param->instance_id);
3183 conn = _bt_find_remote_gatt_client_info(address);
3186 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
3187 conn->connection_id, data->length,
3188 param->need_confirmation, (char *)(&data->data[0]));
3190 if (ret != OAL_STATUS_SUCCESS) {
3191 BT_ERR("ret: %d", ret);
3192 BT_INFO("Indication failed to send to Remote GATT Client [%s]", address);
3194 return _bt_convert_oal_status_to_bt_error(ret);
3196 BT_INFO("Indication sent to Remote GATT Client [%s] wait for Notification completed event from OAL", address);
3198 num_indicate_clients = 1;
3199 return BLUETOOTH_ERROR_NONE;
3201 BT_ERR("Remote GATT client [%s] is not connected..Cant send Indication!!", address);
3203 return BLUETOOTH_ERROR_NOT_CONNECTED;
3206 return BLUETOOTH_ERROR_NONE;
3209 int _bt_gatt_server_update_attribute_value(char *sender, int instance_id,
3210 bluetooth_gatt_server_update_value_t *param)
3212 BT_CHECK_PARAMETER(sender, return);
3213 BT_CHECK_PARAMETER(param, return);
3214 int ret = OAL_STATUS_SUCCESS;
3216 oal_gatt_value_t value;
3217 BT_DBG("GATT Server Update value: Instance ID [%d] attr handle [%d] Value len [%d]",
3218 instance_id, param->attribute_handle, param->length);
3220 memset(&value, 0x00, sizeof(oal_gatt_value_t));
3222 value.handle = param->attribute_handle;
3223 value.len = param->length;
3224 memcpy(&value.value, ¶m->data.data, param->length);
3226 ret = gatts_update_att_value(instance_id, &value);
3228 if (ret != OAL_STATUS_SUCCESS) {
3229 BT_ERR("ret: %d", ret);
3230 return _bt_convert_oal_status_to_bt_error(ret);
3233 return BLUETOOTH_ERROR_NONE;
3236 int _bt_gatt_server_set_phy(bluetooth_device_address_t *device_address,
3237 int tx_phy, int rx_phy, int phy_options)
3239 struct gatt_client_info_t *conn_info = NULL;
3241 //int ret = OAL_STATUS_SUCCESS;
3243 BT_INFO("Setting Preferred PHY");
3244 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3245 _bt_convert_addr_type_to_string(addr, device_address->addr);
3247 /* Check if remote GATT Client is connected or not */
3248 conn_info = _bt_find_remote_gatt_client_info(addr);
3249 if (conn_info == NULL) {
3250 BT_ERR("GATT Client is not yet connected...");
3252 return BLUETOOTH_ERROR_NOT_CONNECTED;
3255 /* TODO: This code is commented as currently this API is not supported in OAL
3256 ret = gatts_set_preferred_phy(conn_info->connection_id, tx_phy, rx_phy, phy_options);
3257 if (ret != OAL_STATUS_SUCCESS) {
3258 BT_ERR("ret: %d", ret);
3260 return BLUETOOTH_ERROR_INTERNAL;
3264 return BLUETOOTH_ERROR_NONE;
3267 int _bt_gatt_server_read_phy(bluetooth_device_address_t *address)
3269 struct gatt_client_info_t *conn_info = NULL;
3270 //int ret = OAL_STATUS_SUCCESS;
3273 BT_CHECK_PARAMETER(address, return);
3275 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3276 _bt_convert_addr_type_to_string(addr, address->addr);
3278 BT_INFO("Read PHY for the server: address:[%s]", addr);
3280 /* Check if remote GATT client is connected or not */
3281 conn_info = _bt_find_remote_gatt_client_info(addr);
3282 if (conn_info == NULL) {
3283 BT_ERR("GATT Client is not yet connected..");
3285 return BLUETOOTH_ERROR_NOT_CONNECTED;
3288 /* TODO: This code is commented as currently this API is not supported in OAL
3289 ret = gatts_read_phy(conn_info->connection_id);
3290 if (ret != OAL_STATUS_SUCCESS) {
3291 BT_ERR("ret: %d", ret);
3293 return BLUETOOTH_ERROR_INTERNAL;
3297 return BLUETOOTH_ERROR_NONE;
3300 int _bt_gatt_client_set_phy(bluetooth_device_address_t *device_address,
3301 int tx_phy, int rx_phy, int phy_options)
3303 struct gatt_server_info_t *conn_info = NULL;
3305 //int ret = OAL_STATUS_SUCCESS;
3307 BT_INFO("Setting Preferred PHY");
3308 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3309 _bt_convert_addr_type_to_string(addr, device_address->addr);
3311 /* Check if remote GATT server is connected or not */
3312 conn_info = _bt_find_remote_gatt_server_info(addr);
3313 if (conn_info == NULL) {
3314 BT_ERR("GATT Server is not yet connected...");
3316 return BLUETOOTH_ERROR_NOT_CONNECTED;
3319 /* TODO: This code is commented as currently this API is not supported in OAL
3320 ret = gattc_set_preferred_phy(conn_info->connection_id, tx_phy, rx_phy, phy_options);
3321 if (ret != OAL_STATUS_SUCCESS) {
3322 BT_ERR("ret: %d", ret);
3324 return BLUETOOTH_ERROR_INTERNAL;
3328 return BLUETOOTH_ERROR_NONE;
3331 int _bt_gatt_client_read_phy(bluetooth_device_address_t *address)
3333 struct gatt_server_info_t *conn_info = NULL;
3334 //int ret = OAL_STATUS_SUCCESS;
3337 BT_CHECK_PARAMETER(address, return);
3339 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3340 _bt_convert_addr_type_to_string(addr, address->addr);
3342 BT_INFO("Read PHY for the server: address:[%s]", addr);
3344 /* Check if remote GATT server is connected or not */
3345 conn_info = _bt_find_remote_gatt_server_info(addr);
3346 if (conn_info == NULL) {
3347 BT_ERR("GATT Server is not yet connected..");
3349 return BLUETOOTH_ERROR_NOT_CONNECTED;
3352 /* TODO: This code is commented as currently this API is not supported in OAL
3353 ret = gattc_read_phy(conn_info->connection_id);
3354 if (ret != OAL_STATUS_SUCCESS) {
3355 BT_ERR("ret: %d", ret);
3357 return BLUETOOTH_ERROR_INTERNAL;
3361 return BLUETOOTH_ERROR_NONE;
3364 int _bt_request_att_mtu(bluetooth_device_address_t *device_address,
3367 struct gatt_server_info_t *conn_info = NULL;
3369 int ret = OAL_STATUS_SUCCESS;
3371 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
3372 _bt_convert_addr_type_to_string(addr, device_address->addr);
3374 /* Check if remote GATT Server is connected or not */
3375 conn_info = _bt_find_remote_gatt_server_info(addr);
3376 if (conn_info == NULL) {
3377 BT_ERR("GATT Server is not yet connected..");
3379 return BLUETOOTH_ERROR_NOT_CONNECTED;
3382 ret = gattc_configure_mtu(conn_info->connection_id, mtu);
3383 if (ret != OAL_STATUS_SUCCESS) {
3384 BT_ERR("ret: %d", ret);
3386 return _bt_convert_oal_status_to_bt_error(ret);
3390 return BLUETOOTH_ERROR_NONE;
3393 int _bt_get_att_mtu(bluetooth_device_address_t *address,
3396 BT_CHECK_PARAMETER(address, return);
3397 BT_CHECK_PARAMETER(mtu, return);
3398 struct gatt_client_info_t *client_info = NULL;
3399 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
3400 int ret = OAL_STATUS_SUCCESS;
3403 _bt_convert_addr_type_to_string(addr, address->addr);
3405 BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]", addr);
3407 client_info = _bt_find_remote_gatt_client_info(addr);
3409 BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
3410 client_info->addr, client_info->connection_id, client_info->instance_id);
3412 ret = gatts_get_att_mtu(client_info->connection_id, &stack_mtu);
3413 if (ret != OAL_STATUS_SUCCESS) {
3414 BT_ERR("ret: %d", ret);
3415 return _bt_convert_oal_status_to_bt_error(ret);
3418 struct gatt_server_info_t *server_info = NULL;
3419 BT_ERR("GATT Client [%s] is not yet connected..", addr);
3420 server_info = _bt_find_remote_gatt_server_info(addr);
3422 BT_INFO("GATT Server [%s] is connected, conn Id [%d] Client ID [%d]",
3423 server_info->addr, server_info->connection_id, server_info->client_id);
3425 ret = gattc_get_att_mtu(server_info->connection_id, &stack_mtu);
3426 if (ret != OAL_STATUS_SUCCESS) {
3427 BT_ERR("ret: %d", ret);
3428 return _bt_convert_oal_status_to_bt_error(ret);
3431 BT_ERR("GATT Server [%s] is not yet connected..", addr);
3432 return BLUETOOTH_ERROR_NOT_CONNECTED;
3436 BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
3437 *mtu = (unsigned int)stack_mtu;
3440 BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
3441 return BLUETOOTH_ERROR_NOT_CONNECTED;
3444 return BLUETOOTH_ERROR_NONE;
3447 /* GATT Client utility static functions */
3448 static bt_gatt_service_info_list_t *__bt_get_service_info_list(int conn_id)
3451 bt_gatt_service_info_list_t *info = NULL;
3453 for (l = list_gatt_info; l != NULL; l = g_slist_next(l)) {
3454 info = (bt_gatt_service_info_list_t *)l->data;
3458 if (info->conn_id == conn_id)
3465 static bt_gatt_service_info_t *__bt_find_matching_service(
3466 bt_gatt_service_info_list_t *svc_list, oal_gatt_srvc_id_t *svc)
3469 bt_gatt_service_info_t *info = NULL;
3471 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3472 info = (bt_gatt_service_info_t *)l->data;
3476 /* Match UUID and instance ID */
3477 if (!memcmp(&svc->id.uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3478 && (svc->id.inst_id == info->inst_id)) {
3485 static bt_gatt_char_info_t *__bt_find_matching_charc(
3486 bt_gatt_service_info_t *svc_info, oal_gatt_id_t *charc)
3489 bt_gatt_char_info_t *info = NULL;
3491 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3492 info = (bt_gatt_char_info_t *)l->data;
3496 /* Match UUID and instance ID */
3497 if (!memcmp(&charc->uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3498 && (charc->inst_id == info->inst_id)) {
3505 static bt_gatt_descriptor_info_t *__bt_find_matching_desc(
3506 bt_gatt_char_info_t *char_info, oal_gatt_id_t *desc)
3509 bt_gatt_descriptor_info_t *info = NULL;
3511 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3512 info = (bt_gatt_descriptor_info_t *)l->data;
3516 /* Match UUID and instance ID */
3517 if (!memcmp(&desc->uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
3518 && (desc->inst_id == info->inst_id)) {
3525 static bt_gatt_service_info_t* __bt_find_removed_service(bt_gatt_service_info_list_t *svc_list)
3528 bt_gatt_service_info_t *info = NULL;
3530 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
3531 info = (bt_gatt_service_info_t*)l->data;
3535 /* Service is marked a removed */
3536 if (info->is_removed == 1)
3542 static void __bt_remove_service_info_from_list(bt_gatt_service_info_t *svc_info)
3548 bt_gatt_char_info_t *charc = NULL;
3549 bt_gatt_included_service_info_t *incl = NULL;
3550 bt_gatt_descriptor_info_t *desc = NULL;
3552 /* Remove all Characteristic and Descriptors within characteristic */
3553 for (l = svc_info->chars; l != NULL;) {
3554 charc = (bt_gatt_char_info_t*)l->data;
3555 l = g_slist_next(l); /* Incase if l is removed, saving next to l */
3560 /* Inside Characteristic */
3561 for (l1 = charc->descs; l1 != NULL;) {
3563 desc = (bt_gatt_descriptor_info_t*)l1->data;
3564 l1 = g_slist_next(l1);
3569 /* Remove Descriptor */
3570 charc->descs = g_slist_remove(charc->descs, desc);
3573 /* Remove Characteristic */
3574 svc_info->chars = g_slist_remove(svc_info->chars, charc);
3578 /* Remove all Included Services */
3579 for (l2 = svc_info->included_svcs; l2 != NULL;) {
3580 incl = (bt_gatt_included_service_info_t*)l2->data;
3581 l2 = g_slist_next(l2); /* Incase if l is removed, saving next to l */
3586 /* Remove included service */
3587 svc_info->included_svcs = g_slist_remove(svc_info->included_svcs, incl);
3594 static void __bt_build_service_browse_info(int conn_id,
3595 bt_services_browse_info_t* info)
3598 bt_gatt_service_info_list_t *svc_info_list;
3599 bt_gatt_service_info_t *svc_info;
3601 service_uuid_t uuid;
3602 struct gatt_server_info_t *conn_info = NULL;
3604 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3606 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3607 if (conn_info == NULL) {
3608 BT_ERR("Cant find connection Information");
3612 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3614 svc_info_list = __bt_get_service_info_list(conn_id);
3618 info->count = g_slist_length(svc_info_list->services);
3619 BT_DBG("Total services present in the svc info list for this conn id [%d] is [%d]",
3620 conn_id, info->count);
3622 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
3623 svc_info = (bt_gatt_service_info_t*)l->data;
3624 if (svc_info == NULL)
3627 memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3628 _bt_uuid_to_string(&uuid, uuid_string);
3630 BT_INFO("[%d] %s [%s]", count, uuid_string, _bt_convert_uuid_to_string(uuid_string));
3632 /* Fill UUID of service */
3633 g_strlcpy(info->uuids[count], uuid_string,
3634 BLUETOOTH_UUID_STRING_MAX);
3636 /* Fill instance ID of service */
3637 info->inst_id[count] = svc_info->inst_id;
3639 /* Fill primary service or not info */
3640 info->primary[count] = svc_info->is_primary;
3642 /* Increment count of services browsed */
3647 static void __bt_build_char_browse_info(int conn_id,
3648 bt_gatt_service_info_t *svc_info,
3649 bt_char_browse_info_t* info)
3652 bt_gatt_char_info_t *char_info;
3653 service_uuid_t uuid;
3655 struct gatt_server_info_t *conn_info = NULL;
3657 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3659 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3660 if (conn_info == NULL) {
3661 BT_ERR("Cant find connection Information");
3665 /* Fill default data, this will be required even in case of failure */
3666 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3667 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3668 info->svc_inst_id = svc_info->inst_id;
3670 if (!svc_info->chars) {
3671 BT_ERR("No Chars browsed for address [%s]", conn_info->addr);
3675 info->count = g_slist_length(svc_info->chars);
3677 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3678 char_info = (bt_gatt_char_info_t*)l->data;
3679 if (char_info == NULL)
3682 memcpy(&uuid.uuid, &char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3683 _bt_uuid_to_string(&uuid, uuid_string);
3685 /* Fill UUID of characteristic */
3686 g_strlcpy(info->uuids[count], uuid_string,
3687 BLUETOOTH_UUID_STRING_MAX);
3689 /* Fill instance ID of characteristic */
3690 info->inst_id[count] = char_info->inst_id;
3692 /* Fill property of characteristic */
3693 info->props[count] = char_info->props;
3695 /* Increment count of services browsed */
3698 BT_DBG("Total characteristics browsed [%d]", count);
3701 static void __bt_build_descriptor_browse_info(int conn_id,
3702 bt_gatt_service_info_t *svc_info,
3703 bt_gatt_char_info_t *char_info,
3704 bt_descriptor_browse_info_t* info)
3707 bt_gatt_descriptor_info_t *desc_info;
3709 service_uuid_t uuid;
3710 struct gatt_server_info_t *conn_info = NULL;
3712 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3714 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3716 /* Fill default data, this will be required even in case of failure */
3717 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3718 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3719 info->svc_inst_id = svc_info->inst_id;
3720 memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3721 info->char_inst_id = char_info->inst_id;
3723 /* Fill property of the parent characteristic of this descriptor */
3724 info->char_props_map = char_info->props;
3726 info->count = g_slist_length(char_info->descs);
3728 if (!char_info->descs) {
3729 BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr + 12);
3733 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3734 desc_info = (bt_gatt_descriptor_info_t*)l->data;
3735 if (desc_info == NULL)
3738 memcpy(&uuid.uuid, &desc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3739 _bt_uuid_to_string(&uuid, uuid_string);
3741 /* Fill UUID of Descriptor */
3742 g_strlcpy(info->uuids[count], uuid_string,
3743 BLUETOOTH_UUID_STRING_MAX);
3745 /* Fill instance ID of Descriptor */
3746 info->inst_id[count] = desc_info->inst_id;
3749 /* Increment count of Descriptor browsed */
3753 BT_INFO("Total descriptors browsed [%d]", count);
3756 static void __bt_free_service_info(bt_gatt_service_info_t *svc)
3758 GSList *ll, *lll, *llll;
3759 bt_gatt_char_info_t *chr = NULL;
3760 bt_gatt_descriptor_info_t *desc = NULL;
3761 bt_gatt_included_service_info_t *incl_svc = NULL;
3763 BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id);
3764 /* Delete all chars and its descriptors */
3765 for (ll = svc->chars; ll != NULL; ) {
3766 chr = (bt_gatt_char_info_t *)ll->data;
3767 ll = g_slist_next(ll);
3771 for (lll = chr->descs; lll != NULL; ) {
3772 desc = (bt_gatt_descriptor_info_t *)lll->data;
3773 lll = g_slist_next(lll);
3776 chr->descs = g_slist_remove(chr->descs, desc);
3779 svc->chars = g_slist_remove(svc->chars, chr);
3783 /* Delete all included services */
3784 for (llll = svc->included_svcs; llll != NULL; ) {
3785 incl_svc = (bt_gatt_included_service_info_t *)llll->data;
3786 llll = g_slist_next(llll);
3787 if (incl_svc == NULL)
3789 svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc);
3794 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
3796 bt_gatt_service_info_list_t *svc_info_list = NULL;
3797 bt_gatt_service_info_t *svc = NULL;
3801 BT_ERR("conn_info is NULL");
3805 svc_info_list = __bt_get_service_info_list(conn_info->connection_id);
3806 if (!svc_info_list) {
3807 BT_INFO("Could not find Svc Info list for the connection ID [%d]",
3808 conn_info->connection_id);
3812 BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services));
3813 for (l = svc_info_list->services; l != NULL; ) {
3814 svc = (bt_gatt_service_info_t *)l->data;
3815 l = g_slist_next(l);
3819 __bt_free_service_info(svc);
3820 svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
3824 list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
3825 g_free(svc_info_list);
3828 int _bt_register_gatt_client_instance(const char *sender,
3829 bluetooth_device_address_t *address)
3831 int ret = OAL_STATUS_SUCCESS;
3832 char *uuid_string = NULL;
3837 /* App should ensure that it should not send */
3838 BT_INFO("Check on which instance GATT Client instance can be initialized....");
3839 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3840 if (numapps[k].is_initialized == 1 || strlen(numapps[k].uuid) > 0) {
3841 BT_DBG("Instance ID [%d] is already in use..Check next slot",
3842 numapps[k].instance_id);
3845 BT_DBG("Time to register GATT client instancer..UUID to be used is [%s] slot [%d]",
3846 uuid_list[slot-1], slot);
3852 BT_ERR("No Slot if free for GATT Client registration..");
3853 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
3856 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3857 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
3858 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
3859 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
3861 /* Register GATT Client */
3862 ret = gattc_register(&uuid);
3863 if (ret != OAL_STATUS_SUCCESS) {
3864 BT_ERR("ret: %d", ret);
3865 g_free(uuid_string);
3866 return _bt_convert_oal_status_to_bt_error(ret);
3869 BT_DBG("GATT Client registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
3871 /* Return & wait for GATT Client Instance Initialization event */
3872 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
3873 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
3875 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
3876 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
3878 /* Address is saved here. When event comes, sender + address are matched for replying pending
3879 request. It is impossible for same sender to have requests with two same addresses */
3880 memcpy(&numapps[slot].address.addr, address->addr, sizeof(bluetooth_device_address_t));
3882 numapps[slot].is_initialized = TRUE; /* Set initialization to true here itself */
3884 g_free(uuid_string);
3885 return BLUETOOTH_ERROR_NONE;
3891 /* GATT client events */
3892 static void __bt_handle_client_instance_registered(event_gattc_register_t *data)
3894 bt_service_app_info_t *info = NULL;
3896 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3898 _bt_uuid_to_string(&(data->client_uuid), uuid_string);
3899 BT_INFO("Client ID is Initialized [%d] UUID initialized [%s]", data->client_if, uuid_string);
3901 /* Platform GATT client framwork does not use Default GATT client instance
3902 This GATT client instance is never deregistred in the lifetime of bt-service */
3903 if (g_strcmp0(uuid_string, DEFAULT_GATT_CLIENT_UUID) == 0) {
3904 BT_INFO("Default client Instance Registered");
3905 gatt_default_client = data->client_if;
3906 g_free(uuid_string);
3910 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3913 if (g_strcmp0(info->uuid, uuid_string) == 0) {
3914 BT_INFO("Found GATT client.. sender [%s] Slot [%d] occupied", info->sender, k);
3915 info->is_initialized = TRUE;
3916 info->client_id = data->client_if;
3917 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_CLIENT_REGISTER,
3918 (void*)info, sizeof(bt_service_app_info_t));
3922 g_free(uuid_string);
3925 static void __bt_handle_client_connected(event_gattc_conn_t *event_data)
3927 int result = BLUETOOTH_ERROR_NONE;
3928 struct gatt_server_info_t *conn_info = NULL;
3929 struct gatt_out_conn_info_t *out_conn_info = NULL;
3931 GVariant *param = NULL;
3933 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3934 _bt_convert_addr_type_to_string(address,
3935 (unsigned char *)event_data->address.addr);
3937 if (event_data->status != OAL_STATUS_SUCCESS)
3938 result = BLUETOOTH_ERROR_INTERNAL;
3940 /* DBUS Return fo BT_CONNECT_LE for all the apps */
3941 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
3942 BT_ADDRESS_STRING_SIZE);
3944 BT_INFO("Local GATT Client Connected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status[%d]",
3945 address, event_data->client_if, event_data->conn_id, event_data->status);
3947 if (result == BLUETOOTH_ERROR_NONE) {
3948 /* Check if device is already in connected list */
3949 conn_info = _bt_find_remote_gatt_server_info(address);
3952 /* Send event to BT-API */
3953 param = g_variant_new("(is)", result, address);
3954 _bt_send_event(BT_DEVICE_EVENT,
3955 BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED, /* Local device is GATT client */
3958 /* Save Connection info */
3959 conn_info = g_new0(struct gatt_server_info_t, 1);
3960 conn_info->addr = g_strdup(address);
3961 conn_info->client_id = event_data->client_if;
3962 conn_info->connection_id = event_data->conn_id;
3963 gatt_server_info_list = g_slist_append(gatt_server_info_list, conn_info);
3964 BT_DBG("Total num of connected Remote GATT server devices [%d]",
3965 g_slist_length(gatt_server_info_list));
3968 BT_INFO("Do a Internal refresh");
3969 if (OAL_STATUS_SUCCESS != gattc_refresh(conn_info->client_id, &event_data->address))
3970 BT_ERR("GATT database refresh failed!!");
3972 BT_INFO("GATT database refresh Success!!");
3975 BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
3977 __bt_add_mtu_gatt_device(address);
3979 _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
3981 BT_ERR("GATT Client Connection failed!!");
3983 /* If outgoing connection Info is present, then remove it */
3984 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
3985 if (out_conn_info) {
3986 BT_ERR("Outgoing Client connect request was sent");
3987 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
3988 g_free(out_conn_info->addr);
3989 g_free(out_conn_info);
3991 _bt_restart_le_scan();
3996 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
3998 int result = BLUETOOTH_ERROR_NONE;
3999 struct gatt_server_info_t *conn_info = NULL;
4000 struct gatt_client_info_t *client_info = NULL;
4001 struct gatt_out_conn_info_t *out_conn_info = NULL;
4002 GVariant *param = NULL;
4004 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4005 _bt_convert_addr_type_to_string(address,
4006 (unsigned char *)event_data->address.addr);
4008 if (event_data->status != OAL_STATUS_SUCCESS)
4009 result = BLUETOOTH_ERROR_INTERNAL;
4011 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
4012 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
4013 result = BLUETOOTH_ERROR_INTERNAL;
4014 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
4015 address, BT_ADDRESS_STRING_SIZE);
4016 BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
4021 /* DBUS Return for BT_DISCONNECT_LE for all the apps */
4022 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE, address,
4023 BT_ADDRESS_STRING_SIZE);
4025 BT_INFO("Local GATT Client DisConnected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status [%d]",
4026 address + 12, event_data->client_if, event_data->conn_id, event_data->status);
4028 /* Remove Connection info */
4029 conn_info = _bt_find_remote_gatt_server_info(address);
4032 param = g_variant_new("(is)", result, address);
4033 /* Send event to application */
4034 _bt_send_event(BT_DEVICE_EVENT,
4035 BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED,
4038 BT_INFO("Remove GATT server info from List..");
4039 /* Remove all services from info list_gatt_info */
4040 __bt_cleanup_remote_services(conn_info);
4042 /* Remove info from List */
4043 gatt_server_info_list = g_slist_remove(gatt_server_info_list, conn_info);
4045 /* Remove all pending invocations from invocatin_list */
4046 BT_INFO("Clear all pending invocations");
4047 __bt_gatt_cleanup_invocation_on_gatt_disconnection(BLUETOOTH_ERROR_INTERNAL,
4048 address, BT_ADDRESS_STRING_SIZE);
4050 BT_INFO("Total num of connected GATT servers [%d]", g_slist_length(gatt_server_info_list));
4051 g_free(conn_info->addr);
4054 BT_INFO("Can not find conn info, already removed!");
4056 /* Remove client info */
4057 client_info = _bt_find_remote_gatt_client_info(address);
4059 BT_DBG("Remove GATT client info from list");
4060 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
4061 g_free(client_info->addr);
4062 g_free(client_info);
4065 __bt_remove_mtu_gatt_device(address);
4067 /* If outgoing connection Info is present, then remove it */
4068 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
4069 if (out_conn_info) {
4070 BT_ERR("Client Disconnected event, but outgoing connect request was sent");
4071 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
4072 g_free(out_conn_info->addr);
4073 g_free(out_conn_info);
4079 static void __bt_handle_client_service_search_result(
4080 event_gattc_service_result_t *event_data)
4082 /* Pre: status is never fail from OAL */
4084 /* Find service list from address */
4085 bt_gatt_service_info_list_t *svc_info_list;
4086 bt_gatt_service_info_t *svc_info;
4088 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4089 if (!svc_info_list) {
4090 BT_DBG("Service info list not present for connection ID %d, means first time browse", event_data->conn_status.conn_id);
4091 /* Means for this conn_id, no services are ever browsed, first time,
4092 create service info list for this conn_id */
4093 svc_info_list = g_malloc0(sizeof(bt_gatt_service_info_list_t));
4094 svc_info_list->conn_id = event_data->conn_status.conn_id;
4095 list_gatt_info = g_slist_append(list_gatt_info, svc_info_list);
4098 /* send list and current service's uuid and instance id to find it */
4099 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4100 /* If not found, check if service changed, if yes, means this is a new service added
4101 in remote GATT device, update uuid info in svc info list structure, to be used when
4102 search is completed */
4104 if (svc_info_list->info.is_changed) {
4105 BT_DBG("Service Changed indication already found for connection ID %d", event_data->conn_status.conn_id);
4106 memcpy(svc_info_list->info.uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4108 /* Create and add new service in service list */
4109 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4110 memcpy(svc_info->uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4111 svc_info->inst_id = event_data->srvc_id.id.inst_id;
4112 svc_info->is_primary = event_data->srvc_id.is_prmry;
4113 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4114 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_status.conn_id);
4116 /* If returned matching service info, then just update service_rmeoved value inside it to 0 */
4117 svc_info->is_removed = 0;
4121 static void __bt_handle_client_service_search_completed(
4122 event_gattc_conn_status_t *event_data)
4124 struct gatt_server_info_t *conn_info = NULL;
4125 bt_gatt_service_info_list_t *svc_info_list;
4126 bt_gatt_service_info_t *svc_info;
4127 bt_services_browse_info_t browse_info;
4128 unsigned char uuid_empty[BLUETOOTH_UUID_HEX_MAX_LEN];
4130 memset(&uuid_empty, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4131 memset(&browse_info, 0x00, sizeof(bt_services_browse_info_t));
4132 BT_INFO("Primary Services browsing completed status[%d] conn ID [%d]",
4133 event_data->status, event_data->conn_id);
4135 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4137 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4138 if (!svc_info_list) {
4139 BT_ERR("No services browsed ever for addr [%s]", conn_info->addr);
4141 /* Just build response and return ERROR */
4142 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4144 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4145 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4146 sizeof(bt_services_browse_info_t));
4150 /* If fail, then send event with error */
4151 if (event_data->status != OAL_STATUS_SUCCESS) {
4152 /* Just build response and return ERROR */
4153 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4155 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
4156 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4157 sizeof(bt_services_browse_info_t));
4161 /* If success, then find service info list from address */
4163 /* If svc_changed == 1 and uuid valid, means a new service is added*/
4164 if (svc_info_list->info.is_changed && !memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4165 /* TODO: Send event -Service added with instance ID and UUID of newly added service */
4166 BT_INFO("new service added");
4168 BT_INFO("TODO new service added");
4171 /* If svc_changed == 1 and uuid invalid, then a service is removed */
4172 if (svc_info_list->info.is_changed && memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4173 /* Scan through the service info list to find service with is_removed = 1*/
4174 svc_info = __bt_find_removed_service(svc_info_list);
4176 /* TODO Send event - Service removed with instance ID and UUID of just rmeoved service */
4178 /* Remove that service info from service info list */
4179 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
4181 /* Delete that service completely from svc_info list*/
4182 __bt_remove_service_info_from_list(svc_info);
4186 /* Reset svc_changed = 0, and reset UUID = all 0's */
4187 svc_info_list->info.is_changed = 0;
4188 memset(&svc_info_list->info.uuid, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
4190 /* Build Reply and send to service browse primary services request of pending apps */
4191 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
4193 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4194 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
4195 sizeof(bt_services_browse_info_t));
4199 static void __bt_handle_client_characteristic_search_result(
4200 event_gattc_characteristic_result_t *event_data)
4202 bt_gatt_service_info_list_t *svc_info_list;
4203 bt_gatt_service_info_t *svc_info;
4204 bt_gatt_char_info_t *char_info;
4205 bt_char_browse_info_t browse_info;
4207 memset(&browse_info, 0x00, sizeof(bt_char_browse_info_t));
4210 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4211 /* Find service info list from address */
4212 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4213 if (svc_info_list == NULL) {
4214 BT_ERR("svc_info_list is NULL");
4218 /* Find matching service info from svc info list */
4219 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4220 if (svc_info == NULL) {
4221 BT_ERR("svc_info is NULL");
4225 /* Find Matching char from service info in event */
4226 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4227 /* If not found, then add new characteristic and return */
4229 BT_DBG("Add new characteristic");
4230 char_info = g_malloc0(sizeof(bt_gatt_char_info_t));
4231 memcpy(char_info->uuid, event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4233 char_info->inst_id = event_data->char_id.inst_id;
4234 char_info->props = event_data->char_prop;
4235 svc_info->chars = g_slist_append(svc_info->chars, char_info);
4237 /* If found, then return */
4238 BT_DBG("update char property as Characteristic browsed is already present");
4239 char_info->props |= event_data->char_prop;
4242 /* If Not success: Means Charc browse is completed */
4243 /* Find char list from service in event */
4244 /* Find service list from address */
4245 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4246 if (svc_info_list == NULL) {
4247 BT_ERR("svc_info_list is NULL");
4251 /* Find service info from service in event */
4252 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4253 if (svc_info == NULL) {
4254 BT_ERR("svc_info is NULL");
4258 /* Build char list from service in event */
4259 __bt_build_char_browse_info(event_data->conn_status.conn_id,
4260 svc_info, &browse_info);
4262 /* Create response and return by sending event*/
4263 /* Build Reply and send to service browse All Included services request of pending apps */
4264 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4265 BT_GATT_GET_SERVICE_PROPERTIES,
4267 sizeof(bt_char_browse_info_t));
4271 static void __bt_handle_client_descriptor_search_result(
4272 event_gattc_descriptor_result_t *event_data)
4274 bt_gatt_service_info_list_t *svc_info_list;
4275 bt_gatt_service_info_t *svc_info;
4276 bt_gatt_char_info_t *char_info;
4277 bt_gatt_descriptor_info_t *desc_info;
4278 bt_descriptor_browse_info_t browse_info;
4280 BT_DBG("descriptor search result status [%d]", event_data->conn_status.status);
4282 memset(&browse_info, 0x00, sizeof(bt_descriptor_browse_info_t));
4285 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
4286 /* Find service list from address */
4287 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4288 if (svc_info_list == NULL) {
4289 BT_ERR("svc_info_list is NULL");
4293 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4294 if (svc_info == NULL) {
4295 BT_ERR("svc_info is NULL");
4299 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4300 if (char_info == NULL) {
4301 BT_ERR("char_info is NULL");
4305 desc_info = __bt_find_matching_desc(char_info, &event_data->descr_id);
4306 /* If not found, add new descriptor and return */
4308 desc_info = g_malloc0(sizeof(bt_gatt_descriptor_info_t));
4309 memcpy(desc_info->uuid, event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4311 desc_info->inst_id = event_data->descr_id.inst_id;
4312 char_info->descs = g_slist_append(char_info->descs, desc_info);
4315 /* If found, then return */
4316 BT_DBG("Descriptor browsed is already presesnt");
4319 /* If Not success */
4320 /* Find service list from address */
4321 /* Find included service list from service in event */
4322 /* Create response and return by sending event*/
4323 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
4324 if (svc_info_list == NULL) {
4325 BT_ERR("svc_info_list is NULL");
4329 /* Find service info from service in event */
4330 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
4331 if (svc_info == NULL) {
4332 BT_ERR("svc_info is NULL");
4336 /* Find char info from char in event */
4337 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
4338 if (char_info == NULL) {
4339 BT_ERR("char_info is NULL");
4343 /* Build descriptor list from char in event */
4344 __bt_build_descriptor_browse_info(event_data->conn_status.conn_id,
4345 svc_info, char_info, &browse_info);
4348 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
4349 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
4351 sizeof(bt_descriptor_browse_info_t));
4355 static void __bt_handle_client_characteristic_read_data(
4356 event_gattc_read_data *event_data)
4358 int result = BLUETOOTH_ERROR_NONE;
4359 struct gatt_server_info_t *conn_info = NULL;
4360 bluetooth_gatt_client_char_prop_info_t read_info;
4362 /* Read Information data structures */
4363 GVariant *param = NULL;
4364 GVariant *data = NULL;
4365 GVariant *data_svc_uuid = NULL;
4366 GVariant *data_char_uuid = NULL;
4367 char *read_val = NULL;
4368 char *svc_uuid = NULL;
4369 char *char_uuid = NULL;
4372 //memset(&read_info, 0x00, sizeof(bt_gatt_handle_property_t));
4373 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4375 /* Extract Address from conn_id of event data */
4376 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4377 event_data->uuid_status.conn_status.conn_id);
4379 BT_INFO("Characteristic Read result from addr [%s] status [%d]",
4380 conn_info->addr, event_data->uuid_status.conn_status.status);
4382 /* Fill char in buffer */
4383 memcpy(&read_info.characteristic.uuid,
4384 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4385 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4387 /* Fill Service in buffer */
4388 memcpy(&read_info.svc.uuid,
4389 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4390 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4392 /* Fill remote device address */
4393 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4395 /* Fill data and reply to all apps waiting for Read result on the same characteristic
4396 Note: Even in case of failure, address, handles and result code should be returned */
4397 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4398 result = BLUETOOTH_ERROR_INTERNAL;
4400 if (event_data->data_len > 0) {
4402 // for (i = 0; i < event_data->data_len; i++)
4403 // BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4406 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4408 data = g_variant_new_from_data(
4409 G_VARIANT_TYPE_BYTESTRING,
4411 event_data->data_len,
4414 BT_ERR("Characteristic Read success, but no data!!!");
4416 data = g_variant_new_from_data(
4417 G_VARIANT_TYPE_BYTESTRING,
4424 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4426 data_svc_uuid = g_variant_new_from_data(
4427 G_VARIANT_TYPE_BYTESTRING,
4433 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4435 data_char_uuid = g_variant_new_from_data(
4436 G_VARIANT_TYPE_BYTESTRING,
4441 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4445 event_data->uuid_status.srvc_id.id.inst_id,
4448 event_data->uuid_status.char_id.inst_id,
4449 event_data->data_len,
4453 char *sender = NULL;
4454 __bt_gatt_get_pending_request_info(BT_GATT_READ_CHARACTERISTIC, &sender);
4455 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4456 BLUETOOTH_EVENT_GATT_READ_CHAR,
4459 /* Send DBUS return */
4460 __bt_gatt_handle_pending_request_info(result,
4461 BT_GATT_READ_CHARACTERISTIC,
4463 sizeof(bluetooth_gatt_client_char_prop_info_t));
4474 static void __bt_handle_client_descriptor_read_data(
4475 event_gattc_read_data *event_data)
4477 int result = BLUETOOTH_ERROR_NONE;
4478 struct gatt_server_info_t *conn_info = NULL;
4479 bluetooth_gatt_client_desc_prop_info_t read_info;
4481 /* Read Information data structures */
4482 GVariant *param = NULL;
4483 GVariant *data = NULL;
4484 GVariant *data_svc_uuid = NULL;
4485 GVariant *data_char_uuid = NULL;
4486 GVariant *data_desc_uuid = NULL;
4487 char *read_val = NULL;
4488 char *svc_uuid = NULL;
4489 char *char_uuid = NULL;
4490 char *desc_uuid = NULL;
4494 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4496 /* Extract Address from conn_id of event data */
4497 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4498 event_data->uuid_status.conn_status.conn_id);
4500 BT_DBG("Descriptor Read result from addr [%s] status [%d]",
4501 conn_info->addr, event_data->uuid_status.conn_status.status);
4503 /* Fill descriptor informations in buffer */
4504 memcpy(&read_info.descriptor.uuid,
4505 event_data->uuid_status.descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4506 read_info.descriptor.instance_id = event_data->uuid_status.descr_id.inst_id;
4508 /* Fill Characteristic informations in buffer */
4509 memcpy(&read_info.characteristic.uuid,
4510 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4511 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
4513 /* Fill Service informations in buffer */
4514 memcpy(&read_info.svc.uuid,
4515 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4516 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
4518 /* Fill remote device address */
4519 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
4521 /* Fill data and reply to all apps waiting for Read result on the same characteristic */
4522 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
4523 result = BLUETOOTH_ERROR_INTERNAL;
4525 if (event_data->data_len > 0) {
4527 for (i = 0; i < event_data->data_len; i++)
4528 BT_DBG("Data[%d] = [0x%x]", i, event_data->data[i]);
4531 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4533 data = g_variant_new_from_data(
4534 G_VARIANT_TYPE_BYTESTRING,
4536 event_data->data_len,
4539 BT_INFO("Descriptor Read success, but no data!!!");
4541 data = g_variant_new_from_data(
4542 G_VARIANT_TYPE_BYTESTRING,
4548 svc_uuid = g_memdup2(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4550 data_svc_uuid = g_variant_new_from_data(
4551 G_VARIANT_TYPE_BYTESTRING,
4557 char_uuid = g_memdup2(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4559 data_char_uuid = g_variant_new_from_data(
4560 G_VARIANT_TYPE_BYTESTRING,
4566 desc_uuid = g_memdup2(&event_data->uuid_status.descr_id.uuid.uuid[0], uuid_len);
4568 data_desc_uuid = g_variant_new_from_data(
4569 G_VARIANT_TYPE_BYTESTRING,
4574 param = g_variant_new("(isn@ayin@ayin@ayin@ay)", result,
4578 event_data->uuid_status.srvc_id.id.inst_id,
4581 event_data->uuid_status.char_id.inst_id,
4584 event_data->uuid_status.descr_id.inst_id,
4585 event_data->data_len,
4589 char *sender = NULL;
4590 __bt_gatt_get_pending_request_info(BT_GATT_READ_DESCRIPTOR_VALUE, &sender);
4591 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4592 BLUETOOTH_EVENT_GATT_READ_DESC,
4596 /* Send DBUS return */
4597 __bt_gatt_handle_pending_request_info(result,
4598 BT_GATT_READ_DESCRIPTOR_VALUE,
4600 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4611 static void __bt_handle_client_characteristic_write_data(
4612 event_gattc_write_data *event_data)
4614 int result = BLUETOOTH_ERROR_NONE;
4615 struct gatt_server_info_t *conn_info = NULL;
4616 bluetooth_gatt_client_char_prop_info_t write_info;
4618 /* Read Information data structures */
4619 GVariant *param = NULL;
4620 GVariant *data_svc_uuid = NULL;
4621 GVariant *data_char_uuid = NULL;
4622 char *svc_uuid = NULL;
4623 char *char_uuid = NULL;
4626 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4628 /* Extract Address from conn_id of event data */
4629 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4630 event_data->conn_status.conn_id);
4632 BT_DBG("Characteristic Write callback from addr [%s] status [%d]",
4633 conn_info->addr, event_data->conn_status.status);
4635 /* Fill char in buffer */
4636 memcpy(&write_info.characteristic.uuid,
4637 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4638 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4640 /* Fill Service in buffer */
4641 memcpy(&write_info.svc.uuid,
4642 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4643 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4645 /* Fill remote device address */
4646 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4648 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4649 result = BLUETOOTH_ERROR_INTERNAL;
4655 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4657 data_svc_uuid = g_variant_new_from_data(
4658 G_VARIANT_TYPE_BYTESTRING,
4664 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4666 data_char_uuid = g_variant_new_from_data(
4667 G_VARIANT_TYPE_BYTESTRING,
4672 param = g_variant_new("(isn@ayin@ayi)", result,
4676 event_data->srvc_id.id.inst_id,
4679 event_data->char_id.inst_id);
4682 char *sender = NULL;
4683 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, &sender);
4684 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4685 BLUETOOTH_EVENT_GATT_WRITE_CHAR,
4695 /* Send DBUS return */
4696 __bt_gatt_handle_pending_request_info(result,
4697 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
4699 sizeof(bluetooth_gatt_client_char_prop_info_t));
4703 static void __bt_handle_client_descriptor_write_data(
4704 event_gattc_write_data *event_data)
4706 int result = BLUETOOTH_ERROR_NONE;
4707 struct gatt_server_info_t *conn_info = NULL;
4708 bluetooth_gatt_client_desc_prop_info_t write_info;
4710 /* Write Information data structures */
4711 GVariant *param = NULL;
4712 GVariant *data_svc_uuid = NULL;
4713 GVariant *data_char_uuid = NULL;
4714 GVariant *data_desc_uuid = NULL;
4715 char *svc_uuid = NULL;
4716 char *char_uuid = NULL;
4717 char *desc_uuid = NULL;
4720 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4722 /* Extract Address from conn_id of event data */
4723 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4724 event_data->conn_status.conn_id);
4726 if (NULL == conn_info) {
4727 BT_ERR("Failed to get the conn info for conn_id [%d]", event_data->conn_status.conn_id);
4731 BT_DBG("Descriptor Write callback from addr [%s] status [%d]",
4732 conn_info->addr, event_data->conn_status.status);
4734 /* Fill descriptor informations in buffer */
4735 memcpy(&write_info.descriptor.uuid,
4736 event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4737 write_info.descriptor.instance_id = event_data->descr_id.inst_id;
4739 /* Fill Characteristic informations in buffer */
4740 memcpy(&write_info.characteristic.uuid,
4741 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4742 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4744 /* Fill Service informations in buffer */
4745 memcpy(&write_info.svc.uuid,
4746 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4747 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4749 /* Fill remote device address */
4750 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4752 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4753 result = BLUETOOTH_ERROR_INTERNAL;
4759 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4761 data_svc_uuid = g_variant_new_from_data(
4762 G_VARIANT_TYPE_BYTESTRING,
4768 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4770 data_char_uuid = g_variant_new_from_data(
4771 G_VARIANT_TYPE_BYTESTRING,
4777 desc_uuid = g_memdup2(&event_data->descr_id.uuid.uuid[0], uuid_len);
4779 data_desc_uuid = g_variant_new_from_data(
4780 G_VARIANT_TYPE_BYTESTRING,
4785 param = g_variant_new("(isn@ayin@ayin@ayi)", result,
4789 event_data->srvc_id.id.inst_id,
4792 event_data->char_id.inst_id,
4795 event_data->descr_id.inst_id);
4798 char *sender = NULL;
4799 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_DESCRIPTOR_VALUE, &sender);
4800 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4801 BLUETOOTH_EVENT_GATT_WRITE_DESC,
4812 /* Send DBUS return */
4813 __bt_gatt_handle_pending_request_info(result,
4814 BT_GATT_WRITE_DESCRIPTOR_VALUE,
4816 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4819 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data)
4821 int result = BLUETOOTH_ERROR_INTERNAL;
4822 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4824 _bt_convert_addr_type_to_string(address, (unsigned char *)event_data->address.addr);
4826 /* DBUS Return with fail of pending BT_CONNECT_LE for all the apps */
4827 BT_INFO("Local GATT Client disconnected: Remote addr[%s] ", address + 12);
4829 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
4830 BT_ADDRESS_STRING_SIZE);
4834 static void __bt_handle_client_notification_registered(
4835 event_gattc_regdereg_notify_t *event_data,
4836 gboolean is_registered)
4838 int result = BLUETOOTH_ERROR_NONE;
4839 struct gatt_server_info_t *conn_info = NULL;
4840 bt_gatt_notif_reg_info_t notif_info;
4843 memset(¬if_info, 0x00, sizeof(bt_gatt_notif_reg_info_t));
4845 BT_INFO("Client Interface [%d] status [%d]",
4846 event_data->conn_id,
4847 event_data->status);
4849 /* Extract Address from conn_id of event data */
4850 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4852 BT_INFO("Connection Info is not present, return");
4855 BT_INFO("Notification Registered for addr [%s]", conn_info->addr);
4857 /* Fill svc informations in buffer */
4858 memcpy(¬if_info.svc_uuid,
4859 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4860 notif_info.svc_inst = event_data->srvc_id.id.inst_id;
4862 /* Fill char in buffer */
4863 memcpy(¬if_info.char_uuid,
4864 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4865 notif_info.char_inst = event_data->char_id.inst_id;
4867 /* Fill remote device address */
4868 _bt_convert_addr_string_to_type(notif_info.addr.addr, conn_info->addr);
4870 notif_info.is_registered = is_registered;
4872 if (event_data->status != OAL_STATUS_SUCCESS)
4873 result = BLUETOOTH_ERROR_INTERNAL;
4875 /* Send DBUS Return for BT_GATT_WATCH_CHARACTERISTIC */
4876 __bt_gatt_handle_pending_request_info(result,
4877 BT_GATT_WATCH_CHARACTERISTIC,
4879 sizeof(bt_gatt_notif_reg_info_t));
4882 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
4884 /* No status in this event from OAL */
4885 int result = BLUETOOTH_ERROR_NONE;
4887 /* Read Information data structures */
4888 GVariant *param = NULL;
4889 GVariant *data = NULL;
4890 GVariant *data_svc_uuid = NULL;
4891 GVariant *data_char_uuid = NULL;
4892 char *read_val = NULL;
4893 char *svc_uuid = NULL;
4894 char *char_uuid = NULL;
4900 BT_INFO("Notifcation of charc data changed");
4902 if (event_data->data_len > 0) {
4904 for (i = 0; i < event_data->data_len; i++)
4905 BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4908 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4909 _bt_convert_addr_type_to_string(addr,
4910 (unsigned char *)&(event_data->address.addr));
4913 read_val = g_memdup2(&event_data->data[0], event_data->data_len);
4915 data = g_variant_new_from_data(
4916 G_VARIANT_TYPE_BYTESTRING,
4918 event_data->data_len,
4921 svc_uuid = g_memdup2(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4923 data_svc_uuid = g_variant_new_from_data(
4924 G_VARIANT_TYPE_BYTESTRING,
4930 char_uuid = g_memdup2(&event_data->char_id.uuid.uuid[0], uuid_len);
4932 data_char_uuid = g_variant_new_from_data(
4933 G_VARIANT_TYPE_BYTESTRING,
4939 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4943 event_data->srvc_id.id.inst_id,
4946 event_data->char_id.inst_id,
4947 event_data->data_len,
4951 _bt_send_event(BT_GATT_CLIENT_EVENT,
4952 BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
4955 BT_ERR("No Data!!");
4968 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data)
4970 bt_gatt_service_info_list_t *svc_info_list;
4972 bt_gatt_service_info_t *svc_info;
4973 GVariant *param = NULL;
4974 char *address_str = NULL;
4975 char *uuid_str = NULL;
4977 #ifndef TIZEN_BLUEDROID_PORTING
4978 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4979 if (svc_info_list == NULL) {
4980 BT_ERR("svc_info_list is NULL");
4984 if (event_data->change_type) {
4985 /* Add service UUID in list */
4986 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4987 memcpy(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4988 svc_info->inst_id = event_data->inst_id;
4989 svc_info->is_primary = 1; // TODO: Need to check is_primary is required or not
4990 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4991 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_id);
4993 /* Remove service UUID in list */
4994 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
4995 svc_info = (bt_gatt_service_info_t *)l->data;
4996 if (svc_info == NULL)
4999 if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
5000 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
5001 __bt_free_service_info(svc_info);
5008 address_str = g_malloc0(BT_ADDRESS_STRING_SIZE);
5009 uuid_str = g_malloc0(BT_UUID_STRING_MAX);
5010 _bt_convert_addr_type_to_string(address_str, event_data->address.addr);
5012 #ifndef TIZEN_BLUEDROID_PORTING
5013 _bt_uuid_to_string(&event_data->uuid, uuid_str);
5015 event_data->change_type = BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_RESYNC;
5018 param = g_variant_new("(iiss)", event_data->inst_id, event_data->change_type, address_str, uuid_str);
5020 _bt_send_event(BT_GATT_CLIENT_EVENT,
5021 BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED,
5023 g_free(address_str);
5027 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
5030 struct gatt_server_info_t *conn_info = NULL;
5031 gboolean connected = FALSE;
5033 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
5034 _bt_convert_addr_type_to_string(addr,
5035 (unsigned char *)&(address->addr));
5037 BT_DBG("Check GATT connection status of [%s]", addr);
5038 /* Check if device is already in connected list */
5039 conn_info = _bt_find_remote_gatt_server_info(addr);
5041 BT_DBG("Remote GATT Server device [%s] is Connected", conn_info->addr);
5044 struct gatt_client_info_t *client_info = NULL;
5046 BT_DBG("Remote GATT Server Device [%s] is not Connected", addr);
5048 /* Check if device is already in connected list */
5049 client_info = _bt_find_remote_gatt_client_info(addr);
5051 BT_DBG("Remote Client device [%s] is Connected", client_info->addr);
5054 BT_DBG("Remote GATT Client Device [%s] is not Connected", addr);
5062 void _bt_handle_invocation_context(int function_name, void *data)
5064 switch (function_name) {
5066 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_CONNECT_LE,
5067 (char *)data, BT_ADDRESS_STRING_SIZE);
5074 int _bt_connect_le_device(bluetooth_device_address_t *address,
5075 int auto_connect, int client_id)
5077 struct gatt_server_info_t *conn_info = NULL;
5078 struct gatt_out_conn_info_t *out_conn_info = NULL;
5080 invocation_info_t *req_info = NULL;
5081 int ret = OAL_STATUS_SUCCESS;
5083 char *remote_address = NULL;
5085 BT_CHECK_PARAMETER(address, return);
5087 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5088 _bt_convert_addr_type_to_string(addr, address->addr);
5089 BT_DBG("GATT Client connect request for address [%s] client instance [%d]",
5093 /* Check if Remote Device is already under connection progress */
5094 req_info = _bt_get_request_info_data_from_function_name(BT_CONNECT_LE);
5096 remote_address = (char*)req_info->user_data;
5097 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5098 BT_DBG("Already Connection ongoing for same remote GATT Server address [%s]", remote_address);
5099 /* Return and wait for events to be sent to all apps */
5101 return BLUETOOTH_ERROR_IN_PROGRESS;
5105 /* Check if remote GATT Server is connected or not */
5106 conn_info = _bt_find_remote_gatt_server_info(addr);
5108 BT_ERR("GATT Server is already connected..");
5110 return BLUETOOTH_ERROR_ALREADY_CONNECT;
5113 /* TODO Check Requirement of holding Advertisement before initiating LE connect */
5116 /* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
5117 if (client_id == 0) {
5118 /* GATT CLient connect request sent by an app without any client instance [0] */
5119 BT_DBG("Assign default GATT client id [%d]", gatt_default_client);
5120 client_id = gatt_default_client;
5123 BT_INFO("Connect using CLient ID [%d]", client_id);
5124 ret = gattc_connect(client_id, (bt_address_t*)(address), auto_connect);
5126 if (ret != OAL_STATUS_SUCCESS) {
5127 BT_ERR("gattc_connect is failed. ret: %d", ret);
5129 _bt_restart_le_scan();
5130 return _bt_convert_oal_status_to_bt_error(ret);
5133 /* Mark this as outgoing connection */
5134 out_conn_info = g_new0(struct gatt_out_conn_info_t, 1);
5135 out_conn_info->addr = g_strdup(addr);
5136 out_conn_info->client_id = client_id;
5137 BT_INFO("Added outgoing connection info addr[%s]", out_conn_info->addr + 12);
5138 outgoing_gatt_conn_list = g_slist_append(outgoing_gatt_conn_list, out_conn_info);
5141 return BLUETOOTH_ERROR_NONE;
5144 int _bt_gatt_get_primary_services(char *address)
5146 BT_CHECK_PARAMETER(address, return);
5147 struct gatt_server_info_t *conn_info = NULL;
5148 invocation_info_t *req_info = NULL;
5149 int ret = OAL_STATUS_SUCCESS;
5151 /* Check if any app is already browsing primary services on the same remote GATT Server */
5152 req_info = _bt_get_request_info_data(BT_GATT_GET_PRIMARY_SERVICES, address);
5154 BT_INFO("Already Primary Service Browsing ongoing for same rmeote GATT Server");
5155 /* Return and wait for events to be sent to all apps */
5156 return BLUETOOTH_ERROR_NONE;
5159 /* Check if remote GATT Server is connected or not */
5160 conn_info = _bt_find_remote_gatt_server_info(address);
5162 BT_ERR("GATT Server is not yet connected..");
5163 return BLUETOOTH_ERROR_NOT_CONNECTED;
5166 BT_INFO("Get all services. GATT Server [%s] is connected, conn Id [%d]",
5167 conn_info->addr + 12, conn_info->connection_id);
5169 /* Send Primary Service Browsing request to stack */
5170 ret = gattc_search_service(conn_info->connection_id, NULL);
5171 if (ret != OAL_STATUS_SUCCESS) {
5172 BT_ERR("ret: %d", ret);
5173 return _bt_convert_oal_status_to_bt_error(ret);
5175 return BLUETOOTH_ERROR_NONE;
5178 int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc)
5180 BT_CHECK_PARAMETER(svc, return);
5181 struct gatt_server_info_t *conn_info = NULL;
5182 invocation_info_t *req_info = NULL;
5183 bluetooth_gatt_client_svc_prop_info_t *prop;
5184 oal_gatt_srvc_id_t srvc_id;
5185 int ret = OAL_STATUS_SUCCESS;
5188 /* Check if any app is already browsing characteristics of the same service on the same remote GATT Server */
5189 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_SERVICE_PROPERTIES);
5191 prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
5192 if (prop && !memcmp(svc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t))
5193 && !memcmp(prop->svc.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
5194 && prop->svc.instance_id == svc->svc.instance_id) {
5195 BT_INFO("Already Properties browsing for Primary Service ongoing for same remote GATT Server");
5196 /* Return and wait for events to be sent to all apps */
5197 return BLUETOOTH_ERROR_NONE;
5201 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5202 _bt_convert_addr_type_to_string(addr, svc->device_address.addr);
5204 /* Check if remote GATT Server is connected or not */
5205 conn_info = _bt_find_remote_gatt_server_info(addr);
5207 BT_ERR("GATT Server is not yet connected..");
5209 return BLUETOOTH_ERROR_NOT_CONNECTED;
5212 BT_DBG("Get all charc. GATT Server [%s] is connected, conn Id [%d]",
5213 conn_info->addr, conn_info->connection_id);
5215 srvc_id.is_prmry = TRUE;
5216 srvc_id.id.inst_id = svc->svc.instance_id;
5217 memcpy(srvc_id.id.uuid.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5219 /* Search All Characteristic */
5220 ret = gattc_get_characteristic(conn_info->connection_id, &srvc_id, NULL);
5221 if (ret != OAL_STATUS_SUCCESS) {
5222 BT_ERR("ret: %d", ret);
5224 return _bt_convert_oal_status_to_bt_error(ret);
5227 return BLUETOOTH_ERROR_NONE;
5230 int _bt_gatt_get_all_characteristic_properties(
5231 bluetooth_gatt_client_char_prop_info_t *chr)
5233 struct gatt_server_info_t *conn_info = NULL;
5234 invocation_info_t *req_info = NULL;
5235 bluetooth_gatt_client_char_prop_info_t *prop;
5236 oal_gatt_srvc_id_t srvc_id;
5237 oal_gatt_id_t char_id;
5238 int ret = OAL_STATUS_SUCCESS;
5241 BT_CHECK_PARAMETER(chr, return);
5243 /* Check if any app is already browsing descriptors of the same char of
5244 particular service on the same remote GATT Server */
5245 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_CHARACTERISTIC_PROPERTIES);
5247 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5248 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5249 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5250 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5251 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5252 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5253 BT_INFO("Already Properties browsing for Characteristic ongoing for same remote GATT Server");
5254 /* Return and wait for events to be sent to all apps */
5255 return BLUETOOTH_ERROR_NONE;
5259 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5260 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5262 /* Check if remote GATT Server is connected or not */
5263 conn_info = _bt_find_remote_gatt_server_info(addr);
5265 BT_ERR("GATT Server is not yet connected..");
5267 return BLUETOOTH_ERROR_NOT_CONNECTED;
5270 BT_DBG("Get all desc. GATT Server [%s] is connected, conn Id [%d]",
5271 conn_info->addr, conn_info->connection_id);
5273 srvc_id.is_prmry = TRUE;
5274 srvc_id.id.inst_id = chr->svc.instance_id;
5275 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5277 char_id.inst_id = chr->characteristic.instance_id;
5278 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5280 /* Search All Descriptors */
5281 ret = gattc_get_descriptor(conn_info->connection_id, &srvc_id, &char_id, NULL);
5282 if (ret != OAL_STATUS_SUCCESS) {
5283 BT_ERR("ret: %d", ret);
5285 return _bt_convert_oal_status_to_bt_error(ret);
5288 return BLUETOOTH_ERROR_NONE;
5291 int _bt_gatt_read_characteristic_value(
5292 bluetooth_gatt_client_char_prop_info_t *chr)
5294 struct gatt_server_info_t *conn_info = NULL;
5295 invocation_info_t *req_info = NULL;
5296 bluetooth_gatt_client_char_prop_info_t *prop;
5297 oal_gatt_srvc_id_t srvc_id;
5298 oal_gatt_id_t char_id;
5299 int ret = OAL_STATUS_SUCCESS;
5302 BT_CHECK_PARAMETER(chr, return);
5304 /* Check if any app is already Reading characteristic of the same char of
5305 particular service on the same remote GATT Server */
5306 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_CHARACTERISTIC);
5308 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5309 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5310 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5311 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5312 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5313 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5314 BT_INFO("Already Characteristic value Read operation in progress for same remote GATT Server");
5315 /* Return and wait for events to be sent to all apps */
5316 return BLUETOOTH_ERROR_NONE;
5320 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5321 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5323 /* Check if remote GATT Server is connected or not */
5324 conn_info = _bt_find_remote_gatt_server_info(addr);
5326 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5327 conn_info->addr, conn_info->connection_id);
5329 BT_ERR("GATT Server is not yet connected..");
5331 return BLUETOOTH_ERROR_NOT_CONNECTED;
5334 srvc_id.is_prmry = TRUE;
5335 srvc_id.id.inst_id = chr->svc.instance_id;
5336 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5338 char_id.inst_id = chr->characteristic.instance_id;
5339 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5341 /* Search All Descriptors */
5342 ret = gattc_read_characteristic(conn_info->connection_id, &srvc_id, &char_id, OAL_GATT_AUTH_REQ_NONE);
5343 if (ret != OAL_STATUS_SUCCESS) {
5344 BT_ERR("ret: %d", ret);
5346 return _bt_convert_oal_status_to_bt_error(ret);
5349 return BLUETOOTH_ERROR_NONE;
5352 int _bt_gatt_read_descriptor_value(
5353 bluetooth_gatt_client_desc_prop_info_t *desc)
5355 struct gatt_server_info_t *conn_info = NULL;
5356 invocation_info_t *req_info = NULL;
5357 bluetooth_gatt_client_desc_prop_info_t *prop;
5358 oal_gatt_srvc_id_t srvc_id;
5359 oal_gatt_id_t char_id;
5360 oal_gatt_id_t desc_id;
5361 int ret = OAL_STATUS_SUCCESS;
5364 BT_CHECK_PARAMETER(desc, return);
5366 /* Check if any app is already Reading descriptors of the same char of
5367 particular service on the same remote GATT Server */
5368 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_DESCRIPTOR_VALUE);
5370 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5371 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5372 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5373 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5374 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5375 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5376 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5377 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5378 BT_INFO("Already Descriptor value Read operation in progress for same remote GATT Server");
5379 /* Return and wait for events to be sent to all apps */
5380 return BLUETOOTH_ERROR_NONE;
5384 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5385 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5387 /* Check if remote GATT Server is connected or not */
5388 conn_info = _bt_find_remote_gatt_server_info(addr);
5390 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5391 conn_info->addr, conn_info->connection_id);
5393 BT_ERR("GATT Server is not yet connected..");
5395 return BLUETOOTH_ERROR_NOT_CONNECTED;
5398 srvc_id.is_prmry = TRUE;
5399 srvc_id.id.inst_id = desc->svc.instance_id;
5400 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5402 char_id.inst_id = desc->characteristic.instance_id;
5403 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5405 desc_id.inst_id = desc->descriptor.instance_id;
5406 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5408 /* Search All Descriptors */
5409 ret = gattc_read_descriptor(conn_info->connection_id, &srvc_id, &char_id,
5410 &desc_id, OAL_GATT_AUTH_REQ_NONE);
5411 if (ret != OAL_STATUS_SUCCESS) {
5412 BT_ERR("ret: %d", ret);
5414 return _bt_convert_oal_status_to_bt_error(ret);
5417 return BLUETOOTH_ERROR_NONE;
5421 int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5423 struct gatt_server_info_t *conn_info = NULL;
5424 oal_gatt_srvc_id_t srvc_id;
5425 oal_gatt_id_t char_id;
5426 int ret = OAL_STATUS_SUCCESS;
5429 BT_CHECK_PARAMETER(chr, return);
5431 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5432 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5434 /* Check if remote GATT Server is connected or not */
5435 conn_info = _bt_find_remote_gatt_server_info(addr);
5437 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5438 conn_info->addr, conn_info->connection_id);
5440 BT_ERR("GATT Server is not yet connected..");
5442 return BLUETOOTH_ERROR_NOT_CONNECTED;
5445 srvc_id.is_prmry = TRUE;
5446 srvc_id.id.inst_id = chr->svc.instance_id;
5447 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5449 char_id.inst_id = chr->characteristic.instance_id;
5450 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5452 ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
5454 if (ret != OAL_STATUS_SUCCESS) {
5455 BT_ERR("ret: %d", ret);
5457 return _bt_convert_oal_status_to_bt_error(ret);
5459 BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
5461 return BLUETOOTH_ERROR_NONE;
5465 int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
5468 struct gatt_server_info_t *conn_info = NULL;
5469 oal_gatt_srvc_id_t srvc_id;
5470 oal_gatt_id_t char_id;
5471 int ret = OAL_STATUS_SUCCESS;
5474 BT_CHECK_PARAMETER(chr, return);
5476 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5477 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5479 /* Check if remote GATT Server is connected or not */
5480 conn_info = _bt_find_remote_gatt_server_info(addr);
5482 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5483 conn_info->addr, conn_info->connection_id);
5485 BT_ERR("GATT Server is not yet connected..");
5487 return BLUETOOTH_ERROR_NOT_CONNECTED;
5490 srvc_id.is_prmry = TRUE;
5491 srvc_id.id.inst_id = chr->svc.instance_id;
5492 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5494 char_id.inst_id = chr->characteristic.instance_id;
5495 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5497 ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
5498 OAL_GATT_AUTH_REQ_NONE, fd, mtu);
5499 if (ret != OAL_STATUS_SUCCESS) {
5500 BT_ERR("ret: %d", ret);
5502 return _bt_convert_oal_status_to_bt_error(ret);
5504 BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
5506 return BLUETOOTH_ERROR_NONE;
5511 /* Write Characteristic */
5512 int _bt_gatt_write_characteristic_value_by_type(
5513 bluetooth_gatt_client_char_prop_info_t *chr,
5514 bluetooth_gatt_att_data_t *data,
5515 bluetooth_gatt_write_type_e write_type)
5517 struct gatt_server_info_t *conn_info = NULL;
5518 invocation_info_t *req_info = NULL;
5519 bluetooth_gatt_client_char_prop_info_t *prop;
5520 oal_gatt_srvc_id_t srvc_id;
5521 oal_gatt_id_t char_id;
5522 int ret = OAL_STATUS_SUCCESS;
5525 BT_CHECK_PARAMETER(chr, return);
5526 BT_CHECK_PARAMETER(data, return);
5528 /* Check if any app is already writing same char of
5529 particular service on the same remote GATT Server */
5530 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE);
5532 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
5533 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5534 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5535 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5536 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5537 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
5538 BT_INFO("Already Characteristic Write Value operation in progress for same remote GATT Server");
5539 /* Return and wait for events to be sent to all apps */
5540 return BLUETOOTH_ERROR_NONE;
5544 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5545 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5547 /* Check if remote GATT Server is connected or not */
5548 conn_info = _bt_find_remote_gatt_server_info(addr);
5550 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5551 conn_info->addr, conn_info->connection_id);
5553 BT_ERR("GATT Server is not yet connected..");
5555 return BLUETOOTH_ERROR_NOT_CONNECTED;
5558 srvc_id.is_prmry = TRUE;
5559 srvc_id.id.inst_id = chr->svc.instance_id;
5560 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5562 char_id.inst_id = chr->characteristic.instance_id;
5563 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5565 /* Write CHar value */
5566 ret = gattc_write_characteristic(conn_info->connection_id,
5568 (oal_gatt_write_type_t)write_type, data->length,
5569 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5570 if (ret != OAL_STATUS_SUCCESS) {
5571 BT_ERR("ret: %d", ret);
5573 return _bt_convert_oal_status_to_bt_error(ret);
5576 return BLUETOOTH_ERROR_NONE;
5579 /* Write Descriptor */
5580 int _bt_gatt_write_descriptor_value_by_type(
5581 bluetooth_gatt_client_desc_prop_info_t *desc,
5582 bluetooth_gatt_att_data_t *data,
5583 bluetooth_gatt_write_type_e write_type)
5585 struct gatt_server_info_t *conn_info = NULL;
5586 invocation_info_t *req_info = NULL;
5587 bluetooth_gatt_client_desc_prop_info_t *prop;
5588 oal_gatt_srvc_id_t srvc_id;
5589 oal_gatt_id_t char_id;
5590 oal_gatt_id_t desc_id;
5591 int ret = OAL_STATUS_SUCCESS;
5595 BT_CHECK_PARAMETER(desc, return);
5596 BT_CHECK_PARAMETER(data, return);
5600 /* Check if any app is already writing on same Descriptor of the same char of
5601 particular service on the same remote GATT Server */
5602 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_DESCRIPTOR_VALUE);
5604 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5605 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5606 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5607 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5608 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5609 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5610 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5611 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5612 BT_INFO("Already Descriptor value Write operation in progress for same remote GATT Server");
5613 /* Return and wait for events to be sent to all apps */
5614 return BLUETOOTH_ERROR_NONE;
5618 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5619 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5621 /* Check if remote GATT Server is connected or not */
5622 conn_info = _bt_find_remote_gatt_server_info(addr);
5624 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5625 conn_info->addr, conn_info->connection_id);
5627 BT_ERR("GATT Server is not yet connected..");
5629 return BLUETOOTH_ERROR_NOT_CONNECTED;
5632 srvc_id.is_prmry = TRUE;
5633 srvc_id.id.inst_id = desc->svc.instance_id;
5634 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5636 char_id.inst_id = desc->characteristic.instance_id;
5637 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5639 desc_id.inst_id = desc->descriptor.instance_id;
5640 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5643 BT_INFO("Connection ID [%d] write type [%d] data length [%d]", conn_info->connection_id, write_type, data->length);
5644 for (k = 0; k < data->length; k++)
5645 BT_INFO("Data[%d] [0x%x]", k, data->data[k]);
5647 ret = gattc_write_descriptor(conn_info->connection_id,
5648 &srvc_id, &char_id, &desc_id,
5649 (oal_gatt_write_type_t)write_type, data->length,
5650 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5651 if (ret != OAL_STATUS_SUCCESS) {
5652 BT_ERR("ret: %d", ret);
5654 return _bt_convert_oal_status_to_bt_error(ret);
5657 return BLUETOOTH_ERROR_NONE;
5660 int _bt_gatt_watch_characteristic(
5661 bluetooth_gatt_client_char_prop_info_t *chr,
5665 struct gatt_server_info_t *conn_info = NULL;
5666 oal_gatt_srvc_id_t srvc_id;
5667 oal_gatt_id_t char_id;
5668 int ret = OAL_STATUS_SUCCESS;
5671 BT_CHECK_PARAMETER(chr, return);
5673 BT_INFO("Client ID [%d] Is Notify [%d]", client_id, is_notify);
5675 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5676 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5678 /* Check if remote GATT Server is connected or not */
5679 conn_info = _bt_find_remote_gatt_server_info(addr);
5681 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5682 conn_info->addr, conn_info->connection_id);
5684 BT_ERR("GATT Server is not yet connected..");
5686 return BLUETOOTH_ERROR_NOT_CONNECTED;
5688 srvc_id.is_prmry = TRUE;
5689 srvc_id.id.inst_id = chr->svc.instance_id;
5690 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5692 char_id.inst_id = chr->characteristic.instance_id;
5693 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5695 /* Register or unregister Notification characteristic */
5697 ret = gattc_register_for_notification(conn_info->connection_id,
5698 (bt_address_t*)&(chr->device_address),
5699 &srvc_id, &char_id);
5701 ret = gattc_deregister_for_notification(conn_info->connection_id,
5702 (bt_address_t*)&(chr->device_address),
5703 &srvc_id, &char_id);
5705 BT_INFO("Result[%d]", ret);
5706 if (ret != OAL_STATUS_SUCCESS) {
5707 BT_ERR("ret: %d", ret);
5709 return _bt_convert_oal_status_to_bt_error(ret);
5712 return BLUETOOTH_ERROR_NONE;
5716 int _bt_disconnect_le_device(bluetooth_device_address_t *address,
5719 struct gatt_server_info_t *conn_info = NULL;
5720 struct gatt_client_info_t *rem_client_conn_info = NULL;
5721 invocation_info_t *req_info = NULL;
5722 int ret = OAL_STATUS_SUCCESS;
5724 char *remote_address = NULL;
5726 BT_CHECK_PARAMETER(address, return);
5728 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5729 _bt_convert_addr_type_to_string(addr, address->addr);
5730 BT_INFO("GATT Client Disconnect request for address [%s]", addr + 12);
5732 /* Check if Remote Device is already under connection progress */
5733 req_info = _bt_get_request_info_data_from_function_name(BT_DISCONNECT_LE);
5735 remote_address = (char*)req_info->user_data;
5736 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5737 BT_DBG("Already DisConnection ongoing for same remote GATT Server address [%s]", remote_address);
5738 /* Return success and wait for events to be sent to all apps */
5740 return BLUETOOTH_ERROR_IN_PROGRESS;
5743 /* Check if remote GATT Server is connected or not */
5744 conn_info = _bt_find_remote_gatt_server_info(addr);
5746 /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
5747 if (client_id == 0) {
5748 BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
5750 BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
5751 client_id = gatt_default_client;
5754 BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
5755 ret = gattc_disconnect(client_id, (bt_address_t*)(address),
5756 conn_info->connection_id);
5758 /* check if remote client is connected */
5759 rem_client_conn_info = _bt_find_remote_gatt_client_info(addr);
5761 if (!rem_client_conn_info || client_id != 0) {
5762 BT_ERR("GATT device is not connected..");
5764 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
5767 BT_INFO("Disconnect remote gatt client ");
5769 ret = gatts_disconnect(rem_client_conn_info->instance_id,
5770 (bt_address_t*)(address), rem_client_conn_info->connection_id);
5773 if (ret != OAL_STATUS_SUCCESS) {
5774 BT_ERR("ret: %d", ret);
5776 return _bt_convert_oal_status_to_bt_error(ret);
5779 return BLUETOOTH_ERROR_NONE;
5782 int _bt_gatt_watch_service_changed_indication(const char *sender,
5783 bluetooth_device_address_t *address,
5784 gboolean is_enabled)
5787 bt_service_app_info_t *info = NULL;
5789 BT_INFO("%s Servic changed Indication watcher for app [%s]",
5790 is_enabled ? "Enable":"Disable", sender);
5792 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5795 if (g_strcmp0(sender, info->sender) == 0 &&
5796 memcmp(info->address.addr, address->addr,
5797 sizeof(bluetooth_device_address_t)) == 0) {
5798 BT_DBG("Found GATT client App.. [%s], sender [%s]", info->uuid, info->sender);
5799 info->is_watcher_enabled = is_enabled;
5803 return BLUETOOTH_ERROR_NONE;
5806 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
5808 bt_service_app_info_t *info = NULL;
5811 BT_DBG("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
5813 /* Unregister CLient instance associated with address X. It is possible that another app still
5814 has client_id valid for same remote address */
5815 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5818 /* Exact matching of sender */
5819 if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) { /* Check for only valid GATT client Instance */
5820 numapps[k].client_id = -1;
5821 numapps[k].is_initialized = FALSE;
5822 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
5823 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
5824 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
5826 /* Its a GATT Client Instance */
5827 ret = gattc_deregister(client_id);
5828 if (ret != OAL_STATUS_SUCCESS) {
5829 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
5830 return _bt_convert_oal_status_to_bt_error(ret);
5832 return BLUETOOTH_ERROR_NONE;
5837 return BLUETOOTH_ERROR_NOT_FOUND;
5840 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data)
5842 int result = BLUETOOTH_ERROR_NONE;
5843 struct gatt_server_info_t *conn_info = NULL;
5844 GVariant *param = NULL;
5848 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
5849 if (conn_info == NULL) {
5850 BT_ERR("Cant find connection Information");
5854 BT_DBG("GATT Client: MTU Configured from addr [%s] status [%d] MTU size [%d]",
5855 conn_info->addr, event_data->status, event_data->mtu);
5857 if (event_data->status != OAL_STATUS_SUCCESS)
5858 result = BLUETOOTH_ERROR_INTERNAL;
5860 /* DBUS Return fo BT_REQ_ATT_MTU for all the apps */
5861 __bt_gatt_handle_pending_request_info(result, BT_REQ_ATT_MTU, conn_info->addr,
5862 BT_ADDRESS_STRING_SIZE);
5864 if (result == BLUETOOTH_ERROR_NONE) {
5865 mtu = event_data->mtu;
5866 param = g_variant_new("(isqy)",
5872 /* Send event to BT-API */
5873 _bt_send_event(BT_DEVICE_EVENT,
5874 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
5877 /* Update the MTU for current connection */
5878 __bt_update_mtu_gatt_device(conn_info->addr, event_data->mtu);
5882 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address)
5885 struct gatt_mtu_info_t *info = NULL;
5887 for (l = gatt_mtu_info_list; l != NULL; l = g_slist_next(l)) {
5888 info = (struct gatt_mtu_info_t*)l->data;
5892 if (!g_strcmp0(info->addr, address)) {
5893 BT_DBG("Remote GATT device found addr[%s]", info->addr);
5898 BT_DBG("Not found Remote GATT device addr[%s]", address);
5902 static void __bt_remove_mtu_gatt_device(char *address)
5904 struct gatt_mtu_info_t *dev_info = NULL;
5906 dev_info = __bt_find_mtu_gatt_device(address);
5909 BT_DBG("removing the gatt device from mtu list");
5910 gatt_mtu_info_list = g_slist_remove(gatt_mtu_info_list, dev_info);
5911 g_free(dev_info->addr);
5916 static void __bt_add_mtu_gatt_device(char *address)
5918 struct gatt_mtu_info_t *dev_info = NULL;
5920 dev_info = __bt_find_mtu_gatt_device(address);
5923 BT_DBG("adding the gatt device in mtu list");
5924 dev_info = g_new0(struct gatt_mtu_info_t, 1);
5925 dev_info->addr = g_strdup(address);
5926 dev_info->att_mtu = BT_DEFAULT_ATT_MTU;
5927 gatt_mtu_info_list = g_slist_append(gatt_mtu_info_list, dev_info);
5931 static void __bt_update_mtu_gatt_device(char *address, int mtu)
5933 struct gatt_mtu_info_t *dev_info = NULL;
5935 dev_info = __bt_find_mtu_gatt_device(address);
5938 dev_info->att_mtu = mtu;
5942 int _bt_gatt_get_data_batching_available_packets(
5943 guint *available_packets)
5945 int ret = OAL_STATUS_SUCCESS;
5947 BT_CHECK_PARAMETER(available_packets, return);
5949 ret = gatt_get_data_batching_available_packets(available_packets);
5950 if (ret != OAL_STATUS_SUCCESS) {
5951 BT_ERR("ret: %d", ret);
5952 return _bt_convert_oal_status_to_bt_error(ret);
5955 return BLUETOOTH_ERROR_NONE;
5958 int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address,
5959 int packet_threshold, int timeout)
5961 int ret = OAL_STATUS_SUCCESS;
5962 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5964 BT_CHECK_PARAMETER(address, return);
5966 _bt_convert_addr_type_to_string(remote_address, address->addr);
5967 BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]",
5968 remote_address, packet_threshold, timeout);
5970 ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout);
5972 if (ret != OAL_STATUS_SUCCESS) {
5973 BT_ERR("ret: %d", ret);
5974 return _bt_convert_oal_status_to_bt_error(ret);
5977 return BLUETOOTH_ERROR_NONE;
5980 int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address)
5982 int ret = OAL_STATUS_SUCCESS;
5983 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5985 BT_CHECK_PARAMETER(address, return);
5987 _bt_convert_addr_type_to_string(remote_address, address->addr);
5988 BT_INFO("Disable GATT data batching. address[%s]", remote_address);
5990 ret = gatt_disable_data_batching((bt_address_t*)(address));
5992 if (ret != OAL_STATUS_SUCCESS) {
5993 BT_ERR("ret: %d", ret);
5994 return _bt_convert_oal_status_to_bt_error(ret);
5997 return BLUETOOTH_ERROR_NONE;