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