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