Fix the memory leak
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-adapter-mgr.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <dlog.h>
23 #include <string.h>
24 #include <vconf.h>
25 #include <sys/wait.h>
26
27 #include <bluetooth.h>
28
29 #include "oal-event.h"
30 #include "oal-internal.h"
31 #include "oal-manager.h"
32 #include "oal-hardware.h"
33 #include "oal-common.h"
34 #include "oal-utils.h"
35 #include "oal-gatt.h"
36
37 #define CHECK_MAX(max, x) (((max) > (x)) ? (x) : (max))
38
39 static const bt_interface_t * blued_api;
40
41 static bt_address_t local_address;
42 static char local_name[BT_DEVICE_NAME_LENGTH_MAX + 1] = {'O', 'A', 'L', 0};
43 static char local_version[BT_VERSION_STR_LEN_MAX + 1];
44 static bt_scan_mode_t scan_mode = BT_SCAN_MODE_NONE;
45 static int discoverable_timeout = 0;
46
47 /* Forward declarations */
48 oal_status_t convert_to_oal_status(bt_status_t status);
49 static gboolean retry_enable_adapter(gpointer data);
50 #ifdef TIZEN_BT_HAL
51 static gboolean retry_enable_le(gpointer data);
52 #endif
53 oal_status_t oal_mgr_init_internal(void);
54
55
56 /* Callback registered with Stack */
57 static void cb_adapter_state_change(bt_state_t status);
58 static void cb_adapter_discovery_state_changed(bt_discovery_state_t state);
59 static void cb_adapter_device_found(int num_properties, bt_property_t *properties);
60 static void cb_adapter_properties(bt_status_t status,
61                 int num_properties, bt_property_t *properties);
62 static void cb_adapter_profile_connected_devices(uint8_t count, uint8_t bdaddr_list[][6]);
63 extern void cb_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr,
64                 int num_properties, bt_property_t *properties);
65 extern void cb_device_bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr,
66                 bt_bond_state_t state);
67 extern void cb_device_acl_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr,
68                 bt_acl_state_t state);
69 extern void cb_device_pin_request(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t device_class);
70 extern void cb_device_ssp_request(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t device_class,
71                         bt_ssp_variant_t pairing_variant, uint32_t pass_key);
72 extern void cb_device_authorize_request(bt_bdaddr_t *remote_bd_addr, bt_service_id_t service_d);
73 extern void cb_device_trust_state_changed(bt_bdaddr_t *remote_bd_addr, bt_device_trust_state_t trusted);
74 #ifdef TIZEN_BT_HAL
75 extern void cb_socket_conn_authorize_request(bt_bdaddr_t *remote_bd_addr, bt_uuid_t *uuid, uint8_t *name, uint8_t *path, uint32_t fd);
76 static void cb_ble_state_change(bt_state_t status);
77 extern void cb_device_le_conn_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr,
78                 bt_le_conn_state_t state);
79 extern void cb_device_trusted_profiles_changed(bt_bdaddr_t *bd_addr, uint32_t trust_val);
80 extern void cb_rssi_monitor_state_changed(bt_bdaddr_t *bd_addr, int32_t link_type, uint8_t state);
81 extern void cb_rssi_alert(bt_bdaddr_t *bd_addr, int32_t link_type, int32_t alert_type, int32_t rssi);
82 extern void cb_raw_rssi_received(bt_bdaddr_t *bd_addr, int32_t link_type, int32_t rssi);
83 extern void cb_dbfw_plus_info_received(unsigned char *data, uint32_t length, uint8_t event_code);
84 extern void cb_controller_error_received(uint8_t error_code);
85 #endif
86
87 static bt_callbacks_t callbacks = {
88         .size = sizeof(callbacks),
89         .adapter_state_changed_cb = cb_adapter_state_change,
90         .adapter_properties_cb = cb_adapter_properties,
91         .adapter_profile_connected_devices_cb = cb_adapter_profile_connected_devices,
92         .remote_device_properties_cb = cb_device_properties,
93         .device_found_cb = cb_adapter_device_found,
94         .discovery_state_changed_cb = cb_adapter_discovery_state_changed,
95         .pin_request_cb = cb_device_pin_request,
96         .ssp_request_cb = cb_device_ssp_request,
97         .bond_state_changed_cb = cb_device_bond_state_changed,
98         .acl_state_changed_cb = cb_device_acl_state_changed,
99         .thread_evt_cb = NULL,
100         .dut_mode_recv_cb = NULL,
101         .le_test_mode_cb = NULL,
102         .energy_info_cb = NULL,
103         .authorize_request_cb = cb_device_authorize_request,
104         .device_trust_state_changed_cb = cb_device_trust_state_changed,
105 #ifdef TIZEN_BT_HAL
106         .socket_authorize_request_cb = cb_socket_conn_authorize_request,
107         .le_state_changed_cb = cb_ble_state_change,
108         .le_conn_state_changed_cb = cb_device_le_conn_state_changed,
109         .device_trusted_profiles_changed_cb = cb_device_trusted_profiles_changed,
110         .rssi_monitor_state_changed_cb = cb_rssi_monitor_state_changed,
111         .rssi_alert_cb = cb_rssi_alert,
112         .raw_rssi_received_cb = cb_raw_rssi_received,
113         .dbfw_plus_info_received_cb = cb_dbfw_plus_info_received,
114         .controller_error_received_cb = cb_controller_error_received,
115 #endif
116 };
117
118 oal_status_t adapter_mgr_init(const bt_interface_t * stack_if)
119 {
120         int ret;
121         blued_api = stack_if;
122
123         ret = blued_api->init(&callbacks);
124
125         if (ret != BT_STATUS_SUCCESS) {
126                 BT_ERR("Adapter callback registration failed: [%s]", status2string(ret));
127                 blued_api->cleanup();
128                 return convert_to_oal_status(ret);
129         }
130
131         return OAL_STATUS_SUCCESS;
132 }
133
134 const bt_interface_t* adapter_get_stack_interface(void)
135 {
136         return blued_api;
137 }
138
139 void adapter_mgr_cleanup(void)
140 {
141         /* Nothing to clean yet , do not set blued_api NULL as it will be used to clean Bluedroid states */
142         BT_DBG();
143 }
144
145 #ifdef TIZEN_BT_HAL
146 int oal_set_adapter_request_state(int enable)
147 {
148         return blued_api->set_hal_adapter_request_state(enable);
149 }
150
151 int oal_set_le_request_state(int enable)
152 {
153         return blued_api->set_hal_le_request_state(enable);
154 }
155 #endif
156
157 oal_status_t adapter_enable(void)
158 {
159         int ret = BT_STATUS_SUCCESS;
160
161         API_TRACE();
162
163         if (blued_api == NULL) {
164                 BT_INFO("Stack is initializing, so pending enable");
165                 g_timeout_add(200, retry_enable_adapter, NULL);
166                 return OAL_STATUS_PENDING;
167         }
168
169         if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
170                 g_timeout_add(200, retry_enable_adapter, NULL);
171                 return OAL_STATUS_PENDING;
172         }
173
174         ret = blued_api->enable();
175
176         if (ret != BT_STATUS_SUCCESS) {
177                 BT_ERR("Enable failed: [%s]", status2string(ret));
178                 return convert_to_oal_status(ret);
179         }
180
181         return OAL_STATUS_SUCCESS;
182 }
183
184 oal_status_t adapter_disable(void)
185 {
186         int ret;
187
188         API_TRACE();
189
190         CHECK_OAL_INITIALIZED();
191
192         ret = blued_api->disable();
193
194         if (ret != BT_STATUS_SUCCESS) {
195                 BT_ERR("Disable failed: [%s]", status2string(ret));
196                 return convert_to_oal_status(ret);
197         }
198         return OAL_STATUS_SUCCESS;
199 }
200
201 oal_status_t le_enable(void)
202 {
203         int ret = BT_STATUS_SUCCESS;
204
205         API_TRACE();
206         CHECK_OAL_INITIALIZED();
207
208 #ifdef TIZEN_BT_HAL
209         if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
210                 g_timeout_add(200, retry_enable_le, NULL);
211                 return OAL_STATUS_PENDING;
212         }
213
214         ret = blued_api->le_enable();
215
216         if (ret != BT_STATUS_SUCCESS) {
217                 BT_ERR("Enable failed: [%s]", status2string(ret));
218                 return convert_to_oal_status(ret);
219         }
220 #else
221         BT_INFO("Not Supported");
222         ret = OAL_STATUS_NOT_SUPPORT;
223 #endif
224
225         return ret;
226 }
227
228 oal_status_t le_disable(void)
229 {
230         int ret;
231
232         API_TRACE();
233
234         CHECK_OAL_INITIALIZED();
235
236 #ifdef TIZEN_BT_HAL
237         ret = blued_api->le_disable();
238
239         if (ret != BT_STATUS_SUCCESS) {
240                 BT_ERR("Disable failed: [%s]", status2string(ret));
241                 return convert_to_oal_status(ret);
242         }
243 #else
244         BT_INFO("Not Supported");
245         ret = OAL_STATUS_NOT_SUPPORT;
246 #endif
247         return ret;
248 }
249
250 oal_status_t le_init(void)
251 {
252         int ret = BT_STATUS_SUCCESS;
253         API_TRACE();
254         CHECK_OAL_INITIALIZED();
255 #ifdef TIZEN_BT_HAL
256         if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
257                 g_timeout_add(200, retry_enable_le, NULL);
258                 return OAL_STATUS_PENDING;
259         }
260         ret = blued_api->le_init();
261         if (ret != BT_STATUS_SUCCESS) {
262                 BT_ERR("Enable failed: [%s]", status2string(ret));
263                 return convert_to_oal_status(ret);
264         }
265 #else
266         BT_INFO("Not Supported");
267         ret = OAL_STATUS_NOT_SUPPORT;
268 #endif
269         return ret;
270 }
271 oal_status_t le_deinit(void)
272 {
273         int ret = BT_STATUS_SUCCESS;
274         API_TRACE();
275         CHECK_OAL_INITIALIZED();
276 #ifdef TIZEN_BT_HAL
277         if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
278                 g_timeout_add(200, retry_enable_le, NULL);
279                 return OAL_STATUS_PENDING;
280         }
281         blued_api->le_deinit();
282 #else
283         BT_INFO("Not Supported");
284         ret = OAL_STATUS_NOT_SUPPORT;
285 #endif
286         return ret;
287 }
288 oal_status_t is_advertising(void)
289 {
290         int ret = BT_STATUS_SUCCESS;
291         API_TRACE();
292         CHECK_OAL_INITIALIZED();
293 #ifdef TIZEN_BT_HAL
294         if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
295                 g_timeout_add(200, retry_enable_le, NULL);
296                 return OAL_STATUS_PENDING;
297         }
298         int r = blued_api->is_advertising();
299         if (r == TRUE)
300                 ret = BT_STATUS_SUCCESS;
301         else
302                 ret = BT_STATUS_FAIL;
303 #else
304         BT_INFO("Not Supported");
305         ret = OAL_STATUS_NOT_SUPPORT;
306 #endif
307         return ret;
308 }
309 oal_status_t adapter_start_custom_inquiry(discovery_type_t disc_type)
310 {
311         int ret;
312
313         API_TRACE();
314
315         CHECK_OAL_INITIALIZED();
316         BT_INFO("Custom Discovery Type [0x%x]", disc_type);
317
318 #ifdef TIZEN_BT_HAL
319         ret = blued_api->start_custom_discovery(disc_type);
320         if (ret != BT_STATUS_SUCCESS) {
321                 BT_ERR("start_custom_discovery failed: [%s]", status2string(ret));
322                 return convert_to_oal_status(ret);
323         }
324 #else
325         BT_INFO("Not Supported");
326         ret = OAL_STATUS_NOT_SUPPORT;
327 #endif
328         return ret;
329 }
330
331 oal_status_t adapter_get_powered_status(gboolean *status)
332 {
333         int ret;
334         unsigned char powered = 0;
335
336         API_TRACE();
337
338         CHECK_OAL_INITIALIZED();
339
340         OAL_CHECK_PARAMETER(status, return);
341         BT_INFO("Get Adapter Powered status");
342
343 #ifdef TIZEN_BT_HAL
344         ret = blued_api->get_adapter_powered_status(&powered);
345         if (ret != BT_STATUS_SUCCESS) {
346                 BT_ERR("adapter_get_powered_status failed: [%s]", status2string(ret));
347                 *status = FALSE;
348                 return convert_to_oal_status(ret);
349         }
350         if (powered == 1)
351                 *status = TRUE;
352         else
353                 *status = FALSE;
354 #else
355         BT_INFO("Not Supported");
356         ret = OAL_STATUS_NOT_SUPPORT;
357 #endif
358         return ret;
359 }
360
361 oal_status_t adapter_get_energy_info(uint32_t *tx_time, uint32_t *rx_time,
362                                         uint32_t *idle_time, uint32_t *energy_used)
363 {
364         int ret;
365
366         CHECK_OAL_INITIALIZED();
367
368         OAL_CHECK_PARAMETER(tx_time, return);
369         OAL_CHECK_PARAMETER(rx_time, return);
370         OAL_CHECK_PARAMETER(idle_time, return);
371         OAL_CHECK_PARAMETER(energy_used, return);
372
373         BT_DBG("Get Adapter Energy Info");
374
375 #ifdef TIZEN_BT_HAL
376         ret = blued_api->get_adapter_energy_info(tx_time, rx_time, idle_time, energy_used);
377         if (ret != BT_STATUS_SUCCESS) {
378                 BT_ERR("get_adapter_energy_info failed: [%s]", status2string(ret));
379                 return convert_to_oal_status(ret);
380         }
381 #else
382         BT_INFO("Not Supported");
383         ret = OAL_STATUS_NOT_SUPPORT;
384 #endif
385         return ret;
386 }
387
388 oal_status_t adapter_reset(void)
389 {
390         int ret;
391
392         API_TRACE();
393
394         CHECK_OAL_INITIALIZED();
395         BT_INFO("Adapter Reset");
396
397 #ifdef TIZEN_BT_HAL
398         ret = blued_api->reset();
399         if (ret != BT_STATUS_SUCCESS) {
400                 BT_ERR("Adapter Reset failed: [%s]", status2string(ret));
401                 return convert_to_oal_status(ret);
402         }
403 #else
404         BT_INFO("Not Supported");
405         ret = OAL_STATUS_NOT_SUPPORT;
406 #endif
407         return ret;
408 }
409
410 oal_status_t adapter_recover(void)
411 {
412         int result;
413
414         API_TRACE();
415
416         CHECK_OAL_INITIALIZED();
417         BT_INFO("Adapter Recover");
418
419         result = blued_api->recover();
420         if (result != BT_STATUS_SUCCESS) {
421                 BT_ERR("Adapter Recover Failed: [%s]", status2string(result));
422                 return convert_to_oal_status(result);
423         }
424
425         return result;
426 }
427
428 oal_status_t adapter_start_inquiry(unsigned short duration)
429 {
430         int ret;
431
432         API_TRACE();
433
434         CHECK_OAL_INITIALIZED();
435
436         ret = blued_api->start_discovery();
437         if (ret != BT_STATUS_SUCCESS) {
438                 BT_ERR("start_discovery failed: [%s]", status2string(ret));
439                 return convert_to_oal_status(ret);
440         }
441
442         return OAL_STATUS_SUCCESS;
443 }
444
445 oal_status_t adapter_stop_inquiry(void)
446 {
447         int ret;
448
449         API_TRACE();
450
451         CHECK_OAL_INITIALIZED();
452
453         ret = blued_api->cancel_discovery();
454         if (ret != BT_STATUS_SUCCESS) {
455                 BT_ERR("cancel_discovery failed: [%s]", status2string(ret));
456                 return convert_to_oal_status(ret);
457         }
458
459         return OAL_STATUS_SUCCESS;
460 }
461
462 /* Callbacks from Stack */
463 static void cb_adapter_state_change(bt_state_t status)
464 {
465         BT_DBG("+");
466         oal_event_t event;
467
468         event = (BT_STATE_ON == status) ? OAL_EVENT_ADAPTER_ENABLED : OAL_EVENT_ADAPTER_DISABLED;
469
470         send_event(event, NULL, 0);
471 }
472
473 #ifdef TIZEN_BT_HAL
474 /* Callbacks from Stack */
475 static void cb_ble_state_change(bt_state_t status)
476 {
477         BT_DBG("+");
478         oal_event_t event;
479
480         event = (BT_STATE_ON == status) ? OAL_EVENT_BLE_ENABLED : OAL_EVENT_BLE_DISABLED;
481
482         send_event(event, NULL, 0);
483 }
484 #endif
485
486 static gboolean retry_enable_adapter(gpointer data)
487 {
488         adapter_enable();
489         return FALSE;
490 }
491
492 #ifdef TIZEN_BT_HAL
493 static gboolean retry_enable_le(gpointer data)
494 {
495         le_enable();
496         return FALSE;
497 }
498 #endif
499 oal_status_t adapter_get_properties(void)
500 {
501         int ret;
502
503         API_TRACE();
504         CHECK_OAL_INITIALIZED();
505
506         ret = blued_api->get_adapter_properties();
507         if (ret != BT_STATUS_SUCCESS) {
508                 BT_ERR("get_adapter_properties failed: [%s]", status2string(ret));
509                 return convert_to_oal_status(ret);
510         }
511
512         return OAL_STATUS_SUCCESS;
513 }
514
515 oal_status_t adapter_get_address(void)
516 {
517         int ret;
518
519         API_TRACE();
520         CHECK_OAL_INITIALIZED();
521
522         ret = blued_api->get_adapter_property(BT_PROPERTY_BDADDR);
523         if (ret != BT_STATUS_SUCCESS) {
524                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
525                 return convert_to_oal_status(ret);
526         }
527
528         return OAL_STATUS_SUCCESS;
529 }
530
531 oal_status_t adapter_get_version(void)
532 {
533         int ret;
534
535         API_TRACE();
536         CHECK_OAL_INITIALIZED();
537
538         ret = blued_api->get_adapter_property(BT_PROPERTY_VERSION);
539         if (ret != BT_STATUS_SUCCESS) {
540                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
541                 return convert_to_oal_status(ret);
542         }
543
544         return OAL_STATUS_SUCCESS;
545 }
546
547 oal_status_t adapter_get_name(void)
548 {
549         int ret;
550
551         CHECK_OAL_INITIALIZED();
552
553         API_TRACE();
554
555         ret = blued_api->get_adapter_property(BT_PROPERTY_BDNAME);
556         if (ret != BT_STATUS_SUCCESS) {
557                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
558                 return convert_to_oal_status(ret);
559         }
560
561         return OAL_STATUS_SUCCESS;
562 }
563
564 oal_status_t adapter_get_connectable(void)
565 {
566         int ret;
567
568         CHECK_OAL_INITIALIZED();
569
570         API_TRACE();
571
572         ret = blued_api->get_adapter_property(BT_PROPERTY_ADAPTER_SCAN_MODE);
573         if (ret != BT_STATUS_SUCCESS) {
574                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
575                 return convert_to_oal_status(ret);
576         }
577
578         return OAL_STATUS_SUCCESS;
579 }
580
581 oal_status_t adapter_set_name(char * name)
582 {
583         int ret;
584         bt_property_t prop;
585
586         CHECK_OAL_INITIALIZED();
587
588         OAL_CHECK_PARAMETER(name, return);
589         API_TRACE("Name: %s", name);
590
591         prop.type = BT_PROPERTY_BDNAME;
592         prop.len = strlen(name);
593         prop.val = name;
594
595         ret = blued_api->set_adapter_property(&prop);
596         if (ret != BT_STATUS_SUCCESS) {
597                 BT_ERR("set_adapter_property: [%s]", status2string(ret));
598                 ret = OAL_STATUS_INTERNAL_ERROR;
599         } else
600                 ret = OAL_STATUS_SUCCESS;
601
602         return ret;
603 }
604
605 oal_status_t adapter_is_discoverable(int *p_discoverable)
606 {
607         OAL_CHECK_PARAMETER(p_discoverable, return);
608
609         *p_discoverable = (scan_mode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
610
611         API_TRACE("%d", *p_discoverable);
612
613         return OAL_STATUS_SUCCESS;
614 }
615
616 oal_status_t adapter_is_connectable(int *p_connectable)
617 {
618         OAL_CHECK_PARAMETER(p_connectable, return);
619
620         *p_connectable = (scan_mode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE)
621                 || (scan_mode == BT_SCAN_MODE_CONNECTABLE);
622
623         API_TRACE("%d", *p_connectable);
624
625         return OAL_STATUS_SUCCESS;
626 }
627
628 oal_status_t adapter_get_discoverable_timeout(int *p_timeout)
629 {
630         API_TRACE("%d", discoverable_timeout);
631
632         *p_timeout = discoverable_timeout;
633
634         return OAL_STATUS_SUCCESS;
635 }
636
637 oal_status_t adapter_get_service_uuids(void)
638 {
639         int ret;
640
641         CHECK_OAL_INITIALIZED();
642
643         API_TRACE();
644         ret = blued_api->get_adapter_property(BT_PROPERTY_UUIDS);
645         if (ret != BT_STATUS_SUCCESS) {
646                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
647                 return convert_to_oal_status(ret);
648         }
649         return OAL_STATUS_SUCCESS;
650 }
651
652 oal_status_t adapter_get_bonded_devices(void)
653 {
654         int ret;
655
656         CHECK_OAL_INITIALIZED();
657
658         API_TRACE();
659
660         ret = blued_api->get_adapter_property(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
661         if (ret != BT_STATUS_SUCCESS) {
662                 BT_ERR("get_adapter_property failed: [%s]", status2string(ret));
663                 return convert_to_oal_status(ret);
664         }
665
666         return OAL_STATUS_SUCCESS;
667 }
668
669 oal_status_t adapter_get_profile_connected_devices(const char *profile_uuid)
670 {
671         int ret;
672
673         CHECK_OAL_INITIALIZED();
674
675         API_TRACE();
676
677         ret = blued_api->get_profile_connected_devices(profile_uuid);
678         if (ret != BT_STATUS_SUCCESS) {
679                 BT_ERR("get_profile_connected_devices failed: [%s]", status2string(ret));
680                 return convert_to_oal_status(ret);
681         }
682
683         return OAL_STATUS_SUCCESS;
684 }
685
686 static oal_status_t set_scan_mode(bt_scan_mode_t mode)
687 {
688         bt_property_t prop;
689         int res;
690
691         BT_DBG("+");
692
693         CHECK_OAL_INITIALIZED();
694
695         prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE;
696         prop.len = sizeof(bt_scan_mode_t);
697         prop.val = &mode;
698         res = blued_api->set_adapter_property(&prop);
699         if (res != BT_STATUS_SUCCESS) {
700                 BT_ERR("set scan mode failed [%s]", status2string(res));
701                 return convert_to_oal_status(res);
702         }
703
704         BT_DBG("-");
705         return OAL_STATUS_SUCCESS;
706 }
707
708 oal_status_t adapter_set_connectable(int connectable)
709 {
710         bt_scan_mode_t mode;
711
712         API_TRACE("%d", connectable);
713
714         CHECK_OAL_INITIALIZED();
715
716         mode = connectable ? BT_SCAN_MODE_CONNECTABLE : BT_SCAN_MODE_NONE;
717
718         return set_scan_mode(mode);
719 }
720
721 oal_status_t adapter_set_discoverable(void)
722 {
723         CHECK_OAL_INITIALIZED();
724         API_TRACE();
725
726         return set_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
727 }
728
729 oal_status_t adapter_set_discoverable_timeout(int timeout)
730 {
731         bt_property_t prop;
732         int res;
733         uint32_t prop_val = timeout;
734
735         CHECK_OAL_INITIALIZED();
736         API_TRACE("%d", timeout);
737
738         prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
739         prop.len = sizeof(prop_val);
740         prop.val = &prop_val;
741         res = blued_api->set_adapter_property(&prop);
742         if (res != BT_STATUS_SUCCESS) {
743                 BT_ERR("set_adapter_property failed [%s]", status2string(res));
744                 return convert_to_oal_status(res);
745         }
746         return OAL_STATUS_SUCCESS;
747 }
748
749 oal_status_t adapter_ble_set_filter_policy(int filter_policy)
750 {
751         int ret = OAL_STATUS_SUCCESS;
752
753         CHECK_OAL_INITIALIZED();
754         API_TRACE();
755
756         BT_DBG("Filter policy applied is [%d]", filter_policy);
757
758         ret = gatts_set_filter_policy(filter_policy);
759
760         if (ret != OAL_STATUS_SUCCESS) {
761                 BT_ERR("gatts_set_filter_policy: [%d]", ret);
762                 return ret;
763         }
764
765         return OAL_STATUS_SUCCESS;
766 }
767
768 oal_status_t adapter_ble_multi_adv_update(int Ins_id, int min_intv, int max_intv,
769                         int adv_type, int chnl_map, int tx_power, int timeout_s)
770 {
771         int res;
772         CHECK_OAL_INITIALIZED();
773         API_TRACE();
774
775         res = gatts_multi_adv_update(Ins_id, min_intv, max_intv,
776                         adv_type, chnl_map, tx_power, timeout_s);
777         if (res != OAL_STATUS_SUCCESS) {
778                 BT_ERR("gatts_multi_adv_update: [%d]", res);
779                 return res;
780         }
781         return OAL_STATUS_SUCCESS;
782 }
783
784 oal_status_t adapter_ble_multi_adv_set_inst_data(int instance_id,
785                         oal_ble_multi_adv_param_setup_t * adv_param_setup)
786 {
787         int res;
788         CHECK_OAL_INITIALIZED();
789         OAL_CHECK_PARAMETER(adv_param_setup, return);
790
791         API_TRACE();
792
793         res = gatts_multi_adv_set_inst_data(instance_id, adv_param_setup);
794         if (res != OAL_STATUS_SUCCESS) {
795                 BT_ERR("failed: [%d]", res);
796                 return res;
797         }
798         return OAL_STATUS_SUCCESS;
799 }
800
801 oal_status_t adapter_ble_multi_adv_enable(int instance_id)
802 {
803         int res;
804         CHECK_OAL_INITIALIZED();
805         API_TRACE();
806
807         res = gatts_multi_adv_enable(instance_id);
808         if (res != OAL_STATUS_SUCCESS) {
809                 BT_ERR("failed: [%d]", res);
810                 return res;
811         }
812
813         return OAL_STATUS_SUCCESS;
814 }
815
816 oal_status_t adapter_ble_multi_adv_disable(int instance_id)
817 {
818         int res;
819         CHECK_OAL_INITIALIZED();
820         API_TRACE();
821
822         res = gatts_multi_adv_disable(instance_id);
823         if (res != OAL_STATUS_SUCCESS) {
824                 BT_ERR("failed: [%d]", res);
825                 return res;
826         }
827
828         return OAL_STATUS_SUCCESS;
829 }
830
831 oal_status_t adapter_set_le_static_random_address(int enable)
832 {
833         int ret;
834
835         CHECK_OAL_INITIALIZED();
836         API_TRACE("%d", enable);
837
838 #ifdef TIZEN_BT_HAL
839         ret = blued_api->set_le_static_random_address((enable ? 1 : 0));
840         if (ret != BT_STATUS_SUCCESS)
841                 BT_ERR("Static address set failed: [%s]", status2string(ret));
842         ret = convert_to_oal_status(ret);
843 #else
844         BT_INFO("Not Supported");
845         ret = OAL_STATUS_NOT_SUPPORT;
846 #endif
847
848         return ret;
849 }
850
851 oal_status_t adapter_set_manufacturer_data(oal_manufacturer_data_t *m_data)
852 {
853         int ret;
854
855         CHECK_OAL_INITIALIZED();
856         API_TRACE();
857
858         OAL_CHECK_PARAMETER(m_data, return);
859         ret = blued_api->adapter_le_set_manufacturer_data((bt_manufacturer_data_t*)m_data);
860         if (ret != BT_STATUS_SUCCESS)
861                 BT_ERR("Setting manufacturer data Failed: [%s]",status2string(ret));
862
863         ret = convert_to_oal_status(ret);
864         return ret;
865 }
866
867 oal_status_t adapter_set_white_list(bt_address_t *device_address, int address_type, bool is_add)
868 {
869         int ret;
870         bdstr_t bdstr;
871
872         CHECK_OAL_INITIALIZED();
873
874         BT_INFO("BT remote device Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
875
876         ret = blued_api->adapter_le_set_white_list((bt_bdaddr_t*)device_address, address_type, is_add);
877         if (ret != BT_STATUS_SUCCESS) {
878                 if(is_add)
879                         BT_ERR("Add to White List Failed: [%s]",status2string(ret));
880                 else
881                         BT_ERR("Remove from White List Failed: [%s]",status2string(ret));
882         }
883         ret = convert_to_oal_status(ret);
884         return ret;
885 }
886
887 oal_status_t adapter_ble_set_privacy(int set_privacy)
888 {
889         int res;
890
891         CHECK_OAL_INITIALIZED();
892         API_TRACE();
893
894         res = blued_api->adapter_le_set_privacy(set_privacy);
895         if (res != BT_STATUS_SUCCESS)
896                 BT_ERR("Setting LE Privacy Failed: [%s]", status2string(res));
897         res = convert_to_oal_status(res);
898
899         return res;
900 }
901
902 static void cb_adapter_properties(bt_status_t status,
903                 int num_properties,
904                 bt_property_t *properties)
905 {
906         int i;
907
908         BT_DBG("status: %d, count: %d", status, num_properties);
909
910         print_bt_properties(num_properties, properties);
911
912         if (status != BT_STATUS_SUCCESS) {
913                 if (num_properties == 1) {
914                         BT_ERR("Adapter Prop failed: status: [%s], count: %d, prop: %d",
915                                 status2string(status), num_properties, properties[num_properties-1].type);
916                 } else {
917                         BT_ERR("Adapter Prop failed: status: [%s], count: %d", status2string(status), num_properties);
918                 }
919                 return;
920         }
921
922         for (i = 0; i < num_properties; i++) {
923                 BT_DBG("prop type %d, len %d", properties[i].type, properties[i].len);
924                 switch (properties[i].type) {
925                 case BT_PROPERTY_VERSION: {
926                         g_strlcpy(local_version, properties[i].val, BT_VERSION_STR_LEN_MAX);
927                         local_version[properties[i].len] = '\0';
928
929                         BT_DBG("Version: %s", local_version);
930                         /* Send event to application */
931                         if (num_properties == 1) {
932                                 char *adapter_ver = g_strdup(local_version);
933
934                                 /* Application has requested this property SET/GET hence send EVENT */
935                                 send_event(OAL_EVENT_ADAPTER_PROPERTY_VERSION, adapter_ver, strlen(adapter_ver));
936                         }
937                         break;
938                 }
939                 case BT_PROPERTY_BDNAME: {
940                         g_strlcpy(local_name, properties[i].val, BT_DEVICE_NAME_LENGTH_MAX);
941                         local_name[properties[i].len] = '\0';
942
943                         BT_DBG("Name: %s", local_name);
944                         /* Send event to application */
945                         if (num_properties == 1) {
946                                 char * adap_name = g_strdup(local_name);
947
948                                 /* Application has requested this property SET/GET hence send EVENT */
949                                 send_event(OAL_EVENT_ADAPTER_PROPERTY_NAME, adap_name, strlen(adap_name)+1);
950                         }
951                         break;
952                 }
953                 case BT_PROPERTY_BDADDR: {
954                         bt_bdaddr_t * addr;
955
956                         addr =  properties[i].val;
957                         memcpy(local_address.addr, addr->address, 6);
958                         if (num_properties == 1) {
959                                 /* Application has requested this property SET/GET hence send EVENT */
960                                 send_event(OAL_EVENT_ADAPTER_PROPERTY_ADDRESS,
961                                                 g_memdup(&local_address, sizeof(local_address)),
962                                                 sizeof(local_address));
963                         }
964                         break;
965                 }
966                 case BT_PROPERTY_UUIDS: {
967                         int num_uuid;
968
969                         num_uuid = properties[i].len/sizeof(bt_uuid_t);
970
971                         BT_DBG("num_uuid: %d", num_uuid);
972
973                         /* Send event to application */
974                         if (num_properties == 1) {
975                                 event_adapter_services_t *uuids_event;
976
977                                 uuids_event = g_malloc(sizeof(event_adapter_services_t) + properties[i].len);
978                                 memcpy(uuids_event->service_list, properties[i].val, properties[i].len);
979                                 uuids_event->num = num_uuid;
980
981                                 /* Application has requested this property SET/GET hence send EVENT */
982                                 send_event(OAL_EVENT_ADAPTER_PROPERTY_SERVICES,
983                                                 uuids_event, (sizeof(event_adapter_services_t) + num_uuid * sizeof(bt_uuid_t)));
984                         }
985                         break;
986                 }
987                 case BT_PROPERTY_ADAPTER_SCAN_MODE: {
988                         bt_scan_mode_t cur_mode = *((bt_scan_mode_t *)properties[i].val);
989
990                         BT_INFO("Scan mode (%d)", cur_mode);
991
992                         scan_mode = cur_mode;
993
994                         /* Send event to application */
995                         if (num_properties == 1) {
996                                 oal_event_t event = OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE;
997
998                                 if (BT_SCAN_MODE_CONNECTABLE == cur_mode)
999                                         event = OAL_EVENT_ADAPTER_MODE_CONNECTABLE;
1000                                 else if (BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE == cur_mode)
1001                                         event = OAL_EVENT_ADAPTER_MODE_DISCOVERABLE;
1002
1003                                 /* Application has requested this property SET/GET hence send EVENT */
1004                                 send_event(event, NULL, 0);
1005                         }
1006                         break;
1007                 }
1008                 case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: {
1009                         int timeout;
1010
1011                         timeout = *((uint32_t*)properties[i].val);
1012
1013                         BT_INFO("Discoverability timeout: %d", timeout);
1014                         discoverable_timeout = timeout;
1015
1016                         send_event(OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT,
1017                                         g_memdup(properties[i].val, sizeof(uint32_t)),
1018                                         sizeof(uint32_t));
1019                         break;
1020                 }
1021                 case BT_PROPERTY_ADAPTER_BONDED_DEVICES: {
1022                         int j;
1023                         int num_bonded;
1024                         bt_bdaddr_t *bonded_addr_list;
1025                         event_device_list_t *event_data;
1026
1027                         num_bonded = properties[i].len/sizeof(bt_bdaddr_t);
1028                         BT_DBG("num_bonded %d", num_bonded);
1029
1030                         if (num_properties > 1) /* No explicit req for this prop, ignore */
1031                                 break;
1032
1033                         bonded_addr_list = properties[i].val;
1034                         event_data = g_malloc(sizeof(event_device_list_t) + num_bonded*sizeof(bt_address_t));
1035                         event_data->num = num_bonded;
1036
1037                         for (j = 0; j < num_bonded; j++)
1038                                 memcpy(event_data->devices[j].addr, bonded_addr_list[j].address, 6);
1039
1040                         send_event(OAL_EVENT_ADAPTER_BONDED_DEVICE_LIST,
1041                                         event_data, (sizeof(event_device_list_t) + num_bonded * sizeof(bt_bdaddr_t)));
1042                         break;
1043                 }
1044                 case BT_PROPERTY_A2DP_ROLE: {
1045                         unsigned int a2dp_role;
1046
1047                         a2dp_role = *((uint32_t*)properties[i].val);
1048
1049                         BT_INFO("A2DP role: %u", a2dp_role);
1050
1051                         send_event(OAL_EVENT_ADAPTER_PROPERTY_A2DP_ROLE,
1052                                         g_memdup(properties[i].val, sizeof(uint32_t)),
1053                                         sizeof(uint32_t));
1054                         break;
1055                 }
1056                 case BT_PROPERTY_LOCAL_LE_FEATURES: {
1057                         event_adapter_le_features_t *le_features;
1058
1059                         le_features = g_malloc(sizeof(event_adapter_le_features_t));
1060
1061                         le_features->max_adv_instance = ((bt_local_le_features_t *)(properties[i].val))->max_adv_instance;
1062                         le_features->rpa_offloading = ((bt_local_le_features_t *)(properties[i].val))->rpa_offload_supported;
1063                         le_features->max_adv_filter = ((bt_local_le_features_t *)(properties[i].val))->max_adv_filter_supported;
1064                         le_features->le_2m_phy_support = ((bt_local_le_features_t *)(properties[i].val))->le_2m_phy_supported;
1065                         le_features->le_coded_phy_support = ((bt_local_le_features_t *)(properties[i].val))->le_2m_phy_supported;
1066
1067                         BT_INFO("LE 2M PHY Support (%d)", le_features->le_2m_phy_support);
1068                         BT_INFO("LE CODED PHY Support (%d)", le_features->le_coded_phy_support);
1069
1070                         send_event(OAL_EVENT_BLE_LOCAL_FEATURES,
1071                                         le_features,
1072                                         sizeof(event_adapter_le_features_t));
1073                         break;
1074                 }
1075                 case BT_PROPERTY_ADAPTER_LE_DISCOVERY_STARTED: {
1076                         BT_INFO("LE Discovery started");
1077                         send_event(OAL_EVENT_BLE_DISCOVERY_STARTED, NULL, 0);
1078                         break;
1079                 }
1080                 case BT_PROPERTY_ADAPTER_LE_DISCOVERY_STOPPED: {
1081                         BT_INFO("LE Discovery stopped");
1082                         send_event(OAL_EVENT_BLE_DISCOVERY_STOPPED, NULL, 0);
1083                         break;
1084                 }
1085                 default:
1086                          BT_WARN("Unhandled property: %d", properties[i].type);
1087                          break;
1088                 }
1089         }
1090 }
1091
1092 static void cb_adapter_profile_connected_devices(uint8_t count, uint8_t addr_list[][6])
1093 {
1094         event_adapter_profile_connected_devices *event_data;
1095         int i;
1096
1097         event_data = g_malloc0(sizeof(event_adapter_profile_connected_devices));
1098         event_data->count = count;
1099         for (i = 0; i < count; i++) {
1100                 memcpy(event_data->addr_list[i].addr, addr_list[i], BT_ADDRESS_BYTES_NUM);
1101         }
1102         send_event(OAL_EVENT_ADAPTER_PROFILE_CONNECTED_DEVICES, event_data, sizeof(event_adapter_profile_connected_devices));
1103 }
1104
1105 static void cb_adapter_discovery_state_changed(bt_discovery_state_t state)
1106 {
1107         oal_event_t event;
1108
1109         event = (BT_DISCOVERY_STARTED == state) ? OAL_EVENT_ADAPTER_INQUIRY_STARTED : OAL_EVENT_ADAPTER_INQUIRY_FINISHED;
1110
1111         BT_DBG("%d", state);
1112         send_event(event, NULL, 0);
1113 }
1114
1115 static void cb_adapter_device_found(int num_properties, bt_property_t *properties)
1116 {
1117         remote_device_t dev_info;
1118         ble_adv_data_t adv_info;
1119         oal_event_t event;
1120         gpointer event_data;
1121         gsize size = 0;
1122         BT_DBG("+");
1123
1124         if (num_properties == 0) {
1125                 BT_ERR("Unexpected, properties count is zero!!");
1126                 return;
1127         }
1128
1129         memset(&dev_info, 0x00, sizeof(remote_device_t));
1130         memset(&adv_info, 0x00, sizeof(ble_adv_data_t));
1131
1132         print_bt_properties(num_properties, properties);
1133         parse_device_properties(num_properties, properties, &dev_info, &adv_info);
1134
1135         BT_INFO("number of properties= [%d] ", num_properties);
1136
1137         if (dev_info.type != DEV_TYPE_BREDR) {
1138                 /* BLE Single or DUAL mode found, so it should have Adv data */
1139                 event_ble_dev_found_t * ble_dev_event = g_new0(event_ble_dev_found_t, 1);
1140
1141                 ble_dev_event->adv_len = adv_info.len;
1142
1143                 if (adv_info.len > 0 && adv_info.adv_data) {
1144                         memcpy(ble_dev_event->adv_data, adv_info.adv_data, adv_info.len);
1145                         ble_dev_event->adv_len = adv_info.len;
1146                 } else
1147                         ble_dev_event->adv_len = 0;
1148
1149                 ble_dev_event->device_info = dev_info;
1150
1151                 event_data = ble_dev_event;
1152                 size = sizeof(event_ble_dev_found_t);
1153                 event = OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE;
1154         } else {
1155                 /* BREDR device, so No Adv data */
1156                 event_dev_found_t * dev_event = g_new0(event_dev_found_t, 1);
1157
1158                 memcpy(dev_event, &dev_info, sizeof(remote_device_t));
1159                 event_data = dev_event;
1160                 size = sizeof(remote_device_t);
1161                 event = OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY;
1162         }
1163
1164         send_event(event, event_data, size);
1165
1166         BT_DBG("-");
1167 }
1168
1169 void cb_controller_error_received(uint8_t error_code)
1170 {
1171         uint8_t *event_data;
1172
1173         event_data = g_new0(uint8_t, 1);
1174         *event_data = error_code;
1175
1176         send_event(OAL_EVENT_CONTROLLER_ERROR_RECEIVED,
1177                 (gpointer)event_data, sizeof(uint8_t));
1178 }