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