4 * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
6 * Contact: Anupam Roy (anupam.r@samsung.com)
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 #include "bt-service-common.h"
24 #include "bt-service-core-adapter.h"
25 #include "bt-service-event-receiver.h"
26 #include "bt-request-handler.h"
27 #include "bluetooth-api.h"
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
31 #include "bt-service-util.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
35 #include "bt-internal-types.h"
36 #include "bt-service-gatt.h"
37 #include "bt-service-gatt.h"
38 #include "bt-service-core-device.h"
39 #include "bt-service-core-adapter-le.h"
40 #include "bluetooth-gatt-client-api.h"
42 #include <oal-hardware.h>
43 #include <oal-manager.h>
44 #include <oal-event.h>
45 #include <oal-adapter-mgr.h>
46 #include <oal-device-mgr.h>
49 #define BT_GATT_TRANSPORT_LE 0
50 #define BT_GATT_TRANSPORT_BR_EDR 1
51 #define BT_GATT_TRANSPORT_LE_BR_EDR 2
52 #define BT_UUID_STRING_MAX 64
53 #define BT_SENDER_MAX_LENGTH 50
54 #define MAX_APPS_SUPPORTED 11 /* Slot 0 is not used */
55 #define BT_DEFAULT_ATT_MTU 23
57 #define UUID_MAX_LEN 50
59 #ifdef TIZEN_BLUEDROID_PORTING
68 bluetooth_gatt_att_request_type_e request_type;
69 int prep_request_count;
70 } bt_gatt_prep_write_data_t;
72 static GSList *g_pending_write_list = NULL;
75 #define BDADDR_ANY (&(bluetooth_device_address_t) {{0, 0, 0, 0, 0, 0} })
77 static char uuid_list[NUM_UUID][BT_UUID_STRING_MAX] = {"0000b00b-0000-0000-f065-080080fa49b5", /* Used by BLEAPP */
78 "0000b00b-1111-1111-0123-456789ab0cd2", /* Used by BLEAPP */
79 "0000b00b-2222-1111-0123-456789ab0cd2",
80 "0000b00b-3333-1111-0123-456789ab0cd2",
81 "0000b00b-4444-1111-0123-456789ab0cd2",
82 "0000b00b-5555-1111-0123-456789ab0cd2",
83 "0000b00b-6666-1111-0123-456789ab0cd2",
84 "0000b00b-7777-1111-0123-456789ab0cd2",
85 "0000b00b-8888-1111-0123-456789ab0cd2",
86 "0000b00b-9999-1111-0123-456789ab0cd2",
87 "0000b00b-aaaa-1111-0123-456789ab0cd2",
88 "0000b00b-bbbb-1111-0123-456789ab0cd2",
89 "0000b00b-cccc-1111-0123-456789ab0cd2",
90 "0000b00b-dddd-1111-0123-456789ab0cd2",
91 "0000b00b-eeee-1111-0123-456789ab0cd2",
92 "0000b00b-ffff-1111-0123-456789ab0cd2",
93 "0000b00c-0000-1111-0123-456789ab0cd2",
94 "0000b00c-1111-1111-0123-456789ab0cd2",
95 "0000b00c-2222-1111-0123-456789ab0cd2",
96 "0000b00c-3333-1111-0123-456789ab0cd2"};
98 /* Reserved GATT client Instance UUID. This is used only internally by bt-service */
99 #define DEFAULT_GATT_CLIENT_UUID "0000a00a-1111-1111-0123-456789abcdef"
101 static int gatt_default_client = -1;
104 gboolean is_registered;
105 bluetooth_device_address_t addr;
106 unsigned char svc_uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
108 unsigned char char_uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
110 } bt_gatt_notif_reg_info_t;
112 struct gatt_out_conn_info_t {
113 int client_id; /* This value unique identifies a GATT Client instance */
114 char *addr; /* Remote GATT Server address */
117 /* Linked List of outgoing gatt connection list
118 Note: This is valid only for local GATT client */
119 static GSList *outgoing_gatt_conn_list = NULL;
121 /* GATT Server Info(Local Client) List Structure */
122 struct gatt_server_info_t {
123 int connection_id; /* This value will uniquely identify a GATT client-server connection */
124 int client_id; /* This value unique identifies a GATT Client instance */
125 char *addr; /* Remote GATT Server address */
128 struct gatt_client_info_t {
129 int connection_id; /* This value will uniquely identify a GATT client-server connection */
130 int instance_id; /* This value unique identifies a GATT server instance */
131 char *addr; /* Remote GATT client address */
135 * Remove this feature if code is verified
136 * Remove gatt_client/server_info_t and use gatt_conn_info_t
137 * Remove gatt_client/server_info_list and use gatt_conn_info_list
139 //#define __INTEGRATE_GATT_INFO__ // TODO: this feature can be used if easy setup scenario is fully supported and the name need to be changed to avoid confusion with existing GATT flags
140 #ifndef __INTEGRATE_GATT_INFO__
141 /* Linked List of connected Remote GATT Servers */
142 static GSList *gatt_server_info_list = NULL;
143 /* Linked List of connected Remote GATT clients */
144 static GSList *gatt_client_info_list = NULL;
146 /* GATT Connection Info List Structure */
147 struct gatt_conn_info_t {
148 char *addr; /* Remote GATT address */
149 int connection_id; /* This value will uniquely identify a GATT client-server connection */
150 int client_id; /* This value unique identifies a GATT Client instance */
151 int instance_id; /* This value unique identifies a GATT Server instance */
154 /* Linked List of connected Remote GATT info */
155 static GSList *gatt_conn_info_list = NULL;
156 #define gatt_server_info_t gatt_conn_info_t
157 #define gatt_client_info_t gatt_conn_info_t
158 #define gatt_server_info_list gatt_conn_info_list
159 #define gatt_client_info_list gatt_conn_info_list
164 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN]; /* If any service added */
165 } bt_gatt_svc_changed_info_t;
170 // bluetooth_device_address_t address; /* Remote BLE Device Address */
171 GSList *services; /* List of all services of above remote device */
172 int count; /* Number of services browsed from remote device */
173 bt_gatt_svc_changed_info_t info;
174 } bt_gatt_service_info_list_t;
177 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
181 GSList *included_svcs;
182 gboolean is_removed; /* 0 => Service is added, 1=> removed */
183 } bt_gatt_service_info_t;
186 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
190 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
192 } bt_gatt_char_info_t;
195 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
198 unsigned char val[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
199 } bt_gatt_descriptor_info_t;
202 unsigned char uuid[BLUETOOTH_UUID_HEX_MAX_LEN];
204 } bt_gatt_included_service_info_t;
206 static GSList *list_gatt_info = NULL;
208 /* App Information structure */
211 char sender[BT_SENDER_MAX_LENGTH];
212 char uuid[BT_UUID_STRING_MAX];
215 bluetooth_advertising_data_t adv_data; /* Will store adv data for specific slot */
217 bluetooth_scan_resp_data_t scan_rsp; /* Will store scan rsp data for specific slot */
219 gboolean is_initialized;
220 GSList *service_handles;
221 int client_id; /* GATT Client instance ID */
222 bluetooth_device_address_t address; /* Remote BLE Device Address */
223 gboolean is_watcher_enabled;
224 } bt_service_app_info_t;
226 /* GATT Server Request Info Structure */
227 struct gatt_server_req_info {
228 int connection_id; /* This value will uniquely identify a GATT client-server connection */
229 int request_id; /* This is an unique transaction ID assigned against each request by stack */
230 int attribute_handle; /* GATT server attribute handle */
231 int offset; /* GATT server attribute offset on which request is invoked by GATT client */
232 bluetooth_gatt_att_request_type_e request_type; /* Read or Write request */
233 char *addr; /* Remote GATT client address */
236 /* GATT Indicate confirm result */
237 struct gatt_indicate_cfm_result_info_t {
238 int result; /* Result of event */
239 char *addr; /* Remote GATT client address */
240 int att_hdl; /* Characteristic Attribute handle */
241 int completed; /* 1 if last event, otheriwse 0 */
244 /* Request Search Utility method */
245 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
246 bluetooth_gatt_att_request_type_e req_type);
248 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
249 bluetooth_gatt_server_indication_params_t *param);
251 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info);
253 static void __bt_free_service_info(bt_gatt_service_info_t *service_info);
255 static int __bt_unregister_gatt_client_instance(int client_if);
257 static void __bt_service_reset_gatt_data(void);
259 static void __bt_handle_client_instance_registered(event_gattc_register_t *data);
260 static void __bt_handle_client_connected(event_gattc_conn_t *event_data);
261 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data);
262 static void __bt_handle_client_service_search_completed(event_gattc_conn_status_t *event_data);
263 static void __bt_handle_client_service_search_result(event_gattc_service_result_t *event_data);
264 static void __bt_handle_client_characteristic_search_result(
265 event_gattc_characteristic_result_t *event_data);
266 static void __bt_handle_client_descriptor_search_result(event_gattc_descriptor_result_t *event_data);
267 static void __bt_handle_client_characteristic_read_data(event_gattc_read_data *event_data);
268 static void __bt_handle_client_descriptor_read_data(event_gattc_read_data *event_data);
269 static void __bt_handle_client_characteristic_write_data(event_gattc_write_data *event_data);
270 static void __bt_handle_client_descriptor_write_data(event_gattc_write_data *event_data);
271 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data);
272 static void __bt_handle_client_notification_registered(event_gattc_regdereg_notify_t *event_data,
273 gboolean is_registered);
274 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data);
275 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data);
276 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data);
278 static int __bt_unregister_gatt_server_instance(int server_instance);
279 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info);
280 #ifdef TIZEN_BLUEDROID_PORTING
281 static void __bt_remove_all_prep_write_req(int conn_id);
285 struct gatt_mtu_info_t {
286 char *addr; /* Remote GATT Server address */
290 static GSList *gatt_mtu_info_list = NULL;
292 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address);
293 static void __bt_remove_mtu_gatt_device(char *address);
294 static void __bt_add_mtu_gatt_device(char *address);
295 static void __bt_update_mtu_gatt_device(char *address, int mtu);
297 /* Linked List of GATT requests from Remote GATT Clients */
298 static GSList *gatt_server_requests = NULL;
300 /* Number of clients to be notified to */
301 static int num_indicate_clients;
303 /* List of applications */
304 static bt_service_app_info_t numapps[MAX_APPS_SUPPORTED];
306 static void __bt_gatt_handle_pending_request_info(int result,
307 int service_function, void *data, unsigned int size);
309 static void __bt_handle_server_instance_registered(event_gatts_register_t *data);
311 static void __bt_gatt_event_handler(int event_type, gpointer event_data);
318 void _bt_check_adv_app_termination(const char *name)
320 bt_service_app_info_t *app = NULL;
322 int apps[MAX_APPS_SUPPORTED] = { 0, };
324 ret_if(NULL == name);
326 memset(&apps, -1, sizeof(apps));
328 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
331 /* Search for a app which has same sender and stop adv is running */
332 if (strcasecmp(app->sender, name) == 0 && app->is_initialized == TRUE) {
333 BT_DBG("numapps[%d] Match found, name: %s", k, name);
335 /* TODO 2: Need to manage app info as list, not array.
336 This loop always run for MAX count if any apps are terminated.
339 /* Save instances of all apps that need to be unregistered */
340 if (app->instance_id != -1) {
342 /* Unregister all service handles with stack */
343 __bt_remove_all_service_handles(app);
345 /* If Advertising is enabled, stop it */
346 if (app->adv_handle != 0) {
347 BT_INFO("Stop advertising on instance ID [%d]", app->instance_id);
348 /* Disable adv if running */
349 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
350 app->adv_handle, name);
351 _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE);
354 apps[app->instance_id] = BT_GATT_SERVER; /* App holds a GATT server Instance */
355 } else if (app->client_id != -1) {
357 apps[app->client_id] = BT_GATT_CLIENT; /* App holds a GATT client Instance */
362 /* Unregister all apps one by one */
363 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
364 if (apps[k] == BT_GATT_SERVER) {
365 BT_INFO("Unregister server app[%d]", k);
366 /* Unregister server instance */
367 __bt_unregister_gatt_server_instance(k);
368 } else if (apps[k] == BT_GATT_CLIENT) {
369 BT_INFO("Unregister client app[%d]", k);
370 /* Unregister client instance */
371 __bt_unregister_gatt_client_instance(k);
376 static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
377 bluetooth_gatt_server_indication_params_t *param)
380 int ret = OAL_STATUS_SUCCESS;
381 int result = OAL_STATUS_INTERNAL_ERROR;
383 BT_INFO("Current total number of connected clients [%d]", g_slist_length(gatt_client_info_list));
384 for (l = gatt_client_info_list; l != NULL; l = l->next) {
385 struct gatt_client_info_t *info = l->data;
388 BT_INFO("GATT Remote client address [%s] connection Id [%d]", info->addr, info->connection_id);
390 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
391 info->connection_id, data->length,
392 param->need_confirmation, (char *)(&data->data[0]));
394 BT_INFO("Send Indication to GATT client [%s] result: [%d]", info->addr, ret);
395 if (ret == OAL_STATUS_SUCCESS) {
396 BT_INFO("Send Indication sent successfully to GATT client [%s]", info->addr);
398 num_indicate_clients++;
402 BT_INFO("Indication sending done for total number of clients [%d]", num_indicate_clients);
406 static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
407 bluetooth_gatt_att_request_type_e req_type)
411 for (l = gatt_server_requests; l != NULL; l = l->next) {
412 struct gatt_server_req_info *req_info = l->data;
414 if (req_info && req_info->request_id == request_id && req_info->request_type == req_type) {
415 BT_DBG("GATT Server request info found Req ID [%d] handle [%d] conn ID [%d]",
416 req_info->request_id, req_info->attribute_handle, req_info->connection_id);
420 BT_ERR("Gatt Request not found");
424 static void __bt_gatt_server_release_request_info(const char *address)
427 struct gatt_server_req_info *req_info = NULL;
429 for (l = gatt_server_requests; l != NULL; l = g_slist_next(l)) {
431 if (req_info == NULL)
434 if (g_strcmp0(req_info->addr, address) == 0) {
435 BT_DBG("Remove unhandled req_info %s", address);
436 g_free(req_info->addr);
437 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
443 void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle)
447 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
448 if (numapps[k].is_initialized == 1 && numapps[k].instance_id == server_inst) {
449 *adv_handle = numapps[k].adv_handle;
455 char * _bt_gatt_get_default_gatt_client_uuid(void)
457 return g_strdup(DEFAULT_GATT_CLIENT_UUID);
461 static void __bt_register_default_gatt_client()
466 uuid_str = _bt_gatt_get_default_gatt_client_uuid();
467 _bt_string_to_uuid(uuid_str, (service_uuid_t*)&uuid);
469 BT_INFO("Register Default GATT client uuid [%s]", uuid_str);
471 if (OAL_STATUS_SUCCESS != gattc_register(&uuid)) /* for only Smart Control */
472 BT_ERR("gattc register failed");
477 int _bt_gatt_init(void)
479 const char *stack_name = NULL;
484 result = gatt_enable();
485 if (result != OAL_STATUS_SUCCESS) {
486 BT_ERR("gatt Init failed");
487 return _bt_convert_oal_status_to_bt_error(result);
490 /* Register gatt event handler */
491 _bt_service_register_event_handler_callback(BT_GATT_MODULE, __bt_gatt_event_handler);
493 __bt_service_reset_gatt_data();
495 stack_name = oal_get_stack_name();
497 if (stack_name && g_strcmp0(stack_name, "bluez") == 0) {
498 /*In the platform, defacult gatt client should be registered */
499 __bt_register_default_gatt_client();
503 return BLUETOOTH_ERROR_NONE;
506 static void __bt_service_reset_gatt_data(void)
510 BT_INFO("Rest numapp");
513 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
514 numapps[k].is_initialized = 0;
515 numapps[k].instance_id = -1;
516 numapps[k].adv_handle = 0;
517 numapps[k].adv_instance = -1;
518 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
519 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
520 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
521 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
522 numapps[k].adv_data_len = 0;
523 numapps[k].scan_rsp_len = 0;
526 numapps[k].client_id = -1;
527 memset(numapps[k].address.addr, 0x00, BLUETOOTH_ADDRESS_LENGTH);
528 numapps[k].is_watcher_enabled = FALSE;
532 void _bt_gatt_deinit(void)
534 BT_INFO("GATT deinit");
536 /* Un-register the default gatt client before */
537 __bt_unregister_gatt_client_instance(gatt_default_client);
539 if (OAL_STATUS_SUCCESS != gatt_disable())
540 BT_ERR("gatt deinit failed");
542 /* Un-register gatt event handler */
543 _bt_service_unregister_event_handler_callback(BT_GATT_MODULE);
545 __bt_service_reset_gatt_data();
548 void _bt_update_adv_handle(const char *sender, int adv_handle)
551 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
552 bt_service_app_info_t *info = NULL;
554 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
556 /* Do not update client instance */
557 if (info->instance_id == -1)
559 /* Search for a app which has same sender and adv handle as 0 */
560 if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0)
561 info->adv_handle = adv_handle;
565 int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
568 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
569 bt_service_app_info_t *info = NULL;
571 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
573 /* Search for a app which has same sender and adv handle as 0
574 It is possible that same sender but different adv handle */
575 if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0) {
576 //info->adv_handle = adv_handle;
577 return info->instance_id;
583 int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot)
586 BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
587 bt_service_app_info_t *info = NULL;
589 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
592 /* Exact matching of Adv handle + sender combination */
593 if (!g_strcmp0(info->sender, sender) && info->adv_handle == adv_handle)
594 return info->instance_id;
596 if (!g_strcmp0(info->sender, sender) && info->adv_handle == -1)
597 return info->instance_id;
603 char * _bt_get_sender_and_handle(int server_instance, int *adv_handle)
606 bt_service_app_info_t *info = NULL;
608 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
611 if (info->instance_id == server_instance && info->adv_handle != 0) {
612 *adv_handle = info->adv_handle;
613 BT_DBG("Server instance [%d] Adv handle [%d] Sender [%s]", server_instance, *adv_handle, info->sender);
614 return g_strdup(info->sender);
620 void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance)
624 bt_service_app_info_t *info = NULL;
625 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
628 if (info->instance_id == instance) {
629 memcpy(info->adv_data.data, &adv->data, len);
635 void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance)
639 bt_service_app_info_t *info = NULL;
640 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
643 if (info->instance_id == instance) {
644 memcpy(info->scan_rsp.data, &scan->data, len);
650 void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance)
653 bt_service_app_info_t *info = NULL;
655 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
658 if (info->instance_id == instance) {
659 memcpy(&adv->data, info->adv_data.data, info->adv_data_len);
660 *len = info->adv_data_len;
666 void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance)
670 bt_service_app_info_t *info = NULL;
672 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
675 if (info->instance_id == instance) {
676 memcpy(&scan->data, info->scan_rsp.data, info->scan_rsp_len);
677 *len = info->scan_rsp_len;
683 static int __bt_unregister_gatt_client_instance(int client_if)
685 int ret = OAL_STATUS_SUCCESS;
688 BT_INFO("DeAllocate client instance ID [%d]", client_if);
690 /* Reset data: instance_id parameter could be either for GATT Server or for GATT client */
691 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
692 if (numapps[k].client_id == client_if) {
693 BT_INFO("This is a GATT client app, unregister: Slot [%d] vacant", k);
694 numapps[k].client_id = -1;
695 numapps[k].is_initialized = FALSE;
696 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
697 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
698 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
700 /* Its a GATT Client Instance */
701 ret = gattc_deregister(client_if);
702 if (ret != OAL_STATUS_SUCCESS) {
703 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
704 return _bt_convert_oal_status_to_bt_error(ret);
709 return BLUETOOTH_ERROR_NONE;
712 static int __bt_unregister_gatt_server_instance(int server_instance)
714 int ret = OAL_STATUS_SUCCESS;
717 /* Unregister the server instance */
718 ret = gatts_unregister(server_instance);
719 if (ret != OAL_STATUS_SUCCESS) {
720 BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret);
721 return _bt_convert_oal_status_to_bt_error(ret);
723 BT_INFO("DeAllocated server instance with stack successful..");
726 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
727 if (numapps[k].instance_id == server_instance) {
728 numapps[k].is_initialized = 0;
729 numapps[k].instance_id = -1;
730 numapps[k].adv_handle = 0;
731 numapps[k].adv_instance = -1;
732 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
733 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
734 memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
735 memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
736 numapps[k].adv_data_len = 0;
737 numapps[k].scan_rsp_len = 0;
741 BT_DBG("Going8 to reset numapp block num [%d]", k);
742 return BLUETOOTH_ERROR_NONE;
745 static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info)
749 int ret = OAL_STATUS_SUCCESS;
752 if (app_info == NULL)
755 count = g_slist_length(app_info->service_handles);
756 BT_INFO("Before handle removal: current count [%d]", count);
758 for (l = app_info->service_handles; l != NULL;) {
763 BT_INFO("Server Handle to be Removed [%d] Instance ID [%d]", *handle, app_info->instance_id);
764 if (_bt_gatt_server_stop_service(app_info->sender, *handle, app_info->instance_id) != BLUETOOTH_ERROR_NONE)
767 ret = gatts_delete_service(app_info->instance_id, *handle);
768 if (ret != OAL_STATUS_SUCCESS) {
769 BT_ERR("ret: %d", ret);
772 app_info->service_handles = g_slist_remove(app_info->service_handles, handle);
775 count = g_slist_length(app_info->service_handles);
776 BT_INFO("After deleting current count [%d]", count);
782 int _bt_unregister_server_instance(const char *sender, int adv_handle)
784 BT_INFO("Unregister Allocated server instance request Sender [%s] Adv handle [%d]", sender, adv_handle);
785 int result = BLUETOOTH_ERROR_NONE;
786 int apps[MAX_APPS_SUPPORTED];
789 bt_service_app_info_t *info = NULL;
791 memset(&apps, -1, sizeof(apps));
793 if (adv_handle == 0) {
794 BT_DBG("Its a direct GATT Server app request to unregister");
795 /* Unregister server instance for each app with same sender (case: GATT Server with multiple adv handle) */
797 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
800 /* Exact matching of sender */
801 if (!g_strcmp0(info->sender, sender)) {
802 BT_INFO("Unregister GATT server instance [%d]", info->instance_id);
803 /* Unregister all service handles with stack */
804 __bt_remove_all_service_handles(info);
806 /* Disable adv if running */
807 BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
808 info->adv_handle, sender);
809 _bt_set_advertising(sender, info->adv_handle, FALSE, FALSE);
811 /* Save all instances which need to be unregistered */
812 apps[info->instance_id] = 1;
816 BT_DBG("Its an Internal unregister request by adv application");
817 server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
818 BT_DBG("Its an Internal unregister request by adv application: Adv disabled srv instance [%d]", server_instance);
819 if (server_instance == -1) {
820 BT_ERR("No allocated server instance to be removed");
821 return BLUETOOTH_ERROR_INVALID_PARAM;
824 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
826 if (info->instance_id == server_instance) {
827 if (info->service_handles == NULL) {
828 BT_INFO("There are no Service handles with this app, safe to unregister");
829 /* Unregister server instance only if this sender does not have any gatt services in it */
830 result = __bt_unregister_gatt_server_instance(server_instance);
832 info->adv_handle = 0;
833 memset(info->adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
834 info->adv_data_len = 0;
835 memset(info->scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
836 info->scan_rsp_len = 0;
843 /* Unregister all apps one by one */
844 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
846 BT_INFO("Unregister app[%d]", k);
847 /* Unregister server instance */
848 __bt_unregister_gatt_server_instance(k);
855 int _bt_register_server_instance(const char *sender, int adv_handle)
857 int ret = OAL_STATUS_SUCCESS;
858 char *uuid_string = NULL;
863 BT_INFO("Check on which instance Server instance can be initialized....");
864 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
865 if (numapps[k].is_initialized == 1 || strlen(numapps[k].uuid) > 0) {
866 BT_DBG("Instance ID [%d] is already in use..Check next slot", numapps[k].instance_id);
869 BT_DBG("Time to register GATT Server..UUID to be used is [%s] slot [%d]", uuid_list[slot-1], slot);
875 BT_ERR("No Slot if free for GATT Server registration..");
876 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
879 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
880 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
881 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
882 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
884 /* Register GATT Server */
885 ret = gatts_register(&uuid);
886 if (ret != OAL_STATUS_SUCCESS) {
887 BT_ERR("ret: %d", ret);
889 return _bt_convert_oal_status_to_bt_error(ret);
891 BT_DBG("GATT Server registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
892 /* Return & wait for GATT Server Instance Initialization event */
893 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
894 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
896 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
897 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
899 numapps[slot].is_initialized = 0; /* Set initialization from app registered callback */
900 numapps[slot].adv_handle = adv_handle;
903 return BLUETOOTH_ERROR_NONE;
907 static void __bt_gatt_get_pending_request_info(int service_function,
911 invocation_info_t *req_info = NULL;
913 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
915 if (req_info == NULL)
918 if (req_info->service_function == service_function) {
919 *sender = req_info->sender;
925 static void __bt_gatt_handle_pending_request_info(int result,
926 int service_function, void *data, unsigned int size)
930 invocation_info_t *req_info = NULL;
931 ret_if(data == NULL);
933 for (l = _bt_get_invocation_list(); l != NULL; ) {
936 if (req_info == NULL || req_info->service_function != service_function)
939 switch (service_function) {
941 case BT_GATT_SERVER_REGISTER: {
942 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
944 if (!g_strcmp0(req_info->sender, param->sender)) {
945 BT_DBG("GATT Server app found [%s]", req_info->sender);
947 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
948 g_array_append_vals(out_param, ¶m->instance_id, sizeof(int));
949 _bt_service_method_return(req_info->context, out_param, result);
951 _bt_free_info_from_invocation_list(req_info);
952 g_array_free(out_param, TRUE);
956 case BT_GATT_SERVER_START_SERVICE:
957 case BT_GATT_SERVER_DELETE_SERVICE: {
958 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
960 int *saved_instance_id = (int*)req_info->user_data;
961 if (!g_strcmp0(req_info->sender, param->sender) && param->instance_id == *saved_instance_id) {
962 BT_DBG("GATT Server app found [%s] Instance ID [%d] Reply DBUS",
963 req_info->sender, *saved_instance_id);
965 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
966 g_array_append_vals(out_param, &saved_instance_id, sizeof(int));
967 _bt_service_method_return(req_info->context, out_param, result);
969 _bt_free_info_from_invocation_list(req_info);
970 g_array_free(out_param, TRUE);
974 case BT_GATT_SERVER_ADD_SERVICE:
975 case BT_GATT_SERVER_ADD_DESCRIPTOR:
976 case BT_GATT_SERVER_ADD_CHARACTERISTIC: {
977 int *handle = (int*)data;
978 BT_DBG("Characteristic added: Handle [%d]", *handle);
979 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
981 g_array_append_vals(out_param, handle, sizeof(int));
982 _bt_service_method_return(req_info->context, out_param, result);
984 _bt_free_info_from_invocation_list(req_info);
985 g_array_free(out_param, TRUE);
990 case BT_DISCONNECT_LE: {
991 char *addr = (char*)req_info->user_data;
992 bluetooth_device_address_t address;
994 if (!g_strcmp0(addr, (char*)data)) {
995 BT_INFO("GATT Client connect-disconnect call pending for app [%s] addr [%s]",
996 req_info->sender, addr + 12);
997 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
998 _bt_convert_addr_string_to_type(address.addr, addr);
1000 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1001 sizeof(bluetooth_device_address_t));
1002 _bt_service_method_return(req_info->context, out_param, result);
1004 _bt_free_info_from_invocation_list(req_info);
1005 g_array_free(out_param, TRUE);
1009 case BT_GATT_CLIENT_REGISTER: {
1010 bt_service_app_info_t *param = (bt_service_app_info_t*)data;
1012 if (!g_strcmp0(req_info->sender, param->sender)) {
1013 BT_DBG("GATT Client app found [%s] created client ID [%d]",
1014 req_info->sender, param->client_id);
1016 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1017 g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1018 _bt_service_method_return(req_info->context, out_param, result);
1020 _bt_free_info_from_invocation_list(req_info);
1021 g_array_free(out_param, TRUE);
1025 case BT_GATT_GET_PRIMARY_SERVICES: {
1026 bt_services_browse_info_t *param = (bt_services_browse_info_t*)data;
1027 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1028 _bt_convert_addr_type_to_string(address,
1029 (unsigned char *)(¶m->device_addr.addr));
1031 /* Match address to determine same request */
1032 if (!g_strcmp0((char*)req_info->user_data, address)) {
1033 BT_DBG("GATT Client app found [%s] Remote address [%s]",
1034 req_info->sender, address);
1036 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1037 g_array_append_vals(out_param, param,
1038 sizeof(bt_services_browse_info_t));
1040 //g_array_append_vals(out_param, ¶m->client_id, sizeof(int));
1041 _bt_service_method_return(req_info->context, out_param, result);
1043 _bt_free_info_from_invocation_list(req_info);
1044 g_array_free(out_param, TRUE);
1049 case BT_GATT_GET_SERVICE_PROPERTIES: {
1050 bt_char_browse_info_t param;
1051 memcpy((void*)¶m, data, sizeof(bt_char_browse_info_t));
1052 //bt_char_browse_info_t *param = (bt_char_browse_info_t*)data;
1054 bluetooth_gatt_client_svc_prop_info_t *prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
1056 /* Match both address and service properties to determine same request */
1057 if (!memcmp(param.device_addr.addr,
1058 prop->device_address.addr,
1059 sizeof(bluetooth_device_address_t)) &&
1060 !memcmp(param.svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1061 param.svc_inst_id == prop->svc.instance_id) {
1062 BT_DBG("Returning Service properties");
1064 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1065 g_array_append_vals(out_param, ¶m, sizeof(bt_char_browse_info_t));
1066 _bt_service_method_return(req_info->context, out_param, result);
1068 _bt_free_info_from_invocation_list(req_info);
1069 g_array_free(out_param, TRUE);
1073 case BT_GATT_GET_CHARACTERISTIC_PROPERTIES: {
1074 bt_descriptor_browse_info_t *param = (bt_descriptor_browse_info_t*)data;
1076 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1078 /* Match both address, service properties &char properties to determine same request */
1079 if (!memcmp(param->device_addr.addr,
1080 prop->device_address.addr,
1081 sizeof(bluetooth_device_address_t)) &&
1082 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1083 param->svc_inst_id == prop->svc.instance_id &&
1084 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1085 param->char_inst_id == prop->characteristic.instance_id) {
1086 BT_DBG("Returning Characteristic properties");
1087 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1088 g_array_append_vals(out_param, param, sizeof(bt_descriptor_browse_info_t));
1089 _bt_service_method_return(req_info->context, out_param, result);
1091 _bt_free_info_from_invocation_list(req_info);
1092 g_array_free(out_param, TRUE);
1096 case BT_GATT_WATCH_CHARACTERISTIC: {
1097 bt_gatt_notif_reg_info_t *param = (bt_gatt_notif_reg_info_t*)data;
1098 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1100 /* Match both address, service properties &char properties to determine same request */
1101 if (!memcmp(param->addr.addr,
1102 prop->device_address.addr,
1103 sizeof(bluetooth_device_address_t)) &&
1104 !memcmp(param->svc_uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1105 param->svc_inst == prop->svc.instance_id &&
1106 !memcmp(param->char_uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) &&
1107 param->char_inst == prop->characteristic.instance_id) {
1108 BT_INFO("Characteristic Watch Successful: Is registered [%d]",
1109 param->is_registered);
1110 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1111 g_array_append_vals(out_param, param, sizeof(bt_gatt_notif_reg_info_t));
1112 _bt_service_method_return(req_info->context, out_param, result);
1113 _bt_free_info_from_invocation_list(req_info);
1114 g_array_free(out_param, TRUE);
1118 case BT_GATT_READ_CHARACTERISTIC:
1119 case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: {
1120 bluetooth_gatt_client_char_prop_info_t *param = (bluetooth_gatt_client_char_prop_info_t*)data;
1122 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1123 bluetooth_gatt_client_char_prop_info_t *prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
1124 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1126 if (!memcmp(param, prop, sizeof(bluetooth_gatt_client_char_prop_info_t))) {
1127 BT_DBG("Gatt Char read or write request matched for address [%s]", addr);
1128 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1129 g_array_append_vals(out_param, param, sizeof(bluetooth_gatt_client_char_prop_info_t));
1130 _bt_service_method_return(req_info->context, out_param, result);
1132 _bt_free_info_from_invocation_list(req_info);
1133 g_array_free(out_param, TRUE);
1138 case BT_GATT_READ_DESCRIPTOR_VALUE:
1139 case BT_GATT_WRITE_DESCRIPTOR_VALUE: {
1140 bluetooth_gatt_client_desc_prop_info_t *param = (bluetooth_gatt_client_desc_prop_info_t*)data;
1142 char *addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
1143 bluetooth_gatt_client_desc_prop_info_t *prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
1144 _bt_convert_addr_type_to_string(addr, prop->device_address.addr);
1146 if (!memcmp(param, prop, sizeof(bluetooth_gatt_client_desc_prop_info_t))) {
1147 BT_DBG("Descriptor read or write request matched for address [%s]", addr);
1148 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1149 g_array_append_vals(out_param, param, sizeof(bluetooth_gatt_client_desc_prop_info_t));
1150 _bt_service_method_return(req_info->context, out_param, result);
1152 _bt_free_info_from_invocation_list(req_info);
1153 g_array_free(out_param, TRUE);
1158 case BT_REQ_ATT_MTU: {
1159 char *addr = (char*)req_info->user_data;
1160 bluetooth_device_address_t address;
1162 if (!g_strcmp0(addr, (char*)data)) {
1163 BT_DBG("GATT Client BT_REQ_ATT_MTU call pending for app [%s] addr [%s]",
1164 req_info->sender, addr);
1165 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1166 _bt_convert_addr_string_to_type(address.addr, addr);
1168 g_array_append_vals(out_param, (bluetooth_device_address_t*)&address,
1169 sizeof(bluetooth_device_address_t));
1170 _bt_service_method_return(req_info->context, out_param, result);
1172 _bt_free_info_from_invocation_list(req_info);
1173 g_array_free(out_param, TRUE);
1182 static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
1184 bt_service_app_info_t *info = NULL;
1186 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
1188 _bt_uuid_to_string(&(data->server_uuid), uuid_string);
1189 BT_INFO("Instance ID is Intialized [%d] UUID initialized [%s]", data->server_inst, uuid_string);
1191 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1192 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1195 if (g_strcmp0(info->uuid, uuid_string) == 0) {
1196 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1197 info->is_initialized = TRUE;
1198 info->instance_id = data->server_inst;
1199 info->adv_instance = data->server_inst;
1200 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_SERVER_REGISTER,
1201 (void*)info, sizeof(bt_service_app_info_t));
1205 g_free(uuid_string);
1208 static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
1210 int result = BLUETOOTH_ERROR_NONE;
1214 bt_service_app_info_t *info = NULL;
1217 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1218 _bt_uuid_to_string(&(event->gatt_srvc_id.id.uuid), uuid_str);
1219 BT_INFO("GATT Added Service UUID: [%s] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1220 uuid_str, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1222 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1223 result = BLUETOOTH_ERROR_INTERNAL;
1224 svc_handle = 0; /* Service handle set to 0 indicates.
1225 0 is reserved by BT SIG, cant be used by app*/
1227 svc_handle = event->gatt_srvc_stat.servic_hndl;
1229 BT_INFO("GATT Added Service Status [%d] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
1230 event->gatt_srvc_stat.status, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
1232 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1233 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1236 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1237 BT_INFO("numapps[%d] Found GATT Server.. UUID [%s], sender [%s]", k, info->uuid, info->sender);
1238 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_SERVICE,
1239 (int*)&svc_handle, sizeof(int));
1241 /* Add Service Handle */
1242 if (svc_handle > 0) {
1243 handle = g_malloc0(sizeof(int));
1244 *handle = svc_handle;
1245 numapps[k].service_handles = g_slist_append(numapps[k].service_handles, handle);
1246 count = g_slist_length(numapps[k].service_handles);
1247 BT_INFO("Added Service handle [%d] to list..current count [%d]", svc_handle, count);
1256 static void __bt_handle_gatt_server_characteristic_added(event_gatts_srvc_charctr_t *event)
1258 int result = BLUETOOTH_ERROR_NONE;
1260 bt_service_app_info_t *info = NULL;
1262 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1264 BT_INFO("GATT Server Char added status [%d]", event->gatt_srvc_stat.status);
1265 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1266 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1267 BT_INFO("GATT Add characteristic Status: [%d]", event->gatt_srvc_stat.status);
1268 BT_INFO("GATT Service characteristic Handle: [%d]", event->charctr_hndl);
1270 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1271 result = BLUETOOTH_ERROR_INTERNAL;
1272 char_handle = 0; /* characteristic handle set to 0 indicates.
1273 0 is reserved by BT SIG, cant be used by app*/
1275 char_handle = event->charctr_hndl;
1278 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1279 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1282 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1283 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1284 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_CHARACTERISTIC,
1285 (int*)&char_handle, sizeof(int));
1291 _bt_uuid_to_string(&(event->charctr_uuid), uuid_str);
1292 BT_INFO("GATT Added Characteristic: UUID: [%s]", uuid_str);
1297 static void __bt_handle_gatt_server_descriptor_added(event_gatts_srvc_descr_t* event)
1299 int result = BLUETOOTH_ERROR_NONE;
1301 bt_service_app_info_t *info = NULL;
1303 char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
1305 BT_INFO("GATT Server Descriptor added status [%d]", event->gatt_srvc_stat.status);
1306 BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
1307 BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
1308 BT_INFO("GATT Add Descriptor Status: [%d]", event->gatt_srvc_stat.status);
1309 BT_INFO("GATT Service Descriptor Handle: [%d]", event->descrptr_hndl);
1311 if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
1312 result = BLUETOOTH_ERROR_INTERNAL;
1313 desc_handle = 0; /* Service handle set to 0 indicates.
1314 0 is reserved by BT SIG, cant be used by app*/
1316 desc_handle = event->descrptr_hndl;
1318 /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
1319 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1322 if (info->instance_id == event->gatt_srvc_stat.server_inst) {
1323 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1324 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_DESCRIPTOR,
1325 (int*)&desc_handle, sizeof(int));
1330 _bt_uuid_to_string(&(event->descrptr_uuid), uuid_str);
1331 BT_INFO("GATT Added Descriptor: UUID: [%s]", uuid_str);
1336 static void __bt_handle_gatt_server_service_started(event_gatts_srvc_t *event)
1338 bt_service_app_info_t *info = NULL;
1339 int result = BLUETOOTH_ERROR_NONE;
1341 BT_INFO("GATT Server Service Started..");
1344 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1345 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1346 BT_INFO("GATT Service Started Status: [%d]", event->status);
1348 if (event->status != OAL_STATUS_SUCCESS) {
1349 BT_ERR("GATT Server Service Start Failed Err: [%d]", event->status);
1350 result = BLUETOOTH_ERROR_INTERNAL;
1353 /* Check if the just registered Instance ID belongs to requester */
1354 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1357 if (info->instance_id == event->server_inst) {
1358 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1359 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_START_SERVICE,
1360 (void*)info, sizeof(bt_service_app_info_t));
1366 static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
1368 int result = BLUETOOTH_ERROR_NONE;
1369 bt_service_app_info_t *info = NULL;
1371 BT_INFO("GATT Server Service Stopped..");
1373 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1374 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1375 BT_INFO("GATT Service Stopped Status: [%d]", event->status);
1377 if (event->status != OAL_STATUS_SUCCESS) {
1378 BT_ERR("GATT Server Service Stop Failed Err: [%d]", event->status);
1379 result = BLUETOOTH_ERROR_INTERNAL;
1382 /* Check if the just registered Instance ID belongs to requester */
1383 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1386 if (info->instance_id == event->server_inst) {
1387 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1388 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_STOP_SERVICE,
1389 (void*)info, sizeof(bt_service_app_info_t));
1395 static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
1397 int result = BLUETOOTH_ERROR_NONE;
1398 bt_service_app_info_t *info = NULL;
1400 BT_INFO("GATT Server Service Deleted..");
1402 BT_INFO("GATT Server_inst: [%d]", event->server_inst);
1403 BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
1404 BT_INFO("GATT Service Deleted Status: [%d]", event->status);
1406 if (event->status != OAL_STATUS_SUCCESS) {
1407 BT_ERR("GATT Server Service Delete Failed Err: [%d]", event->status);
1408 result = BLUETOOTH_ERROR_INTERNAL;
1411 /* Check if the just registered Instance ID belongs to requester */
1412 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
1415 if (info->instance_id == event->server_inst) {
1416 BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
1417 __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_DELETE_SERVICE,
1418 (void*)info, sizeof(bt_service_app_info_t));
1424 struct gatt_client_info_t *_bt_find_remote_gatt_client_info(char *address)
1427 struct gatt_client_info_t *info = NULL;
1428 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1429 info = (struct gatt_client_info_t*)l->data;
1433 if (!g_strcmp0(info->addr, address)) {
1434 BT_DBG("Remote GATT client found addr[%s]", info->addr);
1441 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info_from_conn_id(int conn_id)
1444 struct gatt_client_info_t *info = NULL;
1446 for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
1447 info = (struct gatt_client_info_t*)l->data;
1451 if (info->connection_id == conn_id) {
1452 BT_INFO("Remote GATT client found addr[%s]", info->addr);
1459 struct gatt_server_info_t *_bt_find_remote_gatt_server_info(char *address)
1462 struct gatt_server_info_t *info = NULL;
1463 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
1464 info = (struct gatt_server_info_t*)l->data;
1468 if (!g_strcmp0(info->addr, address)) {
1469 BT_DBG("Remote GATT Server found addr[%s] connection_id %d", info->addr, info->connection_id);
1476 static struct gatt_out_conn_info_t* __bt_find_gatt_outgoing_conn_info(char *address)
1479 struct gatt_out_conn_info_t *info = NULL;
1480 for (l = outgoing_gatt_conn_list; l != NULL; l = g_slist_next(l)) {
1481 info = (struct gatt_out_conn_info_t*)l->data;
1485 if (!g_strcmp0(info->addr, address)) {
1486 BT_INFO("Outgoing connection info found addr[%s]", info->addr + 12);
1493 static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
1495 int result = BLUETOOTH_ERROR_NONE;
1496 struct gatt_client_info_t *client_info = NULL;
1497 #ifndef __INTEGRATE_GATT_INFO__
1498 struct gatt_server_info_t *server_info = NULL;
1500 bluetooth_device_address_t dev_addr;
1501 GVariant *param = NULL;
1504 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1506 memcpy(dev_addr.addr, event->address.addr, 6);
1508 /* REPLY dbus Context to application which called BT_CONNECT_LE. There is status
1510 _bt_convert_addr_type_to_string(address,
1511 (unsigned char *)dev_addr.addr);
1513 if (event->status != OAL_STATUS_SUCCESS)
1514 result = BLUETOOTH_ERROR_INTERNAL;
1516 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1517 address, BT_ADDRESS_STRING_SIZE);
1519 BT_INFO("GATT Server Connedted: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1520 address + 12, event->server_inst, event->conn_id);
1523 /* Check if device is already in connected list */
1524 client_info = _bt_find_remote_gatt_client_info(address);
1527 BT_DBG("Conn Info absent: But no need to Send Local GATT Server Connected event to apps");
1529 param = g_variant_new("(is)", result, address);
1531 /* Send event to application */
1532 _bt_send_event(BT_DEVICE_EVENT,
1533 BLUETOOTH_EVENT_GATT_SERVER_CONNECTED, /* Local device is GATT server */
1536 /* Save client connection info */
1537 client_info = g_new0(struct gatt_client_info_t, 1);
1538 client_info->addr = g_strdup(address);
1539 BT_INFO("Added GATT client addr[%s]", client_info->addr + 12);
1540 client_info->connection_id = event->conn_id;
1541 #ifdef __INTEGRATE_GATT_INFO__
1542 client_info->client_id = -1;
1544 client_info->instance_id = event->server_inst;
1545 gatt_client_info_list = g_slist_append(gatt_client_info_list, client_info);
1546 BT_INFO("Total num of connected Remote GATT Clients [%d]", g_slist_length(gatt_client_info_list));
1548 #ifndef __INTEGRATE_GATT_INFO__
1549 /* Save server connection info */
1550 server_info = g_new0(struct gatt_server_info_t, 1);
1551 server_info->addr = g_strdup(address);
1552 server_info->client_id = -1;
1553 BT_INFO("Added GATT server addr[%s]", server_info->addr + 12);
1554 server_info->connection_id = event->conn_id;
1555 gatt_server_info_list = g_slist_append(gatt_server_info_list, server_info);
1556 BT_INFO("Total num of connected Remote GATT Servers [%d]", g_slist_length(gatt_server_info_list));
1559 ret = gattc_add_connection_info((bt_address_t *)&dev_addr, event->conn_id, event->server_inst);
1560 if (ret != OAL_STATUS_SUCCESS) {
1561 BT_ERR("gattc register server instance failed");
1565 __bt_add_mtu_gatt_device(address);
1570 /* GATT Server Dis connected */
1571 static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *event)
1573 int result = BLUETOOTH_ERROR_NONE;
1574 struct gatt_client_info_t *client_info = NULL;
1575 #ifndef __INTEGRATE_GATT_INFO__
1576 struct gatt_server_info_t *server_info = NULL;
1578 bluetooth_device_address_t dev_addr;
1579 GVariant *param = NULL;
1580 char address[BT_ADDRESS_STRING_SIZE];
1582 memcpy(dev_addr.addr, event->address.addr, 6);
1584 /* REPLY dbus Context to application which called BT_DISCONNECT_LE. There is status
1586 _bt_convert_addr_type_to_string(address,
1587 (unsigned char *)dev_addr.addr);
1589 if (event->status != OAL_STATUS_SUCCESS)
1590 result = BLUETOOTH_ERROR_INTERNAL;
1592 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
1593 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
1594 result = BLUETOOTH_ERROR_INTERNAL;
1596 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
1597 address, BT_ADDRESS_STRING_SIZE);
1599 BT_ERR("Failed to connect Local GATT Server Remote Client addr[%s]", address + 12);
1603 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE,
1604 address, BT_ADDRESS_STRING_SIZE);
1607 /* Remove previous invalid request info */
1608 __bt_gatt_server_release_request_info(address);
1610 BT_INFO("Local GATT Server DisConnected: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
1611 address + 12, event->server_inst, event->conn_id);
1613 #ifdef TIZEN_BLUEDROID_PORTING
1614 __bt_remove_all_prep_write_req(event->conn_id);
1617 /* Remove Connection info */
1618 client_info = _bt_find_remote_gatt_client_info(address);
1620 BT_DBG("No need to Send Local GATT Server Disconnected event to apps, just remove remote client info");
1622 param = g_variant_new("(is)", result, address);
1623 /* Send event to application */
1624 _bt_send_event(BT_DEVICE_EVENT,
1625 BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED, /* Local device is GATT server */
1628 #ifndef __INTEGRATE_GATT_INFO__
1629 /* Remove server info from list */
1630 server_info = _bt_find_remote_gatt_server_info(address);
1632 gatt_server_info_list = g_slist_remove(gatt_server_info_list, server_info);
1634 /* Remove all services from info list_gatt_info */
1635 __bt_cleanup_remote_services(server_info);
1637 BT_INFO("Can not find conn info, already removed!");
1640 /* Remove all services from info list_gatt_info */
1641 __bt_cleanup_remote_services(client_info);
1644 /* Remove client info from List */
1645 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
1646 BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
1647 g_free(client_info->addr);
1648 g_free(client_info);
1651 __bt_remove_mtu_gatt_device(address);
1654 static void __bt_handle_gatt_server_acquire_write_requested(event_gatts_srvc_acquire_attr_t *event)
1656 GVariant *param = NULL;
1657 int result = BLUETOOTH_ERROR_NONE;
1658 struct gatt_server_req_info *req_info = NULL;
1659 bluetooth_device_address_t dev_addr;
1660 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1662 BT_INFO("GATT Server ACQUIRE Write Req");
1663 BT_DBG(" conn id %d, trans id %d, attr andle %d", event->attr_trans.conn_id,
1664 event->attr_trans.trans_id, event->attr_trans.attr_handle);
1666 //address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1667 memcpy(dev_addr.addr, event->address.addr, 6);
1669 req_info = g_new0(struct gatt_server_req_info, 1);
1670 req_info->request_id = event->attr_trans.trans_id;
1671 req_info->attribute_handle = event->attr_trans.attr_handle;
1672 req_info->connection_id = event->attr_trans.conn_id;
1673 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
1674 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
1676 _bt_convert_addr_type_to_string(address,
1677 (unsigned char *)dev_addr.addr);
1679 param = g_variant_new("(iiiiiis)", result,
1680 event->attr_trans.conn_id,
1681 event->attr_trans.trans_id,
1682 event->attr_trans.attr_handle,
1683 event->mtu, event->attr_trans.offset, address);
1684 BT_DBG("remote address : [%s]", address);
1686 _bt_send_event(BT_GATT_SERVER_EVENT,
1687 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
1692 static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_acquire_attr_t *event)
1694 GVariant *param = NULL;
1695 int result = BLUETOOTH_ERROR_NONE;
1696 struct gatt_server_req_info *req_info = NULL;
1697 bluetooth_device_address_t dev_addr;
1698 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1700 BT_INFO("GATT Server ACQUIRE Notify Req");
1701 BT_DBG("conn id %d, trans id %d, attr handle %d, req address %s",
1702 event->attr_trans.conn_id, event->attr_trans.trans_id,
1703 event->attr_trans.attr_handle, address);
1705 memcpy(dev_addr.addr, event->address.addr, 6);
1706 _bt_convert_addr_type_to_string(address,
1707 (unsigned char *)dev_addr.addr);
1708 BT_INFO("Remote address : [%s]", address);
1710 req_info = g_new0(struct gatt_server_req_info, 1);
1711 req_info->request_id = event->attr_trans.trans_id;
1712 req_info->attribute_handle = event->attr_trans.attr_handle;
1713 req_info->connection_id = event->attr_trans.conn_id;
1714 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
1715 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
1717 param = g_variant_new("(iiiiiis)", result,
1718 event->attr_trans.conn_id,
1719 event->attr_trans.trans_id,
1720 event->attr_trans.attr_handle,
1721 event->mtu, event->attr_trans.offset,
1724 _bt_send_event(BT_GATT_SERVER_EVENT,
1725 BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY,
1729 #ifdef TIZEN_BLUEDROID_PORTING
1730 static bt_gatt_prep_write_data_t* __bt_create_prep_write_data(event_gatts_srvc_write_attr_t *event)
1732 bluetooth_device_address_t dev_addr;
1734 bt_gatt_prep_write_data_t *prep_data = NULL;
1736 prep_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
1737 prep_data->connection_id = event->attr_trans.conn_id;
1738 prep_data->request_id = event->attr_trans.trans_id;
1739 prep_data->handle = event->attr_trans.attr_handle;
1740 prep_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
1741 memcpy(dev_addr.addr, event->address.addr, 6);
1742 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1743 _bt_convert_addr_type_to_string(addr,
1744 (unsigned char *)dev_addr.addr);
1745 prep_data->device_address = addr;
1746 prep_data->offset = event->attr_trans.offset;
1747 prep_data->length = event->length;
1748 prep_data->value = g_memdup(&event->value[0], event->length);
1753 static int __bt_gatt_server_send_long_write_response(bt_gatt_prep_write_data_t *prep_data, int resp_status, int auth_req)
1755 int ret = OAL_STATUS_SUCCESS;
1756 oal_gatt_response_t response;
1758 memset(&response, 0x00, sizeof(oal_gatt_response_t));
1760 BT_INFO("GATT Server Write Res Connection ID: [%d]", prep_data->connection_id);
1761 BT_INFO("GATT Server Write Res Transaction ID:[%d]", prep_data->request_id);
1762 BT_INFO("GATT Server Write Res Attribute Handle: [%d]", prep_data->handle);
1763 BT_INFO("GATT Server Write Res Attribute Offset: [%d]", prep_data->offset);
1764 BT_INFO("GATT Server Write Res value length [%d]", prep_data->length);
1766 response.handle = prep_data->handle;
1767 response.attr_value.auth_req = auth_req;
1768 response.attr_value.handle = prep_data->handle;
1769 response.attr_value.offset = prep_data->offset;
1770 response.attr_value.len = prep_data->length;
1771 memcpy(&response.attr_value.value, &prep_data->value[0], prep_data->length);
1773 ret = gatts_send_response(prep_data->connection_id, prep_data->request_id,
1774 resp_status, &response);
1778 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_request_id(int request_id)
1781 bt_gatt_prep_write_data_t *prep_data = NULL;
1783 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
1784 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1785 if (prep_data && (prep_data->request_id == request_id) &&
1786 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
1787 BT_INFO("prep_data found for request id [%d]", request_id);
1791 BT_INFO("prep_data not found for request [%d]", request_id);
1795 static bt_gatt_prep_write_data_t* __bt_find_exec_write_req(int conn_id)
1798 bt_gatt_prep_write_data_t *prep_data = NULL;
1800 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
1801 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1802 if (prep_data && (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE)
1803 && (prep_data->connection_id == conn_id)) {
1804 BT_INFO("Exec request found");
1808 BT_INFO("Exec request not found");
1812 static int __bt_get_prep_request_count(int conn_id)
1816 bt_gatt_prep_write_data_t *prep_data = NULL;
1818 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
1819 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1820 if (prep_data && (prep_data->connection_id == conn_id) &&
1821 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE))
1827 static bt_gatt_prep_write_data_t* __bt_find_prep_write_data_from_handle(int conn_id, int handle)
1830 bt_gatt_prep_write_data_t *prep_data = NULL;
1831 bt_gatt_prep_write_data_t *last_prep_data = NULL;
1833 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
1834 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1835 if (prep_data && (prep_data->connection_id == conn_id) && (prep_data->handle == handle)) {
1836 BT_INFO("prep_data entry found for handle [%d]", handle);
1837 last_prep_data = prep_data;
1841 if (!last_prep_data)
1842 BT_INFO("prep_data entry not found for handle [%d]", handle);
1844 return last_prep_data;
1847 static void __bt_gatt_server_send_prep_write_req(int conn_id)
1849 int result = BLUETOOTH_ERROR_NONE;
1851 bt_gatt_prep_write_data_t *prep_data = NULL;
1853 for (l = g_pending_write_list; l != NULL; l = g_slist_next(l)) {
1854 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1855 if (prep_data && (prep_data->connection_id == conn_id) &&
1856 (prep_data->request_type == BLUETOOTH_GATT_REQUEST_TYPE_WRITE)) {
1857 BT_INFO("sending prep_req, req_id=%d", prep_data->request_id);
1858 GVariant *data = NULL;
1859 GVariant *param = NULL;
1860 data = g_variant_new_from_data(
1861 G_VARIANT_TYPE_BYTESTRING,
1866 param = g_variant_new("(iiiiiibbsn@ay)", result,
1867 prep_data->connection_id,
1868 prep_data->request_id,
1874 prep_data->device_address,
1878 _bt_send_event(BT_GATT_SERVER_EVENT,
1879 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
1885 static void __bt_remove_all_prep_write_req(int conn_id)
1888 bt_gatt_prep_write_data_t *prep_data = NULL;
1890 BT_INFO("Removing all req for conn_id %d", conn_id);
1891 for (l = g_pending_write_list; l != NULL;) {
1892 prep_data = (bt_gatt_prep_write_data_t*)l->data;
1893 l = g_slist_next(l);
1894 if (prep_data && (prep_data->connection_id == conn_id)) {
1895 BT_INFO("Removing req for req_id %d", prep_data->request_id);
1896 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
1897 g_free(prep_data->value);
1898 g_free(prep_data->device_address);
1905 static bool __bt_update_prep_write_data(bt_gatt_prep_write_data_t *prep_data, int offset,
1906 int length, char *value)
1914 len = prep_data->length + length;
1915 val = g_realloc(prep_data->value, len);
1919 memcpy(val + prep_data->length, value, length);
1920 prep_data->value = val;
1921 prep_data->length = len;
1923 BT_INFO("updated prep_data->length %d, prep_data->req_id %d", prep_data->length, prep_data->request_id);
1927 static bool __bt_handle_gatt_server_prepare_write_response(int *res,
1928 bluetooth_gatt_server_response_params_t *param)
1930 bt_gatt_prep_write_data_t *prep_data = NULL;
1931 bt_gatt_prep_write_data_t *exec_data = NULL;
1933 int ret = OAL_STATUS_SUCCESS;
1935 /* Search for matching Request in prepare write List */
1936 prep_data = __bt_find_prep_write_data_from_request_id(param->request_id);
1941 conn_id = prep_data->connection_id;
1942 exec_data = __bt_find_exec_write_req(conn_id);
1945 BT_ERR("Oops, Something weird has happened!!!");
1946 *res = BLUETOOTH_ERROR_INTERNAL;
1947 __bt_remove_all_prep_write_req(conn_id);
1949 // remove pending write request from the list
1950 BT_INFO("Removing prending write request, request id = %d", prep_data->request_id);
1951 g_pending_write_list = g_slist_remove(g_pending_write_list, prep_data);
1952 g_free(prep_data->value);
1953 g_free(prep_data->device_address);
1956 exec_data->prep_request_count--;
1957 if (param->response_status || !exec_data->prep_request_count) {
1958 BT_INFO("Sending exec response with status = %d", param->response_status);
1959 ret = __bt_gatt_server_send_long_write_response(exec_data, param->response_status, param->auth_req);
1960 if (ret != OAL_STATUS_SUCCESS) {
1961 BT_ERR("ret: %d", ret);
1962 *res = BLUETOOTH_ERROR_INTERNAL;
1964 __bt_remove_all_prep_write_req(conn_id);
1970 static void __bt_handle_gatt_server_prepare_write_requested(event_gatts_srvc_write_attr_t *event)
1972 bt_gatt_prep_write_data_t *pdata = NULL;
1973 bt_gatt_prep_write_data_t *prep_data = NULL;
1975 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
1977 prep_data = __bt_create_prep_write_data(event);
1979 /* Find if the req node for that attribute already exists */
1980 pdata = __bt_find_prep_write_data_from_handle(prep_data->connection_id, prep_data->handle);
1982 if (!pdata || (prep_data->offset != (pdata->length + pdata->offset))) {
1983 BT_INFO("prep_write_req node doestn't exist or data is not in continuation, offset=%d", prep_data->offset);
1985 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)pdata);
1986 BT_INFO("Send prep_write_response");
1987 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
1989 /* Update the data and offset in attribute node */
1990 if (!(__bt_update_prep_write_data(pdata, prep_data->offset, prep_data->length, prep_data->value))) {
1991 BT_ERR("prep_data couldnot be updated");
1992 resp_status = BLUETOOTH_ATT_ERROR_INSUFFICIENT_RESOURCES;
1994 BT_INFO("Send prep_write_response");
1995 ret = __bt_gatt_server_send_long_write_response(prep_data, resp_status, 0);
1996 g_free(prep_data->device_address);
1997 g_free(prep_data->value);
2001 if (ret != OAL_STATUS_SUCCESS)
2002 BT_ERR("ret: %d", ret);
2006 static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
2009 bluetooth_device_address_t dev_addr;
2010 GVariant *param = NULL;
2011 int result = BLUETOOTH_ERROR_NONE;
2013 gboolean is_prepare_write;
2014 char *write_val = NULL;
2015 GVariant *data = NULL;
2017 struct gatt_server_req_info *req_info = NULL;
2018 BT_INFO("GATT Server Write Requested");
2020 memcpy(dev_addr.addr, event->address.addr, 6);
2022 BT_INFO("GATT Server Write Req Connection ID: [%d]", event->attr_trans.conn_id);
2023 BT_INFO("GATT Server Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
2024 BT_INFO("GATT Server Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
2025 BT_INFO("GATT Server Write Req Attribute Offset: [%d]", event->attr_trans.offset);
2026 BT_INFO("GATT Server Write Req value length [%d]", event->length);
2027 BT_INFO("GATT Server Write Req needs response: [%d]", event->need_rsp);
2028 BT_INFO("GATT Server Write Req Is Prep: [%d]", event->is_prep);
2030 #ifdef TIZEN_BLUEDROID_PORTING
2031 if (event->is_prep) {
2032 BT_INFO("receive prepare_write request");
2033 return __bt_handle_gatt_server_prepare_write_requested(event);
2037 need_resp = event->need_rsp;
2038 is_prepare_write = event->is_prep;
2040 if (event->length > 0)
2041 write_val = g_memdup(&event->value[0], event->length);
2043 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2044 _bt_convert_addr_type_to_string(address,
2045 (unsigned char *)dev_addr.addr);
2047 BT_INFO("GATT Server Write Request from remote client [%s]", address);
2049 if (event->length > 0) {
2050 for (i = 0; i < event->length; i++)
2051 BT_DBG("Data[%d] = [0x%x]", i, event->value[i]);
2053 /* Save Write Request Info */
2054 req_info = g_new0(struct gatt_server_req_info, 1);
2055 req_info->request_id = event->attr_trans.trans_id;
2056 req_info->attribute_handle = event->attr_trans.attr_handle;
2057 req_info->connection_id = event->attr_trans.conn_id;
2058 req_info->addr = address;
2059 req_info->offset = event->attr_trans.offset;
2060 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2061 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2063 data = g_variant_new_from_data(
2064 G_VARIANT_TYPE_BYTESTRING,
2069 param = g_variant_new("(iiiiiibbsn@ay)", result,
2070 event->attr_trans.conn_id,
2071 event->attr_trans.trans_id,
2072 event->attr_trans.attr_handle,
2073 event->attr_trans.offset,
2081 _bt_send_event(BT_GATT_SERVER_EVENT,
2082 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2088 #ifdef TIZEN_BLUEDROID_PORTING
2089 static void __bt_handle_gatt_server_exec_write_requested(event_gatts_srvc_exec_write_attr_t *event)
2092 bluetooth_device_address_t dev_addr;
2094 bt_gatt_prep_write_data_t *exec_data = NULL;
2095 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2096 BT_INFO("GATT Server Execute Write Requested");
2098 memcpy(dev_addr.addr, event->address.addr, 6);
2099 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2100 _bt_convert_addr_type_to_string(address,
2101 (unsigned char *)dev_addr.addr);
2103 BT_INFO("GATT Server Exec Write Req Connection ID: [%d]", event->conn_id);
2104 BT_INFO("GATT Server Exec Write Req Transaction ID:[%d]", event->trans_id);
2105 BT_INFO("GATT Server Exec Write Req Exec Write: [%d]", event->exec_write);
2107 // prepare exec response data
2108 exec_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2109 exec_data->connection_id = event->conn_id;
2110 exec_data->request_id = event->trans_id;
2111 exec_data->device_address = address;
2112 exec_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE;
2113 exec_data->prep_request_count = __bt_get_prep_request_count(exec_data->connection_id);
2115 if ((exec_data->prep_request_count != 1) || !event->exec_write) {
2116 if (!event->exec_write) {
2117 BT_INFO("Cancelling all prepared writes, removing all pending entries");
2118 __bt_remove_all_prep_write_req(event->conn_id);
2119 } else if (exec_data->prep_request_count > 1) {
2120 /* TODO: Handle reliable-write session */
2121 BT_INFO("This may be reliable write session. Not yet supported!!!, prep_request_count =%d",
2122 exec_data->prep_request_count);
2123 resp_status = BLUETOOTH_ATT_ERROR_REQUEST_NOT_SUPPORTED;
2124 __bt_remove_all_prep_write_req(event->conn_id);
2127 BT_INFO("Send exec response");
2128 // Made response and send it.
2129 ret = __bt_gatt_server_send_long_write_response(exec_data, resp_status, 0);
2130 if (ret != OAL_STATUS_SUCCESS)
2131 BT_ERR("ret: %d", ret);
2133 g_free(exec_data->device_address);
2138 BT_INFO("Write all pending prepared values");
2139 __bt_gatt_server_send_prep_write_req(exec_data->connection_id);
2141 // Add exec request in the queue.
2142 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)exec_data);
2146 static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t *event)
2148 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2149 bluetooth_device_address_t dev_addr;
2150 int result = BLUETOOTH_ERROR_NONE;
2151 struct gatt_server_req_info *req_info = NULL;
2152 GVariant *param = NULL;
2155 memcpy(dev_addr.addr, event->address.addr, 6);
2156 _bt_convert_addr_type_to_string(address,
2157 (unsigned char *)dev_addr.addr);
2159 BT_DBG("conn_id %d, trans id %d, attr handle %d, offset %d, is_long %d, addr %s",
2160 event->attr_trans.conn_id, event->attr_trans.trans_id,
2161 event->attr_trans.attr_handle, event->attr_trans.offset,
2162 event->is_long, address);
2164 is_long = event->is_long;
2166 /* Save Read Request Info */
2167 req_info = g_new0(struct gatt_server_req_info, 1);
2168 req_info->request_id = event->attr_trans.trans_id;
2169 req_info->attribute_handle = event->attr_trans.attr_handle;
2170 req_info->connection_id = event->attr_trans.conn_id;
2171 req_info->addr = address;
2172 req_info->offset = event->attr_trans.offset;
2173 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_READ;
2174 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2176 /* Send event to BT-API */
2177 param = g_variant_new("(iiiiibs)", result,
2178 event->attr_trans.conn_id,
2179 event->attr_trans.trans_id,
2180 event->attr_trans.attr_handle,
2181 event->attr_trans.offset,
2185 _bt_send_event(BT_GATT_SERVER_EVENT,
2186 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
2190 static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
2192 bluetooth_device_address_t dev_addr;
2193 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2194 int cur_connected_clients;
2195 static int recvd = 0;
2196 gboolean completed = 0;
2197 GVariant *param = NULL;
2199 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2200 incase of any issues, check with OAL */
2201 int result = BLUETOOTH_ERROR_NONE;
2203 memcpy(dev_addr.addr, event->address.addr, 6);
2204 _bt_convert_addr_type_to_string(address,
2205 (unsigned char *)dev_addr.addr);
2207 BT_INFO("Indication sent to GATT client [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d]",
2208 address, event->conn_id, event->trans_id, event->attr_handle);
2211 cur_connected_clients = g_slist_length(gatt_client_info_list);
2212 BT_INFO("Number of connected clients during sending Indication [%d] & current connected count [%d]",
2213 num_indicate_clients, cur_connected_clients);
2216 if (recvd == num_indicate_clients) {
2217 BT_INFO("Gatt indication confirm event for last GATT client.. [%s]", address);
2218 completed = 1; /* Last event */
2219 recvd = 0; /* Reset */
2220 num_indicate_clients = 0;
2223 param = g_variant_new("(isib)",
2229 /* Send event to BT-API */
2230 _bt_send_event(BT_GATT_SERVER_EVENT,
2231 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
2234 BT_INFO("Received Indication confirm for client number [%d]", recvd);
2238 /* Tizen Platform Specific */
2239 static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *event)
2241 bluetooth_device_address_t dev_addr;
2242 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2243 GVariant *param = NULL;
2246 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2247 incase of any issues, check with OAL */
2248 int result = BLUETOOTH_ERROR_NONE;
2250 memcpy(dev_addr.addr, event->address.addr, 6);
2251 _bt_convert_addr_type_to_string(address,
2252 (unsigned char *)dev_addr.addr);
2254 BT_INFO("notification_changed [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d] Notify[%d]",
2255 address, event->conn_id, event->trans_id, event->attr_handle, event->notify);
2257 /* Set Notifcation status */
2258 notify = event->notify;
2260 param = g_variant_new("(isib)",
2266 /* Send event to BT-API */
2267 _bt_send_event(BT_GATT_SERVER_EVENT,
2268 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
2274 static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
2276 int result = BLUETOOTH_ERROR_NONE;
2277 struct gatt_client_info_t *conn_info = NULL;
2278 GVariant *param = NULL;
2281 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2282 if (conn_info == NULL) {
2283 BT_ERR("Cant find connection Information");
2286 BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
2287 conn_info->addr, event->mtu_size);
2289 __bt_update_mtu_gatt_device(conn_info->addr, event->mtu_size);
2291 param = g_variant_new("(isqy)",
2297 /* Send event to BT-API */
2298 _bt_send_event(BT_GATT_SERVER_EVENT,
2299 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
2303 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
2305 switch (event_type) {
2306 case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
2307 BT_INFO("OAL Event: Server Instance Registered");
2308 /* GATT Server Registered event is handled in MAIN thread context */
2309 __bt_handle_server_instance_registered((event_gatts_register_t *)event_data);
2312 case OAL_EVENT_GATTS_SERVICE_ADDED: {
2313 BT_INFO("OAL Event: GATT Service added");
2314 __bt_handle_gatt_server_service_added((event_gatts_srvc_prm_t *)event_data);
2317 case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
2318 BT_INFO("OAL Event: GATT characteristic added");
2319 __bt_handle_gatt_server_characteristic_added((event_gatts_srvc_charctr_t *)event_data);
2322 case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
2323 BT_INFO("OAL Event: GATT descriptor added");
2324 __bt_handle_gatt_server_descriptor_added((event_gatts_srvc_descr_t *)event_data);
2327 case OAL_EVENT_GATTS_SERVICE_STARTED: {
2328 BT_INFO("OAL Event: GATT Service started");
2329 __bt_handle_gatt_server_service_started((event_gatts_srvc_t *)event_data);
2332 case OAL_EVENT_GATTS_SERVICE_STOPED: {
2333 BT_INFO("OAL Event: GATT Service stopped");
2334 __bt_handle_gatt_server_service_stopped((event_gatts_srvc_t *)event_data);
2337 case OAL_EVENT_GATTS_SERVICE_DELETED: {
2338 BT_INFO("OAL Event: GATT Service deleted");
2339 __bt_handle_gatt_server_service_deleted((event_gatts_srvc_t *) event_data);
2342 case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
2343 BT_INFO("OAL Event: GATT Server Connected");
2344 __bt_handle_gatt_server_connection_state((event_gatts_conn_t *)event_data);
2347 case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
2348 BT_INFO("OAL Event: GATT Server Disconnected");
2349 __bt_handle_gatt_server_disconnection_state((event_gatts_conn_t *)event_data);
2352 case OAL_EVENT_GATTS_REQUEST_READ: {
2353 BT_DBG("OAL Event: GATT Server Read Request");
2354 __bt_handle_gatt_server_read_requested((event_gatts_srvc_read_attr_t *)event_data);
2357 case OAL_EVENT_GATTS_REQUEST_WRITE: {
2358 BT_DBG("OAL Event: GATT Server Write Request");
2359 __bt_handle_gatt_server_write_requested((event_gatts_srvc_write_attr_t *)event_data);
2362 #ifdef TIZEN_BLUEDROID_PORTING
2363 case OAL_EVENT_GATTS_EXEC_REQUEST_WRITE: {
2364 BT_INFO("OAL Event: GATT Server Exec Write Request");
2365 __bt_handle_gatt_server_exec_write_requested((event_gatts_srvc_exec_write_attr_t *)event_data);
2369 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE: {
2370 BT_INFO("OAL Event: GATT Server Acquire Write Request");
2371 __bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2374 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
2375 BT_INFO("OAL Event: GATT ServerAcquire Notify Request");
2376 __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2379 case OAL_EVENT_GATTS_IND_CONFIRM: {
2380 BT_INFO("OAL Event: GATT Server Indication confirmed");
2381 __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
2384 case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
2385 BT_INFO("OAL Event: GATT Server DisConnected");
2386 __bt_handle_gatt_server_notification_changed((event_gatts_notif_t *)event_data);
2389 case OAL_EVENT_GATTS_MTU_CHANGED: {
2390 BT_INFO("OAL Event: GATT Server MTU changed event callback");
2391 __bt_handle_gatt_mtu_changed_event((event_gatts_mtu_changed_t *)event_data);
2394 case OAL_EVENT_GATTC_REGISTRATION: {
2395 BT_INFO("OAL Event: GATT Client instance Registered");
2396 __bt_handle_client_instance_registered((event_gattc_register_t *) event_data);
2399 case OAL_EVENT_GATTC_CONNECTION_COMPLETED: {
2400 BT_INFO("OAL Event: GATT Client Connected");
2401 __bt_handle_client_connected((event_gattc_conn_t *) event_data);
2404 case OAL_EVENT_GATTC_DISCONNECTION_COMPLETED: {
2405 BT_INFO("OAL Event: GATT Client DisConnected");
2406 __bt_handle_client_disconnected((event_gattc_conn_t *) event_data);
2409 case OAL_EVENT_GATTC_SERVICE_SEARCH_RESULT: {
2410 BT_DBG("OAL Event: GATT Client Service Search Result");
2411 __bt_handle_client_service_search_result((event_gattc_service_result_t *) event_data);
2414 case OAL_EVENT_GATTC_SERVICE_SEARCH_DONE: {
2415 BT_INFO("OAL Event: GATT Client Service Completed");
2416 __bt_handle_client_service_search_completed((event_gattc_conn_status_t *) event_data);
2419 case OAL_EVENT_GATTC_CHARAC_SERACH_RESULT: {
2420 BT_DBG("OAL Event: GATT Client Characteristic Search Result");
2421 __bt_handle_client_characteristic_search_result((event_gattc_characteristic_result_t *) event_data);
2424 case OAL_EVENT_GATTC_DESC_SERACH_RESULT: {
2425 BT_DBG("OAL Event: GATT Client Descriptor Search Result");
2426 __bt_handle_client_descriptor_search_result((event_gattc_descriptor_result_t *) event_data);
2429 case OAL_EVENT_GATTC_READ_CHARAC: {
2430 BT_DBG("OAL Event: GATT Client Characteristic Read Data");
2431 __bt_handle_client_characteristic_read_data((event_gattc_read_data *) event_data);
2434 case OAL_EVENT_GATTC_READ_DESCR: {
2435 BT_DBG("OAL Event: GATT Client Descriptor Read Data");
2436 __bt_handle_client_descriptor_read_data((event_gattc_read_data *) event_data);
2439 case OAL_EVENT_GATTC_WRITE_CHARAC: {
2440 BT_DBG("OAL Event: GATT Client Characteristic Write Data");
2441 __bt_handle_client_characteristic_write_data((event_gattc_write_data *) event_data);
2444 case OAL_EVENT_GATTC_WRITE_DESCR: {
2445 BT_DBG("OAL Event: GATT Client Descriptor Write Data");
2446 __bt_handle_client_descriptor_write_data((event_gattc_write_data *) event_data);
2449 case OAL_EVENT_DEVICE_LE_DISCONNECTED: {
2450 BT_INFO("OAL Event: LE device disconnected");
2451 __bt_hanlde_le_device_disconnection((event_dev_conn_status_t *)event_data);
2454 case OAL_EVENT_GATTC_NOTIFICATION_REGISTERED: {
2455 BT_INFO("OAL Event: GATT Client Notification Registered");
2456 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, TRUE);
2459 case OAL_EVENT_GATTC_NOTIFICATION_DEREGISTERED: {
2460 BT_INFO("OAL Event: GATT Client Notification Registered");
2461 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, FALSE);
2464 case OAL_EVENT_GATTC_NOTIFY_DATA: {
2465 BT_DBG("OAL Event: GATT Client Notification Data");
2466 __bt_handle_client_notification_data((event_gattc_notify_data *) event_data);
2469 case OAL_EVENT_GATTC_SERVICE_CHANGED_IND: {
2470 BT_INFO("OAL Event: GATT Client service changed indication");
2471 __bt_handle_client_service_changed_ind((event_gattc_service_changed_data *)event_data);
2474 case OAL_EVENT_GATTC_MTU_EXCHANGE_COMPLETED: {
2475 BT_INFO("OAL Event: GATT Client MTU Exchange Complete");
2476 __bt_handle_client_mtu_exchange_completed((event_gattc_mtu_configured_t *) event_data);
2480 BT_DBG("Unhandled OAL event = 0x%x", event_type);
2485 int _bt_gatt_server_add_service(char *sender, int service_type,
2486 int num_handles, char *svc_uuid, int instance_id)
2488 BT_CHECK_PARAMETER(svc_uuid, return);
2489 BT_CHECK_PARAMETER(sender, return);
2490 int ret = OAL_STATUS_SUCCESS;
2492 oal_gatt_srvc_id_t svc_data;
2494 svc_data.is_prmry = service_type;
2495 svc_data.id.inst_id = instance_id;
2497 BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id);
2498 _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid);
2500 ret = gatts_add_service(instance_id, &svc_data, num_handles);
2501 if (ret != OAL_STATUS_SUCCESS) {
2502 BT_ERR("ret: %d", ret);
2503 return _bt_convert_oal_status_to_bt_error(ret);
2506 return BLUETOOTH_ERROR_NONE;
2510 int _bt_gatt_server_add_included_service(char *sender, int instance_id,
2511 int service_handle, int included_svc_handle)
2513 BT_CHECK_PARAMETER(sender, return);
2514 int ret = OAL_STATUS_SUCCESS;
2516 ret = gatts_add_included_services(instance_id, service_handle, included_svc_handle);
2517 if (ret != OAL_STATUS_SUCCESS) {
2518 BT_ERR("ret: %d", ret);
2519 return _bt_convert_oal_status_to_bt_error(ret);
2521 return BLUETOOTH_ERROR_NONE;
2524 int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
2525 bluetooth_gatt_server_attribute_params_t *param)
2527 BT_CHECK_PARAMETER(char_uuid, return);
2528 BT_CHECK_PARAMETER(sender, return);
2529 BT_CHECK_PARAMETER(param, return);
2530 int ret = OAL_STATUS_SUCCESS;
2532 oal_uuid_t uuid = {{0} };
2534 BT_INFO("Char UUID [%s] Instance ID [%d]", char_uuid, param->instance_id);
2535 _bt_string_to_uuid(char_uuid, (service_uuid_t*)&uuid);
2537 BT_INFO("Char permission From API [0x%x]", param->permissions);
2539 ret = gatts_add_characteristics(param->instance_id, param->service_handle, &uuid,
2540 param->properties, (int)param->permissions);
2541 if (ret != OAL_STATUS_SUCCESS) {
2542 BT_ERR("ret: %d", ret);
2543 return _bt_convert_oal_status_to_bt_error(ret);
2545 return BLUETOOTH_ERROR_NONE;
2548 int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
2549 bt_gatt_permission_t *param, int service_handle, int instance_id)
2551 BT_CHECK_PARAMETER(desc_uuid, return);
2552 BT_CHECK_PARAMETER(sender, return);
2553 BT_CHECK_PARAMETER(param, return);
2554 int ret = OAL_STATUS_SUCCESS;
2556 oal_uuid_t uuid = {{0} };
2558 BT_INFO("Descriptor UUID [%s] Instance ID [%d] Service handle [%d]",
2559 desc_uuid, service_handle, instance_id);
2561 _bt_string_to_uuid(desc_uuid, (service_uuid_t*)&uuid);
2563 BT_INFO("Descriptor permission From API [0x%x]", *param);
2564 ret = gatts_add_descriptor(instance_id, service_handle, &uuid, (int)*param);
2566 if (ret != OAL_STATUS_SUCCESS) {
2567 BT_ERR("ret: %d", ret);
2568 return _bt_convert_oal_status_to_bt_error(ret);
2570 return BLUETOOTH_ERROR_NONE;
2573 int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id)
2575 BT_CHECK_PARAMETER(sender, return);
2576 int ret = OAL_STATUS_SUCCESS;
2578 ret = gatts_start_service(instance_id, service_handle, BT_GATT_TRANSPORT_LE);
2579 if (ret != OAL_STATUS_SUCCESS) {
2580 BT_ERR("ret: %d", ret);
2581 return _bt_convert_oal_status_to_bt_error(ret);
2583 return BLUETOOTH_ERROR_NONE;
2586 int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id)
2588 BT_CHECK_PARAMETER(sender, return);
2589 int ret = OAL_STATUS_SUCCESS;
2591 ret = gatts_stop_service(instance_id, service_handle);
2592 if (ret != OAL_STATUS_SUCCESS) {
2593 BT_ERR("ret: %d", ret);
2594 return _bt_convert_oal_status_to_bt_error(ret);
2596 return BLUETOOTH_ERROR_NONE;
2599 int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id)
2601 BT_CHECK_PARAMETER(sender, return);
2602 int ret = OAL_STATUS_SUCCESS;
2606 bt_service_app_info_t *info = NULL;
2608 ret = gatts_delete_service(instance_id, service_handle);
2609 if (ret != OAL_STATUS_SUCCESS) {
2610 BT_ERR("ret: %d", ret);
2611 return _bt_convert_oal_status_to_bt_error(ret);
2614 /* Remove the Service Handle */
2615 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
2617 if (info->instance_id == instance_id) {
2618 for (l = info->service_handles; l != NULL; ) {
2620 l = g_slist_next(l);
2621 if (handle && *handle == service_handle) {
2622 BT_INFO("Remove Service handle [%d]", *handle);
2623 info->service_handles = g_slist_remove(info->service_handles, handle);
2632 return BLUETOOTH_ERROR_NONE;
2635 int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
2636 bluetooth_gatt_server_response_params_t *param)
2638 BT_CHECK_PARAMETER(sender, return);
2639 BT_CHECK_PARAMETER(data, return);
2640 BT_CHECK_PARAMETER(param, return);
2641 struct gatt_server_req_info *req_info = NULL;
2642 int ret = OAL_STATUS_SUCCESS;
2643 #ifdef TIZEN_BLUEDROID_PORTING
2644 int res = BLUETOOTH_ERROR_NONE;
2646 oal_gatt_response_t response;
2648 BT_INFO("GATT Server Response: Req Type [%d] req_id [%d] status [%d] auth_req [%d] offset[%d] data len[%d]",
2649 param->req_type, param->request_id,
2650 param->response_status, param->auth_req,
2651 data->offset, data->length);
2653 #ifdef TIZEN_BLUEDROID_PORTING
2654 if (__bt_handle_gatt_server_prepare_write_response(&res, param))
2658 /* Search for matching Request in List */
2659 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
2661 BT_ERR("GATT Server Req Info not found for current response..return Error");
2662 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2665 memset(&response, 0x00, sizeof(oal_gatt_response_t));
2667 response.handle = req_info->attribute_handle;
2668 response.attr_value.auth_req = param->auth_req;
2669 response.attr_value.handle = req_info->attribute_handle;
2670 response.attr_value.offset = data->offset;
2671 response.attr_value.len = data->length;
2672 memcpy(&response.attr_value.value, &data->data, data->length);
2675 ret = gatts_send_response(req_info->connection_id, param->request_id,
2676 param->response_status, &response);
2678 if (ret != OAL_STATUS_SUCCESS) {
2679 BT_ERR("ret: %d", ret);
2680 return _bt_convert_oal_status_to_bt_error(ret);
2683 /* Remove GATT server request from list */
2684 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
2685 g_free(req_info->addr);
2687 return BLUETOOTH_ERROR_NONE;
2690 int _bt_gatt_server_acquire_send_response(char *sender, bluetooth_gatt_server_acquire_response_params_t *param , void *fd_list)
2692 BT_CHECK_PARAMETER(sender, return);
2693 BT_CHECK_PARAMETER(param, return);
2694 struct gatt_server_req_info *req_info = NULL;
2695 int ret = OAL_STATUS_SUCCESS;
2698 BT_INFO("GATT acquire Server Response: Req Type [%d] req_id [%d] fd [%d] mtu[%d]",
2699 param->req_type, param->request_id,
2703 /* Search for matching Request in List */
2704 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
2706 BT_ERR("GATT acquire Server Req Info not found for current response..return Error");
2707 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2710 ret = gatt_send_response_acquire(req_info->connection_id, param->request_id, 0, param->fd, param->mtu, fd_list);
2712 if (ret != OAL_STATUS_SUCCESS) {
2713 BT_ERR("ret: %d", ret);
2714 return _bt_convert_oal_status_to_bt_error(ret);
2717 /* Remove GATT server request from list */
2718 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
2719 g_free(req_info->addr);
2721 return BLUETOOTH_ERROR_NONE;
2726 int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
2727 bluetooth_gatt_att_data_t *data,
2728 bluetooth_gatt_server_indication_params_t *param)
2730 BT_CHECK_PARAMETER(sender, return);
2731 BT_CHECK_PARAMETER(data, return);
2732 BT_CHECK_PARAMETER(param, return);
2734 gboolean all_send = FALSE;
2735 int ret = OAL_STATUS_SUCCESS;
2736 struct gatt_client_info_t *conn;
2738 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2739 _bt_convert_addr_type_to_string(address, dev_addr->addr);
2741 if (memcmp(dev_addr->addr, BDADDR_ANY, 6) == 0) {
2742 BT_INFO("GATT Server: Send Indication to all connected GATT clients..");
2745 BT_INFO("GATT Server: Send Indication to connected GATT client addr [%s]", address);
2748 /* Attempt to send Notification/Indication to all Connected GATT clients */
2750 ret = __bt_gatt_send_indication_to_all_connected_clients(data, param);
2751 if (ret != OAL_STATUS_SUCCESS) {
2752 BT_ERR("ret: %d", ret);
2754 return _bt_convert_oal_status_to_bt_error(ret);
2758 conn = _bt_find_remote_gatt_client_info(address);
2760 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
2761 conn->connection_id, data->length,
2762 param->need_confirmation, (char *)(&data->data[0]));
2764 if (ret != OAL_STATUS_SUCCESS) {
2765 BT_ERR("ret: %d", ret);
2766 BT_INFO("Indication failed to send to Remote GATT Client [%s]", address);
2768 return _bt_convert_oal_status_to_bt_error(ret);
2770 BT_INFO("Indication sent to Remote GATT Client [%s] wait for Notification completed event from OAL", address);
2772 num_indicate_clients = 1;
2773 return BLUETOOTH_ERROR_NONE;
2775 BT_ERR("Remote GATT client [%s] is not connected..Cant send Indication!!", address);
2777 return BLUETOOTH_ERROR_NOT_CONNECTED;
2780 return BLUETOOTH_ERROR_NONE;
2783 int _bt_gatt_server_update_attribute_value(char *sender, int instance_id,
2784 bluetooth_gatt_server_update_value_t *param)
2786 BT_CHECK_PARAMETER(sender, return);
2787 BT_CHECK_PARAMETER(param, return);
2788 int ret = OAL_STATUS_SUCCESS;
2790 oal_gatt_value_t value;
2791 BT_DBG("GATT Server Update value: Instance ID [%d] attr handle [%d] Value len [%d]",
2792 instance_id, param->attribute_handle, param->length);
2794 memset(&value, 0x00, sizeof(oal_gatt_value_t));
2796 value.handle = param->attribute_handle;
2797 value.len = param->length;
2798 memcpy(&value.value, ¶m->data.data, param->length);
2800 ret = gatts_update_att_value(instance_id, &value);
2802 if (ret != OAL_STATUS_SUCCESS) {
2803 BT_ERR("ret: %d", ret);
2804 return _bt_convert_oal_status_to_bt_error(ret);
2807 return BLUETOOTH_ERROR_NONE;
2810 int _bt_request_att_mtu(bluetooth_device_address_t *device_address,
2813 struct gatt_server_info_t *conn_info = NULL;
2815 int ret = OAL_STATUS_SUCCESS;
2817 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
2818 _bt_convert_addr_type_to_string(addr, device_address->addr);
2820 /* Check if remote GATT Server is connected or not */
2821 conn_info = _bt_find_remote_gatt_server_info(addr);
2822 if (conn_info == NULL) {
2823 BT_ERR("GATT Server is not yet connected..");
2825 return BLUETOOTH_ERROR_NOT_CONNECTED;
2828 ret = gattc_configure_mtu(conn_info->connection_id, mtu);
2829 if (ret != OAL_STATUS_SUCCESS) {
2830 BT_ERR("ret: %d", ret);
2832 return _bt_convert_oal_status_to_bt_error(ret);
2836 return BLUETOOTH_ERROR_NONE;
2839 int _bt_get_att_mtu(bluetooth_device_address_t *address,
2842 BT_CHECK_PARAMETER(address, return);
2843 BT_CHECK_PARAMETER(mtu, return);
2844 struct gatt_client_info_t *client_info = NULL;
2845 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
2846 int ret = OAL_STATUS_SUCCESS;
2849 _bt_convert_addr_type_to_string(addr, address->addr);
2851 BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]", addr);
2853 client_info = _bt_find_remote_gatt_client_info(addr);
2855 BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
2856 client_info->addr, client_info->connection_id, client_info->instance_id);
2858 ret = gatts_get_att_mtu(client_info->connection_id, &stack_mtu);
2859 if (ret != OAL_STATUS_SUCCESS) {
2860 BT_ERR("ret: %d", ret);
2861 return _bt_convert_oal_status_to_bt_error(ret);
2864 struct gatt_server_info_t *server_info = NULL;
2865 BT_ERR("GATT Client [%s] is not yet connected..", addr);
2866 server_info = _bt_find_remote_gatt_server_info(addr);
2868 BT_INFO("GATT Server [%s] is connected, conn Id [%d] Client ID [%d]",
2869 server_info->addr, server_info->connection_id, server_info->client_id);
2871 ret = gattc_get_att_mtu(server_info->connection_id, &stack_mtu);
2872 if (ret != OAL_STATUS_SUCCESS) {
2873 BT_ERR("ret: %d", ret);
2874 return _bt_convert_oal_status_to_bt_error(ret);
2877 BT_ERR("GATT Server [%s] is not yet connected..", addr);
2878 return BLUETOOTH_ERROR_NOT_CONNECTED;
2882 BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
2883 *mtu = (unsigned int)stack_mtu;
2886 BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
2887 return BLUETOOTH_ERROR_NOT_CONNECTED;
2890 return BLUETOOTH_ERROR_NONE;
2893 /* GATT Client utility static functions */
2894 static bt_gatt_service_info_list_t *__bt_get_service_info_list(int conn_id)
2897 bt_gatt_service_info_list_t *info = NULL;
2899 for (l = list_gatt_info; l != NULL; l = g_slist_next(l)) {
2900 info = (bt_gatt_service_info_list_t *)l->data;
2904 if (info->conn_id == conn_id)
2911 static bt_gatt_service_info_t *__bt_find_matching_service(
2912 bt_gatt_service_info_list_t *svc_list, oal_gatt_srvc_id_t *svc)
2915 bt_gatt_service_info_t *info = NULL;
2917 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
2918 info = (bt_gatt_service_info_t *)l->data;
2922 /* Match UUID and instance ID */
2923 if (!memcmp(&svc->id.uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2924 && (svc->id.inst_id == info->inst_id)) {
2931 static bt_gatt_char_info_t *__bt_find_matching_charc(
2932 bt_gatt_service_info_t *svc_info, oal_gatt_id_t *charc)
2935 bt_gatt_char_info_t *info = NULL;
2937 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
2938 info = (bt_gatt_char_info_t *)l->data;
2942 /* Match UUID and instance ID */
2943 if (!memcmp(&charc->uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2944 && (charc->inst_id == info->inst_id)) {
2951 static bt_gatt_descriptor_info_t *__bt_find_matching_desc(
2952 bt_gatt_char_info_t *char_info, oal_gatt_id_t *desc)
2955 bt_gatt_descriptor_info_t *info = NULL;
2957 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
2958 info = (bt_gatt_descriptor_info_t *)l->data;
2962 /* Match UUID and instance ID */
2963 if (!memcmp(&desc->uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2964 && (desc->inst_id == info->inst_id)) {
2972 static struct gatt_server_info_t *__bt_find_remote_gatt_server_info_from_conn_id(int conn_id)
2975 struct gatt_server_info_t *info = NULL;
2977 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
2978 info = (struct gatt_server_info_t*)l->data;
2982 if (info->connection_id == conn_id)
2988 static bt_gatt_service_info_t* __bt_find_removed_service(bt_gatt_service_info_list_t *svc_list)
2991 bt_gatt_service_info_t *info = NULL;
2993 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
2994 info = (bt_gatt_service_info_t*)l->data;
2998 /* Service is marked a removed */
2999 if (info->is_removed == 1)
3005 static void __bt_remove_service_info_from_list(bt_gatt_service_info_t *svc_info)
3011 bt_gatt_char_info_t *charc = NULL;
3012 bt_gatt_included_service_info_t *incl = NULL;
3013 bt_gatt_descriptor_info_t *desc = NULL;
3015 /* Remove all Characteristic and Descriptors within characteristic */
3016 for (l = svc_info->chars; l != NULL;) {
3017 charc = (bt_gatt_char_info_t*)l->data;
3018 l = g_slist_next(l); /* Incase if l is removed, saving next to l */
3023 /* Inside Characteristic */
3024 for (l1 = charc->descs; l1 != NULL;) {
3026 desc = (bt_gatt_descriptor_info_t*)l1->data;
3027 l1 = g_slist_next(l1);
3032 /* Remove Descriptor */
3033 charc->descs = g_slist_remove(charc->descs, desc);
3036 /* Remove Characteristic */
3037 svc_info->chars = g_slist_remove(svc_info->chars, charc);
3041 /* Remove all Included Services */
3042 for (l2 = svc_info->included_svcs; l2 != NULL;) {
3043 incl = (bt_gatt_included_service_info_t*)l2->data;
3044 l2 = g_slist_next(l2); /* Incase if l is removed, saving next to l */
3049 /* Remove included service */
3050 svc_info->included_svcs = g_slist_remove(svc_info->included_svcs, incl);
3057 static void __bt_build_service_browse_info(int conn_id,
3058 bt_services_browse_info_t* info)
3061 bt_gatt_service_info_list_t *svc_info_list;
3062 bt_gatt_service_info_t *svc_info;
3064 service_uuid_t uuid;
3065 struct gatt_server_info_t *conn_info = NULL;
3067 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3069 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3070 if (conn_info == NULL) {
3071 BT_ERR("Cant find connection Information");
3075 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3077 svc_info_list = __bt_get_service_info_list(conn_id);
3081 info->count = g_slist_length(svc_info_list->services);
3082 BT_DBG("Total services present in the svc info list for this conn id [%d] is [%d]",
3083 conn_id, info->count);
3085 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
3086 svc_info = (bt_gatt_service_info_t*)l->data;
3087 if (svc_info == NULL)
3090 memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3091 _bt_uuid_to_string(&uuid, uuid_string);
3093 BT_INFO("[%d] %s [%s]", count, uuid_string, _bt_convert_uuid_to_string(uuid_string));
3095 /* Fill UUID of service */
3096 g_strlcpy(info->uuids[count], uuid_string,
3097 BLUETOOTH_UUID_STRING_MAX);
3099 /* Fill instance ID of service */
3100 info->inst_id[count] = svc_info->inst_id;
3102 /* Fill primary service or not info */
3103 info->primary[count] = svc_info->is_primary;
3105 /* Increment count of services browsed */
3110 static void __bt_build_char_browse_info(int conn_id,
3111 bt_gatt_service_info_t *svc_info,
3112 bt_char_browse_info_t* info)
3115 bt_gatt_char_info_t *char_info;
3116 service_uuid_t uuid;
3118 struct gatt_server_info_t *conn_info = NULL;
3120 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3122 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3123 if (conn_info == NULL) {
3124 BT_ERR("Cant find connection Information");
3128 /* Fill default data, this will be required even in case of failure */
3129 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3130 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3131 info->svc_inst_id = svc_info->inst_id;
3133 if (!svc_info->chars) {
3134 BT_ERR("No Chars browsed for address [%s]", conn_info->addr);
3138 info->count = g_slist_length(svc_info->chars);
3140 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3141 char_info = (bt_gatt_char_info_t*)l->data;
3142 if (char_info == NULL)
3145 memcpy(&uuid.uuid, &char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3146 _bt_uuid_to_string(&uuid, uuid_string);
3148 /* Fill UUID of characteristic */
3149 g_strlcpy(info->uuids[count], uuid_string,
3150 BLUETOOTH_UUID_STRING_MAX);
3152 /* Fill instance ID of characteristic */
3153 info->inst_id[count] = char_info->inst_id;
3155 /* Fill property of characteristic */
3156 info->props[count] = char_info->props;
3158 /* Increment count of services browsed */
3161 BT_DBG("Total characteristics browsed [%d]", count);
3164 static void __bt_build_descriptor_browse_info(int conn_id,
3165 bt_gatt_service_info_t *svc_info,
3166 bt_gatt_char_info_t *char_info,
3167 bt_descriptor_browse_info_t* info)
3170 bt_gatt_descriptor_info_t *desc_info;
3172 service_uuid_t uuid;
3173 struct gatt_server_info_t *conn_info = NULL;
3175 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3177 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3179 /* Fill default data, this will be required even in case of failure */
3180 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3181 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3182 info->svc_inst_id = svc_info->inst_id;
3183 memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3184 info->char_inst_id = char_info->inst_id;
3186 /* Fill property of the parent characteristic of this descriptor */
3187 info->char_props_map = char_info->props;
3189 info->count = g_slist_length(char_info->descs);
3191 if (!char_info->descs) {
3192 BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr + 12);
3196 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3197 desc_info = (bt_gatt_descriptor_info_t*)l->data;
3198 if (desc_info == NULL)
3201 memcpy(&uuid.uuid, &desc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3202 _bt_uuid_to_string(&uuid, uuid_string);
3204 /* Fill UUID of Descriptor */
3205 g_strlcpy(info->uuids[count], uuid_string,
3206 BLUETOOTH_UUID_STRING_MAX);
3208 /* Fill instance ID of Descriptor */
3209 info->inst_id[count] = desc_info->inst_id;
3212 /* Increment count of Descriptor browsed */
3216 BT_INFO("Total descriptors browsed [%d]", count);
3219 static void __bt_free_service_info(bt_gatt_service_info_t *svc)
3221 GSList *ll, *lll, *llll;
3222 bt_gatt_char_info_t *chr = NULL;
3223 bt_gatt_descriptor_info_t *desc = NULL;
3224 bt_gatt_included_service_info_t *incl_svc = NULL;
3226 BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id);
3227 /* Delete all chars and its descriptors */
3228 for (ll = svc->chars; ll != NULL; ) {
3229 chr = (bt_gatt_char_info_t *)ll->data;
3230 ll = g_slist_next(ll);
3234 for (lll = chr->descs; lll != NULL; ) {
3235 desc = (bt_gatt_descriptor_info_t *)lll->data;
3236 lll = g_slist_next(lll);
3239 chr->descs = g_slist_remove(chr->descs, desc);
3242 svc->chars = g_slist_remove(svc->chars, chr);
3246 /* Delete all included services */
3247 for (llll = svc->included_svcs; llll != NULL; ) {
3248 incl_svc = (bt_gatt_included_service_info_t *)llll->data;
3249 llll = g_slist_next(llll);
3250 if (incl_svc == NULL)
3252 svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc);
3257 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
3259 bt_gatt_service_info_list_t *svc_info_list = NULL;
3260 bt_gatt_service_info_t *svc = NULL;
3264 BT_ERR("conn_info is NULL");
3268 svc_info_list = __bt_get_service_info_list(conn_info->connection_id);
3269 if (!svc_info_list) {
3270 BT_INFO("Could not find Svc Info list for the connection ID [%d]",
3271 conn_info->connection_id);
3275 BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services));
3276 for (l = svc_info_list->services; l != NULL; ) {
3277 svc = (bt_gatt_service_info_t *)l->data;
3278 l = g_slist_next(l);
3282 __bt_free_service_info(svc);
3283 svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
3287 list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
3288 g_free(svc_info_list);
3291 int _bt_register_gatt_client_instance(const char *sender,
3292 bluetooth_device_address_t *address)
3294 int ret = OAL_STATUS_SUCCESS;
3295 char *uuid_string = NULL;
3300 /* App should ensure that it should not send */
3301 BT_INFO("Check on which instance GATT Client instance can be initialized....");
3302 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3303 if (numapps[k].is_initialized == 1) {
3304 BT_DBG("Instance ID [%d] is already in use..Check next slot",
3305 numapps[k].instance_id);
3308 BT_DBG("Time to register GATT client instancer..UUID to be used is [%s] slot [%d]",
3309 uuid_list[slot-1], slot);
3315 BT_ERR("No Slot if free for GATT Client registration..");
3316 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
3319 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3320 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
3321 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
3322 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
3324 /* Register GATT Client */
3325 ret = gattc_register(&uuid);
3326 if (ret != OAL_STATUS_SUCCESS) {
3327 BT_ERR("ret: %d", ret);
3328 g_free(uuid_string);
3329 return _bt_convert_oal_status_to_bt_error(ret);
3332 BT_DBG("GATT Client registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
3334 /* Return & wait for GATT Client Instance Initialization event */
3335 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
3336 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
3338 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
3339 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
3341 /* Address is saved here. When event comes, sender + address are matched for replying pending
3342 request. It is impossible for same sender to have requests with two same addresses */
3343 memcpy(&numapps[slot].address.addr, address->addr, sizeof(bluetooth_device_address_t));
3345 numapps[slot].is_initialized = TRUE; /* Set initialization to true here itself */
3347 g_free(uuid_string);
3348 return BLUETOOTH_ERROR_NONE;
3354 /* GATT client events */
3355 static void __bt_handle_client_instance_registered(event_gattc_register_t *data)
3357 bt_service_app_info_t *info = NULL;
3359 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3361 _bt_uuid_to_string(&(data->client_uuid), uuid_string);
3362 BT_INFO("Client ID is Initialized [%d] UUID initialized [%s]", data->client_if, uuid_string);
3364 /* Platform GATT client framwork does not use Default GATT client instance
3365 This GATT client instance is never deregistred in the lifetime of bt-service */
3366 if (g_strcmp0(uuid_string, DEFAULT_GATT_CLIENT_UUID) == 0) {
3367 BT_INFO("Default client Instance Registered");
3368 gatt_default_client = data->client_if;
3369 g_free(uuid_string);
3373 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3376 if (g_strcmp0(info->uuid, uuid_string) == 0) {
3377 BT_INFO("Found GATT client.. sender [%s] Slot [%d] occupied", info->sender, k);
3378 info->is_initialized = TRUE;
3379 info->client_id = data->client_if;
3380 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_CLIENT_REGISTER,
3381 (void*)info, sizeof(bt_service_app_info_t));
3385 g_free(uuid_string);
3388 static void __bt_handle_client_connected(event_gattc_conn_t *event_data)
3390 int result = BLUETOOTH_ERROR_NONE;
3391 struct gatt_server_info_t *conn_info = NULL;
3392 struct gatt_out_conn_info_t *out_conn_info = NULL;
3394 GVariant *param = NULL;
3396 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3397 _bt_convert_addr_type_to_string(address,
3398 (unsigned char *)event_data->address.addr);
3400 if (event_data->status != OAL_STATUS_SUCCESS)
3401 result = BLUETOOTH_ERROR_INTERNAL;
3403 /* DBUS Return fo BT_CONNECT_LE for all the apps */
3404 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
3405 BT_ADDRESS_STRING_SIZE);
3407 BT_INFO("Local GATT Client Connected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status[%d]",
3408 address, event_data->client_if, event_data->conn_id, event_data->status);
3410 if (result == BLUETOOTH_ERROR_NONE) {
3411 /* Check if device is already in connected list */
3412 conn_info = _bt_find_remote_gatt_server_info(address);
3415 /* Send event to BT-API */
3416 param = g_variant_new("(is)", result, address);
3417 _bt_send_event(BT_DEVICE_EVENT,
3418 BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED, /* Local device is GATT client */
3421 /* Save Connection info */
3422 conn_info = g_new0(struct gatt_server_info_t, 1);
3423 conn_info->addr = g_strdup(address);
3424 conn_info->client_id = event_data->client_if;
3425 #ifdef __INTEGRATE_GATT_INFO__
3426 conn_info->instance_id = -1;
3428 conn_info->connection_id = event_data->conn_id;
3429 gatt_server_info_list = g_slist_append(gatt_server_info_list, conn_info);
3430 BT_DBG("Total num of connected Remote GATT server devices [%d]",
3431 g_slist_length(gatt_server_info_list));
3434 BT_INFO("Do a Internal refresh");
3435 if (OAL_STATUS_SUCCESS != gattc_refresh(conn_info->client_id, &event_data->address))
3436 BT_ERR("GATT database refresh failed!!");
3438 BT_INFO("GATT database refresh Success!!");
3441 BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
3443 __bt_add_mtu_gatt_device(address);
3445 _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
3447 BT_ERR("GATT Client Connection failed!!");
3449 /* If outgoing connection Info is present, then remove it */
3450 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
3451 if (out_conn_info) {
3452 BT_ERR("Outgoing Client connect request was sent");
3453 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
3454 g_free(out_conn_info->addr);
3455 g_free(out_conn_info);
3457 _bt_restart_le_scan();
3462 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
3464 int result = BLUETOOTH_ERROR_NONE;
3465 struct gatt_server_info_t *conn_info = NULL;
3466 #ifndef __INTEGRATE_GATT_INFO__
3467 struct gatt_client_info_t *client_info = NULL;
3469 struct gatt_out_conn_info_t *out_conn_info = NULL;
3470 GVariant *param = NULL;
3472 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3473 _bt_convert_addr_type_to_string(address,
3474 (unsigned char *)event_data->address.addr);
3476 if (event_data->status != OAL_STATUS_SUCCESS)
3477 result = BLUETOOTH_ERROR_INTERNAL;
3479 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
3480 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
3481 result = BLUETOOTH_ERROR_INTERNAL;
3482 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
3483 address, BT_ADDRESS_STRING_SIZE);
3484 BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
3489 /* DBUS Return for BT_DISCONNECT_LE for all the apps */
3490 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE, address,
3491 BT_ADDRESS_STRING_SIZE);
3493 BT_INFO("Local GATT Client DisConnected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status [%d]",
3494 address + 12, event_data->client_if, event_data->conn_id, event_data->status);
3496 /* Remove Connection info */
3497 conn_info = _bt_find_remote_gatt_server_info(address);
3500 param = g_variant_new("(is)", result, address);
3501 /* Send event to application */
3502 _bt_send_event(BT_DEVICE_EVENT,
3503 BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED,
3506 BT_INFO("Remove GATT server info from List..");
3507 /* Remove all services from info list_gatt_info */
3508 __bt_cleanup_remote_services(conn_info);
3510 /* Remove info from List */
3511 gatt_server_info_list = g_slist_remove(gatt_server_info_list, conn_info);
3512 BT_INFO("Total num of connected GATT servers [%d]", g_slist_length(gatt_server_info_list));
3513 g_free(conn_info->addr);
3516 BT_INFO("Can not find conn info, already removed!");
3518 #ifndef __INTEGRATE_GATT_INFO__
3519 /* Remove client info */
3520 client_info = _bt_find_remote_gatt_client_info(address);
3522 BT_DBG("Remove GATT client info from list");
3523 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
3524 g_free(client_info->addr);
3525 g_free(client_info);
3529 __bt_remove_mtu_gatt_device(address);
3531 /* If outgoing connection Info is present, then remove it */
3532 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
3533 if (out_conn_info) {
3534 BT_ERR("Client Disconnected event, but outgoing connect request was sent");
3535 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
3536 g_free(out_conn_info->addr);
3537 g_free(out_conn_info);
3543 static void __bt_handle_client_service_search_result(
3544 event_gattc_service_result_t *event_data)
3546 /* Pre: status is never fail from OAL */
3548 /* Find service list from address */
3549 bt_gatt_service_info_list_t *svc_info_list;
3550 bt_gatt_service_info_t *svc_info;
3552 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3553 if (!svc_info_list) {
3554 BT_DBG("Service info list not present for connection ID %d, means first time browse", event_data->conn_status.conn_id);
3555 /* Means for this conn_id, no services are ever browsed, first time,
3556 create service info list for this conn_id */
3557 svc_info_list = g_malloc0(sizeof(bt_gatt_service_info_list_t));
3558 svc_info_list->conn_id = event_data->conn_status.conn_id;
3559 list_gatt_info = g_slist_append(list_gatt_info, svc_info_list);
3562 /* send list and current service's uuid and instance id to find it */
3563 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3564 /* If not found, check if service changed, if yes, means this is a new service added
3565 in remote GATT device, update uuid info in svc info list structure, to be used when
3566 search is completed */
3568 if (svc_info_list->info.is_changed) {
3569 BT_DBG("Service Changed indication already found for connection ID %d", event_data->conn_status.conn_id);
3570 memcpy(svc_info_list->info.uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3572 /* Create and add new service in service list */
3573 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
3574 memcpy(svc_info->uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3575 svc_info->inst_id = event_data->srvc_id.id.inst_id;
3576 svc_info->is_primary = event_data->srvc_id.is_prmry;
3577 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
3578 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_status.conn_id);
3580 /* If returned matching service info, then just update service_rmeoved value inside it to 0 */
3581 svc_info->is_removed = 0;
3585 static void __bt_handle_client_service_search_completed(
3586 event_gattc_conn_status_t *event_data)
3588 struct gatt_server_info_t *conn_info = NULL;
3589 bt_gatt_service_info_list_t *svc_info_list;
3590 bt_gatt_service_info_t *svc_info;
3591 bt_services_browse_info_t browse_info;
3592 unsigned char uuid_empty[BLUETOOTH_UUID_HEX_MAX_LEN];
3594 memset(&uuid_empty, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
3595 memset(&browse_info, 0x00, sizeof(bt_services_browse_info_t));
3596 BT_INFO("Primary Services browsing completed status[%d] conn ID [%d]",
3597 event_data->status, event_data->conn_id);
3599 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
3601 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
3602 if (!svc_info_list) {
3603 BT_ERR("No services browsed ever for addr [%s]", conn_info->addr);
3605 /* Just build response and return ERROR */
3606 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3608 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
3609 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3610 sizeof(bt_services_browse_info_t));
3614 /* If fail, then send event with error */
3615 if (event_data->status != OAL_STATUS_SUCCESS) {
3616 /* Just build response and return ERROR */
3617 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3619 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
3620 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3621 sizeof(bt_services_browse_info_t));
3625 /* If success, then find service info list from address */
3627 /* If svc_changed == 1 and uuid valid, means a new service is added*/
3628 if (svc_info_list->info.is_changed && !memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
3629 /* TODO: Send event -Service added with instance ID and UUID of newly added service */
3630 BT_INFO("new service added");
3632 BT_INFO("TODO new service added");
3635 /* If svc_changed == 1 and uuid invalid, then a service is removed */
3636 if (svc_info_list->info.is_changed && memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
3637 /* Scan through the service info list to find service with is_removed = 1*/
3638 svc_info = __bt_find_removed_service(svc_info_list);
3640 /* TODO Send event - Service removed with instance ID and UUID of just rmeoved service */
3642 /* Remove that service info from service info list */
3643 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
3645 /* Delete that service completely from svc_info list*/
3646 __bt_remove_service_info_from_list(svc_info);
3650 /* Reset svc_changed = 0, and reset UUID = all 0's */
3651 svc_info_list->info.is_changed = 0;
3652 memset(&svc_info_list->info.uuid, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
3654 /* Build Reply and send to service browse primary services request of pending apps */
3655 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3657 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3658 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3659 sizeof(bt_services_browse_info_t));
3663 static void __bt_handle_client_characteristic_search_result(
3664 event_gattc_characteristic_result_t *event_data)
3666 bt_gatt_service_info_list_t *svc_info_list;
3667 bt_gatt_service_info_t *svc_info;
3668 bt_gatt_char_info_t *char_info;
3669 bt_char_browse_info_t browse_info;
3671 memset(&browse_info, 0x00, sizeof(bt_char_browse_info_t));
3674 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
3675 /* Find service info list from address */
3676 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3677 if (svc_info_list == NULL) {
3678 BT_ERR("svc_info_list is NULL");
3682 /* Find matching service info from svc info list */
3683 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3684 if (svc_info == NULL) {
3685 BT_ERR("svc_info is NULL");
3689 /* Find Matching char from service info in event */
3690 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3691 /* If not found, then add new characteristic and return */
3693 BT_DBG("Add new characteristic");
3694 char_info = g_malloc0(sizeof(bt_gatt_char_info_t));
3695 memcpy(char_info->uuid, event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3697 char_info->inst_id = event_data->char_id.inst_id;
3698 char_info->props = event_data->char_prop;
3699 svc_info->chars = g_slist_append(svc_info->chars, char_info);
3701 /* If found, then return */
3702 BT_DBG("update char property as Characteristic browsed is already present");
3703 char_info->props |= event_data->char_prop;
3706 /* If Not success: Means Charc browse is completed */
3707 /* Find char list from service in event */
3708 /* Find service list from address */
3709 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3710 if (svc_info_list == NULL) {
3711 BT_ERR("svc_info_list is NULL");
3715 /* Find service info from service in event */
3716 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3717 if (svc_info == NULL) {
3718 BT_ERR("svc_info is NULL");
3722 /* Build char list from service in event */
3723 __bt_build_char_browse_info(event_data->conn_status.conn_id,
3724 svc_info, &browse_info);
3726 /* Create response and return by sending event*/
3727 /* Build Reply and send to service browse All Included services request of pending apps */
3728 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3729 BT_GATT_GET_SERVICE_PROPERTIES,
3731 sizeof(bt_char_browse_info_t));
3735 static void __bt_handle_client_descriptor_search_result(
3736 event_gattc_descriptor_result_t *event_data)
3738 bt_gatt_service_info_list_t *svc_info_list;
3739 bt_gatt_service_info_t *svc_info;
3740 bt_gatt_char_info_t *char_info;
3741 bt_gatt_descriptor_info_t *desc_info;
3742 bt_descriptor_browse_info_t browse_info;
3744 BT_DBG("descriptor search result status [%d]", event_data->conn_status.status);
3746 memset(&browse_info, 0x00, sizeof(bt_descriptor_browse_info_t));
3749 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
3750 /* Find service list from address */
3751 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3752 if (svc_info_list == NULL) {
3753 BT_ERR("svc_info_list is NULL");
3757 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3758 if (svc_info == NULL) {
3759 BT_ERR("svc_info is NULL");
3763 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3764 if (char_info == NULL) {
3765 BT_ERR("char_info is NULL");
3769 desc_info = __bt_find_matching_desc(char_info, &event_data->descr_id);
3770 /* If not found, add new descriptor and return */
3772 desc_info = g_malloc0(sizeof(bt_gatt_descriptor_info_t));
3773 memcpy(desc_info->uuid, event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3775 desc_info->inst_id = event_data->descr_id.inst_id;
3776 char_info->descs = g_slist_append(char_info->descs, desc_info);
3779 /* If found, then return */
3780 BT_DBG("Descriptor browsed is already presesnt");
3783 /* If Not success */
3784 /* Find service list from address */
3785 /* Find included service list from service in event */
3786 /* Create response and return by sending event*/
3787 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3788 if (svc_info_list == NULL) {
3789 BT_ERR("svc_info_list is NULL");
3793 /* Find service info from service in event */
3794 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3795 if (svc_info == NULL) {
3796 BT_ERR("svc_info is NULL");
3800 /* Find char info from char in event */
3801 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3802 if (char_info == NULL) {
3803 BT_ERR("char_info is NULL");
3807 /* Build descriptor list from char in event */
3808 __bt_build_descriptor_browse_info(event_data->conn_status.conn_id,
3809 svc_info, char_info, &browse_info);
3812 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3813 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
3815 sizeof(bt_descriptor_browse_info_t));
3819 static void __bt_handle_client_characteristic_read_data(
3820 event_gattc_read_data *event_data)
3822 int result = BLUETOOTH_ERROR_NONE;
3823 struct gatt_server_info_t *conn_info = NULL;
3824 bluetooth_gatt_client_char_prop_info_t read_info;
3826 /* Read Information data structures */
3827 GVariant *param = NULL;
3828 GVariant *data = NULL;
3829 GVariant *data_svc_uuid = NULL;
3830 GVariant *data_char_uuid = NULL;
3831 char *read_val = NULL;
3832 char *svc_uuid = NULL;
3833 char *char_uuid = NULL;
3836 //memset(&read_info, 0x00, sizeof(bt_gatt_handle_property_t));
3837 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
3839 /* Extract Address from conn_id of event data */
3840 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
3841 event_data->uuid_status.conn_status.conn_id);
3843 BT_INFO("Characteristic Read result from addr [%s] status [%d]",
3844 conn_info->addr, event_data->uuid_status.conn_status.status);
3846 /* Fill char in buffer */
3847 memcpy(&read_info.characteristic.uuid,
3848 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3849 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
3851 /* Fill Service in buffer */
3852 memcpy(&read_info.svc.uuid,
3853 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3854 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
3856 /* Fill remote device address */
3857 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
3859 /* Fill data and reply to all apps waiting for Read result on the same characteristic
3860 Note: Even in case of failure, address, handles and result code should be returned */
3861 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
3862 result = BLUETOOTH_ERROR_INTERNAL;
3864 if (event_data->data_len > 0) {
3866 // for (i = 0; i < event_data->data_len; i++)
3867 // BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
3870 read_val = g_memdup(&event_data->data[0], event_data->data_len);
3872 data = g_variant_new_from_data(
3873 G_VARIANT_TYPE_BYTESTRING,
3875 event_data->data_len,
3878 BT_ERR("Characteristic Read success, but no data!!!");
3880 data = g_variant_new_from_data(
3881 G_VARIANT_TYPE_BYTESTRING,
3888 svc_uuid = g_memdup(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
3890 data_svc_uuid = g_variant_new_from_data(
3891 G_VARIANT_TYPE_BYTESTRING,
3897 char_uuid = g_memdup(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
3899 data_char_uuid = g_variant_new_from_data(
3900 G_VARIANT_TYPE_BYTESTRING,
3905 param = g_variant_new("(isn@ayin@ayin@ay)", result,
3909 event_data->uuid_status.srvc_id.id.inst_id,
3912 event_data->uuid_status.char_id.inst_id,
3913 event_data->data_len,
3917 char *sender = NULL;
3918 __bt_gatt_get_pending_request_info(BT_GATT_READ_CHARACTERISTIC, &sender);
3919 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
3920 BLUETOOTH_EVENT_GATT_READ_CHAR,
3923 /* Send DBUS return */
3924 __bt_gatt_handle_pending_request_info(result,
3925 BT_GATT_READ_CHARACTERISTIC,
3927 sizeof(bluetooth_gatt_client_char_prop_info_t));
3938 static void __bt_handle_client_descriptor_read_data(
3939 event_gattc_read_data *event_data)
3941 int result = BLUETOOTH_ERROR_NONE;
3942 struct gatt_server_info_t *conn_info = NULL;
3943 bluetooth_gatt_client_desc_prop_info_t read_info;
3945 /* Read Information data structures */
3946 GVariant *param = NULL;
3947 GVariant *data = NULL;
3948 GVariant *data_svc_uuid = NULL;
3949 GVariant *data_char_uuid = NULL;
3950 GVariant *data_desc_uuid = NULL;
3951 char *read_val = NULL;
3952 char *svc_uuid = NULL;
3953 char *char_uuid = NULL;
3954 char *desc_uuid = NULL;
3958 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
3960 /* Extract Address from conn_id of event data */
3961 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
3962 event_data->uuid_status.conn_status.conn_id);
3964 BT_DBG("Descriptor Read result from addr [%s] status [%d]",
3965 conn_info->addr, event_data->uuid_status.conn_status.status);
3967 /* Fill descriptor informations in buffer */
3968 memcpy(&read_info.descriptor.uuid,
3969 event_data->uuid_status.descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3970 read_info.descriptor.instance_id = event_data->uuid_status.descr_id.inst_id;
3972 /* Fill Characteristic informations in buffer */
3973 memcpy(&read_info.characteristic.uuid,
3974 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3975 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
3977 /* Fill Service informations in buffer */
3978 memcpy(&read_info.svc.uuid,
3979 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3980 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
3982 /* Fill remote device address */
3983 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
3985 /* Fill data and reply to all apps waiting for Read result on the same characteristic */
3986 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
3987 result = BLUETOOTH_ERROR_INTERNAL;
3989 if (event_data->data_len > 0) {
3991 for (i = 0; i < event_data->data_len; i++)
3992 BT_DBG("Data[%d] = [0x%x]", i, event_data->data[i]);
3995 read_val = g_memdup(&event_data->data[0], event_data->data_len);
3997 data = g_variant_new_from_data(
3998 G_VARIANT_TYPE_BYTESTRING,
4000 event_data->data_len,
4003 BT_INFO("Descriptor Read success, but no data!!!");
4005 data = g_variant_new_from_data(
4006 G_VARIANT_TYPE_BYTESTRING,
4012 svc_uuid = g_memdup(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4014 data_svc_uuid = g_variant_new_from_data(
4015 G_VARIANT_TYPE_BYTESTRING,
4021 char_uuid = g_memdup(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4023 data_char_uuid = g_variant_new_from_data(
4024 G_VARIANT_TYPE_BYTESTRING,
4030 desc_uuid = g_memdup(&event_data->uuid_status.descr_id.uuid.uuid[0], uuid_len);
4032 data_desc_uuid = g_variant_new_from_data(
4033 G_VARIANT_TYPE_BYTESTRING,
4038 param = g_variant_new("(isn@ayin@ayin@ayin@ay)", result,
4042 event_data->uuid_status.srvc_id.id.inst_id,
4045 event_data->uuid_status.char_id.inst_id,
4048 event_data->uuid_status.descr_id.inst_id,
4049 event_data->data_len,
4053 char *sender = NULL;
4054 __bt_gatt_get_pending_request_info(BT_GATT_READ_DESCRIPTOR_VALUE, &sender);
4055 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4056 BLUETOOTH_EVENT_GATT_READ_DESC,
4060 /* Send DBUS return */
4061 __bt_gatt_handle_pending_request_info(result,
4062 BT_GATT_READ_DESCRIPTOR_VALUE,
4064 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4075 static void __bt_handle_client_characteristic_write_data(
4076 event_gattc_write_data *event_data)
4078 int result = BLUETOOTH_ERROR_NONE;
4079 struct gatt_server_info_t *conn_info = NULL;
4080 bluetooth_gatt_client_char_prop_info_t write_info;
4082 /* Read Information data structures */
4083 GVariant *param = NULL;
4084 GVariant *data_svc_uuid = NULL;
4085 GVariant *data_char_uuid = NULL;
4086 char *svc_uuid = NULL;
4087 char *char_uuid = NULL;
4090 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4092 /* Extract Address from conn_id of event data */
4093 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4094 event_data->conn_status.conn_id);
4096 BT_DBG("Characteristic Write callback from addr [%s] status [%d]",
4097 conn_info->addr, event_data->conn_status.status);
4099 /* Fill char in buffer */
4100 memcpy(&write_info.characteristic.uuid,
4101 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4102 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4104 /* Fill Service in buffer */
4105 memcpy(&write_info.svc.uuid,
4106 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4107 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4109 /* Fill remote device address */
4110 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4112 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4113 result = BLUETOOTH_ERROR_INTERNAL;
4119 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4121 data_svc_uuid = g_variant_new_from_data(
4122 G_VARIANT_TYPE_BYTESTRING,
4128 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4130 data_char_uuid = g_variant_new_from_data(
4131 G_VARIANT_TYPE_BYTESTRING,
4136 param = g_variant_new("(isn@ayin@ayi)", result,
4140 event_data->srvc_id.id.inst_id,
4143 event_data->char_id.inst_id);
4146 char *sender = NULL;
4147 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, &sender);
4148 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4149 BLUETOOTH_EVENT_GATT_WRITE_CHAR,
4159 /* Send DBUS return */
4160 __bt_gatt_handle_pending_request_info(result,
4161 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
4163 sizeof(bluetooth_gatt_client_char_prop_info_t));
4167 static void __bt_handle_client_descriptor_write_data(
4168 event_gattc_write_data *event_data)
4170 int result = BLUETOOTH_ERROR_NONE;
4171 struct gatt_server_info_t *conn_info = NULL;
4172 bluetooth_gatt_client_desc_prop_info_t write_info;
4174 /* Write Information data structures */
4175 GVariant *param = NULL;
4176 GVariant *data_svc_uuid = NULL;
4177 GVariant *data_char_uuid = NULL;
4178 GVariant *data_desc_uuid = NULL;
4179 char *svc_uuid = NULL;
4180 char *char_uuid = NULL;
4181 char *desc_uuid = NULL;
4184 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4186 /* Extract Address from conn_id of event data */
4187 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4188 event_data->conn_status.conn_id);
4190 if (NULL == conn_info) {
4191 BT_ERR("Failed to get the conn info for conn_id [%d]", event_data->conn_status.conn_id);
4195 BT_DBG("Descriptor Write callback from addr [%s] status [%d]",
4196 conn_info->addr, event_data->conn_status.status);
4198 /* Fill descriptor informations in buffer */
4199 memcpy(&write_info.descriptor.uuid,
4200 event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4201 write_info.descriptor.instance_id = event_data->descr_id.inst_id;
4203 /* Fill Characteristic informations in buffer */
4204 memcpy(&write_info.characteristic.uuid,
4205 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4206 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4208 /* Fill Service informations in buffer */
4209 memcpy(&write_info.svc.uuid,
4210 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4211 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4213 /* Fill remote device address */
4214 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4216 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4217 result = BLUETOOTH_ERROR_INTERNAL;
4223 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4225 data_svc_uuid = g_variant_new_from_data(
4226 G_VARIANT_TYPE_BYTESTRING,
4232 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4234 data_char_uuid = g_variant_new_from_data(
4235 G_VARIANT_TYPE_BYTESTRING,
4241 desc_uuid = g_memdup(&event_data->descr_id.uuid.uuid[0], uuid_len);
4243 data_desc_uuid = g_variant_new_from_data(
4244 G_VARIANT_TYPE_BYTESTRING,
4249 param = g_variant_new("(isn@ayin@ayin@ayi)", result,
4253 event_data->srvc_id.id.inst_id,
4256 event_data->char_id.inst_id,
4259 event_data->descr_id.inst_id);
4262 char *sender = NULL;
4263 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_DESCRIPTOR_VALUE, &sender);
4264 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4265 BLUETOOTH_EVENT_GATT_WRITE_DESC,
4276 /* Send DBUS return */
4277 __bt_gatt_handle_pending_request_info(result,
4278 BT_GATT_WRITE_DESCRIPTOR_VALUE,
4280 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4283 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data)
4285 int result = BLUETOOTH_ERROR_INTERNAL;
4286 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4288 _bt_convert_addr_type_to_string(address, (unsigned char *)event_data->address.addr);
4290 /* DBUS Return with fail of pending BT_CONNECT_LE for all the apps */
4291 BT_INFO("Local GATT Client disconnected: Remote addr[%s] ", address + 12);
4293 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
4294 BT_ADDRESS_STRING_SIZE);
4298 static void __bt_handle_client_notification_registered(
4299 event_gattc_regdereg_notify_t *event_data,
4300 gboolean is_registered)
4302 int result = BLUETOOTH_ERROR_NONE;
4303 struct gatt_server_info_t *conn_info = NULL;
4304 bt_gatt_notif_reg_info_t notif_info;
4307 memset(¬if_info, 0x00, sizeof(bt_gatt_notif_reg_info_t));
4309 BT_INFO("Client Interface [%d] status [%d]",
4310 event_data->conn_id,
4311 event_data->status);
4313 /* Extract Address from conn_id of event data */
4314 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4316 BT_INFO("Connection Info is not present, return");
4319 BT_INFO("Notification Registered for addr [%s]", conn_info->addr);
4321 /* Fill svc informations in buffer */
4322 memcpy(¬if_info.svc_uuid,
4323 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4324 notif_info.svc_inst = event_data->srvc_id.id.inst_id;
4326 /* Fill char in buffer */
4327 memcpy(¬if_info.char_uuid,
4328 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4329 notif_info.char_inst = event_data->char_id.inst_id;
4331 /* Fill remote device address */
4332 _bt_convert_addr_string_to_type(notif_info.addr.addr, conn_info->addr);
4334 notif_info.is_registered = is_registered;
4336 if (event_data->status != OAL_STATUS_SUCCESS)
4337 result = BLUETOOTH_ERROR_INTERNAL;
4339 /* Send DBUS Return for BT_GATT_WATCH_CHARACTERISTIC */
4340 __bt_gatt_handle_pending_request_info(result,
4341 BT_GATT_WATCH_CHARACTERISTIC,
4343 sizeof(bt_gatt_notif_reg_info_t));
4346 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
4348 /* No status in this event from OAL */
4349 int result = BLUETOOTH_ERROR_NONE;
4351 /* Read Information data structures */
4352 GVariant *param = NULL;
4353 GVariant *data = NULL;
4354 GVariant *data_svc_uuid = NULL;
4355 GVariant *data_char_uuid = NULL;
4356 char *read_val = NULL;
4357 char *svc_uuid = NULL;
4358 char *char_uuid = NULL;
4364 BT_INFO("Notifcation of charc data changed");
4366 if (event_data->data_len > 0) {
4368 for (i = 0; i < event_data->data_len; i++)
4369 BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4372 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4373 _bt_convert_addr_type_to_string(addr,
4374 (unsigned char *)&(event_data->address.addr));
4377 read_val = g_memdup(&event_data->data[0], event_data->data_len);
4379 data = g_variant_new_from_data(
4380 G_VARIANT_TYPE_BYTESTRING,
4382 event_data->data_len,
4385 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4387 data_svc_uuid = g_variant_new_from_data(
4388 G_VARIANT_TYPE_BYTESTRING,
4394 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4396 data_char_uuid = g_variant_new_from_data(
4397 G_VARIANT_TYPE_BYTESTRING,
4403 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4407 event_data->srvc_id.id.inst_id,
4410 event_data->char_id.inst_id,
4411 event_data->data_len,
4415 _bt_send_event(BT_GATT_CLIENT_EVENT,
4416 BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
4419 BT_ERR("No Data!!");
4432 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data)
4434 bt_gatt_service_info_list_t *svc_info_list;
4436 bt_gatt_service_info_t *svc_info;
4437 GVariant *param = NULL;
4438 char *address_str = NULL;
4439 char *uuid_str = NULL;
4441 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4442 if (svc_info_list == NULL) {
4443 BT_ERR("svc_info_list is NULL");
4447 if (event_data->change_type) {
4448 /* Add service UUID in list */
4449 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4450 memcpy(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4451 svc_info->inst_id = event_data->inst_id;
4452 svc_info->is_primary = 1; // TODO: Need to check is_primary is required or not
4453 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4454 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_id);
4456 /* Remove service UUID in list */
4457 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
4458 svc_info = (bt_gatt_service_info_t *)l->data;
4459 if (svc_info == NULL)
4462 if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4463 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
4464 __bt_free_service_info(svc_info);
4470 address_str = g_malloc0(BT_ADDRESS_STRING_SIZE);
4471 uuid_str = g_malloc0(BT_UUID_STRING_MAX);
4472 _bt_convert_addr_type_to_string(address_str, event_data->address.addr);
4473 _bt_uuid_to_string(&event_data->uuid, uuid_str);
4475 param = g_variant_new("(iiss)", event_data->inst_id, event_data->change_type, address_str, uuid_str);
4477 _bt_send_event(BT_GATT_CLIENT_EVENT,
4478 BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED,
4480 g_free(address_str);
4484 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
4487 struct gatt_server_info_t *conn_info = NULL;
4488 gboolean connected = FALSE;
4490 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4491 _bt_convert_addr_type_to_string(addr,
4492 (unsigned char *)&(address->addr));
4494 BT_DBG("Check GATT connection status of [%s]", addr);
4495 /* Check if device is already in connected list */
4496 conn_info = _bt_find_remote_gatt_server_info(addr);
4498 BT_DBG("Remote GATT Server device [%s] is Connected", conn_info->addr);
4501 struct gatt_client_info_t *client_info = NULL;
4503 BT_DBG("Remote GATT Server Device [%s] is not Connected", addr);
4505 /* Check if device is already in connected list */
4506 client_info = _bt_find_remote_gatt_client_info(addr);
4508 BT_DBG("Remote Client device [%s] is Connected", client_info->addr);
4511 BT_DBG("Remote GATT Client Device [%s] is not Connected", addr);
4519 void _bt_handle_invocation_context(int function_name, void *data)
4521 switch (function_name) {
4523 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_CONNECT_LE,
4524 (char *)data, BT_ADDRESS_STRING_SIZE);
4531 int _bt_connect_le_device(bluetooth_device_address_t *address,
4532 int auto_connect, int client_id)
4534 struct gatt_server_info_t *conn_info = NULL;
4535 struct gatt_out_conn_info_t *out_conn_info = NULL;
4537 invocation_info_t *req_info = NULL;
4538 int ret = OAL_STATUS_SUCCESS;
4540 char *remote_address = NULL;
4542 BT_CHECK_PARAMETER(address, return);
4544 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4545 _bt_convert_addr_type_to_string(addr, address->addr);
4546 BT_DBG("GATT Client connect request for address [%s] client instance [%d]",
4550 /* Check if Remote Device is already under connection progress */
4551 req_info = _bt_get_request_info_data_from_function_name(BT_CONNECT_LE);
4553 remote_address = (char*)req_info->user_data;
4554 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
4555 BT_DBG("Already Connection ongoing for same remote GATT Server address [%s]", remote_address);
4556 /* Return and wait for events to be sent to all apps */
4558 return BLUETOOTH_ERROR_IN_PROGRESS;
4562 /* Check if remote GATT Server is connected or not */
4563 conn_info = _bt_find_remote_gatt_server_info(addr);
4565 BT_ERR("GATT Server is already connected..");
4567 return BLUETOOTH_ERROR_ALREADY_CONNECT;
4570 /* TODO Check Requirement of holding Advertisement before initiating LE connect */
4573 /* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
4574 if (client_id == 0) {
4575 /* GATT CLient connect request sent by an app without any client instance [0] */
4576 BT_DBG("Assign default GATT client id [%d]", gatt_default_client);
4577 client_id = gatt_default_client;
4580 BT_INFO("Connect using CLient ID [%d]", client_id);
4581 ret = gattc_connect(client_id, (bt_address_t*)(address), auto_connect);
4583 if (ret != OAL_STATUS_SUCCESS) {
4584 BT_ERR("gattc_connect is failed. ret: %d", ret);
4586 _bt_restart_le_scan();
4587 return _bt_convert_oal_status_to_bt_error(ret);
4590 /* Mark this as outgoing connection */
4591 out_conn_info = g_new0(struct gatt_out_conn_info_t, 1);
4592 out_conn_info->addr = g_strdup(addr);
4593 out_conn_info->client_id = client_id;
4594 BT_INFO("Added outgoing connection info addr[%s]", out_conn_info->addr + 12);
4595 outgoing_gatt_conn_list = g_slist_append(outgoing_gatt_conn_list, out_conn_info);
4598 return BLUETOOTH_ERROR_NONE;
4601 int _bt_gatt_get_primary_services(char *address)
4603 BT_CHECK_PARAMETER(address, return);
4604 struct gatt_server_info_t *conn_info = NULL;
4605 invocation_info_t *req_info = NULL;
4606 int ret = OAL_STATUS_SUCCESS;
4608 /* Check if any app is already browsing primary services on the same remote GATT Server */
4609 req_info = _bt_get_request_info_data(BT_GATT_GET_PRIMARY_SERVICES, address);
4611 BT_INFO("Already Primary Service Browsing ongoing for same rmeote GATT Server");
4612 /* Return and wait for events to be sent to all apps */
4613 return BLUETOOTH_ERROR_NONE;
4616 /* Check if remote GATT Server is connected or not */
4617 conn_info = _bt_find_remote_gatt_server_info(address);
4619 BT_ERR("GATT Server is not yet connected..");
4620 return BLUETOOTH_ERROR_NOT_CONNECTED;
4623 BT_INFO("Get all services. GATT Server [%s] is connected, conn Id [%d]",
4624 conn_info->addr + 12, conn_info->connection_id);
4626 /* Send Primary Service Browsing request to stack */
4627 ret = gattc_search_service(conn_info->connection_id, NULL);
4628 if (ret != OAL_STATUS_SUCCESS) {
4629 BT_ERR("ret: %d", ret);
4630 return _bt_convert_oal_status_to_bt_error(ret);
4632 return BLUETOOTH_ERROR_NONE;
4635 int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc)
4637 BT_CHECK_PARAMETER(svc, return);
4638 struct gatt_server_info_t *conn_info = NULL;
4639 invocation_info_t *req_info = NULL;
4640 bluetooth_gatt_client_svc_prop_info_t *prop;
4641 oal_gatt_srvc_id_t srvc_id;
4642 int ret = OAL_STATUS_SUCCESS;
4645 /* Check if any app is already browsing characteristics of the same service on the same remote GATT Server */
4646 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_SERVICE_PROPERTIES);
4648 prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
4649 if (prop && !memcmp(svc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t))
4650 && !memcmp(prop->svc.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
4651 && prop->svc.instance_id == svc->svc.instance_id) {
4652 BT_INFO("Already Properties browsing for Primary Service ongoing for same remote GATT Server");
4653 /* Return and wait for events to be sent to all apps */
4654 return BLUETOOTH_ERROR_NONE;
4658 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4659 _bt_convert_addr_type_to_string(addr, svc->device_address.addr);
4661 /* Check if remote GATT Server is connected or not */
4662 conn_info = _bt_find_remote_gatt_server_info(addr);
4664 BT_ERR("GATT Server is not yet connected..");
4666 return BLUETOOTH_ERROR_NOT_CONNECTED;
4669 BT_DBG("Get all charc. GATT Server [%s] is connected, conn Id [%d]",
4670 conn_info->addr, conn_info->connection_id);
4672 srvc_id.is_prmry = TRUE;
4673 srvc_id.id.inst_id = svc->svc.instance_id;
4674 memcpy(srvc_id.id.uuid.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4676 /* Search All Characteristic */
4677 ret = gattc_get_characteristic(conn_info->connection_id, &srvc_id, NULL);
4678 if (ret != OAL_STATUS_SUCCESS) {
4679 BT_ERR("ret: %d", ret);
4681 return _bt_convert_oal_status_to_bt_error(ret);
4684 return BLUETOOTH_ERROR_NONE;
4687 int _bt_gatt_get_all_characteristic_properties(
4688 bluetooth_gatt_client_char_prop_info_t *chr)
4690 struct gatt_server_info_t *conn_info = NULL;
4691 invocation_info_t *req_info = NULL;
4692 bluetooth_gatt_client_char_prop_info_t *prop;
4693 oal_gatt_srvc_id_t srvc_id;
4694 oal_gatt_id_t char_id;
4695 int ret = OAL_STATUS_SUCCESS;
4698 BT_CHECK_PARAMETER(chr, return);
4700 /* Check if any app is already browsing descriptors of the same char of
4701 particular service on the same remote GATT Server */
4702 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_CHARACTERISTIC_PROPERTIES);
4704 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4705 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4706 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4707 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4708 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4709 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4710 BT_INFO("Already Properties browsing for Characteristic ongoing for same remote GATT Server");
4711 /* Return and wait for events to be sent to all apps */
4712 return BLUETOOTH_ERROR_NONE;
4716 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4717 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4719 /* Check if remote GATT Server is connected or not */
4720 conn_info = _bt_find_remote_gatt_server_info(addr);
4722 BT_ERR("GATT Server is not yet connected..");
4724 return BLUETOOTH_ERROR_NOT_CONNECTED;
4727 BT_DBG("Get all desc. GATT Server [%s] is connected, conn Id [%d]",
4728 conn_info->addr, conn_info->connection_id);
4730 srvc_id.is_prmry = TRUE;
4731 srvc_id.id.inst_id = chr->svc.instance_id;
4732 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4734 char_id.inst_id = chr->characteristic.instance_id;
4735 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4737 /* Search All Descriptors */
4738 ret = gattc_get_descriptor(conn_info->connection_id, &srvc_id, &char_id, NULL);
4739 if (ret != OAL_STATUS_SUCCESS) {
4740 BT_ERR("ret: %d", ret);
4742 return _bt_convert_oal_status_to_bt_error(ret);
4745 return BLUETOOTH_ERROR_NONE;
4748 int _bt_gatt_read_characteristic_value(
4749 bluetooth_gatt_client_char_prop_info_t *chr)
4751 struct gatt_server_info_t *conn_info = NULL;
4752 invocation_info_t *req_info = NULL;
4753 bluetooth_gatt_client_char_prop_info_t *prop;
4754 oal_gatt_srvc_id_t srvc_id;
4755 oal_gatt_id_t char_id;
4756 int ret = OAL_STATUS_SUCCESS;
4759 BT_CHECK_PARAMETER(chr, return);
4761 /* Check if any app is already Reading characteristic of the same char of
4762 particular service on the same remote GATT Server */
4763 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_CHARACTERISTIC);
4765 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4766 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4767 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4768 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4769 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4770 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4771 BT_INFO("Already Characteristic value Read operation in progress for same remote GATT Server");
4772 /* Return and wait for events to be sent to all apps */
4773 return BLUETOOTH_ERROR_NONE;
4777 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4778 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4780 /* Check if remote GATT Server is connected or not */
4781 conn_info = _bt_find_remote_gatt_server_info(addr);
4783 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4784 conn_info->addr, conn_info->connection_id);
4786 BT_ERR("GATT Server is not yet connected..");
4788 return BLUETOOTH_ERROR_NOT_CONNECTED;
4791 srvc_id.is_prmry = TRUE;
4792 srvc_id.id.inst_id = chr->svc.instance_id;
4793 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4795 char_id.inst_id = chr->characteristic.instance_id;
4796 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4798 /* Search All Descriptors */
4799 ret = gattc_read_characteristic(conn_info->connection_id, &srvc_id, &char_id, OAL_GATT_AUTH_REQ_NONE);
4800 if (ret != OAL_STATUS_SUCCESS) {
4801 BT_ERR("ret: %d", ret);
4803 return _bt_convert_oal_status_to_bt_error(ret);
4806 return BLUETOOTH_ERROR_NONE;
4809 int _bt_gatt_read_descriptor_value(
4810 bluetooth_gatt_client_desc_prop_info_t *desc)
4812 struct gatt_server_info_t *conn_info = NULL;
4813 invocation_info_t *req_info = NULL;
4814 bluetooth_gatt_client_desc_prop_info_t *prop;
4815 oal_gatt_srvc_id_t srvc_id;
4816 oal_gatt_id_t char_id;
4817 oal_gatt_id_t desc_id;
4818 int ret = OAL_STATUS_SUCCESS;
4821 BT_CHECK_PARAMETER(desc, return);
4823 /* Check if any app is already Reading descriptors of the same char of
4824 particular service on the same remote GATT Server */
4825 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_DESCRIPTOR_VALUE);
4827 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
4828 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4829 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4830 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4831 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4832 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
4833 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
4834 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
4835 BT_INFO("Already Descriptor value Read operation in progress for same remote GATT Server");
4836 /* Return and wait for events to be sent to all apps */
4837 return BLUETOOTH_ERROR_NONE;
4841 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4842 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
4844 /* Check if remote GATT Server is connected or not */
4845 conn_info = _bt_find_remote_gatt_server_info(addr);
4847 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4848 conn_info->addr, conn_info->connection_id);
4850 BT_ERR("GATT Server is not yet connected..");
4852 return BLUETOOTH_ERROR_NOT_CONNECTED;
4855 srvc_id.is_prmry = TRUE;
4856 srvc_id.id.inst_id = desc->svc.instance_id;
4857 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4859 char_id.inst_id = desc->characteristic.instance_id;
4860 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4862 desc_id.inst_id = desc->descriptor.instance_id;
4863 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4865 /* Search All Descriptors */
4866 ret = gattc_read_descriptor(conn_info->connection_id, &srvc_id, &char_id,
4867 &desc_id, OAL_GATT_AUTH_REQ_NONE);
4868 if (ret != OAL_STATUS_SUCCESS) {
4869 BT_ERR("ret: %d", ret);
4871 return _bt_convert_oal_status_to_bt_error(ret);
4874 return BLUETOOTH_ERROR_NONE;
4878 int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
4880 struct gatt_server_info_t *conn_info = NULL;
4881 oal_gatt_srvc_id_t srvc_id;
4882 oal_gatt_id_t char_id;
4883 int ret = OAL_STATUS_SUCCESS;
4886 BT_CHECK_PARAMETER(chr, return);
4888 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4889 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4891 /* Check if remote GATT Server is connected or not */
4892 conn_info = _bt_find_remote_gatt_server_info(addr);
4894 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4895 conn_info->addr, conn_info->connection_id);
4897 BT_ERR("GATT Server is not yet connected..");
4899 return BLUETOOTH_ERROR_NOT_CONNECTED;
4902 srvc_id.is_prmry = TRUE;
4903 srvc_id.id.inst_id = chr->svc.instance_id;
4904 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4906 char_id.inst_id = chr->characteristic.instance_id;
4907 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4909 ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
4911 if (ret != OAL_STATUS_SUCCESS) {
4912 BT_ERR("ret: %d", ret);
4914 return _bt_convert_oal_status_to_bt_error(ret);
4916 BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
4918 return BLUETOOTH_ERROR_NONE;
4922 int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
4925 struct gatt_server_info_t *conn_info = NULL;
4926 oal_gatt_srvc_id_t srvc_id;
4927 oal_gatt_id_t char_id;
4928 int ret = OAL_STATUS_SUCCESS;
4931 BT_CHECK_PARAMETER(chr, return);
4933 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4934 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4936 /* Check if remote GATT Server is connected or not */
4937 conn_info = _bt_find_remote_gatt_server_info(addr);
4939 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4940 conn_info->addr, conn_info->connection_id);
4942 BT_ERR("GATT Server is not yet connected..");
4944 return BLUETOOTH_ERROR_NOT_CONNECTED;
4947 srvc_id.is_prmry = TRUE;
4948 srvc_id.id.inst_id = chr->svc.instance_id;
4949 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4951 char_id.inst_id = chr->characteristic.instance_id;
4952 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4954 ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
4955 OAL_GATT_AUTH_REQ_NONE, fd, mtu);
4956 if (ret != OAL_STATUS_SUCCESS) {
4957 BT_ERR("ret: %d", ret);
4959 return _bt_convert_oal_status_to_bt_error(ret);
4961 BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
4963 return BLUETOOTH_ERROR_NONE;
4968 /* Write Characteristic */
4969 int _bt_gatt_write_characteristic_value_by_type(
4970 bluetooth_gatt_client_char_prop_info_t *chr,
4971 bluetooth_gatt_att_data_t *data,
4972 bluetooth_gatt_write_type_e write_type)
4974 struct gatt_server_info_t *conn_info = NULL;
4975 invocation_info_t *req_info = NULL;
4976 bluetooth_gatt_client_char_prop_info_t *prop;
4977 oal_gatt_srvc_id_t srvc_id;
4978 oal_gatt_id_t char_id;
4979 int ret = OAL_STATUS_SUCCESS;
4982 BT_CHECK_PARAMETER(chr, return);
4983 BT_CHECK_PARAMETER(data, return);
4985 /* Check if any app is already writing same char of
4986 particular service on the same remote GATT Server */
4987 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE);
4989 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4990 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4991 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4992 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4993 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4994 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4995 BT_INFO("Already Characteristic Write Value operation in progress for same remote GATT Server");
4996 /* Return and wait for events to be sent to all apps */
4997 return BLUETOOTH_ERROR_NONE;
5001 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5002 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5004 /* Check if remote GATT Server is connected or not */
5005 conn_info = _bt_find_remote_gatt_server_info(addr);
5007 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5008 conn_info->addr, conn_info->connection_id);
5010 BT_ERR("GATT Server is not yet connected..");
5012 return BLUETOOTH_ERROR_NOT_CONNECTED;
5015 srvc_id.is_prmry = TRUE;
5016 srvc_id.id.inst_id = chr->svc.instance_id;
5017 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5019 char_id.inst_id = chr->characteristic.instance_id;
5020 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5022 /* Write CHar value */
5023 ret = gattc_write_characteristic(conn_info->connection_id,
5025 (oal_gatt_write_type_t)write_type, data->length,
5026 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5027 if (ret != OAL_STATUS_SUCCESS) {
5028 BT_ERR("ret: %d", ret);
5030 return _bt_convert_oal_status_to_bt_error(ret);
5033 return BLUETOOTH_ERROR_NONE;
5036 /* Write Descriptor */
5037 int _bt_gatt_write_descriptor_value_by_type(
5038 bluetooth_gatt_client_desc_prop_info_t *desc,
5039 bluetooth_gatt_att_data_t *data,
5040 bluetooth_gatt_write_type_e write_type)
5042 struct gatt_server_info_t *conn_info = NULL;
5043 invocation_info_t *req_info = NULL;
5044 bluetooth_gatt_client_desc_prop_info_t *prop;
5045 oal_gatt_srvc_id_t srvc_id;
5046 oal_gatt_id_t char_id;
5047 oal_gatt_id_t desc_id;
5048 int ret = OAL_STATUS_SUCCESS;
5052 BT_CHECK_PARAMETER(desc, return);
5053 BT_CHECK_PARAMETER(data, return);
5057 /* Check if any app is already writing on same Descriptor of the same char of
5058 particular service on the same remote GATT Server */
5059 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_DESCRIPTOR_VALUE);
5061 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5062 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5063 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5064 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5065 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5066 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5067 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5068 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5069 BT_INFO("Already Descriptor value Write operation in progress for same remote GATT Server");
5070 /* Return and wait for events to be sent to all apps */
5071 return BLUETOOTH_ERROR_NONE;
5075 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5076 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5078 /* Check if remote GATT Server is connected or not */
5079 conn_info = _bt_find_remote_gatt_server_info(addr);
5081 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5082 conn_info->addr, conn_info->connection_id);
5084 BT_ERR("GATT Server is not yet connected..");
5086 return BLUETOOTH_ERROR_NOT_CONNECTED;
5089 srvc_id.is_prmry = TRUE;
5090 srvc_id.id.inst_id = desc->svc.instance_id;
5091 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5093 char_id.inst_id = desc->characteristic.instance_id;
5094 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5096 desc_id.inst_id = desc->descriptor.instance_id;
5097 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5100 BT_INFO("Connection ID [%d] write type [%d] data length [%d]", conn_info->connection_id, write_type, data->length);
5101 for (k = 0; k < data->length; k++)
5102 BT_INFO("Data[%d] [0x%x]", k, data->data[k]);
5104 ret = gattc_write_descriptor(conn_info->connection_id,
5105 &srvc_id, &char_id, &desc_id,
5106 (oal_gatt_write_type_t)write_type, data->length,
5107 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5108 if (ret != OAL_STATUS_SUCCESS) {
5109 BT_ERR("ret: %d", ret);
5111 return _bt_convert_oal_status_to_bt_error(ret);
5114 return BLUETOOTH_ERROR_NONE;
5117 int _bt_gatt_watch_characteristic(
5118 bluetooth_gatt_client_char_prop_info_t *chr,
5122 struct gatt_server_info_t *conn_info = NULL;
5123 oal_gatt_srvc_id_t srvc_id;
5124 oal_gatt_id_t char_id;
5125 int ret = OAL_STATUS_SUCCESS;
5128 BT_CHECK_PARAMETER(chr, return);
5130 BT_INFO("Client ID [%d] Is Notify [%d]", client_id, is_notify);
5132 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5133 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5135 /* Check if remote GATT Server is connected or not */
5136 conn_info = _bt_find_remote_gatt_server_info(addr);
5138 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5139 conn_info->addr, conn_info->connection_id);
5141 BT_ERR("GATT Server is not yet connected..");
5143 return BLUETOOTH_ERROR_NOT_CONNECTED;
5145 srvc_id.is_prmry = TRUE;
5146 srvc_id.id.inst_id = chr->svc.instance_id;
5147 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5149 char_id.inst_id = chr->characteristic.instance_id;
5150 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5152 /* Register or unregister Notification characteristic */
5154 ret = gattc_register_for_notification(conn_info->connection_id,
5155 (bt_address_t*)&(chr->device_address),
5156 &srvc_id, &char_id);
5158 ret = gattc_deregister_for_notification(conn_info->connection_id,
5159 (bt_address_t*)&(chr->device_address),
5160 &srvc_id, &char_id);
5162 BT_INFO("Result[%d]", ret);
5163 if (ret != OAL_STATUS_SUCCESS) {
5164 BT_ERR("ret: %d", ret);
5166 return _bt_convert_oal_status_to_bt_error(ret);
5169 return BLUETOOTH_ERROR_NONE;
5173 int _bt_disconnect_le_device(bluetooth_device_address_t *address,
5176 struct gatt_server_info_t *conn_info = NULL;
5177 struct gatt_client_info_t *rem_client_conn_info = NULL;
5178 invocation_info_t *req_info = NULL;
5179 int ret = OAL_STATUS_SUCCESS;
5181 char *remote_address = NULL;
5183 BT_CHECK_PARAMETER(address, return);
5185 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5186 _bt_convert_addr_type_to_string(addr, address->addr);
5187 BT_INFO("GATT Client Disconnect request for address [%s]", addr + 12);
5189 /* Check if Remote Device is already under connection progress */
5190 req_info = _bt_get_request_info_data_from_function_name(BT_DISCONNECT_LE);
5192 remote_address = (char*)req_info->user_data;
5193 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5194 BT_DBG("Already DisConnection ongoing for same remote GATT Server address [%s]", remote_address);
5195 /* Return success and wait for events to be sent to all apps */
5197 return BLUETOOTH_ERROR_IN_PROGRESS;
5200 /* Check if remote GATT Server is connected or not */
5201 conn_info = _bt_find_remote_gatt_server_info(addr);
5203 /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
5204 if (client_id == 0) {
5205 BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
5207 BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
5208 client_id = gatt_default_client;
5211 BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
5212 ret = gattc_disconnect(client_id, (bt_address_t*)(address),
5213 conn_info->connection_id);
5215 /* check if remote client is connected */
5216 rem_client_conn_info = _bt_find_remote_gatt_client_info(addr);
5218 if (!rem_client_conn_info || client_id != 0) {
5219 BT_ERR("GATT device is not connected..");
5221 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
5224 BT_INFO("Disconnect remote gatt client ");
5226 ret = gatts_disconnect(rem_client_conn_info->instance_id,
5227 (bt_address_t*)(address), rem_client_conn_info->connection_id);
5230 if (ret != OAL_STATUS_SUCCESS) {
5231 BT_ERR("ret: %d", ret);
5233 return _bt_convert_oal_status_to_bt_error(ret);
5236 return BLUETOOTH_ERROR_NONE;
5239 int _bt_gatt_watch_service_changed_indication(const char *sender,
5240 bluetooth_device_address_t *address,
5241 gboolean is_enabled)
5244 bt_service_app_info_t *info = NULL;
5246 BT_INFO("%s Servic changed Indication watcher for app [%s]",
5247 is_enabled ? "Enable":"Disable", sender);
5249 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5252 if (g_strcmp0(sender, info->sender) == 0 &&
5253 memcmp(info->address.addr, address->addr,
5254 sizeof(bluetooth_device_address_t)) == 0) {
5255 BT_DBG("Found GATT client App.. [%s], sender [%s]", info->uuid, info->sender);
5256 info->is_watcher_enabled = is_enabled;
5260 return BLUETOOTH_ERROR_NONE;
5263 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
5265 bt_service_app_info_t *info = NULL;
5268 BT_DBG("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
5270 /* Unregister CLient instance associated with address X. It is possible that another app still
5271 has client_id valid for same remote address */
5272 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5275 /* Exact matching of sender */
5276 if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) { /* Check for only valid GATT client Instance */
5277 numapps[k].client_id = -1;
5278 numapps[k].is_initialized = FALSE;
5279 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
5280 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
5281 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
5283 /* Its a GATT Client Instance */
5284 ret = gattc_deregister(client_id);
5285 if (ret != OAL_STATUS_SUCCESS) {
5286 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
5287 return _bt_convert_oal_status_to_bt_error(ret);
5289 return BLUETOOTH_ERROR_NONE;
5294 return BLUETOOTH_ERROR_NOT_FOUND;
5297 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data)
5299 int result = BLUETOOTH_ERROR_NONE;
5300 struct gatt_server_info_t *conn_info = NULL;
5301 GVariant *param = NULL;
5305 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
5306 if (conn_info == NULL) {
5307 BT_ERR("Cant find connection Information");
5311 BT_DBG("GATT Client: MTU Configured from addr [%s] status [%d] MTU size [%d]",
5312 conn_info->addr, event_data->status, event_data->mtu);
5314 if (event_data->status != OAL_STATUS_SUCCESS)
5315 result = BLUETOOTH_ERROR_INTERNAL;
5317 /* DBUS Return fo BT_REQ_ATT_MTU for all the apps */
5318 __bt_gatt_handle_pending_request_info(result, BT_REQ_ATT_MTU, conn_info->addr,
5319 BT_ADDRESS_STRING_SIZE);
5321 if (result == BLUETOOTH_ERROR_NONE) {
5322 mtu = event_data->mtu;
5323 param = g_variant_new("(isqy)",
5329 /* Send event to BT-API */
5330 _bt_send_event(BT_DEVICE_EVENT,
5331 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
5334 /* Update the MTU for current connection */
5335 __bt_update_mtu_gatt_device(conn_info->addr, event_data->mtu);
5339 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address)
5342 struct gatt_mtu_info_t *info = NULL;
5344 for (l = gatt_mtu_info_list; l != NULL; l = g_slist_next(l)) {
5345 info = (struct gatt_mtu_info_t*)l->data;
5349 if (!g_strcmp0(info->addr, address)) {
5350 BT_DBG("Remote GATT device found addr[%s]", info->addr);
5355 BT_DBG("Not found Remote GATT device addr[%s]", address);
5359 static void __bt_remove_mtu_gatt_device(char *address)
5361 struct gatt_mtu_info_t *dev_info = NULL;
5363 dev_info = __bt_find_mtu_gatt_device(address);
5366 BT_DBG("removing the gatt device from mtu list");
5367 gatt_mtu_info_list = g_slist_remove(gatt_mtu_info_list, dev_info);
5368 g_free(dev_info->addr);
5373 static void __bt_add_mtu_gatt_device(char *address)
5375 struct gatt_mtu_info_t *dev_info = NULL;
5377 dev_info = __bt_find_mtu_gatt_device(address);
5380 BT_DBG("adding the gatt device in mtu list");
5381 dev_info = g_new0(struct gatt_mtu_info_t, 1);
5382 dev_info->addr = g_strdup(address);
5383 dev_info->att_mtu = BT_DEFAULT_ATT_MTU;
5384 gatt_mtu_info_list = g_slist_append(gatt_mtu_info_list, dev_info);
5388 static void __bt_update_mtu_gatt_device(char *address, int mtu)
5390 struct gatt_mtu_info_t *dev_info = NULL;
5392 dev_info = __bt_find_mtu_gatt_device(address);
5395 dev_info->att_mtu = mtu;
5399 int _bt_gatt_get_data_batching_available_packets(
5400 guint *available_packets)
5402 int ret = OAL_STATUS_SUCCESS;
5404 BT_CHECK_PARAMETER(available_packets, return);
5406 ret = gatt_get_data_batching_available_packets(available_packets);
5407 if (ret != OAL_STATUS_SUCCESS) {
5408 BT_ERR("ret: %d", ret);
5409 return _bt_convert_oal_status_to_bt_error(ret);
5412 return BLUETOOTH_ERROR_NONE;
5415 int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address,
5416 int packet_threshold, int timeout)
5418 int ret = OAL_STATUS_SUCCESS;
5419 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5421 BT_CHECK_PARAMETER(address, return);
5423 _bt_convert_addr_type_to_string(remote_address, address->addr);
5424 BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]",
5425 remote_address, packet_threshold, timeout);
5427 ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout);
5429 if (ret != OAL_STATUS_SUCCESS) {
5430 BT_ERR("ret: %d", ret);
5431 return _bt_convert_oal_status_to_bt_error(ret);
5434 return BLUETOOTH_ERROR_NONE;
5437 int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address)
5439 int ret = OAL_STATUS_SUCCESS;
5440 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5442 BT_CHECK_PARAMETER(address, return);
5444 _bt_convert_addr_type_to_string(remote_address, address->addr);
5445 BT_INFO("Disable GATT data batching. address[%s]", remote_address);
5447 ret = gatt_disable_data_batching((bt_address_t*)(address));
5449 if (ret != OAL_STATUS_SUCCESS) {
5450 BT_ERR("ret: %d", ret);
5451 return _bt_convert_oal_status_to_bt_error(ret);
5454 return BLUETOOTH_ERROR_NONE;