4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
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 /*******************************************************************************
25 * Description: GATT Profile Bluetooth Interface
27 *******************************************************************************/
29 #include <hardware/bluetooth.h>
30 #include <hardware/bt_gatt.h>
38 #include "bt-hal-log.h"
39 #include "bt-hal-msg.h"
40 #include "bt-hal-utils.h"
42 #include "bt-hal-adapter-le.h"
43 #include "bt-hal-gatt-server.h"
44 #include "bt-hal-gatt-client.h"
45 #include "bt_gatt_types.h"
47 /* Advertising report event types */
48 #define BT_LE_ADV_IND 0x00
49 #define BT_LE_ADV_DIRECT_IND 0x01
50 #define BT_LE_ADV_SCAN_IND 0x02
51 #define BT_LE_ADV_NONCONN_IND 0x03
52 #define BT_LE_ADV_SCAN_RSP 0x04
54 #define BT_HAL_ADV_DATA_MAX_SIZE 31
55 #define BT_HAL_GATTC_READ_VALUE_TYPE_VALUE 0x0000 /* Attribute value itself */
62 uint8_t data[BT_HAL_ADV_DATA_MAX_SIZE * 2];
64 } bt_hal_le_adv_info_t;
66 /****************************************** Global Variables ******************************************/
67 const btgatt_callbacks_t *bt_gatt_callbacks = NULL;
69 extern btgatt_client_interface_t btgatt_client_interface;
70 extern btgatt_server_interface_t btgatt_server_interface;
72 static GSList *adv_ind_list = NULL;
73 /****************************************** Forward Declarations *************************************/
74 static void __bt_handle_gatt_client_registered(void *buf, uint16_t len);
75 static void __bt_hal_handle_gatt_client_scan_result(void *buf, uint16_t len);
76 static void __bt_handle_gatt_client_connected(void *buf, uint16_t len);
77 static void __bt_handle_gatt_client_disconnected(void *buf, uint16_t len);
78 static void __bt_handle_gatt_client_search_result(void *buf, uint16_t len);
79 static void __bt_handle_gatt_client_search_complete(void *buf, uint16_t len);
80 static void __bt_handle_gatt_client_search_char_result(void *buf, uint16_t len);
81 static void __bt_handle_gatt_client_search_desc_result(void *buf, uint16_t len);
82 static void __bt_handle_gatt_client_read_charac(void *buf, uint16_t len);
83 static void __bt_handle_gatt_client_read_desc(void *buf, uint16_t len);
84 static void __bt_handle_gatt_client_write_char(void *buf, uint16_t len);
85 static void __bt_handle_gatt_client_write_desc(void *buf, uint16_t len);
86 static void __bt_handle_gatt_client_watch_notification(void *buf, uint16_t len);
87 static void __bt_handle_gatt_client_changed_value(void *buf, uint16_t len);
88 static void __bt_hal_handle_gatt_client_service_changed(void *buf, uint16_t len);
89 static void __bt_hal_handle_gatt_client_mtu_exchange_completed(void *buf, uint16_t len);
90 /*****************************************************************************************************/
92 static bool interface_ready(void)
94 return bt_gatt_callbacks != NULL;
97 static void __bt_hal_handle_server_instance_initialized(void *buf, uint16_t len)
99 struct hal_ev_server_instance_registered *ev = buf;
101 if (bt_gatt_callbacks->server->register_server_cb)
102 bt_gatt_callbacks->server->register_server_cb(ev->status, ev->server_instance, (bt_uuid_t*)&ev->app_uuid);
105 static void __bt_hal_handle_multi_adv_data_set(void *buf, uint16_t len)
107 struct hal_ev_multi_adv_data_set *ev = buf;
109 if (bt_gatt_callbacks->server->multi_adv_data_cb)
110 bt_gatt_callbacks->server->multi_adv_data_cb(ev->server_instance, ev->status);
113 static void __bt_hal_handle_multi_adv_data_update(void *buf, uint16_t len)
115 struct hal_ev_multi_adv_update *ev = buf;
117 if (bt_gatt_callbacks->server->multi_adv_update_cb)
118 bt_gatt_callbacks->server->multi_adv_update_cb(ev->server_instance, ev->status);
121 static void __bt_hal_handle_multi_adv_enable(void *buf, uint16_t len)
123 struct hal_ev_multi_adv_enable *ev = buf;
125 if (bt_gatt_callbacks->server->multi_adv_enable_cb)
126 bt_gatt_callbacks->server->multi_adv_enable_cb(ev->server_instance, ev->status);
129 static void __bt_hal_handle_multi_adv_disable(void *buf, uint16_t len)
131 struct hal_ev_multi_adv_disable *ev = buf;
133 if (bt_gatt_callbacks->server->multi_adv_disable_cb)
134 bt_gatt_callbacks->server->multi_adv_disable_cb(ev->server_instance, ev->status);
137 /* Same callback for both Enable and DIsable */
138 static void __bt_hal_handle_legacy_adv_status(void *buf, uint16_t len)
140 struct hal_ev_legacy_adv_status *ev = buf;
142 if (bt_gatt_callbacks->server->listen_cb)
143 bt_gatt_callbacks->server->listen_cb(ev->status, ev->server_instance);
146 static void __bt_hal_handle_service_added(void *buf, uint16_t len)
148 struct hal_ev_gatt_service_added *ev = buf;
149 btgatt_srvc_id_t srvc_id;
151 memset(&srvc_id, 0x00, sizeof(btgatt_srvc_id_t));
152 srvc_id.is_primary = ev->is_primary;
153 srvc_id.id.inst_id = ev->server_instance;
154 memcpy(srvc_id.id.uuid.uu, ev->svc_uuid, sizeof(ev->svc_uuid));
156 if (bt_gatt_callbacks->server->service_added_cb)
157 bt_gatt_callbacks->server->service_added_cb(ev->status, ev->server_instance,
158 &srvc_id, ev->service_handle);
161 static void __bt_hal_handle_char_added(void *buf, uint16_t len)
163 struct hal_ev_gatt_char_added *ev = buf;
166 memcpy(uuid.uu, ev->char_uuid, sizeof(ev->char_uuid));
168 if (bt_gatt_callbacks->server->characteristic_added_cb)
169 bt_gatt_callbacks->server->characteristic_added_cb(ev->status, ev->server_instance,
170 &uuid, ev->service_handle, ev->char_handle);
173 static void __bt_hal_handle_desc_added(void *buf, uint16_t len)
175 struct hal_ev_gatt_desc_added *ev = buf;
178 memcpy(uuid.uu, ev->desc_uuid, sizeof(ev->desc_uuid));
180 if (bt_gatt_callbacks->server->descriptor_added_cb)
181 bt_gatt_callbacks->server->descriptor_added_cb(ev->status, ev->server_instance,
182 &uuid, ev->service_handle, ev->desc_handle);
185 static void __bt_hal_handle_service_started(void *buf, uint16_t len)
187 struct hal_ev_gatt_service_started *ev = buf;
189 if (bt_gatt_callbacks->server->service_started_cb)
190 bt_gatt_callbacks->server->service_started_cb(ev->status, ev->server_instance,
194 static void __bt_hal_handle_service_deleted(void *buf, uint16_t len)
196 struct hal_ev_gatt_service_deleted *ev = buf;
198 if (bt_gatt_callbacks->server->service_deleted_cb)
199 bt_gatt_callbacks->server->service_deleted_cb(ev->status, ev->server_instance,
203 static void __bt_hal_handle_gatt_server_connected(void *buf, uint16_t len)
205 struct hal_ev_gatt_server_connected *ev = buf;
208 memcpy(bd_addr.address, ev->bdaddr, 6);
210 if (bt_gatt_callbacks->server->connection_cb)
211 bt_gatt_callbacks->server->connection_cb(ev->conn_id, ev->server_instance,
212 ev->connected, &bd_addr);
215 static void __bt_hal_handle_gatt_server_notification_changed(void *buf, uint16_t len)
217 struct hal_ev_gatt_server_notifcation_change *ev = buf;
220 memcpy(bd_addr.address, ev->bdaddr, 6);
222 if (bt_gatt_callbacks->server->notif_enabled_cb)
223 bt_gatt_callbacks->server->notif_enabled_cb(ev->conn_id, ev->trans_id,
224 ev->att_handle, ev->notify, &bd_addr);
227 static void __bt_hal_handle_gatt_server_read_requested(void *buf, uint16_t len)
229 struct hal_ev_gatt_server_read_req *ev = buf;
232 memcpy(bd_addr.address, ev->bdaddr, 6);
234 if (bt_gatt_callbacks->server->request_read_cb)
235 bt_gatt_callbacks->server->request_read_cb(ev->conn_id, ev->trans_id, &bd_addr,
236 ev->att_handle, ev->offset, ev->is_long);
239 static void __bt_hal_handle_gatt_server_write_requested(void *buf, uint16_t len)
241 struct hal_ev_gatt_server_write_req *ev = buf;
243 if (bt_gatt_callbacks->server->request_write_cb)
244 bt_gatt_callbacks->server->request_write_cb(ev->conn_id, ev->trans_id,
245 (bt_bdaddr_t *) ev->bdaddr,
246 ev->att_handle, ev->offset,
247 ev->length, ev->need_rsp,
248 ev->is_prep, ev->value);
251 static void __bt_hal_handle_gatt_server_acquire_write_requested(void *buf, uint16_t len)
253 struct hal_ev_gatt_server_acquire_write_res *ev = buf;
255 DBG("acquire write requested event recived");
257 if (bt_gatt_callbacks->server->request_acquire_write_cb)
258 bt_gatt_callbacks->server->request_acquire_write_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl, (bt_bdaddr_t *)ev->bdaddr);
261 static void __bt_hal_handle_gatt_server_acquire_notify_requested(void *buf, uint16_t len)
263 struct hal_ev_gatt_server_acquire_notify *ev = buf;
265 DBG("acquire notify requested event recived");
267 if (bt_gatt_callbacks->server->request_acquire_notify_cb)
268 bt_gatt_callbacks->server->request_acquire_notify_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl);
271 static void __bt_hal_handle_gatt_server_indicate_confirmed(void *buf, uint16_t len)
273 struct hal_ev_gatt_server_indicate_cfm *ev = buf;
275 if (bt_gatt_callbacks->server->indication_confirmation_cb)
276 bt_gatt_callbacks->server->indication_confirmation_cb(ev->conn_id, ev->trans_id,
277 ev->att_handle, (bt_bdaddr_t *) ev->bdaddr);
281 static void __bt_hal_handle_gatt_server_mtu_changed(void *buf, uint16_t len)
283 struct hal_ev_gatt_server_mtu_changed *ev = buf;
285 DBG("GATT Server MTU changed event recived");
287 if (bt_gatt_callbacks->server->mtu_changed_cb)
288 bt_gatt_callbacks->server->mtu_changed_cb(ev->conn_id, ev->mtu);
291 static void __bt_hal_gatt_events(int message, void *buf, uint16_t len)
293 DBG("GATT event 0x%x", message);
294 /* Check if GATT interface is Ready */
295 if (!interface_ready())
299 case HAL_EV_SERVER_INSTANCE_INITIALIZED: {
300 __bt_hal_handle_server_instance_initialized(buf, len);
303 case HAL_EV_MULTI_ADV_ENABLE: {
304 __bt_hal_handle_multi_adv_enable(buf, len);
307 case HAL_EV_MULTI_ADV_DISABLE: {
308 __bt_hal_handle_multi_adv_disable(buf, len);
311 case HAL_EV_MULTI_ADV_DATA_SET: {
312 __bt_hal_handle_multi_adv_data_set(buf, len);
315 case HAL_EV_MULTI_ADV_UPDATE: {
316 __bt_hal_handle_multi_adv_data_update(buf, len);
319 case HAL_EV_LEGACY_ADV_ENABLE: {
320 __bt_hal_handle_legacy_adv_status(buf, len);
323 case HAL_EV_GATT_CLIENT_REGISTERED: {
324 __bt_handle_gatt_client_registered(buf, len);
327 case HAL_EV_GATT_CLIENT_SCAN_RESULT: {
328 __bt_hal_handle_gatt_client_scan_result(buf, len);
331 case HAL_EV_GATT_SERVICE_ADDED: {
332 __bt_hal_handle_service_added(buf, len);
335 case HAL_EV_GATT_CHAR_ADDED: {
336 __bt_hal_handle_char_added(buf, len);
339 case HAL_EV_GATT_DESC_ADDED: {
340 __bt_hal_handle_desc_added(buf, len);
343 case HAL_EV_GATT_SERVICE_STARTED: {
344 __bt_hal_handle_service_started(buf, len);
347 case HAL_EV_GATT_SERVICE_DELETED: {
348 __bt_hal_handle_service_deleted(buf, len);
351 case HAL_EV_GATT_SERVER_CONNECTED: {
352 __bt_hal_handle_gatt_server_connected(buf, len);
355 case HAL_EV_GATT_NOTIFICATION_CHANGE: {
356 __bt_hal_handle_gatt_server_notification_changed(buf, len);
359 case HAL_EV_GATT_READ_REQUESTED: {
360 __bt_hal_handle_gatt_server_read_requested(buf, len);
363 case HAL_EV_GATT_WRITE_REQUESTED: {
364 __bt_hal_handle_gatt_server_write_requested(buf, len);
367 case HAL_EV_GATT_INDICATE_CFM: {
368 __bt_hal_handle_gatt_server_indicate_confirmed(buf, len);
371 case HAL_EV_GATT_CLIENT_CONNECTED: {
372 __bt_handle_gatt_client_connected(buf, len);
375 case HAL_EV_GATT_CLIENT_DISCONNECTED: {
376 __bt_handle_gatt_client_disconnected(buf, len);
379 case HAL_EV_GATT_CLIENT_SEARCH_RESULT: {
380 __bt_handle_gatt_client_search_result(buf, len);
383 case HAL_EV_GATT_CLIENT_SEARCH_COMPLETE: {
384 __bt_handle_gatt_client_search_complete(buf, len);
387 case HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT: {
388 __bt_handle_gatt_client_search_char_result(buf, len);
391 case HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT: {
392 __bt_handle_gatt_client_search_desc_result(buf, len);
395 case HAL_EV_GATT_CLIENT_READ_CHARAC: {
396 __bt_handle_gatt_client_read_charac(buf, len);
399 case HAL_EV_GATT_CLIENT_READ_DESC: {
400 __bt_handle_gatt_client_read_desc(buf, len);
403 case HAL_EV_GATT_CLIENT_WRITE_CHARAC: {
404 __bt_handle_gatt_client_write_char(buf, len);
407 case HAL_EV_GATT_CLIENT_WRITE_DESC: {
408 __bt_handle_gatt_client_write_desc(buf, len);
411 case HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION: {
412 __bt_handle_gatt_client_watch_notification(buf, len);
415 case HAL_EV_GATT_CLIENT_NOTIFY_CHANGED_VALUE: {
416 __bt_handle_gatt_client_changed_value(buf, len);
419 case HAL_EV_GATT_CLIENT_SERVICE_CHANGED: {
420 __bt_hal_handle_gatt_client_service_changed(buf, len);
423 case HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES:{
424 __bt_hal_handle_gatt_server_acquire_write_requested(buf, len);
427 case HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES:{
428 __bt_hal_handle_gatt_server_acquire_notify_requested(buf, len);
431 case HAL_EV_GATT_SERVER_MTU_CHANGED:{
432 __bt_hal_handle_gatt_server_mtu_changed(buf, len);
436 case HAL_EV_GATT_CLIENT_MTU_EXCHANGE_COMPLETED:{
437 __bt_hal_handle_gatt_client_mtu_exchange_completed(buf, len);
441 DBG("Event Currently not handled!!");
446 /************************************* GATT CLIENT EVENTS ****************************************/
447 static void __bt_handle_gatt_client_registered(void *buf, uint16_t len)
449 struct hal_ev_gatt_client_registered *ev = buf;
452 memcpy(uuid.uu, ev->app_uuid, 16);
453 if (bt_gatt_callbacks->client->register_client_cb)
454 bt_gatt_callbacks->client->register_client_cb(
455 ev->status, ev->client_if, &uuid);
458 static void __bt_hal_send_le_scan_result_event(bt_hal_le_adv_info_t *adv_info)
462 str2bt_bdaddr_t(adv_info->addr, &bd_addr);
463 if (bt_gatt_callbacks->client->scan_result_cb)
464 bt_gatt_callbacks->client->scan_result_cb(
465 &bd_addr, adv_info->rssi, adv_info->data);
468 static void __bt_handle_gatt_client_connected(void *buf, uint16_t len)
470 struct hal_ev_gatt_client_connected *ev = buf;
473 memcpy(bd_addr.address, ev->bdaddr, 6);
474 if (bt_gatt_callbacks->client->open_cb)
475 bt_gatt_callbacks->client->open_cb(ev->conn_id,
476 ev->status, ev->client_if, &bd_addr);
479 static void __bt_handle_gatt_client_disconnected(void *buf, uint16_t len)
481 struct hal_ev_gatt_client_connected *ev = buf;
484 memcpy(bd_addr.address, ev->bdaddr, 6);
485 if (bt_gatt_callbacks->client->close_cb)
486 bt_gatt_callbacks->client->close_cb(ev->conn_id,
487 ev->status, ev->client_if, &bd_addr);
490 static void __bt_handle_gatt_client_search_result(void *buf, uint16_t len)
492 struct hal_ev_gatt_client_search_result *ev = buf;
493 btgatt_srvc_id_t gatt_srvc_id;
495 gatt_srvc_id.is_primary = ev->is_primary;
496 gatt_srvc_id.id.inst_id = ev->inst_id;
497 memcpy(gatt_srvc_id.id.uuid.uu, ev->uuid, 16);
499 if (bt_gatt_callbacks->client->search_result_cb)
500 bt_gatt_callbacks->client->search_result_cb(ev->conn_id,
504 static void __bt_handle_gatt_client_search_complete(void *buf, uint16_t len)
506 struct hal_ev_gatt_client_search_complete *ev = buf;
508 if (bt_gatt_callbacks->client->search_complete_cb)
509 bt_gatt_callbacks->client->search_complete_cb(ev->conn_id,
513 static void __bt_handle_gatt_client_search_char_result(void *buf, uint16_t len)
515 struct hal_ev_gatt_client_char_search_result *ev = buf;
516 btgatt_srvc_id_t gatt_srvc_id;
517 btgatt_gatt_id_t gatt_char_id;
519 gatt_srvc_id.is_primary = ev->is_primary;
520 gatt_srvc_id.id.inst_id = ev->inst_id;
521 memcpy(gatt_srvc_id.id.uuid.uu, ev->svc_uuid, 16);
523 if (BT_STATUS_SUCCESS == ev->status) {
524 memcpy(gatt_char_id.uuid.uu, ev->char_uuid, 16);
525 gatt_char_id.inst_id = ev->inst_id;
528 if (bt_gatt_callbacks->client->get_characteristic_cb)
529 bt_gatt_callbacks->client->get_characteristic_cb(ev->conn_id,
530 ev->status, &gatt_srvc_id, &gatt_char_id, ev->char_prop);
533 static void __bt_handle_gatt_client_search_desc_result(void *buf, uint16_t len)
535 struct hal_ev_gatt_client_desc_search_result *ev = buf;
536 btgatt_srvc_id_t gatt_srvc_id;
537 btgatt_gatt_id_t gatt_char_id;
538 btgatt_gatt_id_t gatt_desc_id;
541 gatt_srvc_id.is_primary = ev->is_primary;
542 gatt_srvc_id.id.inst_id = ev->inst_id;
543 memcpy(gatt_srvc_id.id.uuid.uu, ev->svc_uuid, 16);
545 memcpy(gatt_char_id.uuid.uu, ev->char_uuid, 16);
546 gatt_char_id.inst_id = ev->inst_id;
548 if (BT_STATUS_SUCCESS == ev->status) {
549 memcpy(gatt_desc_id.uuid.uu, ev->desc_uuid, 16);
550 gatt_desc_id.inst_id = ev->inst_id;
553 if (bt_gatt_callbacks->client->get_descriptor_cb)
554 bt_gatt_callbacks->client->get_descriptor_cb(ev->conn_id,
555 ev->status, &gatt_srvc_id, &gatt_char_id, &gatt_desc_id);
558 static void __bt_handle_gatt_client_read_charac(void *buf, uint16_t len)
560 struct hal_ev_gatt_client_read_data *ev = buf;
561 btgatt_read_params_t char_read_parm;
563 char_read_parm.srvc_id.is_primary = ev->is_primary;
564 char_read_parm.srvc_id.id.inst_id = ev->inst_id;
565 memcpy(char_read_parm.srvc_id.id.uuid.uu, ev->svc_uuid, 16);
567 char_read_parm.char_id.inst_id = ev->inst_id;
568 memcpy(char_read_parm.char_id.uuid.uu, ev->char_uuid, 16);
570 char_read_parm.value.len = ev->len;
572 memcpy(char_read_parm.value.value, ev->value, ev->len);
573 char_read_parm.value_type = BT_HAL_GATTC_READ_VALUE_TYPE_VALUE;
576 if (bt_gatt_callbacks->client->read_characteristic_cb)
577 bt_gatt_callbacks->client->read_characteristic_cb(ev->conn_id,
578 ev->status, &char_read_parm);
581 static void __bt_handle_gatt_client_read_desc(void *buf, uint16_t len)
583 struct hal_ev_gatt_client_read_data *ev = buf;
584 btgatt_read_params_t desc_read_parm;
586 desc_read_parm.srvc_id.is_primary = ev->is_primary;
587 desc_read_parm.srvc_id.id.inst_id = ev->inst_id;
588 memcpy(desc_read_parm.srvc_id.id.uuid.uu, ev->svc_uuid, 16);
590 desc_read_parm.char_id.inst_id = ev->inst_id;
591 memcpy(desc_read_parm.char_id.uuid.uu, ev->char_uuid, 16);
593 desc_read_parm.descr_id.inst_id = ev->inst_id;
594 memcpy(desc_read_parm.descr_id.uuid.uu, ev->desc_uuid, 16);
596 desc_read_parm.value.len = ev->len;
598 memcpy(desc_read_parm.value.value, ev->value, ev->len);
599 desc_read_parm.value_type = BT_HAL_GATTC_READ_VALUE_TYPE_VALUE;
602 if (bt_gatt_callbacks->client->read_descriptor_cb)
603 bt_gatt_callbacks->client->read_descriptor_cb(ev->conn_id,
604 ev->status, &desc_read_parm);
607 static void __bt_handle_gatt_client_write_char(void *buf, uint16_t len)
609 struct hal_ev_gatt_client_write_result *ev = buf;
610 btgatt_write_params_t char_write_parm;
612 char_write_parm.srvc_id.is_primary = ev->is_primary;
613 char_write_parm.srvc_id.id.inst_id = ev->inst_id;
614 memcpy(char_write_parm.srvc_id.id.uuid.uu, ev->svc_uuid, 16);
616 char_write_parm.char_id.inst_id = ev->inst_id;
617 memcpy(char_write_parm.char_id.uuid.uu, ev->char_uuid, 16);
619 if (bt_gatt_callbacks->client->write_characteristic_cb)
620 bt_gatt_callbacks->client->write_characteristic_cb(ev->conn_id,
621 ev->status, &char_write_parm);
624 static void __bt_handle_gatt_client_write_desc(void *buf, uint16_t len)
626 struct hal_ev_gatt_client_write_result *ev = buf;
627 btgatt_write_params_t desc_write_parm;
629 desc_write_parm.srvc_id.is_primary = ev->is_primary;
630 desc_write_parm.srvc_id.id.inst_id = ev->inst_id;
631 memcpy(desc_write_parm.srvc_id.id.uuid.uu, ev->svc_uuid, 16);
633 desc_write_parm.char_id.inst_id = ev->inst_id;
634 memcpy(desc_write_parm.char_id.uuid.uu, ev->char_uuid, 16);
636 desc_write_parm.descr_id.inst_id = ev->inst_id;
637 memcpy(desc_write_parm.descr_id.uuid.uu, ev->desc_uuid, 16);
639 if (bt_gatt_callbacks->client->write_descriptor_cb)
640 bt_gatt_callbacks->client->write_descriptor_cb(ev->conn_id,
641 ev->status, &desc_write_parm);
644 static void __bt_handle_gatt_client_watch_notification(void *buf, uint16_t len)
646 struct hal_ev_gatt_client_watch_notification *ev = buf;
647 btgatt_srvc_id_t gatt_srvc_id;
648 btgatt_gatt_id_t gatt_char_id;
650 gatt_srvc_id.is_primary = ev->is_primary;
651 gatt_srvc_id.id.inst_id = ev->inst_id;
652 memcpy(gatt_srvc_id.id.uuid.uu, ev->svc_uuid, 16);
654 memcpy(gatt_char_id.uuid.uu, ev->char_uuid, 16);
655 gatt_char_id.inst_id = ev->inst_id;
657 if (bt_gatt_callbacks->client->register_for_notification_cb)
658 bt_gatt_callbacks->client->register_for_notification_cb(ev->client_if,
659 ev->registered, ev->status, &gatt_srvc_id, &gatt_char_id);
662 static void __bt_handle_gatt_client_changed_value(void *buf, uint16_t len)
664 struct hal_ev_gatt_client_notify_changed_value *ev = buf;
665 btgatt_notify_params_t changd_value_parm;
667 changd_value_parm.srvc_id.is_primary = ev->is_primary;
668 changd_value_parm.srvc_id.id.inst_id = ev->inst_id;
669 memcpy(changd_value_parm.srvc_id.id.uuid.uu, ev->svc_uuid, 16);
671 changd_value_parm.char_id.inst_id = ev->inst_id;
672 memcpy(changd_value_parm.char_id.uuid.uu, ev->char_uuid, 16);
673 changd_value_parm.is_notify = ev->is_notify;
675 memcpy(changd_value_parm.bda.address, ev->bdaddr, 6);
677 changd_value_parm.len = ev->len;
679 memcpy(changd_value_parm.value, ev->value, ev->len);
681 if (bt_gatt_callbacks->client->notify_cb)
682 bt_gatt_callbacks->client->notify_cb(ev->conn_id, &changd_value_parm);
685 static void __bt_hal_handle_gatt_client_service_changed(void *buf, uint16_t len)
687 struct hal_ev_gatt_client_service_changed *ev = buf;
689 DBG("GATT Client service changed event received");
691 if (bt_gatt_callbacks->client->service_changed_cb)
692 bt_gatt_callbacks->client->service_changed_cb((bt_bdaddr_t *)ev->bdaddr,
693 ev->change_type, ev->uuid, ev->conn_id, ev->inst_id);
696 static bt_hal_le_adv_info_t *__bt_hal_get_adv_ind_info(char *addr)
703 for (l = adv_ind_list; NULL != l; l = g_slist_next(l)) {
704 bt_hal_le_adv_info_t *adv_info = l->data;
709 if (!g_strcmp0(adv_info->addr, addr))
716 static int __bt_hal_add_adv_ind_info(bt_hal_le_adv_info_t *adv_info)
721 if (__bt_hal_get_adv_ind_info(adv_info->addr) != NULL) {
722 DBG("Adv info already present");
726 adv_ind_list = g_slist_append(adv_ind_list, adv_info);
730 static void __bt_hal_free_adv_info_list(gpointer data)
732 bt_hal_le_adv_info_t *adv_info = data;
734 if (adv_info->timer_id)
735 g_source_remove(adv_info->timer_id);
736 adv_info->timer_id = 0;
741 void bt_hal_release_pending_adv_ind_list(void)
743 g_slist_free_full(adv_ind_list, __bt_hal_free_adv_info_list);
747 static gboolean __bt_hal_adv_scan_req_timeout_cb(gpointer user_data)
749 bt_hal_le_adv_info_t *adv_info = user_data;
751 __bt_hal_send_le_scan_result_event(adv_info);
752 adv_ind_list = g_slist_remove(adv_ind_list, adv_info);
757 static void __bt_hal_handle_gatt_client_scan_result(void *buf, uint16_t len)
761 struct hal_ev_gatt_client_scan_result *ev = buf;
762 bt_hal_le_adv_info_t *adv_info;
765 memcpy(bd_addr.address, ev->bd_addr, 6);
766 bt_bdaddr_t2str(&bd_addr, address);
767 data_len = (ev->len < BT_HAL_ADV_DATA_MAX_SIZE) ? ev->len : BT_HAL_ADV_DATA_MAX_SIZE;
768 if (data_len == 0 && ev->adv_type != BT_LE_ADV_SCAN_RSP) {
769 ERR("Unexpected: Data len is 0");
773 if (ev->adv_type == BT_LE_ADV_SCAN_RSP) { /* SCAN_RSP */
774 adv_info = __bt_hal_get_adv_ind_info(address);
776 /* Copy scan response data in data field and send event */
777 memcpy(&(adv_info->data[adv_info->data_len]), ev->adv_data, data_len);
778 __bt_hal_send_le_scan_result_event(adv_info);
779 adv_ind_list = g_slist_remove(adv_ind_list, adv_info);
780 if (adv_info->timer_id)
781 g_source_remove(adv_info->timer_id);
788 adv_info = g_malloc0(sizeof(bt_hal_le_adv_info_t));
790 ERR("Not enough memory");
795 g_strlcpy(adv_info->addr, address, 18);
796 adv_info->addr_type = ev->addr_type;
797 adv_info->adv_type = ev->adv_type;
798 adv_info->rssi = ev->rssi;
799 adv_info->data_len = data_len;
800 memcpy(adv_info->data, ev->adv_data, data_len);
803 if (_bt_hal_gatt_client_get_le_scan_type() == BT_GATTC_LE_SCAN_TYPE_PASSIVE) {
804 __bt_hal_send_le_scan_result_event(adv_info);
810 if (adv_info->adv_type == BT_LE_ADV_DIRECT_IND ||
811 adv_info->adv_type == BT_LE_ADV_NONCONN_IND) {
812 __bt_hal_send_le_scan_result_event(adv_info);
813 } else if (adv_info->adv_type == BT_LE_ADV_IND ||
814 adv_info->adv_type == BT_LE_ADV_SCAN_IND) {
816 if (__bt_hal_add_adv_ind_info(adv_info) == 0)
817 adv_info->timer_id = g_timeout_add(1000,
818 __bt_hal_adv_scan_req_timeout_cb,
823 static void __bt_hal_handle_gatt_client_mtu_exchange_completed(void *buf, uint16_t len)
825 struct hal_ev_gatt_client_mtu_exchange_completed *ev = buf;
827 if (bt_gatt_callbacks->client->configure_mtu_cb)
828 bt_gatt_callbacks->client->configure_mtu_cb(ev->conn_id, ev->status, ev->mtu);
832 /*******************************************************************************
834 ** Function gatt_init
836 ** Description Initializes the GATT interface
838 ** Returns bt_status_t
840 *******************************************************************************/
841 static bt_status_t gatt_init(const btgatt_callbacks_t* callbacks)
843 bt_gatt_callbacks = callbacks;
845 DBG("Register A2DP Src events callback function");
846 _bt_hal_register_gatt_le_dbus_handler_cb(__bt_hal_gatt_events);
847 _bt_hal_register_gatt_server_handler_cb(__bt_hal_gatt_events);
848 _bt_hal_register_gatt_client_handler_cb(__bt_hal_gatt_events);
849 _bt_hal_register_event_handler_cb(HAL_GATT, __bt_hal_gatt_events);
851 _bt_hal_gatt_server_init();
852 _bt_hal_gatt_client_init();
854 return BT_STATUS_SUCCESS;
857 /*******************************************************************************
859 ** Function gatt_cleanup
861 ** Description Closes the GATT interface
865 *******************************************************************************/
866 static void gatt_cleanup(void)
868 _bt_hal_unregister_gatt_le_dbus_handler_cb();
869 _bt_hal_unregister_gatt_client_handler_cb();
870 _bt_hal_unregister_gatt_server_handler_cb();
871 _bt_hal_unregister_event_handler_cb(HAL_GATT);
873 if (bt_gatt_callbacks)
874 bt_gatt_callbacks = NULL;
877 static const btgatt_interface_t btgatt_interface = {
878 sizeof(btgatt_interface),
883 &btgatt_client_interface,
884 &btgatt_server_interface,
887 /*******************************************************************************
889 ** Function bt_get_gatt_interface
891 ** Description Get the gatt callback interface
893 ** Returns btgatt_interface_t
895 *******************************************************************************/
896 const btgatt_interface_t *bt_get_gatt_interface()
898 return &btgatt_interface;