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;
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 if (event->length <= 0) {
2031 BT_INFO("GATT Server write requested, but length of attr value is 0");
2035 #ifdef TIZEN_BLUEDROID_PORTING
2036 if (event->is_prep) {
2037 BT_INFO("receive prepare_write request");
2038 return __bt_handle_gatt_server_prepare_write_requested(event);
2042 need_resp = event->need_rsp;
2043 is_prepare_write = event->is_prep;
2045 write_val = g_memdup(&event->value[0], event->length);
2047 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2048 _bt_convert_addr_type_to_string(address,
2049 (unsigned char *)dev_addr.addr);
2051 BT_INFO("GATT Server Write Request from remote client [%s]", address);
2053 if (event->length > 0) {
2054 for (i = 0; i < event->length; i++)
2055 BT_DBG("Data[%d] = [0x%x]", i, event->value[i]);
2057 /* Save Write Request Info */
2058 req_info = g_new0(struct gatt_server_req_info, 1);
2059 req_info->request_id = event->attr_trans.trans_id;
2060 req_info->attribute_handle = event->attr_trans.attr_handle;
2061 req_info->connection_id = event->attr_trans.conn_id;
2062 req_info->addr = address;
2063 req_info->offset = event->attr_trans.offset;
2064 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
2065 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2067 data = g_variant_new_from_data(
2068 G_VARIANT_TYPE_BYTESTRING,
2073 param = g_variant_new("(iiiiiibbsn@ay)", result,
2074 event->attr_trans.conn_id,
2075 event->attr_trans.trans_id,
2076 event->attr_trans.attr_handle,
2077 event->attr_trans.offset,
2085 _bt_send_event(BT_GATT_SERVER_EVENT,
2086 BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
2092 #ifdef TIZEN_BLUEDROID_PORTING
2093 static void __bt_handle_gatt_server_exec_write_requested(event_gatts_srvc_exec_write_attr_t *event)
2096 bluetooth_device_address_t dev_addr;
2098 bt_gatt_prep_write_data_t *exec_data = NULL;
2099 int resp_status = BLUETOOTH_ATT_ERROR_NONE;
2100 BT_INFO("GATT Server Execute Write Requested");
2102 memcpy(dev_addr.addr, event->address.addr, 6);
2103 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2104 _bt_convert_addr_type_to_string(address,
2105 (unsigned char *)dev_addr.addr);
2107 BT_INFO("GATT Server Exec Write Req Connection ID: [%d]", event->conn_id);
2108 BT_INFO("GATT Server Exec Write Req Transaction ID:[%d]", event->trans_id);
2109 BT_INFO("GATT Server Exec Write Req Exec Write: [%d]", event->exec_write);
2111 // prepare exec response data
2112 exec_data = g_malloc0(sizeof(bt_gatt_prep_write_data_t));
2113 exec_data->connection_id = event->conn_id;
2114 exec_data->request_id = event->trans_id;
2115 exec_data->device_address = address;
2116 exec_data->request_type = BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE;
2117 exec_data->prep_request_count = __bt_get_prep_request_count(exec_data->connection_id);
2119 if ((exec_data->prep_request_count != 1) || !event->exec_write) {
2120 if (!event->exec_write) {
2121 BT_INFO("Cancelling all prepared writes, removing all pending entries");
2122 __bt_remove_all_prep_write_req(event->conn_id);
2123 } else if (exec_data->prep_request_count > 1) {
2124 /* TODO: Handle reliable-write session */
2125 BT_INFO("This may be reliable write session. Not yet supported!!!, prep_request_count =%d",
2126 exec_data->prep_request_count);
2127 resp_status = BLUETOOTH_ATT_ERROR_REQUEST_NOT_SUPPORTED;
2128 __bt_remove_all_prep_write_req(event->conn_id);
2131 BT_INFO("Send exec response");
2132 // Made response and send it.
2133 ret = __bt_gatt_server_send_long_write_response(exec_data, resp_status, 0);
2134 if (ret != OAL_STATUS_SUCCESS)
2135 BT_ERR("ret: %d", ret);
2137 g_free(exec_data->device_address);
2142 BT_INFO("Write all pending prepared values");
2143 __bt_gatt_server_send_prep_write_req(exec_data->connection_id);
2145 // Add exec request in the queue.
2146 g_pending_write_list = g_slist_append(g_pending_write_list, (gpointer)exec_data);
2150 static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t *event)
2152 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2153 bluetooth_device_address_t dev_addr;
2154 int result = BLUETOOTH_ERROR_NONE;
2155 struct gatt_server_req_info *req_info = NULL;
2156 GVariant *param = NULL;
2159 memcpy(dev_addr.addr, event->address.addr, 6);
2160 _bt_convert_addr_type_to_string(address,
2161 (unsigned char *)dev_addr.addr);
2163 BT_DBG("conn_id %d, trans id %d, attr handle %d, offset %d, is_long %d, addr %s",
2164 event->attr_trans.conn_id, event->attr_trans.trans_id,
2165 event->attr_trans.attr_handle, event->attr_trans.offset,
2166 event->is_long, address);
2168 is_long = event->is_long;
2170 /* Save Read Request Info */
2171 req_info = g_new0(struct gatt_server_req_info, 1);
2172 req_info->request_id = event->attr_trans.trans_id;
2173 req_info->attribute_handle = event->attr_trans.attr_handle;
2174 req_info->connection_id = event->attr_trans.conn_id;
2175 req_info->addr = address;
2176 req_info->offset = event->attr_trans.offset;
2177 req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_READ;
2178 gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
2180 /* Send event to BT-API */
2181 param = g_variant_new("(iiiiibs)", result,
2182 event->attr_trans.conn_id,
2183 event->attr_trans.trans_id,
2184 event->attr_trans.attr_handle,
2185 event->attr_trans.offset,
2189 _bt_send_event(BT_GATT_SERVER_EVENT,
2190 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
2194 static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
2196 bluetooth_device_address_t dev_addr;
2197 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2198 int cur_connected_clients;
2199 static int recvd = 0;
2200 gboolean completed = 0;
2201 GVariant *param = NULL;
2203 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2204 incase of any issues, check with OAL */
2205 int result = BLUETOOTH_ERROR_NONE;
2207 memcpy(dev_addr.addr, event->address.addr, 6);
2208 _bt_convert_addr_type_to_string(address,
2209 (unsigned char *)dev_addr.addr);
2211 BT_INFO("Indication sent to GATT client [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d]",
2212 address, event->conn_id, event->trans_id, event->attr_handle);
2215 cur_connected_clients = g_slist_length(gatt_client_info_list);
2216 BT_INFO("Number of connected clients during sending Indication [%d] & current connected count [%d]",
2217 num_indicate_clients, cur_connected_clients);
2220 if (recvd == num_indicate_clients) {
2221 BT_INFO("Gatt indication confirm event for last GATT client.. [%s]", address);
2222 completed = 1; /* Last event */
2223 recvd = 0; /* Reset */
2224 num_indicate_clients = 0;
2227 param = g_variant_new("(isib)",
2233 /* Send event to BT-API */
2234 _bt_send_event(BT_GATT_SERVER_EVENT,
2235 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
2238 BT_INFO("Received Indication confirm for client number [%d]", recvd);
2242 /* Tizen Platform Specific */
2243 static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *event)
2245 bluetooth_device_address_t dev_addr;
2246 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2247 GVariant *param = NULL;
2250 /* OAL event does provide error, so MW assumes event will never contain wrong data,
2251 incase of any issues, check with OAL */
2252 int result = BLUETOOTH_ERROR_NONE;
2254 memcpy(dev_addr.addr, event->address.addr, 6);
2255 _bt_convert_addr_type_to_string(address,
2256 (unsigned char *)dev_addr.addr);
2258 BT_INFO("notification_changed [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d] Notify[%d]",
2259 address, event->conn_id, event->trans_id, event->attr_handle, event->notify);
2261 /* Set Notifcation status */
2262 notify = event->notify;
2264 param = g_variant_new("(isib)",
2270 /* Send event to BT-API */
2271 _bt_send_event(BT_GATT_SERVER_EVENT,
2272 BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
2278 static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
2280 int result = BLUETOOTH_ERROR_NONE;
2281 struct gatt_client_info_t *conn_info = NULL;
2282 GVariant *param = NULL;
2285 conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
2286 if (conn_info == NULL) {
2287 BT_ERR("Cant find connection Information");
2290 BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
2291 conn_info->addr, event->mtu_size);
2293 __bt_update_mtu_gatt_device(conn_info->addr, event->mtu_size);
2295 param = g_variant_new("(isqy)",
2301 /* Send event to BT-API */
2302 _bt_send_event(BT_GATT_SERVER_EVENT,
2303 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
2307 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
2309 switch (event_type) {
2310 case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
2311 BT_INFO("OAL Event: Server Instance Registered");
2312 /* GATT Server Registered event is handled in MAIN thread context */
2313 __bt_handle_server_instance_registered((event_gatts_register_t *)event_data);
2316 case OAL_EVENT_GATTS_SERVICE_ADDED: {
2317 BT_INFO("OAL Event: GATT Service added");
2318 __bt_handle_gatt_server_service_added((event_gatts_srvc_prm_t *)event_data);
2321 case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
2322 BT_INFO("OAL Event: GATT characteristic added");
2323 __bt_handle_gatt_server_characteristic_added((event_gatts_srvc_charctr_t *)event_data);
2326 case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
2327 BT_INFO("OAL Event: GATT descriptor added");
2328 __bt_handle_gatt_server_descriptor_added((event_gatts_srvc_descr_t *)event_data);
2331 case OAL_EVENT_GATTS_SERVICE_STARTED: {
2332 BT_INFO("OAL Event: GATT Service started");
2333 __bt_handle_gatt_server_service_started((event_gatts_srvc_t *)event_data);
2336 case OAL_EVENT_GATTS_SERVICE_STOPED: {
2337 BT_INFO("OAL Event: GATT Service stopped");
2338 __bt_handle_gatt_server_service_stopped((event_gatts_srvc_t *)event_data);
2341 case OAL_EVENT_GATTS_SERVICE_DELETED: {
2342 BT_INFO("OAL Event: GATT Service deleted");
2343 __bt_handle_gatt_server_service_deleted((event_gatts_srvc_t *) event_data);
2346 case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
2347 BT_INFO("OAL Event: GATT Server Connected");
2348 __bt_handle_gatt_server_connection_state((event_gatts_conn_t *)event_data);
2351 case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
2352 BT_INFO("OAL Event: GATT Server Disconnected");
2353 __bt_handle_gatt_server_disconnection_state((event_gatts_conn_t *)event_data);
2356 case OAL_EVENT_GATTS_REQUEST_READ: {
2357 BT_DBG("OAL Event: GATT Server Read Request");
2358 __bt_handle_gatt_server_read_requested((event_gatts_srvc_read_attr_t *)event_data);
2361 case OAL_EVENT_GATTS_REQUEST_WRITE: {
2362 BT_DBG("OAL Event: GATT Server Write Request");
2363 __bt_handle_gatt_server_write_requested((event_gatts_srvc_write_attr_t *)event_data);
2366 #ifdef TIZEN_BLUEDROID_PORTING
2367 case OAL_EVENT_GATTS_EXEC_REQUEST_WRITE: {
2368 BT_INFO("OAL Event: GATT Server Exec Write Request");
2369 __bt_handle_gatt_server_exec_write_requested((event_gatts_srvc_exec_write_attr_t *)event_data);
2373 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE: {
2374 BT_INFO("OAL Event: GATT Server Acquire Write Request");
2375 __bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2378 case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
2379 BT_INFO("OAL Event: GATT ServerAcquire Notify Request");
2380 __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
2383 case OAL_EVENT_GATTS_IND_CONFIRM: {
2384 BT_INFO("OAL Event: GATT Server Indication confirmed");
2385 __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
2388 case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
2389 BT_INFO("OAL Event: GATT Server DisConnected");
2390 __bt_handle_gatt_server_notification_changed((event_gatts_notif_t *)event_data);
2393 case OAL_EVENT_GATTS_MTU_CHANGED: {
2394 BT_INFO("OAL Event: GATT Server MTU changed event callback");
2395 __bt_handle_gatt_mtu_changed_event((event_gatts_mtu_changed_t *)event_data);
2398 case OAL_EVENT_GATTC_REGISTRATION: {
2399 BT_INFO("OAL Event: GATT Client instance Registered");
2400 __bt_handle_client_instance_registered((event_gattc_register_t *) event_data);
2403 case OAL_EVENT_GATTC_CONNECTION_COMPLETED: {
2404 BT_INFO("OAL Event: GATT Client Connected");
2405 __bt_handle_client_connected((event_gattc_conn_t *) event_data);
2408 case OAL_EVENT_GATTC_DISCONNECTION_COMPLETED: {
2409 BT_INFO("OAL Event: GATT Client DisConnected");
2410 __bt_handle_client_disconnected((event_gattc_conn_t *) event_data);
2413 case OAL_EVENT_GATTC_SERVICE_SEARCH_RESULT: {
2414 BT_DBG("OAL Event: GATT Client Service Search Result");
2415 __bt_handle_client_service_search_result((event_gattc_service_result_t *) event_data);
2418 case OAL_EVENT_GATTC_SERVICE_SEARCH_DONE: {
2419 BT_INFO("OAL Event: GATT Client Service Completed");
2420 __bt_handle_client_service_search_completed((event_gattc_conn_status_t *) event_data);
2423 case OAL_EVENT_GATTC_CHARAC_SERACH_RESULT: {
2424 BT_DBG("OAL Event: GATT Client Characteristic Search Result");
2425 __bt_handle_client_characteristic_search_result((event_gattc_characteristic_result_t *) event_data);
2428 case OAL_EVENT_GATTC_DESC_SERACH_RESULT: {
2429 BT_DBG("OAL Event: GATT Client Descriptor Search Result");
2430 __bt_handle_client_descriptor_search_result((event_gattc_descriptor_result_t *) event_data);
2433 case OAL_EVENT_GATTC_READ_CHARAC: {
2434 BT_DBG("OAL Event: GATT Client Characteristic Read Data");
2435 __bt_handle_client_characteristic_read_data((event_gattc_read_data *) event_data);
2438 case OAL_EVENT_GATTC_READ_DESCR: {
2439 BT_DBG("OAL Event: GATT Client Descriptor Read Data");
2440 __bt_handle_client_descriptor_read_data((event_gattc_read_data *) event_data);
2443 case OAL_EVENT_GATTC_WRITE_CHARAC: {
2444 BT_DBG("OAL Event: GATT Client Characteristic Write Data");
2445 __bt_handle_client_characteristic_write_data((event_gattc_write_data *) event_data);
2448 case OAL_EVENT_GATTC_WRITE_DESCR: {
2449 BT_DBG("OAL Event: GATT Client Descriptor Write Data");
2450 __bt_handle_client_descriptor_write_data((event_gattc_write_data *) event_data);
2453 case OAL_EVENT_DEVICE_LE_DISCONNECTED: {
2454 BT_INFO("OAL Event: LE device disconnected");
2455 __bt_hanlde_le_device_disconnection((event_dev_conn_status_t *)event_data);
2458 case OAL_EVENT_GATTC_NOTIFICATION_REGISTERED: {
2459 BT_INFO("OAL Event: GATT Client Notification Registered");
2460 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, TRUE);
2463 case OAL_EVENT_GATTC_NOTIFICATION_DEREGISTERED: {
2464 BT_INFO("OAL Event: GATT Client Notification Registered");
2465 __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, FALSE);
2468 case OAL_EVENT_GATTC_NOTIFY_DATA: {
2469 BT_DBG("OAL Event: GATT Client Notification Data");
2470 __bt_handle_client_notification_data((event_gattc_notify_data *) event_data);
2473 case OAL_EVENT_GATTC_SERVICE_CHANGED_IND: {
2474 BT_INFO("OAL Event: GATT Client service changed indication");
2475 __bt_handle_client_service_changed_ind((event_gattc_service_changed_data *)event_data);
2478 case OAL_EVENT_GATTC_MTU_EXCHANGE_COMPLETED: {
2479 BT_INFO("OAL Event: GATT Client MTU Exchange Complete");
2480 __bt_handle_client_mtu_exchange_completed((event_gattc_mtu_configured_t *) event_data);
2484 BT_DBG("Unhandled OAL event = 0x%x", event_type);
2489 int _bt_gatt_server_add_service(char *sender, int service_type,
2490 int num_handles, char *svc_uuid, int instance_id)
2492 BT_CHECK_PARAMETER(svc_uuid, return);
2493 BT_CHECK_PARAMETER(sender, return);
2494 int ret = OAL_STATUS_SUCCESS;
2496 oal_gatt_srvc_id_t svc_data;
2498 svc_data.is_prmry = service_type;
2499 svc_data.id.inst_id = instance_id;
2501 BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id);
2502 _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid);
2504 ret = gatts_add_service(instance_id, &svc_data, num_handles);
2505 if (ret != OAL_STATUS_SUCCESS) {
2506 BT_ERR("ret: %d", ret);
2507 return _bt_convert_oal_status_to_bt_error(ret);
2510 return BLUETOOTH_ERROR_NONE;
2514 int _bt_gatt_server_add_included_service(char *sender, int instance_id,
2515 int service_handle, int included_svc_handle)
2517 BT_CHECK_PARAMETER(sender, return);
2518 int ret = OAL_STATUS_SUCCESS;
2520 ret = gatts_add_included_services(instance_id, service_handle, included_svc_handle);
2521 if (ret != OAL_STATUS_SUCCESS) {
2522 BT_ERR("ret: %d", ret);
2523 return _bt_convert_oal_status_to_bt_error(ret);
2525 return BLUETOOTH_ERROR_NONE;
2528 int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
2529 bluetooth_gatt_server_attribute_params_t *param)
2531 BT_CHECK_PARAMETER(char_uuid, return);
2532 BT_CHECK_PARAMETER(sender, return);
2533 BT_CHECK_PARAMETER(param, return);
2534 int ret = OAL_STATUS_SUCCESS;
2536 oal_uuid_t uuid = {{0} };
2538 BT_INFO("Char UUID [%s] Instance ID [%d]", char_uuid, param->instance_id);
2539 _bt_string_to_uuid(char_uuid, (service_uuid_t*)&uuid);
2541 BT_INFO("Char permission From API [0x%x]", param->permissions);
2543 ret = gatts_add_characteristics(param->instance_id, param->service_handle, &uuid,
2544 param->properties, (int)param->permissions);
2545 if (ret != OAL_STATUS_SUCCESS) {
2546 BT_ERR("ret: %d", ret);
2547 return _bt_convert_oal_status_to_bt_error(ret);
2549 return BLUETOOTH_ERROR_NONE;
2552 int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
2553 bt_gatt_permission_t *param, int service_handle, int instance_id)
2555 BT_CHECK_PARAMETER(desc_uuid, return);
2556 BT_CHECK_PARAMETER(sender, return);
2557 BT_CHECK_PARAMETER(param, return);
2558 int ret = OAL_STATUS_SUCCESS;
2560 oal_uuid_t uuid = {{0} };
2562 BT_INFO("Descriptor UUID [%s] Instance ID [%d] Service handle [%d]",
2563 desc_uuid, service_handle, instance_id);
2565 _bt_string_to_uuid(desc_uuid, (service_uuid_t*)&uuid);
2567 BT_INFO("Descriptor permission From API [0x%x]", *param);
2568 ret = gatts_add_descriptor(instance_id, service_handle, &uuid, (int)*param);
2570 if (ret != OAL_STATUS_SUCCESS) {
2571 BT_ERR("ret: %d", ret);
2572 return _bt_convert_oal_status_to_bt_error(ret);
2574 return BLUETOOTH_ERROR_NONE;
2577 int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id)
2579 BT_CHECK_PARAMETER(sender, return);
2580 int ret = OAL_STATUS_SUCCESS;
2582 ret = gatts_start_service(instance_id, service_handle, BT_GATT_TRANSPORT_LE);
2583 if (ret != OAL_STATUS_SUCCESS) {
2584 BT_ERR("ret: %d", ret);
2585 return _bt_convert_oal_status_to_bt_error(ret);
2587 return BLUETOOTH_ERROR_NONE;
2590 int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id)
2592 BT_CHECK_PARAMETER(sender, return);
2593 int ret = OAL_STATUS_SUCCESS;
2595 ret = gatts_stop_service(instance_id, service_handle);
2596 if (ret != OAL_STATUS_SUCCESS) {
2597 BT_ERR("ret: %d", ret);
2598 return _bt_convert_oal_status_to_bt_error(ret);
2600 return BLUETOOTH_ERROR_NONE;
2603 int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id)
2605 BT_CHECK_PARAMETER(sender, return);
2606 int ret = OAL_STATUS_SUCCESS;
2610 bt_service_app_info_t *info = NULL;
2612 ret = gatts_delete_service(instance_id, service_handle);
2613 if (ret != OAL_STATUS_SUCCESS) {
2614 BT_ERR("ret: %d", ret);
2615 return _bt_convert_oal_status_to_bt_error(ret);
2618 /* Remove the Service Handle */
2619 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
2621 if (info->instance_id == instance_id) {
2622 for (l = info->service_handles; l != NULL; ) {
2624 l = g_slist_next(l);
2625 if (handle && *handle == service_handle) {
2626 BT_INFO("Remove Service handle [%d]", *handle);
2627 info->service_handles = g_slist_remove(info->service_handles, handle);
2636 return BLUETOOTH_ERROR_NONE;
2639 int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
2640 bluetooth_gatt_server_response_params_t *param)
2642 BT_CHECK_PARAMETER(sender, return);
2643 BT_CHECK_PARAMETER(data, return);
2644 BT_CHECK_PARAMETER(param, return);
2645 struct gatt_server_req_info *req_info = NULL;
2646 int ret = OAL_STATUS_SUCCESS;
2647 #ifdef TIZEN_BLUEDROID_PORTING
2648 int res = BLUETOOTH_ERROR_NONE;
2650 oal_gatt_response_t response;
2652 BT_INFO("GATT Server Response: Req Type [%d] req_id [%d] status [%d] auth_req [%d] offset[%d] data len[%d]",
2653 param->req_type, param->request_id,
2654 param->response_status, param->auth_req,
2655 data->offset, data->length);
2657 #ifdef TIZEN_BLUEDROID_PORTING
2658 if (__bt_handle_gatt_server_prepare_write_response(&res, param))
2662 /* Search for matching Request in List */
2663 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
2665 BT_ERR("GATT Server Req Info not found for current response..return Error");
2666 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2669 memset(&response, 0x00, sizeof(oal_gatt_response_t));
2671 response.handle = req_info->attribute_handle;
2672 response.attr_value.auth_req = param->auth_req;
2673 response.attr_value.handle = req_info->attribute_handle;
2674 response.attr_value.offset = data->offset;
2675 response.attr_value.len = data->length;
2676 memcpy(&response.attr_value.value, &data->data, data->length);
2679 ret = gatts_send_response(req_info->connection_id, param->request_id,
2680 param->response_status, &response);
2682 if (ret != OAL_STATUS_SUCCESS) {
2683 BT_ERR("ret: %d", ret);
2684 return _bt_convert_oal_status_to_bt_error(ret);
2687 /* Remove GATT server request from list */
2688 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
2689 g_free(req_info->addr);
2691 return BLUETOOTH_ERROR_NONE;
2694 int _bt_gatt_server_acquire_send_response(char *sender, bluetooth_gatt_server_acquire_response_params_t *param , void *fd_list)
2696 BT_CHECK_PARAMETER(sender, return);
2697 BT_CHECK_PARAMETER(param, return);
2698 struct gatt_server_req_info *req_info = NULL;
2699 int ret = OAL_STATUS_SUCCESS;
2702 BT_INFO("GATT acquire Server Response: Req Type [%d] req_id [%d] fd [%d] mtu[%d]",
2703 param->req_type, param->request_id,
2707 /* Search for matching Request in List */
2708 req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
2710 BT_ERR("GATT acquire Server Req Info not found for current response..return Error");
2711 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2714 ret = gatt_send_response_acquire(req_info->connection_id, param->request_id, 0, param->fd, param->mtu, fd_list);
2716 if (ret != OAL_STATUS_SUCCESS) {
2717 BT_ERR("ret: %d", ret);
2718 return _bt_convert_oal_status_to_bt_error(ret);
2721 /* Remove GATT server request from list */
2722 gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
2723 g_free(req_info->addr);
2725 return BLUETOOTH_ERROR_NONE;
2730 int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
2731 bluetooth_gatt_att_data_t *data,
2732 bluetooth_gatt_server_indication_params_t *param)
2734 BT_CHECK_PARAMETER(sender, return);
2735 BT_CHECK_PARAMETER(data, return);
2736 BT_CHECK_PARAMETER(param, return);
2738 gboolean all_send = FALSE;
2739 int ret = OAL_STATUS_SUCCESS;
2740 struct gatt_client_info_t *conn;
2742 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2743 _bt_convert_addr_type_to_string(address, dev_addr->addr);
2745 if (memcmp(dev_addr->addr, BDADDR_ANY, 6) == 0) {
2746 BT_INFO("GATT Server: Send Indication to all connected GATT clients..");
2749 BT_INFO("GATT Server: Send Indication to connected GATT client addr [%s]", address);
2752 /* Attempt to send Notification/Indication to all Connected GATT clients */
2754 ret = __bt_gatt_send_indication_to_all_connected_clients(data, param);
2755 if (ret != OAL_STATUS_SUCCESS) {
2756 BT_ERR("ret: %d", ret);
2758 return _bt_convert_oal_status_to_bt_error(ret);
2762 conn = _bt_find_remote_gatt_client_info(address);
2764 ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
2765 conn->connection_id, data->length,
2766 param->need_confirmation, (char *)(&data->data[0]));
2768 if (ret != OAL_STATUS_SUCCESS) {
2769 BT_ERR("ret: %d", ret);
2770 BT_INFO("Indication failed to send to Remote GATT Client [%s]", address);
2772 return _bt_convert_oal_status_to_bt_error(ret);
2774 BT_INFO("Indication sent to Remote GATT Client [%s] wait for Notification completed event from OAL", address);
2776 num_indicate_clients = 1;
2777 return BLUETOOTH_ERROR_NONE;
2779 BT_ERR("Remote GATT client [%s] is not connected..Cant send Indication!!", address);
2781 return BLUETOOTH_ERROR_NOT_CONNECTED;
2784 return BLUETOOTH_ERROR_NONE;
2787 int _bt_gatt_server_update_attribute_value(char *sender, int instance_id,
2788 bluetooth_gatt_server_update_value_t *param)
2790 BT_CHECK_PARAMETER(sender, return);
2791 BT_CHECK_PARAMETER(param, return);
2792 int ret = OAL_STATUS_SUCCESS;
2794 oal_gatt_value_t value;
2795 BT_DBG("GATT Server Update value: Instance ID [%d] attr handle [%d] Value len [%d]",
2796 instance_id, param->attribute_handle, param->length);
2798 memset(&value, 0x00, sizeof(oal_gatt_value_t));
2800 value.handle = param->attribute_handle;
2801 value.len = param->length;
2802 memcpy(&value.value, ¶m->data.data, param->length);
2804 ret = gatts_update_att_value(instance_id, &value);
2806 if (ret != OAL_STATUS_SUCCESS) {
2807 BT_ERR("ret: %d", ret);
2808 return _bt_convert_oal_status_to_bt_error(ret);
2811 return BLUETOOTH_ERROR_NONE;
2814 int _bt_request_att_mtu(bluetooth_device_address_t *device_address,
2817 struct gatt_server_info_t *conn_info = NULL;
2819 int ret = OAL_STATUS_SUCCESS;
2821 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
2822 _bt_convert_addr_type_to_string(addr, device_address->addr);
2824 /* Check if remote GATT Server is connected or not */
2825 conn_info = _bt_find_remote_gatt_server_info(addr);
2826 if (conn_info == NULL) {
2827 BT_ERR("GATT Server is not yet connected..");
2829 return BLUETOOTH_ERROR_NOT_CONNECTED;
2832 ret = gattc_configure_mtu(conn_info->connection_id, mtu);
2833 if (ret != OAL_STATUS_SUCCESS) {
2834 BT_ERR("ret: %d", ret);
2836 return _bt_convert_oal_status_to_bt_error(ret);
2840 return BLUETOOTH_ERROR_NONE;
2843 int _bt_get_att_mtu(bluetooth_device_address_t *address,
2846 BT_CHECK_PARAMETER(address, return);
2847 BT_CHECK_PARAMETER(mtu, return);
2848 struct gatt_client_info_t *client_info = NULL;
2849 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
2850 int ret = OAL_STATUS_SUCCESS;
2853 _bt_convert_addr_type_to_string(addr, address->addr);
2855 BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]", addr);
2857 client_info = _bt_find_remote_gatt_client_info(addr);
2859 BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
2860 client_info->addr, client_info->connection_id, client_info->instance_id);
2862 ret = gatts_get_att_mtu(client_info->connection_id, &stack_mtu);
2863 if (ret != OAL_STATUS_SUCCESS) {
2864 BT_ERR("ret: %d", ret);
2865 return _bt_convert_oal_status_to_bt_error(ret);
2868 struct gatt_server_info_t *server_info = NULL;
2869 BT_ERR("GATT Client [%s] is not yet connected..", addr);
2870 server_info = _bt_find_remote_gatt_server_info(addr);
2872 BT_INFO("GATT Server [%s] is connected, conn Id [%d] Client ID [%d]",
2873 server_info->addr, server_info->connection_id, server_info->client_id);
2875 ret = gattc_get_att_mtu(server_info->connection_id, &stack_mtu);
2876 if (ret != OAL_STATUS_SUCCESS) {
2877 BT_ERR("ret: %d", ret);
2878 return _bt_convert_oal_status_to_bt_error(ret);
2881 BT_ERR("GATT Server [%s] is not yet connected..", addr);
2882 return BLUETOOTH_ERROR_NOT_CONNECTED;
2886 BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
2887 *mtu = (unsigned int)stack_mtu;
2890 BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
2891 return BLUETOOTH_ERROR_NOT_CONNECTED;
2894 return BLUETOOTH_ERROR_NONE;
2897 /* GATT Client utility static functions */
2898 static bt_gatt_service_info_list_t *__bt_get_service_info_list(int conn_id)
2901 bt_gatt_service_info_list_t *info = NULL;
2903 for (l = list_gatt_info; l != NULL; l = g_slist_next(l)) {
2904 info = (bt_gatt_service_info_list_t *)l->data;
2908 if (info->conn_id == conn_id)
2915 static bt_gatt_service_info_t *__bt_find_matching_service(
2916 bt_gatt_service_info_list_t *svc_list, oal_gatt_srvc_id_t *svc)
2919 bt_gatt_service_info_t *info = NULL;
2921 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
2922 info = (bt_gatt_service_info_t *)l->data;
2926 /* Match UUID and instance ID */
2927 if (!memcmp(&svc->id.uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2928 && (svc->id.inst_id == info->inst_id)) {
2935 static bt_gatt_char_info_t *__bt_find_matching_charc(
2936 bt_gatt_service_info_t *svc_info, oal_gatt_id_t *charc)
2939 bt_gatt_char_info_t *info = NULL;
2941 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
2942 info = (bt_gatt_char_info_t *)l->data;
2946 /* Match UUID and instance ID */
2947 if (!memcmp(&charc->uuid.uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2948 && (charc->inst_id == info->inst_id)) {
2955 static bt_gatt_descriptor_info_t *__bt_find_matching_desc(
2956 bt_gatt_char_info_t *char_info, oal_gatt_id_t *desc)
2959 bt_gatt_descriptor_info_t *info = NULL;
2961 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
2962 info = (bt_gatt_descriptor_info_t *)l->data;
2966 /* Match UUID and instance ID */
2967 if (!memcmp(&desc->uuid, &info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
2968 && (desc->inst_id == info->inst_id)) {
2976 static struct gatt_server_info_t *__bt_find_remote_gatt_server_info_from_conn_id(int conn_id)
2979 struct gatt_server_info_t *info = NULL;
2981 for (l = gatt_server_info_list; l != NULL; l = g_slist_next(l)) {
2982 info = (struct gatt_server_info_t*)l->data;
2986 if (info->connection_id == conn_id)
2992 static bt_gatt_service_info_t* __bt_find_removed_service(bt_gatt_service_info_list_t *svc_list)
2995 bt_gatt_service_info_t *info = NULL;
2997 for (l = svc_list->services; l != NULL; l = g_slist_next(l)) {
2998 info = (bt_gatt_service_info_t*)l->data;
3002 /* Service is marked a removed */
3003 if (info->is_removed == 1)
3009 static void __bt_remove_service_info_from_list(bt_gatt_service_info_t *svc_info)
3015 bt_gatt_char_info_t *charc = NULL;
3016 bt_gatt_included_service_info_t *incl = NULL;
3017 bt_gatt_descriptor_info_t *desc = NULL;
3019 /* Remove all Characteristic and Descriptors within characteristic */
3020 for (l = svc_info->chars; l != NULL;) {
3021 charc = (bt_gatt_char_info_t*)l->data;
3022 l = g_slist_next(l); /* Incase if l is removed, saving next to l */
3027 /* Inside Characteristic */
3028 for (l1 = charc->descs; l1 != NULL;) {
3030 desc = (bt_gatt_descriptor_info_t*)l1->data;
3031 l1 = g_slist_next(l1);
3036 /* Remove Descriptor */
3037 charc->descs = g_slist_remove(charc->descs, desc);
3040 /* Remove Characteristic */
3041 svc_info->chars = g_slist_remove(svc_info->chars, charc);
3045 /* Remove all Included Services */
3046 for (l2 = svc_info->included_svcs; l2 != NULL;) {
3047 incl = (bt_gatt_included_service_info_t*)l2->data;
3048 l2 = g_slist_next(l2); /* Incase if l is removed, saving next to l */
3053 /* Remove included service */
3054 svc_info->included_svcs = g_slist_remove(svc_info->included_svcs, incl);
3061 static void __bt_build_service_browse_info(int conn_id,
3062 bt_services_browse_info_t* info)
3065 bt_gatt_service_info_list_t *svc_info_list;
3066 bt_gatt_service_info_t *svc_info;
3068 service_uuid_t uuid;
3069 struct gatt_server_info_t *conn_info = NULL;
3071 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3073 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3074 if (conn_info == NULL) {
3075 BT_ERR("Cant find connection Information");
3079 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3081 svc_info_list = __bt_get_service_info_list(conn_id);
3085 info->count = g_slist_length(svc_info_list->services);
3086 BT_DBG("Total services present in the svc info list for this conn id [%d] is [%d]",
3087 conn_id, info->count);
3089 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
3090 svc_info = (bt_gatt_service_info_t*)l->data;
3091 if (svc_info == NULL)
3094 memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3095 _bt_uuid_to_string(&uuid, uuid_string);
3097 BT_INFO("[%d] %s [%s]", count, uuid_string, _bt_convert_uuid_to_string(uuid_string));
3099 /* Fill UUID of service */
3100 g_strlcpy(info->uuids[count], uuid_string,
3101 BLUETOOTH_UUID_STRING_MAX);
3103 /* Fill instance ID of service */
3104 info->inst_id[count] = svc_info->inst_id;
3106 /* Fill primary service or not info */
3107 info->primary[count] = svc_info->is_primary;
3109 /* Increment count of services browsed */
3114 static void __bt_build_char_browse_info(int conn_id,
3115 bt_gatt_service_info_t *svc_info,
3116 bt_char_browse_info_t* info)
3119 bt_gatt_char_info_t *char_info;
3120 service_uuid_t uuid;
3122 struct gatt_server_info_t *conn_info = NULL;
3124 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3126 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3127 if (conn_info == NULL) {
3128 BT_ERR("Cant find connection Information");
3132 /* Fill default data, this will be required even in case of failure */
3133 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3134 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3135 info->svc_inst_id = svc_info->inst_id;
3137 if (!svc_info->chars) {
3138 BT_ERR("No Chars browsed for address [%s]", conn_info->addr);
3142 info->count = g_slist_length(svc_info->chars);
3144 for (l = svc_info->chars; l != NULL; l = g_slist_next(l)) {
3145 char_info = (bt_gatt_char_info_t*)l->data;
3146 if (char_info == NULL)
3149 memcpy(&uuid.uuid, &char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3150 _bt_uuid_to_string(&uuid, uuid_string);
3152 /* Fill UUID of characteristic */
3153 g_strlcpy(info->uuids[count], uuid_string,
3154 BLUETOOTH_UUID_STRING_MAX);
3156 /* Fill instance ID of characteristic */
3157 info->inst_id[count] = char_info->inst_id;
3159 /* Fill property of characteristic */
3160 info->props[count] = char_info->props;
3162 /* Increment count of services browsed */
3165 BT_DBG("Total characteristics browsed [%d]", count);
3168 static void __bt_build_descriptor_browse_info(int conn_id,
3169 bt_gatt_service_info_t *svc_info,
3170 bt_gatt_char_info_t *char_info,
3171 bt_descriptor_browse_info_t* info)
3174 bt_gatt_descriptor_info_t *desc_info;
3176 service_uuid_t uuid;
3177 struct gatt_server_info_t *conn_info = NULL;
3179 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
3181 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(conn_id);
3183 /* Fill default data, this will be required even in case of failure */
3184 _bt_convert_addr_string_to_type(info->device_addr.addr, conn_info->addr);
3185 memcpy(&info->svc_uuid, svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3186 info->svc_inst_id = svc_info->inst_id;
3187 memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3188 info->char_inst_id = char_info->inst_id;
3190 /* Fill property of the parent characteristic of this descriptor */
3191 info->char_props_map = char_info->props;
3193 info->count = g_slist_length(char_info->descs);
3195 if (!char_info->descs) {
3196 BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr + 12);
3200 for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
3201 desc_info = (bt_gatt_descriptor_info_t*)l->data;
3202 if (desc_info == NULL)
3205 memcpy(&uuid.uuid, &desc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3206 _bt_uuid_to_string(&uuid, uuid_string);
3208 /* Fill UUID of Descriptor */
3209 g_strlcpy(info->uuids[count], uuid_string,
3210 BLUETOOTH_UUID_STRING_MAX);
3212 /* Fill instance ID of Descriptor */
3213 info->inst_id[count] = desc_info->inst_id;
3216 /* Increment count of Descriptor browsed */
3220 BT_INFO("Total descriptors browsed [%d]", count);
3223 static void __bt_free_service_info(bt_gatt_service_info_t *svc)
3225 GSList *ll, *lll, *llll;
3226 bt_gatt_char_info_t *chr = NULL;
3227 bt_gatt_descriptor_info_t *desc = NULL;
3228 bt_gatt_included_service_info_t *incl_svc = NULL;
3230 BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id);
3231 /* Delete all chars and its descriptors */
3232 for (ll = svc->chars; ll != NULL; ) {
3233 chr = (bt_gatt_char_info_t *)ll->data;
3234 ll = g_slist_next(ll);
3238 for (lll = chr->descs; lll != NULL; ) {
3239 desc = (bt_gatt_descriptor_info_t *)lll->data;
3240 lll = g_slist_next(lll);
3243 chr->descs = g_slist_remove(chr->descs, desc);
3246 svc->chars = g_slist_remove(svc->chars, chr);
3250 /* Delete all included services */
3251 for (llll = svc->included_svcs; llll != NULL; ) {
3252 incl_svc = (bt_gatt_included_service_info_t *)llll->data;
3253 llll = g_slist_next(llll);
3254 if (incl_svc == NULL)
3256 svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc);
3261 static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
3263 bt_gatt_service_info_list_t *svc_info_list = NULL;
3264 bt_gatt_service_info_t *svc = NULL;
3268 BT_ERR("conn_info is NULL");
3272 svc_info_list = __bt_get_service_info_list(conn_info->connection_id);
3273 if (!svc_info_list) {
3274 BT_INFO("Could not find Svc Info list for the connection ID [%d]",
3275 conn_info->connection_id);
3279 BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services));
3280 for (l = svc_info_list->services; l != NULL; ) {
3281 svc = (bt_gatt_service_info_t *)l->data;
3282 l = g_slist_next(l);
3286 __bt_free_service_info(svc);
3287 svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
3291 list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
3292 g_free(svc_info_list);
3295 int _bt_register_gatt_client_instance(const char *sender,
3296 bluetooth_device_address_t *address)
3298 int ret = OAL_STATUS_SUCCESS;
3299 char *uuid_string = NULL;
3304 /* App should ensure that it should not send */
3305 BT_INFO("Check on which instance GATT Client instance can be initialized....");
3306 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3307 if (numapps[k].is_initialized == 1) {
3308 BT_DBG("Instance ID [%d] is already in use..Check next slot",
3309 numapps[k].instance_id);
3312 BT_DBG("Time to register GATT client instancer..UUID to be used is [%s] slot [%d]",
3313 uuid_list[slot-1], slot);
3319 BT_ERR("No Slot if free for GATT Client registration..");
3320 return BLUETOOTH_ERROR_REGISTRATION_FAILED;
3323 uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3324 _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
3325 g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
3326 BT_INFO("Copied UUID string [%s] slot [%d]", uuid_string, slot);
3328 /* Register GATT Client */
3329 ret = gattc_register(&uuid);
3330 if (ret != OAL_STATUS_SUCCESS) {
3331 BT_ERR("ret: %d", ret);
3332 g_free(uuid_string);
3333 return _bt_convert_oal_status_to_bt_error(ret);
3336 BT_DBG("GATT Client registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
3338 /* Return & wait for GATT Client Instance Initialization event */
3339 memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
3340 memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
3342 g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
3343 g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
3345 /* Address is saved here. When event comes, sender + address are matched for replying pending
3346 request. It is impossible for same sender to have requests with two same addresses */
3347 memcpy(&numapps[slot].address.addr, address->addr, sizeof(bluetooth_device_address_t));
3349 numapps[slot].is_initialized = TRUE; /* Set initialization to true here itself */
3351 g_free(uuid_string);
3352 return BLUETOOTH_ERROR_NONE;
3358 /* GATT client events */
3359 static void __bt_handle_client_instance_registered(event_gattc_register_t *data)
3361 bt_service_app_info_t *info = NULL;
3363 char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
3365 _bt_uuid_to_string(&(data->client_uuid), uuid_string);
3366 BT_INFO("Client ID is Initialized [%d] UUID initialized [%s]", data->client_if, uuid_string);
3368 /* Platform GATT client framwork does not use Default GATT client instance
3369 This GATT client instance is never deregistred in the lifetime of bt-service */
3370 if (g_strcmp0(uuid_string, DEFAULT_GATT_CLIENT_UUID) == 0) {
3371 BT_INFO("Default client Instance Registered");
3372 gatt_default_client = data->client_if;
3373 g_free(uuid_string);
3377 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
3380 if (g_strcmp0(info->uuid, uuid_string) == 0) {
3381 BT_INFO("Found GATT client.. sender [%s] Slot [%d] occupied", info->sender, k);
3382 info->is_initialized = TRUE;
3383 info->client_id = data->client_if;
3384 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_CLIENT_REGISTER,
3385 (void*)info, sizeof(bt_service_app_info_t));
3389 g_free(uuid_string);
3392 static void __bt_handle_client_connected(event_gattc_conn_t *event_data)
3394 int result = BLUETOOTH_ERROR_NONE;
3395 struct gatt_server_info_t *conn_info = NULL;
3396 struct gatt_out_conn_info_t *out_conn_info = NULL;
3398 GVariant *param = NULL;
3400 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3401 _bt_convert_addr_type_to_string(address,
3402 (unsigned char *)event_data->address.addr);
3404 if (event_data->status != OAL_STATUS_SUCCESS)
3405 result = BLUETOOTH_ERROR_INTERNAL;
3407 /* DBUS Return fo BT_CONNECT_LE for all the apps */
3408 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
3409 BT_ADDRESS_STRING_SIZE);
3411 BT_INFO("Local GATT Client Connected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status[%d]",
3412 address, event_data->client_if, event_data->conn_id, event_data->status);
3414 if (result == BLUETOOTH_ERROR_NONE) {
3415 /* Check if device is already in connected list */
3416 conn_info = _bt_find_remote_gatt_server_info(address);
3419 /* Send event to BT-API */
3420 param = g_variant_new("(is)", result, address);
3421 _bt_send_event(BT_DEVICE_EVENT,
3422 BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED, /* Local device is GATT client */
3425 /* Save Connection info */
3426 conn_info = g_new0(struct gatt_server_info_t, 1);
3427 conn_info->addr = g_strdup(address);
3428 conn_info->client_id = event_data->client_if;
3429 #ifdef __INTEGRATE_GATT_INFO__
3430 conn_info->instance_id = -1;
3432 conn_info->connection_id = event_data->conn_id;
3433 gatt_server_info_list = g_slist_append(gatt_server_info_list, conn_info);
3434 BT_DBG("Total num of connected Remote GATT server devices [%d]",
3435 g_slist_length(gatt_server_info_list));
3438 BT_INFO("Do a Internal refresh");
3439 if (OAL_STATUS_SUCCESS != gattc_refresh(conn_info->client_id, &event_data->address))
3440 BT_ERR("GATT database refresh failed!!");
3442 BT_INFO("GATT database refresh Success!!");
3445 BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
3447 __bt_add_mtu_gatt_device(address);
3449 _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
3451 BT_ERR("GATT Client Connection failed!!");
3453 /* If outgoing connection Info is present, then remove it */
3454 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
3455 if (out_conn_info) {
3456 BT_ERR("Outgoing Client connect request was sent");
3457 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
3458 g_free(out_conn_info->addr);
3459 g_free(out_conn_info);
3461 _bt_restart_le_scan();
3466 static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
3468 int result = BLUETOOTH_ERROR_NONE;
3469 struct gatt_server_info_t *conn_info = NULL;
3470 #ifndef __INTEGRATE_GATT_INFO__
3471 struct gatt_client_info_t *client_info = NULL;
3473 struct gatt_out_conn_info_t *out_conn_info = NULL;
3474 GVariant *param = NULL;
3476 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
3477 _bt_convert_addr_type_to_string(address,
3478 (unsigned char *)event_data->address.addr);
3480 if (event_data->status != OAL_STATUS_SUCCESS)
3481 result = BLUETOOTH_ERROR_INTERNAL;
3483 if (NULL == _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
3484 if (NULL != _bt_get_request_info_data(BT_CONNECT_LE, address)) {
3485 result = BLUETOOTH_ERROR_INTERNAL;
3486 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
3487 address, BT_ADDRESS_STRING_SIZE);
3488 BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
3493 /* DBUS Return for BT_DISCONNECT_LE for all the apps */
3494 __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE, address,
3495 BT_ADDRESS_STRING_SIZE);
3497 BT_INFO("Local GATT Client DisConnected: Remote addr[%s] Client Interface [%d] Connection ID [%d] status [%d]",
3498 address + 12, event_data->client_if, event_data->conn_id, event_data->status);
3500 /* Remove Connection info */
3501 conn_info = _bt_find_remote_gatt_server_info(address);
3504 param = g_variant_new("(is)", result, address);
3505 /* Send event to application */
3506 _bt_send_event(BT_DEVICE_EVENT,
3507 BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED,
3510 BT_INFO("Remove GATT server info from List..");
3511 /* Remove all services from info list_gatt_info */
3512 __bt_cleanup_remote_services(conn_info);
3514 /* Remove info from List */
3515 gatt_server_info_list = g_slist_remove(gatt_server_info_list, conn_info);
3516 BT_INFO("Total num of connected GATT servers [%d]", g_slist_length(gatt_server_info_list));
3517 g_free(conn_info->addr);
3520 BT_INFO("Can not find conn info, already removed!");
3522 #ifndef __INTEGRATE_GATT_INFO__
3523 /* Remove client info */
3524 client_info = _bt_find_remote_gatt_client_info(address);
3526 BT_DBG("Remove GATT client info from list");
3527 gatt_client_info_list = g_slist_remove(gatt_client_info_list, client_info);
3528 g_free(client_info->addr);
3529 g_free(client_info);
3533 __bt_remove_mtu_gatt_device(address);
3535 /* If outgoing connection Info is present, then remove it */
3536 out_conn_info = __bt_find_gatt_outgoing_conn_info(address);
3537 if (out_conn_info) {
3538 BT_ERR("Client Disconnected event, but outgoing connect request was sent");
3539 outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
3540 g_free(out_conn_info->addr);
3541 g_free(out_conn_info);
3547 static void __bt_handle_client_service_search_result(
3548 event_gattc_service_result_t *event_data)
3550 /* Pre: status is never fail from OAL */
3552 /* Find service list from address */
3553 bt_gatt_service_info_list_t *svc_info_list;
3554 bt_gatt_service_info_t *svc_info;
3556 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3557 if (!svc_info_list) {
3558 BT_DBG("Service info list not present for connection ID %d, means first time browse", event_data->conn_status.conn_id);
3559 /* Means for this conn_id, no services are ever browsed, first time,
3560 create service info list for this conn_id */
3561 svc_info_list = g_malloc0(sizeof(bt_gatt_service_info_list_t));
3562 svc_info_list->conn_id = event_data->conn_status.conn_id;
3563 list_gatt_info = g_slist_append(list_gatt_info, svc_info_list);
3566 /* send list and current service's uuid and instance id to find it */
3567 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3568 /* If not found, check if service changed, if yes, means this is a new service added
3569 in remote GATT device, update uuid info in svc info list structure, to be used when
3570 search is completed */
3572 if (svc_info_list->info.is_changed) {
3573 BT_DBG("Service Changed indication already found for connection ID %d", event_data->conn_status.conn_id);
3574 memcpy(svc_info_list->info.uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3576 /* Create and add new service in service list */
3577 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
3578 memcpy(svc_info->uuid, event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3579 svc_info->inst_id = event_data->srvc_id.id.inst_id;
3580 svc_info->is_primary = event_data->srvc_id.is_prmry;
3581 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
3582 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_status.conn_id);
3584 /* If returned matching service info, then just update service_rmeoved value inside it to 0 */
3585 svc_info->is_removed = 0;
3589 static void __bt_handle_client_service_search_completed(
3590 event_gattc_conn_status_t *event_data)
3592 struct gatt_server_info_t *conn_info = NULL;
3593 bt_gatt_service_info_list_t *svc_info_list;
3594 bt_gatt_service_info_t *svc_info;
3595 bt_services_browse_info_t browse_info;
3596 unsigned char uuid_empty[BLUETOOTH_UUID_HEX_MAX_LEN];
3598 memset(&uuid_empty, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
3599 memset(&browse_info, 0x00, sizeof(bt_services_browse_info_t));
3600 BT_INFO("Primary Services browsing completed status[%d] conn ID [%d]",
3601 event_data->status, event_data->conn_id);
3603 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
3605 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
3606 if (!svc_info_list) {
3607 BT_ERR("No services browsed ever for addr [%s]", conn_info->addr);
3609 /* Just build response and return ERROR */
3610 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3612 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
3613 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3614 sizeof(bt_services_browse_info_t));
3618 /* If fail, then send event with error */
3619 if (event_data->status != OAL_STATUS_SUCCESS) {
3620 /* Just build response and return ERROR */
3621 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3623 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_INTERNAL,
3624 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3625 sizeof(bt_services_browse_info_t));
3629 /* If success, then find service info list from address */
3631 /* If svc_changed == 1 and uuid valid, means a new service is added*/
3632 if (svc_info_list->info.is_changed && !memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
3633 /* TODO: Send event -Service added with instance ID and UUID of newly added service */
3634 BT_INFO("new service added");
3636 BT_INFO("TODO new service added");
3639 /* If svc_changed == 1 and uuid invalid, then a service is removed */
3640 if (svc_info_list->info.is_changed && memcmp(uuid_empty, svc_info_list->info.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
3641 /* Scan through the service info list to find service with is_removed = 1*/
3642 svc_info = __bt_find_removed_service(svc_info_list);
3644 /* TODO Send event - Service removed with instance ID and UUID of just rmeoved service */
3646 /* Remove that service info from service info list */
3647 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
3649 /* Delete that service completely from svc_info list*/
3650 __bt_remove_service_info_from_list(svc_info);
3654 /* Reset svc_changed = 0, and reset UUID = all 0's */
3655 svc_info_list->info.is_changed = 0;
3656 memset(&svc_info_list->info.uuid, 0x00, BLUETOOTH_UUID_HEX_MAX_LEN);
3658 /* Build Reply and send to service browse primary services request of pending apps */
3659 __bt_build_service_browse_info(event_data->conn_id, &browse_info);
3661 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3662 BT_GATT_GET_PRIMARY_SERVICES, &browse_info,
3663 sizeof(bt_services_browse_info_t));
3667 static void __bt_handle_client_characteristic_search_result(
3668 event_gattc_characteristic_result_t *event_data)
3670 bt_gatt_service_info_list_t *svc_info_list;
3671 bt_gatt_service_info_t *svc_info;
3672 bt_gatt_char_info_t *char_info;
3673 bt_char_browse_info_t browse_info;
3675 memset(&browse_info, 0x00, sizeof(bt_char_browse_info_t));
3678 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
3679 /* Find service info list from address */
3680 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3681 if (svc_info_list == NULL) {
3682 BT_ERR("svc_info_list is NULL");
3686 /* Find matching service info from svc info list */
3687 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3688 if (svc_info == NULL) {
3689 BT_ERR("svc_info is NULL");
3693 /* Find Matching char from service info in event */
3694 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3695 /* If not found, then add new characteristic and return */
3697 BT_DBG("Add new characteristic");
3698 char_info = g_malloc0(sizeof(bt_gatt_char_info_t));
3699 memcpy(char_info->uuid, event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3701 char_info->inst_id = event_data->char_id.inst_id;
3702 char_info->props = event_data->char_prop;
3703 svc_info->chars = g_slist_append(svc_info->chars, char_info);
3705 /* If found, then return */
3706 BT_DBG("update char property as Characteristic browsed is already present");
3707 char_info->props |= event_data->char_prop;
3710 /* If Not success: Means Charc browse is completed */
3711 /* Find char list from service in event */
3712 /* Find service list from address */
3713 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3714 if (svc_info_list == NULL) {
3715 BT_ERR("svc_info_list is NULL");
3719 /* Find service info from service in event */
3720 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3721 if (svc_info == NULL) {
3722 BT_ERR("svc_info is NULL");
3726 /* Build char list from service in event */
3727 __bt_build_char_browse_info(event_data->conn_status.conn_id,
3728 svc_info, &browse_info);
3730 /* Create response and return by sending event*/
3731 /* Build Reply and send to service browse All Included services request of pending apps */
3732 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3733 BT_GATT_GET_SERVICE_PROPERTIES,
3735 sizeof(bt_char_browse_info_t));
3739 static void __bt_handle_client_descriptor_search_result(
3740 event_gattc_descriptor_result_t *event_data)
3742 bt_gatt_service_info_list_t *svc_info_list;
3743 bt_gatt_service_info_t *svc_info;
3744 bt_gatt_char_info_t *char_info;
3745 bt_gatt_descriptor_info_t *desc_info;
3746 bt_descriptor_browse_info_t browse_info;
3748 BT_DBG("descriptor search result status [%d]", event_data->conn_status.status);
3750 memset(&browse_info, 0x00, sizeof(bt_descriptor_browse_info_t));
3753 if (event_data->conn_status.status == OAL_STATUS_SUCCESS) {
3754 /* Find service list from address */
3755 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3756 if (svc_info_list == NULL) {
3757 BT_ERR("svc_info_list is NULL");
3761 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3762 if (svc_info == NULL) {
3763 BT_ERR("svc_info is NULL");
3767 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3768 if (char_info == NULL) {
3769 BT_ERR("char_info is NULL");
3773 desc_info = __bt_find_matching_desc(char_info, &event_data->descr_id);
3774 /* If not found, add new descriptor and return */
3776 desc_info = g_malloc0(sizeof(bt_gatt_descriptor_info_t));
3777 memcpy(desc_info->uuid, event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3779 desc_info->inst_id = event_data->descr_id.inst_id;
3780 char_info->descs = g_slist_append(char_info->descs, desc_info);
3783 /* If found, then return */
3784 BT_DBG("Descriptor browsed is already presesnt");
3787 /* If Not success */
3788 /* Find service list from address */
3789 /* Find included service list from service in event */
3790 /* Create response and return by sending event*/
3791 svc_info_list = __bt_get_service_info_list(event_data->conn_status.conn_id);
3792 if (svc_info_list == NULL) {
3793 BT_ERR("svc_info_list is NULL");
3797 /* Find service info from service in event */
3798 svc_info = __bt_find_matching_service(svc_info_list, &event_data->srvc_id);
3799 if (svc_info == NULL) {
3800 BT_ERR("svc_info is NULL");
3804 /* Find char info from char in event */
3805 char_info = __bt_find_matching_charc(svc_info, &event_data->char_id);
3806 if (char_info == NULL) {
3807 BT_ERR("char_info is NULL");
3811 /* Build descriptor list from char in event */
3812 __bt_build_descriptor_browse_info(event_data->conn_status.conn_id,
3813 svc_info, char_info, &browse_info);
3816 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE,
3817 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
3819 sizeof(bt_descriptor_browse_info_t));
3823 static void __bt_handle_client_characteristic_read_data(
3824 event_gattc_read_data *event_data)
3826 int result = BLUETOOTH_ERROR_NONE;
3827 struct gatt_server_info_t *conn_info = NULL;
3828 bluetooth_gatt_client_char_prop_info_t read_info;
3830 /* Read Information data structures */
3831 GVariant *param = NULL;
3832 GVariant *data = NULL;
3833 GVariant *data_svc_uuid = NULL;
3834 GVariant *data_char_uuid = NULL;
3835 char *read_val = NULL;
3836 char *svc_uuid = NULL;
3837 char *char_uuid = NULL;
3840 //memset(&read_info, 0x00, sizeof(bt_gatt_handle_property_t));
3841 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
3843 /* Extract Address from conn_id of event data */
3844 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
3845 event_data->uuid_status.conn_status.conn_id);
3847 BT_INFO("Characteristic Read result from addr [%s] status [%d]",
3848 conn_info->addr, event_data->uuid_status.conn_status.status);
3850 /* Fill char in buffer */
3851 memcpy(&read_info.characteristic.uuid,
3852 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3853 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
3855 /* Fill Service in buffer */
3856 memcpy(&read_info.svc.uuid,
3857 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3858 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
3860 /* Fill remote device address */
3861 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
3863 /* Fill data and reply to all apps waiting for Read result on the same characteristic
3864 Note: Even in case of failure, address, handles and result code should be returned */
3865 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
3866 result = BLUETOOTH_ERROR_INTERNAL;
3868 if (event_data->data_len > 0) {
3870 // for (i = 0; i < event_data->data_len; i++)
3871 // BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
3874 read_val = g_memdup(&event_data->data[0], event_data->data_len);
3876 data = g_variant_new_from_data(
3877 G_VARIANT_TYPE_BYTESTRING,
3879 event_data->data_len,
3882 BT_ERR("Characteristic Read success, but no data!!!");
3884 data = g_variant_new_from_data(
3885 G_VARIANT_TYPE_BYTESTRING,
3892 svc_uuid = g_memdup(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
3894 data_svc_uuid = g_variant_new_from_data(
3895 G_VARIANT_TYPE_BYTESTRING,
3901 char_uuid = g_memdup(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
3903 data_char_uuid = g_variant_new_from_data(
3904 G_VARIANT_TYPE_BYTESTRING,
3909 param = g_variant_new("(isn@ayin@ayin@ay)", result,
3913 event_data->uuid_status.srvc_id.id.inst_id,
3916 event_data->uuid_status.char_id.inst_id,
3917 event_data->data_len,
3921 char *sender = NULL;
3922 __bt_gatt_get_pending_request_info(BT_GATT_READ_CHARACTERISTIC, &sender);
3923 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
3924 BLUETOOTH_EVENT_GATT_READ_CHAR,
3927 /* Send DBUS return */
3928 __bt_gatt_handle_pending_request_info(result,
3929 BT_GATT_READ_CHARACTERISTIC,
3931 sizeof(bluetooth_gatt_client_char_prop_info_t));
3942 static void __bt_handle_client_descriptor_read_data(
3943 event_gattc_read_data *event_data)
3945 int result = BLUETOOTH_ERROR_NONE;
3946 struct gatt_server_info_t *conn_info = NULL;
3947 bluetooth_gatt_client_desc_prop_info_t read_info;
3949 /* Read Information data structures */
3950 GVariant *param = NULL;
3951 GVariant *data = NULL;
3952 GVariant *data_svc_uuid = NULL;
3953 GVariant *data_char_uuid = NULL;
3954 GVariant *data_desc_uuid = NULL;
3955 char *read_val = NULL;
3956 char *svc_uuid = NULL;
3957 char *char_uuid = NULL;
3958 char *desc_uuid = NULL;
3962 memset(&read_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
3964 /* Extract Address from conn_id of event data */
3965 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
3966 event_data->uuid_status.conn_status.conn_id);
3968 BT_DBG("Descriptor Read result from addr [%s] status [%d]",
3969 conn_info->addr, event_data->uuid_status.conn_status.status);
3971 /* Fill descriptor informations in buffer */
3972 memcpy(&read_info.descriptor.uuid,
3973 event_data->uuid_status.descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3974 read_info.descriptor.instance_id = event_data->uuid_status.descr_id.inst_id;
3976 /* Fill Characteristic informations in buffer */
3977 memcpy(&read_info.characteristic.uuid,
3978 event_data->uuid_status.char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3979 read_info.characteristic.instance_id = event_data->uuid_status.char_id.inst_id;
3981 /* Fill Service informations in buffer */
3982 memcpy(&read_info.svc.uuid,
3983 event_data->uuid_status.srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
3984 read_info.svc.instance_id = event_data->uuid_status.srvc_id.id.inst_id;
3986 /* Fill remote device address */
3987 _bt_convert_addr_string_to_type(read_info.device_address.addr, conn_info->addr);
3989 /* Fill data and reply to all apps waiting for Read result on the same characteristic */
3990 if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
3991 result = BLUETOOTH_ERROR_INTERNAL;
3993 if (event_data->data_len > 0) {
3995 for (i = 0; i < event_data->data_len; i++)
3996 BT_DBG("Data[%d] = [0x%x]", i, event_data->data[i]);
3999 read_val = g_memdup(&event_data->data[0], event_data->data_len);
4001 data = g_variant_new_from_data(
4002 G_VARIANT_TYPE_BYTESTRING,
4004 event_data->data_len,
4007 BT_INFO("Descriptor Read success, but no data!!!");
4009 data = g_variant_new_from_data(
4010 G_VARIANT_TYPE_BYTESTRING,
4016 svc_uuid = g_memdup(&event_data->uuid_status.srvc_id.id.uuid.uuid[0], uuid_len);
4018 data_svc_uuid = g_variant_new_from_data(
4019 G_VARIANT_TYPE_BYTESTRING,
4025 char_uuid = g_memdup(&event_data->uuid_status.char_id.uuid.uuid[0], uuid_len);
4027 data_char_uuid = g_variant_new_from_data(
4028 G_VARIANT_TYPE_BYTESTRING,
4034 desc_uuid = g_memdup(&event_data->uuid_status.descr_id.uuid.uuid[0], uuid_len);
4036 data_desc_uuid = g_variant_new_from_data(
4037 G_VARIANT_TYPE_BYTESTRING,
4042 param = g_variant_new("(isn@ayin@ayin@ayin@ay)", result,
4046 event_data->uuid_status.srvc_id.id.inst_id,
4049 event_data->uuid_status.char_id.inst_id,
4052 event_data->uuid_status.descr_id.inst_id,
4053 event_data->data_len,
4057 char *sender = NULL;
4058 __bt_gatt_get_pending_request_info(BT_GATT_READ_DESCRIPTOR_VALUE, &sender);
4059 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4060 BLUETOOTH_EVENT_GATT_READ_DESC,
4064 /* Send DBUS return */
4065 __bt_gatt_handle_pending_request_info(result,
4066 BT_GATT_READ_DESCRIPTOR_VALUE,
4068 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4079 static void __bt_handle_client_characteristic_write_data(
4080 event_gattc_write_data *event_data)
4082 int result = BLUETOOTH_ERROR_NONE;
4083 struct gatt_server_info_t *conn_info = NULL;
4084 bluetooth_gatt_client_char_prop_info_t write_info;
4086 /* Read Information data structures */
4087 GVariant *param = NULL;
4088 GVariant *data_svc_uuid = NULL;
4089 GVariant *data_char_uuid = NULL;
4090 char *svc_uuid = NULL;
4091 char *char_uuid = NULL;
4094 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
4096 /* Extract Address from conn_id of event data */
4097 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4098 event_data->conn_status.conn_id);
4100 BT_DBG("Characteristic Write callback from addr [%s] status [%d]",
4101 conn_info->addr, event_data->conn_status.status);
4103 /* Fill char in buffer */
4104 memcpy(&write_info.characteristic.uuid,
4105 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4106 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4108 /* Fill Service in buffer */
4109 memcpy(&write_info.svc.uuid,
4110 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4111 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4113 /* Fill remote device address */
4114 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4116 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4117 result = BLUETOOTH_ERROR_INTERNAL;
4123 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4125 data_svc_uuid = g_variant_new_from_data(
4126 G_VARIANT_TYPE_BYTESTRING,
4132 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4134 data_char_uuid = g_variant_new_from_data(
4135 G_VARIANT_TYPE_BYTESTRING,
4140 param = g_variant_new("(isn@ayin@ayi)", result,
4144 event_data->srvc_id.id.inst_id,
4147 event_data->char_id.inst_id);
4150 char *sender = NULL;
4151 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, &sender);
4152 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4153 BLUETOOTH_EVENT_GATT_WRITE_CHAR,
4163 /* Send DBUS return */
4164 __bt_gatt_handle_pending_request_info(result,
4165 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
4167 sizeof(bluetooth_gatt_client_char_prop_info_t));
4171 static void __bt_handle_client_descriptor_write_data(
4172 event_gattc_write_data *event_data)
4174 int result = BLUETOOTH_ERROR_NONE;
4175 struct gatt_server_info_t *conn_info = NULL;
4176 bluetooth_gatt_client_desc_prop_info_t write_info;
4178 /* Write Information data structures */
4179 GVariant *param = NULL;
4180 GVariant *data_svc_uuid = NULL;
4181 GVariant *data_char_uuid = NULL;
4182 GVariant *data_desc_uuid = NULL;
4183 char *svc_uuid = NULL;
4184 char *char_uuid = NULL;
4185 char *desc_uuid = NULL;
4188 memset(&write_info, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
4190 /* Extract Address from conn_id of event data */
4191 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(
4192 event_data->conn_status.conn_id);
4194 if (NULL == conn_info) {
4195 BT_ERR("Failed to get the conn info for conn_id [%d]", event_data->conn_status.conn_id);
4199 BT_DBG("Descriptor Write callback from addr [%s] status [%d]",
4200 conn_info->addr, event_data->conn_status.status);
4202 /* Fill descriptor informations in buffer */
4203 memcpy(&write_info.descriptor.uuid,
4204 event_data->descr_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4205 write_info.descriptor.instance_id = event_data->descr_id.inst_id;
4207 /* Fill Characteristic informations in buffer */
4208 memcpy(&write_info.characteristic.uuid,
4209 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4210 write_info.characteristic.instance_id = event_data->char_id.inst_id;
4212 /* Fill Service informations in buffer */
4213 memcpy(&write_info.svc.uuid,
4214 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4215 write_info.svc.instance_id = event_data->srvc_id.id.inst_id;
4217 /* Fill remote device address */
4218 _bt_convert_addr_string_to_type(write_info.device_address.addr, conn_info->addr);
4220 if (event_data->conn_status.status != OAL_STATUS_SUCCESS) {
4221 result = BLUETOOTH_ERROR_INTERNAL;
4227 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4229 data_svc_uuid = g_variant_new_from_data(
4230 G_VARIANT_TYPE_BYTESTRING,
4236 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4238 data_char_uuid = g_variant_new_from_data(
4239 G_VARIANT_TYPE_BYTESTRING,
4245 desc_uuid = g_memdup(&event_data->descr_id.uuid.uuid[0], uuid_len);
4247 data_desc_uuid = g_variant_new_from_data(
4248 G_VARIANT_TYPE_BYTESTRING,
4253 param = g_variant_new("(isn@ayin@ayin@ayi)", result,
4257 event_data->srvc_id.id.inst_id,
4260 event_data->char_id.inst_id,
4263 event_data->descr_id.inst_id);
4266 char *sender = NULL;
4267 __bt_gatt_get_pending_request_info(BT_GATT_WRITE_DESCRIPTOR_VALUE, &sender);
4268 _bt_send_event_to_dest(sender, BT_GATT_CLIENT_EVENT,
4269 BLUETOOTH_EVENT_GATT_WRITE_DESC,
4280 /* Send DBUS return */
4281 __bt_gatt_handle_pending_request_info(result,
4282 BT_GATT_WRITE_DESCRIPTOR_VALUE,
4284 sizeof(bluetooth_gatt_client_desc_prop_info_t));
4287 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data)
4289 int result = BLUETOOTH_ERROR_INTERNAL;
4290 char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
4292 _bt_convert_addr_type_to_string(address, (unsigned char *)event_data->address.addr);
4294 /* DBUS Return with fail of pending BT_CONNECT_LE for all the apps */
4295 BT_INFO("Local GATT Client disconnected: Remote addr[%s] ", address + 12);
4297 __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
4298 BT_ADDRESS_STRING_SIZE);
4302 static void __bt_handle_client_notification_registered(
4303 event_gattc_regdereg_notify_t *event_data,
4304 gboolean is_registered)
4306 int result = BLUETOOTH_ERROR_NONE;
4307 struct gatt_server_info_t *conn_info = NULL;
4308 bt_gatt_notif_reg_info_t notif_info;
4311 memset(¬if_info, 0x00, sizeof(bt_gatt_notif_reg_info_t));
4313 BT_INFO("Client Interface [%d] status [%d]",
4314 event_data->conn_id,
4315 event_data->status);
4317 /* Extract Address from conn_id of event data */
4318 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
4320 BT_INFO("Connection Info is not present, return");
4323 BT_INFO("Notification Registered for addr [%s]", conn_info->addr);
4325 /* Fill svc informations in buffer */
4326 memcpy(¬if_info.svc_uuid,
4327 event_data->srvc_id.id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4328 notif_info.svc_inst = event_data->srvc_id.id.inst_id;
4330 /* Fill char in buffer */
4331 memcpy(¬if_info.char_uuid,
4332 event_data->char_id.uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4333 notif_info.char_inst = event_data->char_id.inst_id;
4335 /* Fill remote device address */
4336 _bt_convert_addr_string_to_type(notif_info.addr.addr, conn_info->addr);
4338 notif_info.is_registered = is_registered;
4340 if (event_data->status != OAL_STATUS_SUCCESS)
4341 result = BLUETOOTH_ERROR_INTERNAL;
4343 /* Send DBUS Return for BT_GATT_WATCH_CHARACTERISTIC */
4344 __bt_gatt_handle_pending_request_info(result,
4345 BT_GATT_WATCH_CHARACTERISTIC,
4347 sizeof(bt_gatt_notif_reg_info_t));
4350 static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
4352 /* No status in this event from OAL */
4353 int result = BLUETOOTH_ERROR_NONE;
4355 /* Read Information data structures */
4356 GVariant *param = NULL;
4357 GVariant *data = NULL;
4358 GVariant *data_svc_uuid = NULL;
4359 GVariant *data_char_uuid = NULL;
4360 char *read_val = NULL;
4361 char *svc_uuid = NULL;
4362 char *char_uuid = NULL;
4368 BT_INFO("Notifcation of charc data changed");
4370 if (event_data->data_len > 0) {
4372 for (i = 0; i < event_data->data_len; i++)
4373 BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
4376 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4377 _bt_convert_addr_type_to_string(addr,
4378 (unsigned char *)&(event_data->address.addr));
4381 read_val = g_memdup(&event_data->data[0], event_data->data_len);
4383 data = g_variant_new_from_data(
4384 G_VARIANT_TYPE_BYTESTRING,
4386 event_data->data_len,
4389 svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
4391 data_svc_uuid = g_variant_new_from_data(
4392 G_VARIANT_TYPE_BYTESTRING,
4398 char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
4400 data_char_uuid = g_variant_new_from_data(
4401 G_VARIANT_TYPE_BYTESTRING,
4407 param = g_variant_new("(isn@ayin@ayin@ay)", result,
4411 event_data->srvc_id.id.inst_id,
4414 event_data->char_id.inst_id,
4415 event_data->data_len,
4419 _bt_send_event(BT_GATT_CLIENT_EVENT,
4420 BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
4423 BT_ERR("No Data!!");
4436 static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data)
4438 bt_gatt_service_info_list_t *svc_info_list;
4440 bt_gatt_service_info_t *svc_info;
4441 GVariant *param = NULL;
4442 char *address_str = NULL;
4443 char *uuid_str = NULL;
4445 svc_info_list = __bt_get_service_info_list(event_data->conn_id);
4446 if (svc_info_list == NULL) {
4447 BT_ERR("svc_info_list is NULL");
4451 if (event_data->change_type) {
4452 /* Add service UUID in list */
4453 svc_info = g_malloc0(sizeof(bt_gatt_service_info_t));
4454 memcpy(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4455 svc_info->inst_id = event_data->inst_id;
4456 svc_info->is_primary = 1; // TODO: Need to check is_primary is required or not
4457 svc_info_list->services = g_slist_append(svc_info_list->services, svc_info);
4458 BT_DBG("Service created and added in Svc info list or connection ID %d", event_data->conn_id);
4460 /* Remove service UUID in list */
4461 for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) {
4462 svc_info = (bt_gatt_service_info_t *)l->data;
4463 if (svc_info == NULL)
4466 if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) {
4467 svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info);
4468 __bt_free_service_info(svc_info);
4474 address_str = g_malloc0(BT_ADDRESS_STRING_SIZE);
4475 uuid_str = g_malloc0(BT_UUID_STRING_MAX);
4476 _bt_convert_addr_type_to_string(address_str, event_data->address.addr);
4477 _bt_uuid_to_string(&event_data->uuid, uuid_str);
4479 param = g_variant_new("(iiss)", event_data->inst_id, event_data->change_type, address_str, uuid_str);
4481 _bt_send_event(BT_GATT_CLIENT_EVENT,
4482 BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED,
4484 g_free(address_str);
4488 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
4491 struct gatt_server_info_t *conn_info = NULL;
4492 gboolean connected = FALSE;
4494 addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
4495 _bt_convert_addr_type_to_string(addr,
4496 (unsigned char *)&(address->addr));
4498 BT_DBG("Check GATT connection status of [%s]", addr);
4499 /* Check if device is already in connected list */
4500 conn_info = _bt_find_remote_gatt_server_info(addr);
4502 BT_DBG("Remote GATT Server device [%s] is Connected", conn_info->addr);
4505 struct gatt_client_info_t *client_info = NULL;
4507 BT_DBG("Remote GATT Server Device [%s] is not Connected", addr);
4509 /* Check if device is already in connected list */
4510 client_info = _bt_find_remote_gatt_client_info(addr);
4512 BT_DBG("Remote Client device [%s] is Connected", client_info->addr);
4515 BT_DBG("Remote GATT Client Device [%s] is not Connected", addr);
4523 void _bt_handle_invocation_context(int function_name, void *data)
4525 switch (function_name) {
4527 __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_CONNECT_LE,
4528 (char *)data, BT_ADDRESS_STRING_SIZE);
4535 int _bt_connect_le_device(bluetooth_device_address_t *address,
4536 int auto_connect, int client_id)
4538 struct gatt_server_info_t *conn_info = NULL;
4539 struct gatt_out_conn_info_t *out_conn_info = NULL;
4541 invocation_info_t *req_info = NULL;
4542 int ret = OAL_STATUS_SUCCESS;
4544 char *remote_address = NULL;
4546 BT_CHECK_PARAMETER(address, return);
4548 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4549 _bt_convert_addr_type_to_string(addr, address->addr);
4550 BT_DBG("GATT Client connect request for address [%s] client instance [%d]",
4554 /* Check if Remote Device is already under connection progress */
4555 req_info = _bt_get_request_info_data_from_function_name(BT_CONNECT_LE);
4557 remote_address = (char*)req_info->user_data;
4558 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
4559 BT_DBG("Already Connection ongoing for same remote GATT Server address [%s]", remote_address);
4560 /* Return and wait for events to be sent to all apps */
4562 return BLUETOOTH_ERROR_IN_PROGRESS;
4566 /* Check if remote GATT Server is connected or not */
4567 conn_info = _bt_find_remote_gatt_server_info(addr);
4569 BT_ERR("GATT Server is already connected..");
4571 return BLUETOOTH_ERROR_ALREADY_CONNECT;
4574 /* TODO Check Requirement of holding Advertisement before initiating LE connect */
4577 /* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
4578 if (client_id == 0) {
4579 /* GATT CLient connect request sent by an app without any client instance [0] */
4580 BT_DBG("Assign default GATT client id [%d]", gatt_default_client);
4581 client_id = gatt_default_client;
4584 BT_INFO("Connect using CLient ID [%d]", client_id);
4585 ret = gattc_connect(client_id, (bt_address_t*)(address), auto_connect);
4587 if (ret != OAL_STATUS_SUCCESS) {
4588 BT_ERR("gattc_connect is failed. ret: %d", ret);
4590 _bt_restart_le_scan();
4591 return _bt_convert_oal_status_to_bt_error(ret);
4594 /* Mark this as outgoing connection */
4595 out_conn_info = g_new0(struct gatt_out_conn_info_t, 1);
4596 out_conn_info->addr = g_strdup(addr);
4597 out_conn_info->client_id = client_id;
4598 BT_INFO("Added outgoing connection info addr[%s]", out_conn_info->addr + 12);
4599 outgoing_gatt_conn_list = g_slist_append(outgoing_gatt_conn_list, out_conn_info);
4602 return BLUETOOTH_ERROR_NONE;
4605 int _bt_gatt_get_primary_services(char *address)
4607 BT_CHECK_PARAMETER(address, return);
4608 struct gatt_server_info_t *conn_info = NULL;
4609 invocation_info_t *req_info = NULL;
4610 int ret = OAL_STATUS_SUCCESS;
4612 /* Check if any app is already browsing primary services on the same remote GATT Server */
4613 req_info = _bt_get_request_info_data(BT_GATT_GET_PRIMARY_SERVICES, address);
4615 BT_INFO("Already Primary Service Browsing ongoing for same rmeote GATT Server");
4616 /* Return and wait for events to be sent to all apps */
4617 return BLUETOOTH_ERROR_NONE;
4620 /* Check if remote GATT Server is connected or not */
4621 conn_info = _bt_find_remote_gatt_server_info(address);
4623 BT_ERR("GATT Server is not yet connected..");
4624 return BLUETOOTH_ERROR_NOT_CONNECTED;
4627 BT_INFO("Get all services. GATT Server [%s] is connected, conn Id [%d]",
4628 conn_info->addr + 12, conn_info->connection_id);
4630 /* Send Primary Service Browsing request to stack */
4631 ret = gattc_search_service(conn_info->connection_id, NULL);
4632 if (ret != OAL_STATUS_SUCCESS) {
4633 BT_ERR("ret: %d", ret);
4634 return _bt_convert_oal_status_to_bt_error(ret);
4636 return BLUETOOTH_ERROR_NONE;
4639 int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc)
4641 BT_CHECK_PARAMETER(svc, return);
4642 struct gatt_server_info_t *conn_info = NULL;
4643 invocation_info_t *req_info = NULL;
4644 bluetooth_gatt_client_svc_prop_info_t *prop;
4645 oal_gatt_srvc_id_t srvc_id;
4646 int ret = OAL_STATUS_SUCCESS;
4649 /* Check if any app is already browsing characteristics of the same service on the same remote GATT Server */
4650 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_SERVICE_PROPERTIES);
4652 prop = (bluetooth_gatt_client_svc_prop_info_t*)req_info->user_data;
4653 if (prop && !memcmp(svc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t))
4654 && !memcmp(prop->svc.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)
4655 && prop->svc.instance_id == svc->svc.instance_id) {
4656 BT_INFO("Already Properties browsing for Primary Service ongoing for same remote GATT Server");
4657 /* Return and wait for events to be sent to all apps */
4658 return BLUETOOTH_ERROR_NONE;
4662 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4663 _bt_convert_addr_type_to_string(addr, svc->device_address.addr);
4665 /* Check if remote GATT Server is connected or not */
4666 conn_info = _bt_find_remote_gatt_server_info(addr);
4668 BT_ERR("GATT Server is not yet connected..");
4670 return BLUETOOTH_ERROR_NOT_CONNECTED;
4673 BT_DBG("Get all charc. GATT Server [%s] is connected, conn Id [%d]",
4674 conn_info->addr, conn_info->connection_id);
4676 srvc_id.is_prmry = TRUE;
4677 srvc_id.id.inst_id = svc->svc.instance_id;
4678 memcpy(srvc_id.id.uuid.uuid, svc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4680 /* Search All Characteristic */
4681 ret = gattc_get_characteristic(conn_info->connection_id, &srvc_id, NULL);
4682 if (ret != OAL_STATUS_SUCCESS) {
4683 BT_ERR("ret: %d", ret);
4685 return _bt_convert_oal_status_to_bt_error(ret);
4688 return BLUETOOTH_ERROR_NONE;
4691 int _bt_gatt_get_all_characteristic_properties(
4692 bluetooth_gatt_client_char_prop_info_t *chr)
4694 struct gatt_server_info_t *conn_info = NULL;
4695 invocation_info_t *req_info = NULL;
4696 bluetooth_gatt_client_char_prop_info_t *prop;
4697 oal_gatt_srvc_id_t srvc_id;
4698 oal_gatt_id_t char_id;
4699 int ret = OAL_STATUS_SUCCESS;
4702 BT_CHECK_PARAMETER(chr, return);
4704 /* Check if any app is already browsing descriptors of the same char of
4705 particular service on the same remote GATT Server */
4706 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_GET_CHARACTERISTIC_PROPERTIES);
4708 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4709 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4710 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4711 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4712 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4713 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4714 BT_INFO("Already Properties browsing for Characteristic ongoing for same remote GATT Server");
4715 /* Return and wait for events to be sent to all apps */
4716 return BLUETOOTH_ERROR_NONE;
4720 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4721 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4723 /* Check if remote GATT Server is connected or not */
4724 conn_info = _bt_find_remote_gatt_server_info(addr);
4726 BT_ERR("GATT Server is not yet connected..");
4728 return BLUETOOTH_ERROR_NOT_CONNECTED;
4731 BT_DBG("Get all desc. GATT Server [%s] is connected, conn Id [%d]",
4732 conn_info->addr, conn_info->connection_id);
4734 srvc_id.is_prmry = TRUE;
4735 srvc_id.id.inst_id = chr->svc.instance_id;
4736 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4738 char_id.inst_id = chr->characteristic.instance_id;
4739 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4741 /* Search All Descriptors */
4742 ret = gattc_get_descriptor(conn_info->connection_id, &srvc_id, &char_id, NULL);
4743 if (ret != OAL_STATUS_SUCCESS) {
4744 BT_ERR("ret: %d", ret);
4746 return _bt_convert_oal_status_to_bt_error(ret);
4749 return BLUETOOTH_ERROR_NONE;
4752 int _bt_gatt_read_characteristic_value(
4753 bluetooth_gatt_client_char_prop_info_t *chr)
4755 struct gatt_server_info_t *conn_info = NULL;
4756 invocation_info_t *req_info = NULL;
4757 bluetooth_gatt_client_char_prop_info_t *prop;
4758 oal_gatt_srvc_id_t srvc_id;
4759 oal_gatt_id_t char_id;
4760 int ret = OAL_STATUS_SUCCESS;
4763 BT_CHECK_PARAMETER(chr, return);
4765 /* Check if any app is already Reading characteristic of the same char of
4766 particular service on the same remote GATT Server */
4767 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_CHARACTERISTIC);
4769 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4770 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4771 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4772 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4773 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4774 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4775 BT_INFO("Already Characteristic value Read operation in progress for same remote GATT Server");
4776 /* Return and wait for events to be sent to all apps */
4777 return BLUETOOTH_ERROR_NONE;
4781 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4782 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4784 /* Check if remote GATT Server is connected or not */
4785 conn_info = _bt_find_remote_gatt_server_info(addr);
4787 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4788 conn_info->addr, conn_info->connection_id);
4790 BT_ERR("GATT Server is not yet connected..");
4792 return BLUETOOTH_ERROR_NOT_CONNECTED;
4795 srvc_id.is_prmry = TRUE;
4796 srvc_id.id.inst_id = chr->svc.instance_id;
4797 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4799 char_id.inst_id = chr->characteristic.instance_id;
4800 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4802 /* Search All Descriptors */
4803 ret = gattc_read_characteristic(conn_info->connection_id, &srvc_id, &char_id, OAL_GATT_AUTH_REQ_NONE);
4804 if (ret != OAL_STATUS_SUCCESS) {
4805 BT_ERR("ret: %d", ret);
4807 return _bt_convert_oal_status_to_bt_error(ret);
4810 return BLUETOOTH_ERROR_NONE;
4813 int _bt_gatt_read_descriptor_value(
4814 bluetooth_gatt_client_desc_prop_info_t *desc)
4816 struct gatt_server_info_t *conn_info = NULL;
4817 invocation_info_t *req_info = NULL;
4818 bluetooth_gatt_client_desc_prop_info_t *prop;
4819 oal_gatt_srvc_id_t srvc_id;
4820 oal_gatt_id_t char_id;
4821 oal_gatt_id_t desc_id;
4822 int ret = OAL_STATUS_SUCCESS;
4825 BT_CHECK_PARAMETER(desc, return);
4827 /* Check if any app is already Reading descriptors of the same char of
4828 particular service on the same remote GATT Server */
4829 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_READ_DESCRIPTOR_VALUE);
4831 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
4832 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4833 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4834 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4835 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4836 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
4837 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
4838 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
4839 BT_INFO("Already Descriptor value Read operation in progress for same remote GATT Server");
4840 /* Return and wait for events to be sent to all apps */
4841 return BLUETOOTH_ERROR_NONE;
4845 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4846 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
4848 /* Check if remote GATT Server is connected or not */
4849 conn_info = _bt_find_remote_gatt_server_info(addr);
4851 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4852 conn_info->addr, conn_info->connection_id);
4854 BT_ERR("GATT Server is not yet connected..");
4856 return BLUETOOTH_ERROR_NOT_CONNECTED;
4859 srvc_id.is_prmry = TRUE;
4860 srvc_id.id.inst_id = desc->svc.instance_id;
4861 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4863 char_id.inst_id = desc->characteristic.instance_id;
4864 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4866 desc_id.inst_id = desc->descriptor.instance_id;
4867 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4869 /* Search All Descriptors */
4870 ret = gattc_read_descriptor(conn_info->connection_id, &srvc_id, &char_id,
4871 &desc_id, OAL_GATT_AUTH_REQ_NONE);
4872 if (ret != OAL_STATUS_SUCCESS) {
4873 BT_ERR("ret: %d", ret);
4875 return _bt_convert_oal_status_to_bt_error(ret);
4878 return BLUETOOTH_ERROR_NONE;
4882 int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
4884 struct gatt_server_info_t *conn_info = NULL;
4885 oal_gatt_srvc_id_t srvc_id;
4886 oal_gatt_id_t char_id;
4887 int ret = OAL_STATUS_SUCCESS;
4890 BT_CHECK_PARAMETER(chr, return);
4892 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4893 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4895 /* Check if remote GATT Server is connected or not */
4896 conn_info = _bt_find_remote_gatt_server_info(addr);
4898 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4899 conn_info->addr, conn_info->connection_id);
4901 BT_ERR("GATT Server is not yet connected..");
4903 return BLUETOOTH_ERROR_NOT_CONNECTED;
4906 srvc_id.is_prmry = TRUE;
4907 srvc_id.id.inst_id = chr->svc.instance_id;
4908 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4910 char_id.inst_id = chr->characteristic.instance_id;
4911 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4913 ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
4915 if (ret != OAL_STATUS_SUCCESS) {
4916 BT_ERR("ret: %d", ret);
4918 return _bt_convert_oal_status_to_bt_error(ret);
4920 BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
4922 return BLUETOOTH_ERROR_NONE;
4926 int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
4929 struct gatt_server_info_t *conn_info = NULL;
4930 oal_gatt_srvc_id_t srvc_id;
4931 oal_gatt_id_t char_id;
4932 int ret = OAL_STATUS_SUCCESS;
4935 BT_CHECK_PARAMETER(chr, return);
4937 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
4938 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
4940 /* Check if remote GATT Server is connected or not */
4941 conn_info = _bt_find_remote_gatt_server_info(addr);
4943 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
4944 conn_info->addr, conn_info->connection_id);
4946 BT_ERR("GATT Server is not yet connected..");
4948 return BLUETOOTH_ERROR_NOT_CONNECTED;
4951 srvc_id.is_prmry = TRUE;
4952 srvc_id.id.inst_id = chr->svc.instance_id;
4953 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4955 char_id.inst_id = chr->characteristic.instance_id;
4956 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
4958 ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
4959 OAL_GATT_AUTH_REQ_NONE, fd, mtu);
4960 if (ret != OAL_STATUS_SUCCESS) {
4961 BT_ERR("ret: %d", ret);
4963 return _bt_convert_oal_status_to_bt_error(ret);
4965 BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
4967 return BLUETOOTH_ERROR_NONE;
4972 /* Write Characteristic */
4973 int _bt_gatt_write_characteristic_value_by_type(
4974 bluetooth_gatt_client_char_prop_info_t *chr,
4975 bluetooth_gatt_att_data_t *data,
4976 bluetooth_gatt_write_type_e write_type)
4978 struct gatt_server_info_t *conn_info = NULL;
4979 invocation_info_t *req_info = NULL;
4980 bluetooth_gatt_client_char_prop_info_t *prop;
4981 oal_gatt_srvc_id_t srvc_id;
4982 oal_gatt_id_t char_id;
4983 int ret = OAL_STATUS_SUCCESS;
4986 BT_CHECK_PARAMETER(chr, return);
4987 BT_CHECK_PARAMETER(data, return);
4989 /* Check if any app is already writing same char of
4990 particular service on the same remote GATT Server */
4991 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE);
4993 prop = (bluetooth_gatt_client_char_prop_info_t*)req_info->user_data;
4994 if (prop && !memcmp(chr->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
4995 && !memcmp(chr->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
4996 && chr->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
4997 && !memcmp(chr->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
4998 && chr->characteristic.instance_id == prop->characteristic.instance_id) { /* Characteristic Instance ID matched */
4999 BT_INFO("Already Characteristic Write Value operation in progress for same remote GATT Server");
5000 /* Return and wait for events to be sent to all apps */
5001 return BLUETOOTH_ERROR_NONE;
5005 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5006 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5008 /* Check if remote GATT Server is connected or not */
5009 conn_info = _bt_find_remote_gatt_server_info(addr);
5011 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5012 conn_info->addr, conn_info->connection_id);
5014 BT_ERR("GATT Server is not yet connected..");
5016 return BLUETOOTH_ERROR_NOT_CONNECTED;
5019 srvc_id.is_prmry = TRUE;
5020 srvc_id.id.inst_id = chr->svc.instance_id;
5021 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5023 char_id.inst_id = chr->characteristic.instance_id;
5024 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5026 /* Write CHar value */
5027 ret = gattc_write_characteristic(conn_info->connection_id,
5029 (oal_gatt_write_type_t)write_type, data->length,
5030 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5031 if (ret != OAL_STATUS_SUCCESS) {
5032 BT_ERR("ret: %d", ret);
5034 return _bt_convert_oal_status_to_bt_error(ret);
5037 return BLUETOOTH_ERROR_NONE;
5040 /* Write Descriptor */
5041 int _bt_gatt_write_descriptor_value_by_type(
5042 bluetooth_gatt_client_desc_prop_info_t *desc,
5043 bluetooth_gatt_att_data_t *data,
5044 bluetooth_gatt_write_type_e write_type)
5046 struct gatt_server_info_t *conn_info = NULL;
5047 invocation_info_t *req_info = NULL;
5048 bluetooth_gatt_client_desc_prop_info_t *prop;
5049 oal_gatt_srvc_id_t srvc_id;
5050 oal_gatt_id_t char_id;
5051 oal_gatt_id_t desc_id;
5052 int ret = OAL_STATUS_SUCCESS;
5056 BT_CHECK_PARAMETER(desc, return);
5057 BT_CHECK_PARAMETER(data, return);
5061 /* Check if any app is already writing on same Descriptor of the same char of
5062 particular service on the same remote GATT Server */
5063 req_info = _bt_get_request_info_data_from_function_name(BT_GATT_WRITE_DESCRIPTOR_VALUE);
5065 prop = (bluetooth_gatt_client_desc_prop_info_t*)req_info->user_data;
5066 if (prop && !memcmp(desc->device_address.addr, prop->device_address.addr, sizeof(bluetooth_device_address_t)) /* Address matched */
5067 && !memcmp(desc->svc.uuid, prop->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Service UUID matched */
5068 && desc->svc.instance_id == prop->svc.instance_id /* Service Instance ID matched */
5069 && !memcmp(desc->characteristic.uuid, prop->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Characteristic UUID matched */
5070 && desc->characteristic.instance_id == prop->characteristic.instance_id /* Characteristic Instance ID matched */
5071 && !memcmp(desc->descriptor.uuid, prop->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN) /* Descriptor UUID matched */
5072 && desc->descriptor.instance_id == prop->descriptor.instance_id) { /* Descriptor Instance ID matched */
5073 BT_INFO("Already Descriptor value Write operation in progress for same remote GATT Server");
5074 /* Return and wait for events to be sent to all apps */
5075 return BLUETOOTH_ERROR_NONE;
5079 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5080 _bt_convert_addr_type_to_string(addr, desc->device_address.addr);
5082 /* Check if remote GATT Server is connected or not */
5083 conn_info = _bt_find_remote_gatt_server_info(addr);
5085 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5086 conn_info->addr, conn_info->connection_id);
5088 BT_ERR("GATT Server is not yet connected..");
5090 return BLUETOOTH_ERROR_NOT_CONNECTED;
5093 srvc_id.is_prmry = TRUE;
5094 srvc_id.id.inst_id = desc->svc.instance_id;
5095 memcpy(srvc_id.id.uuid.uuid, desc->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5097 char_id.inst_id = desc->characteristic.instance_id;
5098 memcpy(char_id.uuid.uuid, desc->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5100 desc_id.inst_id = desc->descriptor.instance_id;
5101 memcpy(desc_id.uuid.uuid, desc->descriptor.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5104 BT_INFO("Connection ID [%d] write type [%d] data length [%d]", conn_info->connection_id, write_type, data->length);
5105 for (k = 0; k < data->length; k++)
5106 BT_INFO("Data[%d] [0x%x]", k, data->data[k]);
5108 ret = gattc_write_descriptor(conn_info->connection_id,
5109 &srvc_id, &char_id, &desc_id,
5110 (oal_gatt_write_type_t)write_type, data->length,
5111 OAL_GATT_AUTH_REQ_NONE, (char *)(&data->data[0]));
5112 if (ret != OAL_STATUS_SUCCESS) {
5113 BT_ERR("ret: %d", ret);
5115 return _bt_convert_oal_status_to_bt_error(ret);
5118 return BLUETOOTH_ERROR_NONE;
5121 int _bt_gatt_watch_characteristic(
5122 bluetooth_gatt_client_char_prop_info_t *chr,
5126 struct gatt_server_info_t *conn_info = NULL;
5127 oal_gatt_srvc_id_t srvc_id;
5128 oal_gatt_id_t char_id;
5129 int ret = OAL_STATUS_SUCCESS;
5132 BT_CHECK_PARAMETER(chr, return);
5134 BT_INFO("Client ID [%d] Is Notify [%d]", client_id, is_notify);
5136 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5137 _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
5139 /* Check if remote GATT Server is connected or not */
5140 conn_info = _bt_find_remote_gatt_server_info(addr);
5142 BT_DBG("GATT Server [%s] is connected, conn Id [%d]",
5143 conn_info->addr, conn_info->connection_id);
5145 BT_ERR("GATT Server is not yet connected..");
5147 return BLUETOOTH_ERROR_NOT_CONNECTED;
5149 srvc_id.is_prmry = TRUE;
5150 srvc_id.id.inst_id = chr->svc.instance_id;
5151 memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5153 char_id.inst_id = chr->characteristic.instance_id;
5154 memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
5156 /* Register or unregister Notification characteristic */
5158 ret = gattc_register_for_notification(conn_info->connection_id,
5159 (bt_address_t*)&(chr->device_address),
5160 &srvc_id, &char_id);
5162 ret = gattc_deregister_for_notification(conn_info->connection_id,
5163 (bt_address_t*)&(chr->device_address),
5164 &srvc_id, &char_id);
5166 BT_INFO("Result[%d]", ret);
5167 if (ret != OAL_STATUS_SUCCESS) {
5168 BT_ERR("ret: %d", ret);
5170 return _bt_convert_oal_status_to_bt_error(ret);
5173 return BLUETOOTH_ERROR_NONE;
5177 int _bt_disconnect_le_device(bluetooth_device_address_t *address,
5180 struct gatt_server_info_t *conn_info = NULL;
5181 struct gatt_client_info_t *rem_client_conn_info = NULL;
5182 invocation_info_t *req_info = NULL;
5183 int ret = OAL_STATUS_SUCCESS;
5185 char *remote_address = NULL;
5187 BT_CHECK_PARAMETER(address, return);
5189 addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
5190 _bt_convert_addr_type_to_string(addr, address->addr);
5191 BT_INFO("GATT Client Disconnect request for address [%s]", addr + 12);
5193 /* Check if Remote Device is already under connection progress */
5194 req_info = _bt_get_request_info_data_from_function_name(BT_DISCONNECT_LE);
5196 remote_address = (char*)req_info->user_data;
5197 if (remote_address && !strcasecmp(remote_address, addr)) {/* Address matched */
5198 BT_DBG("Already DisConnection ongoing for same remote GATT Server address [%s]", remote_address);
5199 /* Return success and wait for events to be sent to all apps */
5201 return BLUETOOTH_ERROR_IN_PROGRESS;
5204 /* Check if remote GATT Server is connected or not */
5205 conn_info = _bt_find_remote_gatt_server_info(addr);
5207 /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
5208 if (client_id == 0) {
5209 BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
5211 BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
5212 client_id = gatt_default_client;
5215 BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
5216 ret = gattc_disconnect(client_id, (bt_address_t*)(address),
5217 conn_info->connection_id);
5219 /* check if remote client is connected */
5220 rem_client_conn_info = _bt_find_remote_gatt_client_info(addr);
5222 if (!rem_client_conn_info || client_id != 0) {
5223 BT_ERR("GATT device is not connected..");
5225 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
5228 BT_INFO("Disconnect remote gatt client ");
5230 ret = gatts_disconnect(rem_client_conn_info->instance_id,
5231 (bt_address_t*)(address), rem_client_conn_info->connection_id);
5234 if (ret != OAL_STATUS_SUCCESS) {
5235 BT_ERR("ret: %d", ret);
5237 return _bt_convert_oal_status_to_bt_error(ret);
5240 return BLUETOOTH_ERROR_NONE;
5243 int _bt_gatt_watch_service_changed_indication(const char *sender,
5244 bluetooth_device_address_t *address,
5245 gboolean is_enabled)
5248 bt_service_app_info_t *info = NULL;
5250 BT_INFO("%s Servic changed Indication watcher for app [%s]",
5251 is_enabled ? "Enable":"Disable", sender);
5253 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5256 if (g_strcmp0(sender, info->sender) == 0 &&
5257 memcmp(info->address.addr, address->addr,
5258 sizeof(bluetooth_device_address_t)) == 0) {
5259 BT_DBG("Found GATT client App.. [%s], sender [%s]", info->uuid, info->sender);
5260 info->is_watcher_enabled = is_enabled;
5264 return BLUETOOTH_ERROR_NONE;
5267 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
5269 bt_service_app_info_t *info = NULL;
5272 BT_DBG("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
5274 /* Unregister CLient instance associated with address X. It is possible that another app still
5275 has client_id valid for same remote address */
5276 for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
5279 /* Exact matching of sender */
5280 if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) { /* Check for only valid GATT client Instance */
5281 numapps[k].client_id = -1;
5282 numapps[k].is_initialized = FALSE;
5283 memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
5284 memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
5285 memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
5287 /* Its a GATT Client Instance */
5288 ret = gattc_deregister(client_id);
5289 if (ret != OAL_STATUS_SUCCESS) {
5290 BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
5291 return _bt_convert_oal_status_to_bt_error(ret);
5293 return BLUETOOTH_ERROR_NONE;
5298 return BLUETOOTH_ERROR_NOT_FOUND;
5301 static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data)
5303 int result = BLUETOOTH_ERROR_NONE;
5304 struct gatt_server_info_t *conn_info = NULL;
5305 GVariant *param = NULL;
5309 conn_info = __bt_find_remote_gatt_server_info_from_conn_id(event_data->conn_id);
5310 if (conn_info == NULL) {
5311 BT_ERR("Cant find connection Information");
5315 BT_DBG("GATT Client: MTU Configured from addr [%s] status [%d] MTU size [%d]",
5316 conn_info->addr, event_data->status, event_data->mtu);
5318 if (event_data->status != OAL_STATUS_SUCCESS)
5319 result = BLUETOOTH_ERROR_INTERNAL;
5321 /* DBUS Return fo BT_REQ_ATT_MTU for all the apps */
5322 __bt_gatt_handle_pending_request_info(result, BT_REQ_ATT_MTU, conn_info->addr,
5323 BT_ADDRESS_STRING_SIZE);
5325 if (result == BLUETOOTH_ERROR_NONE) {
5326 mtu = event_data->mtu;
5327 param = g_variant_new("(isqy)",
5333 /* Send event to BT-API */
5334 _bt_send_event(BT_DEVICE_EVENT,
5335 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
5338 /* Update the MTU for current connection */
5339 __bt_update_mtu_gatt_device(conn_info->addr, event_data->mtu);
5343 static struct gatt_mtu_info_t *__bt_find_mtu_gatt_device(char *address)
5346 struct gatt_mtu_info_t *info = NULL;
5348 for (l = gatt_mtu_info_list; l != NULL; l = g_slist_next(l)) {
5349 info = (struct gatt_mtu_info_t*)l->data;
5353 if (!g_strcmp0(info->addr, address)) {
5354 BT_DBG("Remote GATT device found addr[%s]", info->addr);
5359 BT_DBG("Not found Remote GATT device addr[%s]", address);
5363 static void __bt_remove_mtu_gatt_device(char *address)
5365 struct gatt_mtu_info_t *dev_info = NULL;
5367 dev_info = __bt_find_mtu_gatt_device(address);
5370 BT_DBG("removing the gatt device from mtu list");
5371 gatt_mtu_info_list = g_slist_remove(gatt_mtu_info_list, dev_info);
5372 g_free(dev_info->addr);
5377 static void __bt_add_mtu_gatt_device(char *address)
5379 struct gatt_mtu_info_t *dev_info = NULL;
5381 dev_info = __bt_find_mtu_gatt_device(address);
5384 BT_DBG("adding the gatt device in mtu list");
5385 dev_info = g_new0(struct gatt_mtu_info_t, 1);
5386 dev_info->addr = g_strdup(address);
5387 dev_info->att_mtu = BT_DEFAULT_ATT_MTU;
5388 gatt_mtu_info_list = g_slist_append(gatt_mtu_info_list, dev_info);
5392 static void __bt_update_mtu_gatt_device(char *address, int mtu)
5394 struct gatt_mtu_info_t *dev_info = NULL;
5396 dev_info = __bt_find_mtu_gatt_device(address);
5399 dev_info->att_mtu = mtu;
5403 int _bt_gatt_get_data_batching_available_packets(
5404 guint *available_packets)
5406 int ret = OAL_STATUS_SUCCESS;
5408 BT_CHECK_PARAMETER(available_packets, return);
5410 ret = gatt_get_data_batching_available_packets(available_packets);
5411 if (ret != OAL_STATUS_SUCCESS) {
5412 BT_ERR("ret: %d", ret);
5413 return _bt_convert_oal_status_to_bt_error(ret);
5416 return BLUETOOTH_ERROR_NONE;
5419 int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address,
5420 int packet_threshold, int timeout)
5422 int ret = OAL_STATUS_SUCCESS;
5423 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5425 BT_CHECK_PARAMETER(address, return);
5427 _bt_convert_addr_type_to_string(remote_address, address->addr);
5428 BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]",
5429 remote_address, packet_threshold, timeout);
5431 ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout);
5433 if (ret != OAL_STATUS_SUCCESS) {
5434 BT_ERR("ret: %d", ret);
5435 return _bt_convert_oal_status_to_bt_error(ret);
5438 return BLUETOOTH_ERROR_NONE;
5441 int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address)
5443 int ret = OAL_STATUS_SUCCESS;
5444 char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
5446 BT_CHECK_PARAMETER(address, return);
5448 _bt_convert_addr_type_to_string(remote_address, address->addr);
5449 BT_INFO("Disable GATT data batching. address[%s]", remote_address);
5451 ret = gatt_disable_data_batching((bt_address_t*)(address));
5453 if (ret != OAL_STATUS_SUCCESS) {
5454 BT_ERR("ret: %d", ret);
5455 return _bt_convert_oal_status_to_bt_error(ret);
5458 return BLUETOOTH_ERROR_NONE;