95ac2ff753ec710c7b8985da54ae0f4fbf4438ca
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-adapter-le.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <glib.h>
23
24 #include <hardware/bluetooth.h>
25 #include <hardware/bt_gatt.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <gio/gio.h>
31 #include <glib.h>
32 #include <dlog.h>
33 #include <vconf.h>
34 #include <vconf-keys.h>
35 #include <vconf-internal-radio-keys.h>
36 #include <stdbool.h>
37 #include <stddef.h>
38 #include <string.h>
39 #include <fcntl.h>
40
41 #include "bt-hal.h"
42 #include "bt-hal-log.h"
43 #include "bt-hal-msg.h"
44 #include "bt-hal-utils.h"
45
46 #include <bt-hal-adapter-dbus-handler.h>
47 #include <bt-hal-dbus-common-utils.h>
48
49 #include "bt-hal-gatt-server.h"
50
51 typedef struct {
52         int adv_inst_max;
53         int rpa_offloading;
54         int max_filter;
55         int le_2m_phy;
56         int le_coded_phy;
57 } bt_adapter_le_feature_info_t;
58
59 typedef struct {
60         int initialized;
61         gboolean is_multi_adv; /* To be removed once we complete descope Legacy Adv */
62         int adv_handle;
63         gboolean is_advertising;
64         guint hold_timer_id;
65         bt_uuid_t app_uuid;
66 } bt_adapter_le_adv_slot_t;
67
68 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
69 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
70
71 typedef struct {
72         uint8_t event;
73         int server_if;
74         uint8_t status;
75         uint8_t data[31];
76 } bt_hal_adv_event_data_t;
77
78 /* Macros */
79 #define BT_HAL_ADV_CONNECTABLE  0x00 /* ADV_IND */
80 #define BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH  0x01 /* ADV_DIRECT_IND, high duty cycle */
81 #define BT_HAL_ADV_SCANNABLE 0x02 /* ADV_SCAN_IND */
82 #define BT_HAL_ADV_NON_CONNECTABLE  0x03 /* ADV_NONCOND_IND */
83 #define BT_HAL_ADV_CONNECTABLE_DIRECT_LOW  0x04 /* ADV_DIRECT_IND, low duty cycle */
84
85 #define BT_HAL_ADV_INTERVAL_MIN 20 /* msec */
86 #define BT_HAL_ADV_INTERVAL_MAX 10240
87 #define BT_HAL_ADV_INTERVAL_SPLIT 0.625
88 #define BT_HAL_DEFAULT_ADV_MIN_INTERVAL 500
89 #define BT_HAL_DEFAULT_ADV_MAX_INTERVAL 500
90 #define BT_HAL_ADV_FILTER_POLICY_DEFAULT    0x00
91 #define BT_HAL_ADV_TYPE_DEFAULT     0x00
92 #define BT_HAL_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY    0x03
93
94 /* Multi Advertisement callback event */
95 #define BT_HAL_MULTI_ADV_ENB_EVT           1
96 #define BT_HAL_MULTI_ADV_DISABLE_EVT       2
97 #define BT_HAL_MULTI_ADV_PARAM_EVT         3
98 #define BT_HAL_MULTI_ADV_DATA_EVT          4
99 #define BT_HAL_MULTI_ADV_UPDATE_EVT        5
100 #define BT_HAL_LEGACY_ADV_STATUS           6
101
102 handle_stack_msg gatt_le_event_cb;
103
104 /* Forward declarations */
105 static gboolean __bt_hal_is_factory_test_mode(void);
106 static void __bt_hal_free_le_adv_slot(void);
107 static gboolean __bt_hal_adv_event_cb(gpointer param);
108
109 #ifdef TIZEN_BT_HAL
110 /* Enable LE Adapter */
111 int _bt_hal_le_enable(void)
112 {
113         return _bt_hal_dbus_enable_le();
114 }
115
116 /* Disable LE Adapter */
117 int _bt_hal_le_disable(void)
118 {
119         return _bt_hal_dbus_disable_le();
120 }
121 #endif
122
123 static void __bt_hal_free_le_adv_slot(void)
124 {
125         int i;
126
127         if (le_adv_slot == NULL)
128                 return;
129
130         for (i = 0; i < le_feature_info.adv_inst_max; i++)
131                 memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
132
133         g_free(le_adv_slot);
134         le_adv_slot = NULL;
135 }
136
137 void _bt_hal_unregister_adv_slot_owner(int slot_id)
138 {
139         if (le_adv_slot == NULL)
140                 return;
141         INFO("Unregister Adv Slot [%d]", slot_id);
142         memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
143 }
144
145 int _bt_hal_get_adv_slot_adv_handle(int slot_id)
146 {
147         if (le_adv_slot == NULL)
148                 return 0;
149
150         return le_adv_slot[slot_id].adv_handle;
151 }
152
153 gboolean _bt_hal_is_advertising_in_slot(int slot)
154 {
155         return le_adv_slot[slot].is_advertising;
156 }
157
158 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
159 {
160
161         DBG("Advertising enabled [%s] slot [%d]",  mode ? "TRUE" : "FALSE", slot_id);
162         bt_hal_adv_event_data_t *event;
163
164         if (le_adv_slot == NULL)
165                 return;
166
167         le_adv_slot[slot_id].is_advertising = mode;
168
169         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
170         event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
171         event->server_if = slot_id;
172         event->status = BT_STATUS_SUCCESS;
173         /* To be removed later when we completely descope Legacy Adv concept */
174         DBG("Is multi ? [%d]", le_adv_slot[slot_id].is_multi_adv);
175         if (le_adv_slot[slot_id].is_multi_adv == FALSE)
176                 event->event = BT_HAL_LEGACY_ADV_STATUS;
177
178         __bt_hal_adv_event_cb((gpointer)event);
179 }
180
181 gboolean _bt_hal_is_advertising(void)
182 {
183         int i;
184
185         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
186                 if (le_adv_slot[i].is_advertising == TRUE)
187                         return TRUE;
188         }
189
190         return FALSE;
191 }
192
193 int _bt_hal_le_init(void)
194 {
195         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
196         return BT_STATUS_SUCCESS;
197 }
198 void _bt_hal_le_deinit(void)
199 {
200         __bt_hal_free_le_adv_slot();
201 }
202
203 gboolean _bt_hal_update_le_feature_support(const char *item, const char *value,
204                         bt_local_le_features_t *le_features)
205 {
206         if (item == NULL || value == NULL)
207                 return FALSE;
208         if (!le_adv_slot)
209                 _bt_hal_le_init();
210
211         if (g_strcmp0(item, "adv_inst_max") == 0) {
212                 int slot_num;
213
214                 slot_num = atoi(value);
215                 if (slot_num < 0) {
216                         ERR("ERR:Advertising MAX instance [%d]", slot_num);
217                         return FALSE;
218                 }
219
220                 if (slot_num != le_feature_info.adv_inst_max) {
221                         __bt_hal_free_le_adv_slot();
222                         le_feature_info.adv_inst_max = slot_num;
223                         INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
224                         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
225                 }
226                 /* Fill LE feature bytes */
227                 le_features->max_adv_instance = atoi(value);
228
229         } else if (g_strcmp0(item, "rpa_offloading") == 0) {
230                 le_feature_info.rpa_offloading = atoi(value);
231                 INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
232
233                 /* Fill LE feature bytes */
234                 le_features->rpa_offload_supported = atoi(value);
235
236         } else if (g_strcmp0(item, "max_filter") == 0) {
237                 le_feature_info.max_filter = atoi(value);
238                 INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
239
240                 /* Fill LE feature bytes */
241                 le_features->max_adv_filter_supported = atoi(value);
242
243         } else if (g_strcmp0(item, "2m_phy") == 0) {
244                 if (g_strcmp0(value, "true") == 0) {
245                         le_feature_info.le_2m_phy = TRUE;
246                         /* Fill LE feature bytes */
247                         le_features->le_2m_phy_supported = 0x1;
248                 } else {
249                         le_feature_info.le_2m_phy = FALSE;
250                         /* Fill LE feature bytes */
251                         le_features->le_2m_phy_supported = 0x0;
252                 }
253                 INFO("2M PHY Supported [%s]",  le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
254         } else if (g_strcmp0(item, "coded_phy") == 0) {
255                 if (g_strcmp0(value, "true") == 0) {
256                         le_feature_info.le_coded_phy = TRUE;
257                         /* Fill LE feature bytes */
258                         le_features->le_coded_phy_supported = 0x1;
259                 } else {
260                         le_feature_info.le_coded_phy = FALSE;
261                         /* Fill LE feature bytes */
262                         le_features->le_coded_phy_supported = 0x0;
263                 }
264                 INFO("CODED PHY Supported [%s]",  le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
265         } else {
266                 DBG("No registered item");
267                 return FALSE;
268         }
269
270         return TRUE;
271 }
272
273 void _bt_hal_free_server_slot(int slot_id)
274 {
275         if (le_adv_slot == NULL)
276                 return;
277         memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
278 }
279
280 int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid)
281 {
282         int i;
283
284         if (le_adv_slot == NULL) {
285                 ERR("le_adv_slot is NULL");
286                 return -1;
287         }
288
289         DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
290
291         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
292                 if (le_adv_slot[i].initialized == 0)
293                         continue;
294                 if (memcmp(uuid->uu, le_adv_slot[i].app_uuid.uu, sizeof(bt_uuid_t)) == 0) {
295                         DBG("UUID [%s] matched, return slot [%d]", btuuid2str(uuid->uu), i);
296                         return i;
297                 }
298         }
299
300         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
301                 if (le_adv_slot[i].initialized == 0) {
302                         DBG("Slot to be allocated [%d] UUID to be registered [%s]",
303                                 i, btuuid2str(uuid->uu));
304                         le_adv_slot[i].initialized = 1;
305                         memcpy(&le_adv_slot[i].app_uuid.uu, &uuid->uu, sizeof(bt_uuid_t));
306                         return i;
307                 }
308         }
309
310         return -1;
311 }
312
313 void _bt_hal_get_gatt_server_instance_initialized(int *instance)
314 {
315         int i;
316         if (le_adv_slot == NULL) {
317                 ERR("le_adv_slot is NULL");
318                 return;
319         }
320
321         DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
322
323         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
324                 if (le_adv_slot[i].initialized == 0)
325                         continue;
326                 DBG("Initialized Slot found: UUID [%s] slot [%d]", le_adv_slot[i].app_uuid.uu, i);
327                 *instance = i;
328                 break;
329         }
330 }
331
332 gboolean _bt_is_advertising(void)
333 {
334         return FALSE;
335 }
336
337 int _bt_set_advertising(const char *sender, int adv_handle,
338                         gboolean enable, gboolean use_reserved_slot)
339 {
340         DBG("+");
341         return BT_STATUS_UNSUPPORTED;
342 }
343
344 static int __bt_hal_uuid_type(uint8_t* p_uuid)
345 {
346         int i = 0;
347         int match = 0;
348         int all_zero = 1;
349
350         for (i = 0; i != 16; ++i) {
351                 if (i == 12 || i == 13)
352                         continue;
353
354                 if (p_uuid[i] == BASE_UUID_CONVERTED[i])
355                         ++match;
356
357                 if (p_uuid[i] != 0)
358                         all_zero = 0;
359         }
360         if (all_zero)
361                 return 0;
362         if (match == 12)
363                 return BT_HAL_UUID_32;
364         if (match == 14)
365                 return BT_HAL_UUID_16;
366         return BT_HAL_UUID_128;
367 }
368
369 static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length, int is_solicit)
370 {
371         DBG("+");
372         int prev_byte_len = 0;
373         /* dest[index] will contain the length followed by AD Type
374            Move length only when different byte_len is found Ex) 2->4, 2->16, 4->16 etc */
375         int index = 0;
376
377         while (len >= 16) {
378
379                 /* Create Local buffer & copy source 16 bytes in sequence */
380                 int byte_len;
381                 bt_uuid_t uuid;
382                 memset(&uuid, 0, sizeof(bt_uuid_t));
383                 memcpy(&uuid.uu, src, 16);
384
385                 /* Compute current UUID's byte length */
386                 byte_len = __bt_hal_uuid_type(uuid.uu);
387
388                 switch (byte_len) {
389                 case 2: {
390                         if (prev_byte_len == byte_len) {
391                                 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);
392                                 *length += 2;
393                                 dest[index] += 2;
394                         } else {
395                                 if (dest[index] != 0)
396                                         index = dest[index] +1;
397                                 dest[index] = byte_len + 1;
398                                 if (is_solicit)
399                                         dest[index+1] = 0x14; /* AD Type */
400                                 else
401                                         dest[index+1] = 0x02; /* AD Type */
402                                 memcpy(&(dest[index + 2]), &src[12], byte_len);
403                                 *length += 4;
404                         }
405
406                         /* Update current type */
407                         prev_byte_len = byte_len;
408                         break;
409                 }
410                 case 4: {
411                         if (prev_byte_len == byte_len) {
412                                 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);;
413                                 *length += 4;
414                                 dest[index] += 4;
415                         } else {
416                                 if (dest[index] != 0)
417                                         index = dest[index] +1;
418                                 dest[index] = byte_len + 1;
419                                 if (is_solicit)
420                                         dest[index+1] = 0x1F; /* AD Type */
421                                 else
422                                         dest[index+1] = 0x04; /* AD Type */
423                                 memcpy(&(dest[index + 2]), &src[12], byte_len);
424                                 *length += 6;
425                         }
426                         /* Update current type */
427                         prev_byte_len = byte_len;
428                         break;
429                 }
430                 case 16: {
431                         if (dest[index] != 0)
432                                 index = dest[index] +1;
433                         dest[index] = byte_len + 1;
434                         if (is_solicit)
435                                 dest[index+1] = 0x15; /* AD Type */
436                         else
437                                 dest[index+1] = 0x06; /* AD Type */
438                         memcpy(&(dest[index + 2]), &src[12], byte_len);
439                         /* Update current type */
440                         prev_byte_len = byte_len;
441                         *length += 18;
442                         break;
443                 }
444                 default: {
445                         ERR("Abnormal Byte len [%d]", byte_len);
446                         break;
447                 }
448                 }
449
450                 /* Process Next 16 bytes of MW UUID */
451                 src += 16;
452                 len -= 16;
453         }
454         DBG("-");
455 }
456
457 static gboolean __bt_hal_is_factory_test_mode(void)
458 {
459         int mode = 0;
460
461         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
462                 ERR("Get the DUT Mode fail");
463                 return TRUE;
464         }
465
466         if (mode != FALSE) {
467                 INFO("DUT Test Mode !!");
468                 return TRUE;
469         }
470
471         return FALSE;
472 }
473
474 static gboolean __bt_hal_adv_event_cb(gpointer param)
475 {
476         bt_hal_adv_event_data_t *event = (bt_hal_adv_event_data_t*)param;
477         DBG("+");
478
479         if (!event)
480                 return FALSE;
481
482         if (!gatt_le_event_cb) {
483                 ERR("GATT event callback not registered!!!");
484                 return FALSE;
485         }
486
487         switch (event->event) {
488         case BT_HAL_MULTI_ADV_ENB_EVT: {
489                 INFO("BLE Advertising enabled slot [%d]", event->server_if);
490                 struct hal_ev_multi_adv_enable ev;
491                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_enable));
492                 ev.status = event->status;
493                 ev.server_instance = event->server_if;
494                 gatt_le_event_cb(HAL_EV_MULTI_ADV_ENABLE, (void *)&ev, sizeof(ev));
495                 break;
496         }
497         case BT_HAL_MULTI_ADV_DISABLE_EVT: {
498                 INFO("BLE Advertising disabled slot [%d]", event->server_if);
499                 struct hal_ev_multi_adv_disable ev;
500                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_disable));
501                 ev.status = event->status;
502                 ev.server_instance = event->server_if;
503                 gatt_le_event_cb(HAL_EV_MULTI_ADV_DISABLE, (void *)&ev, sizeof(ev));
504                 break;
505         }
506         case BT_HAL_MULTI_ADV_PARAM_EVT: {
507                 INFO("Unhandled event slot [%d]", event->server_if);
508                 break;
509         }
510         case BT_HAL_MULTI_ADV_UPDATE_EVT: {
511                 INFO("BLE Advertising Param update slot [%d]", event->server_if);
512                 struct hal_ev_multi_adv_update ev;
513                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_update));
514                 ev.status = event->status;
515                 ev.server_instance = event->server_if;
516                 gatt_le_event_cb(HAL_EV_MULTI_ADV_UPDATE, (void *)&ev, sizeof(ev));
517                 break;
518         }
519         case BT_HAL_MULTI_ADV_DATA_EVT: {
520                 INFO("BLE Advertising data set slot [%d]", event->server_if);
521                 struct hal_ev_multi_adv_data_set ev_data_set;
522                 /* Copy data */
523                 memset(&ev_data_set, 0, sizeof(struct hal_ev_multi_adv_data_set));
524                 ev_data_set.status = event->status;
525                 ev_data_set.server_instance = event->server_if;
526                 gatt_le_event_cb(HAL_EV_MULTI_ADV_DATA_SET, (void *)&ev_data_set, sizeof(ev_data_set));
527                 break;
528         }
529         case BT_HAL_LEGACY_ADV_STATUS: {
530                 INFO("BLE Legacy Advertising [%d]", event->server_if);
531                 struct hal_ev_legacy_adv_status ev;
532                 /* Copy data */
533                 memset(&ev, 0, sizeof(struct hal_ev_legacy_adv_status));
534                 ev.status = event->status;
535                 ev.server_instance = event->server_if;
536                 gatt_le_event_cb(HAL_EV_LEGACY_ADV_ENABLE, (void *)&ev, sizeof(ev));
537                 break;
538         }
539         default:
540                 ERR("Unknown event");
541                 break;
542         }
543
544         g_free(event);
545
546         DBG("-");
547         return FALSE;
548 }
549
550 int _bt_hal_enable_advertising(int server_if, bool enable, bool is_multi_adv)
551 {
552         DBG("+");
553         GError *error = NULL;
554         GVariant *ret;
555         GDBusProxy *proxy;
556
557         proxy = _bt_hal_get_adapter_proxy();
558         if (proxy == NULL)
559                 return BT_STATUS_FAIL;
560
561         if (le_adv_slot[server_if].is_advertising == TRUE && enable == TRUE)
562                 return BT_STATUS_BUSY;
563
564         if (le_adv_slot[server_if].initialized == TRUE &&
565                         le_adv_slot[server_if].is_advertising == FALSE &&
566                         enable == FALSE)
567                 return BT_STATUS_DONE;
568
569         if (le_adv_slot[server_if].hold_timer_id > 0) {
570                 g_source_remove(le_adv_slot[server_if].hold_timer_id);
571                 le_adv_slot[server_if].hold_timer_id = 0;
572         }
573
574         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
575                         g_variant_new("(bi)", enable, server_if),
576                         G_DBUS_CALL_FLAGS_NONE,
577                         -1,
578                         NULL,
579                         &error);
580
581         if (error) {
582                 ERR("SetAdvertising Fail: %s", error->message);
583                 g_clear_error(&error);
584                 return BT_STATUS_FAIL;
585         }
586
587         INFO("Enable advertising [%d] SLot Id [%d] Is Multi? [%d]", enable, server_if, is_multi_adv);
588         if (ret)
589                 g_variant_unref(ret);
590
591         le_adv_slot[server_if].is_multi_adv = is_multi_adv;
592         le_adv_slot[server_if].is_advertising = enable;
593         return BT_STATUS_SUCCESS;
594 }
595
596 int _bt_hal_set_advertising_params(int server_if, int min_interval,
597                 int max_interval, int adv_type,
598                 int chnl_map, int tx_power, int timeout_s)
599 {
600         DBG("+");
601         GDBusProxy *proxy;
602         GVariant *ret;
603         GError *error = NULL;
604         guint32 min = 0;
605         guint32 max = 0;
606         bt_hal_adv_event_data_t *event;
607
608
609         proxy = _bt_hal_get_adapter_proxy();
610         if (proxy == NULL)
611                 return BT_STATUS_FAIL;
612
613         if (min_interval > max_interval ||
614                         min_interval < BT_HAL_ADV_INTERVAL_MIN ||
615                         max_interval > BT_HAL_ADV_INTERVAL_MAX)
616                 return BT_STATUS_PARM_INVALID;
617
618
619         if (adv_type  == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
620                         adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
621                         adv_type == BT_HAL_ADV_NON_CONNECTABLE)
622                 return BT_STATUS_UNSUPPORTED;
623
624
625         min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
626         max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
627
628         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
629                         g_variant_new("(uuuui)", min, max,
630                         BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
631                         server_if), G_DBUS_CALL_FLAGS_NONE,
632                         -1, NULL, &error);
633         if (error) {
634                 ERR("SetAdvertisingParameters Fail: %s", error->message);
635                 g_clear_error(&error);
636                 return BT_STATUS_FAIL;
637         }
638
639         INFO("Set advertising data");
640         if (ret)
641                 g_variant_unref(ret);
642
643         /*
644          * As we need to provide async callback to user from HAL, simply schedule a
645          * callback method which will carry actual result
646          */
647         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
648         event->event  = BT_HAL_MULTI_ADV_UPDATE_EVT;
649         event->server_if = server_if;
650         event->status = BT_STATUS_SUCCESS;
651         g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
652
653         return BT_STATUS_SUCCESS;
654 }
655
656 /* Takes care of both Scan Response and Advertising data */
657 int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
658 {
659         DBG("+");
660         uint8_t adv_data[31];
661         int index = 0;
662         GDBusProxy *proxy;
663         GError *error = NULL;
664         GVariant *ret = NULL;
665         GVariant *temp = NULL;
666         GVariantBuilder *builder;
667         bt_hal_adv_event_data_t *event;
668         int length = 0;
669         int i;
670
671         /* Parse data according to Bluez Interface */
672         if (__bt_hal_is_factory_test_mode()) {
673                 ERR("Unable to set advertising data in factory binary !!");
674                 return BT_STATUS_UNSUPPORTED;
675         }
676
677         /* TODO: Check adapter and LE adapter status */
678         proxy = _bt_hal_get_adapter_proxy();
679         if (proxy == NULL)
680                 return BT_STATUS_FAIL;
681
682         memset(&adv_data, 0, 31);
683
684         /* Service UUID */
685         DBG("Service UUID length [%d]", adv_param_setup.service_uuid_len);
686         if (adv_param_setup.service_uuid_len > 0) {
687                 __bt_hal_parse_uuid(adv_param_setup.service_uuid_len,
688                                 adv_param_setup.service_uuid, &adv_data[index], &length, FALSE);
689                 index = length;
690                 DBG("After Service UUID:Index [%d]", index);
691         }
692
693         /* Solicit UUID */
694         DBG("Solicit UUID length [%d]", adv_param_setup.solicit_uuid_len);
695         if (adv_param_setup.solicit_uuid_len > 0) {
696                 __bt_hal_parse_uuid(adv_param_setup.solicit_uuid_len,
697                                 adv_param_setup.solicit_uuid, &adv_data[index], &length, TRUE);
698                 index = length;
699                 DBG("After Solicit UUID: Index [%d]", index);
700         }
701
702         /* Service Data  UUID*/
703         DBG("Service Data length [%d]", adv_param_setup.service_data_len);
704         if (adv_param_setup.service_data_len > 0) {
705                 adv_data[index] = 1 + adv_param_setup.service_data_len;
706                 adv_data[index+1] = 0x16; /* Fixed */
707                 memcpy(&adv_data[index+2], adv_param_setup.service_data, adv_param_setup.service_data_len);
708                 index += (2 + adv_param_setup.service_data_len);
709                 length += (2 + adv_param_setup.service_data_len);
710                 DBG("After Service data: Index [%d]", index);
711         }
712
713         /* Set Apperance */
714         if (adv_param_setup.appearance > 0) {
715                 adv_data[index] = 0x03;
716                 adv_data[index+1] = 0x19;
717                 adv_data[index+2] = (uint8_t) (adv_param_setup.appearance & 0xFF);
718                 adv_data[index+3] = (uint8_t) ((adv_param_setup.appearance  >> 8) & 0xFF);
719                 index += 4;
720                 length += 4;
721                 DBG("After Apperance: Index [%d]", index);
722         }
723
724         /* TX Power */
725         if (adv_param_setup.include_txpower != 0) {
726                 adv_data[index] = 0x01;
727                 adv_data[index+1] = 0x0A;
728                 index += 2;
729                 length += 2;
730                 DBG("After TX Power: Index [%d]", index);
731         }
732
733         /* Device Name */
734         if (adv_param_setup.include_name != 0) {
735                 adv_data[index] = 0x01;
736                 adv_data[index+1] = 0x09;
737                 index += 2;
738                 length += 2;
739                 DBG("After Name: Index [%d]", index);
740         }
741
742         /* Manufacturer data */
743         if (adv_param_setup.manufacturer_data_len > 0) {
744                 adv_data[index] = 1 + adv_param_setup.manufacturer_data_len;
745                 adv_data[index+1] = 0xFF;
746                 memcpy(&adv_data[index+2], adv_param_setup.manufacturer_data, adv_param_setup.manufacturer_data_len);
747                 index += (2 + adv_param_setup.manufacturer_data_len);
748                 length += (2 + adv_param_setup.manufacturer_data_len);
749                 DBG("After Manuf Data: Index [%d]", index);
750         }
751
752         /* Create Builder */
753         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
754         for (i = 0; i < length; i++)
755                 g_variant_builder_add(builder, "y", adv_data[i]);
756
757         temp = g_variant_new("ay", builder);
758         g_variant_builder_unref(builder);
759
760         DBG("####Adv data length [%d] Index [%d]", length, index);
761         for (i = 0; i < length; i++)
762                 DBG("##Data[%d] [0x%x]", i, adv_data[i]);
763
764         if (adv_param_setup.set_scan_rsp == 0) {
765                 /* Set Advertising data to stack */
766                 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
767                                 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
768                                 G_DBUS_CALL_FLAGS_NONE,
769                                 -1, NULL, &error);
770         } else {
771                 /* Set Scan response data to stack */
772                 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
773                                 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
774                                 G_DBUS_CALL_FLAGS_NONE,
775                                 -1, NULL, &error);
776         }
777
778         if (error) {
779                 ERR("SetAdvertisingData Fail: %s", error->message);
780                 g_clear_error(&error);
781                 return BT_STATUS_FAIL;
782         }
783
784         INFO("Set advertising data");
785         if (ret)
786                 g_variant_unref(ret);
787
788         /*
789          * As we need to provide async callback to user from HAL, simply schedule a
790          * callback method which will carry actual result
791          */
792         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
793         event->event  = BT_HAL_MULTI_ADV_DATA_EVT;
794         event->server_if = adv_param_setup.server_if;
795         event->status = BT_STATUS_SUCCESS;
796         memcpy(&event->data, adv_data, 31);
797         g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
798
799         return BT_STATUS_SUCCESS;
800 }
801
802 int _bt_hal_adapter_le_start_scan(void)
803 {
804         GDBusProxy *proxy;
805         GError *error = NULL;
806         GVariant *ret;
807
808         DBG("+");
809
810         /* TODO: Check adapter and LE adapter status */
811         proxy = _bt_hal_get_adapter_proxy();
812         if (proxy == NULL)
813                 return BT_STATUS_FAIL;
814
815         ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
816                         NULL, G_DBUS_CALL_FLAGS_NONE,
817                         -1, NULL, &error);
818         if (ret == NULL) {
819                 if (error) {
820                         ERR("StartLEDiscovery Fail: %s", error->message);
821                         g_clear_error(&error);
822                 }
823
824                 return BT_STATUS_FAIL;
825         }
826
827         g_variant_unref(ret);
828
829         DBG("-");
830         return BT_STATUS_SUCCESS;
831 }
832
833 int _bt_hal_adapter_le_stop_scan(void)
834 {
835         GDBusProxy *proxy;
836         GError *error = NULL;
837         GVariant *ret;
838
839         DBG("+");
840
841         /* TODO: Check adapter and LE adapter status */
842         proxy = _bt_hal_get_adapter_proxy();
843         if (proxy == NULL)
844                 return BT_STATUS_FAIL;
845
846         ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
847                         NULL, G_DBUS_CALL_FLAGS_NONE,
848                         -1, NULL, &error);
849         if (ret == NULL) {
850                 if (error) {
851                         g_dbus_error_strip_remote_error(error);
852                         ERR("StopLEDiscovery Fail: %s", error->message);
853
854                         /* Abnormal case for ARTIK530 */
855                         if (g_strrstr(error->message, "No discovery started") ||
856                                  g_strrstr(error->message, "Operation already in progress")) {
857                                 g_clear_error(&error);
858                                 return BT_STATUS_SUCCESS;
859                         }
860
861                         g_clear_error(&error);
862                         return BT_STATUS_FAIL;
863                 }
864         }
865
866         g_variant_unref(ret);
867
868         DBG("-");
869         return BT_STATUS_SUCCESS;
870 }
871
872
873 int _bt_hal_adapter_le_set_scan_parameters(
874                 int scan_type, int scan_interval, int scan_window)
875 {
876         GDBusProxy *proxy;
877         GError *error = NULL;
878         GVariant *ret;
879
880         DBG("+");
881
882         /* TODO: Check adapter and LE adapter status */
883         proxy = _bt_hal_get_adapter_proxy();
884         if (proxy == NULL)
885                 return BT_STATUS_FAIL;
886
887         ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
888                         g_variant_new("(uuu)", scan_type, scan_interval, scan_window),
889                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
890         if (ret == NULL) {
891                 if (error) {
892                         ERR("SetScanParameters Fail: %s", error->message);
893                         g_clear_error(&error);
894                 }
895
896                 return BT_STATUS_FAIL;
897         }
898
899         g_variant_unref(ret);
900
901         DBG("-");
902         return BT_STATUS_SUCCESS;
903 }
904
905 /* To send stack event to hal-av handler */
906 void _bt_hal_register_gatt_le_dbus_handler_cb(handle_stack_msg cb)
907 {
908         gatt_le_event_cb = cb;
909 }
910
911 void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
912 {
913         gatt_le_event_cb = NULL;
914 }