27b56fb907ee5aeb8ed14a418701cf61ac842da4
[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
122 int _bt_hal_set_le_static_random_address(uint8_t enable)
123 {
124         DBG("+");
125         GError *error = NULL;
126         GVariant *ret;
127         GDBusProxy *proxy;
128
129         proxy = _bt_hal_get_adapter_proxy();
130         if (proxy == NULL)
131                 return BT_STATUS_FAIL;
132
133         ret = g_dbus_proxy_call_sync(proxy, "SetLeStaticRandomAddress",
134                         g_variant_new("(b)", (enable ? TRUE : FALSE)),
135                         G_DBUS_CALL_FLAGS_NONE,
136                         -1,
137                         NULL,
138                         &error);
139
140         if (error) {
141                 ERR("Set static address Fail: %s", error->message);
142                 g_clear_error(&error);
143                 return BT_STATUS_FAIL;
144         }
145
146         INFO("Set le static address [%d]", enable);
147         if (ret)
148                 g_variant_unref(ret);
149
150         return BT_STATUS_SUCCESS;
151 }
152 #endif
153
154 static void __bt_hal_free_le_adv_slot(void)
155 {
156         int i;
157
158         if (le_adv_slot == NULL)
159                 return;
160
161         for (i = 0; i < le_feature_info.adv_inst_max; i++)
162                 memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
163
164         g_free(le_adv_slot);
165         le_adv_slot = NULL;
166 }
167
168 void _bt_hal_unregister_adv_slot_owner(int slot_id)
169 {
170         if (le_adv_slot == NULL)
171                 return;
172         INFO("Unregister Adv Slot [%d]", slot_id);
173         memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
174 }
175
176 int _bt_hal_get_adv_slot_adv_handle(int slot_id)
177 {
178         if (le_adv_slot == NULL)
179                 return 0;
180
181         return le_adv_slot[slot_id].adv_handle;
182 }
183
184 gboolean _bt_hal_is_advertising_in_slot(int slot)
185 {
186         return le_adv_slot[slot].is_advertising;
187 }
188
189 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
190 {
191         bt_hal_adv_event_data_t *event;
192         int adv_slot_id = slot_id;
193         int server_if = 0;
194
195         server_if = bt_hal_gatts_get_server_if(slot_id);
196
197         DBG("Advertising enabled [%s] server_slot [%d] server_if[%d]",  mode ? "TRUE" : "FALSE", slot_id, server_if);
198
199         if (le_adv_slot == NULL)
200                 return;
201
202         le_adv_slot[adv_slot_id].is_advertising = mode;
203
204         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
205         event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
206
207         event->server_if = server_if;
208         event->status = BT_STATUS_SUCCESS;
209         /* To be removed later when we completely descope Legacy Adv concept */
210
211         DBG("adv_slot_id[%d] Is multi ? [%d]", adv_slot_id, le_adv_slot[adv_slot_id].is_multi_adv);
212         if (le_adv_slot[adv_slot_id].is_multi_adv == FALSE)
213                 event->event = BT_HAL_LEGACY_ADV_STATUS;
214
215         if (mode == false ) {
216                 DBG("release the adv_slot");
217                 bt_hal_gatts_release_adv_slot(server_if);
218         }
219
220         __bt_hal_adv_event_cb((gpointer)event);
221 }
222
223 gboolean _bt_hal_is_advertising(void)
224 {
225         int i;
226
227         if (le_adv_slot == NULL)
228                 return FALSE;
229
230         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
231                 if (le_adv_slot[i].is_advertising == TRUE)
232                         return TRUE;
233         }
234
235         return FALSE;
236 }
237
238 int _bt_hal_le_init(void)
239 {
240         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
241         return BT_STATUS_SUCCESS;
242 }
243 void _bt_hal_le_deinit(void)
244 {
245         __bt_hal_free_le_adv_slot();
246 }
247
248 gboolean _bt_hal_update_le_feature_support(const char *item, const char *value,
249                         bt_local_le_features_t *le_features)
250 {
251         if (item == NULL || value == NULL)
252                 return FALSE;
253         if (!le_adv_slot)
254                 _bt_hal_le_init();
255
256         if (g_strcmp0(item, "adv_inst_max") == 0) {
257                 int slot_num;
258
259                 slot_num = atoi(value);
260                 INFO("slot_num:[%d]", slot_num);
261                 if (slot_num < 0) {
262                         ERR("ERR:Advertising MAX instance [%d]", slot_num);
263                         return FALSE;
264                 }
265
266                 if (slot_num != le_feature_info.adv_inst_max) {
267                         __bt_hal_free_le_adv_slot();
268                         le_feature_info.adv_inst_max = slot_num;
269                         INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
270                         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
271                 }
272
273                 INFO("Advertising instance max: [%d]", le_feature_info.adv_inst_max);
274                 /* Fill LE feature bytes */
275                 le_features->max_adv_instance = atoi(value);
276
277         } else if (g_strcmp0(item, "rpa_offloading") == 0) {
278                 le_feature_info.rpa_offloading = atoi(value);
279                 INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
280
281                 /* Fill LE feature bytes */
282                 le_features->rpa_offload_supported = atoi(value);
283
284         } else if (g_strcmp0(item, "max_filter") == 0) {
285                 le_feature_info.max_filter = atoi(value);
286                 INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
287
288                 /* Fill LE feature bytes */
289                 le_features->max_adv_filter_supported = atoi(value);
290
291         } else if (g_strcmp0(item, "2m_phy") == 0) {
292                 if (g_strcmp0(value, "true") == 0) {
293                         le_feature_info.le_2m_phy = TRUE;
294                         /* Fill LE feature bytes */
295                         le_features->le_2m_phy_supported = 0x1;
296                 } else {
297                         le_feature_info.le_2m_phy = FALSE;
298                         /* Fill LE feature bytes */
299                         le_features->le_2m_phy_supported = 0x0;
300                 }
301                 INFO("2M PHY Supported [%s]",  le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
302         } else if (g_strcmp0(item, "coded_phy") == 0) {
303                 if (g_strcmp0(value, "true") == 0) {
304                         le_feature_info.le_coded_phy = TRUE;
305                         /* Fill LE feature bytes */
306                         le_features->le_coded_phy_supported = 0x1;
307                 } else {
308                         le_feature_info.le_coded_phy = FALSE;
309                         /* Fill LE feature bytes */
310                         le_features->le_coded_phy_supported = 0x0;
311                 }
312                 INFO("CODED PHY Supported [%s]",  le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
313         } else {
314                 DBG("No registered item");
315                 return FALSE;
316         }
317
318         return TRUE;
319 }
320
321 void _bt_hal_free_server_slot(int slot_id)
322 {
323         if (le_adv_slot == NULL)
324                 return;
325         memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
326 }
327
328 int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid, gboolean use_reserved_slot)
329 {
330         int i;
331
332         if (le_adv_slot == NULL) {
333                 ERR("le_adv_slot is NULL");
334                 return -1;
335         }
336
337         DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
338
339         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
340                 if (le_adv_slot[i].initialized == 0)
341                         continue;
342                 if (memcmp(uuid->uu, le_adv_slot[i].app_uuid.uu, sizeof(bt_uuid_t)) == 0) {
343                         DBG("UUID [%s] matched, return slot [%d]", btuuid2str(uuid->uu), i);
344                         return i;
345                 }
346         }
347
348         /* We should consider 'use_reverved_slot' in later */
349         if (le_feature_info.adv_inst_max <= 1)
350                 i = 0;
351         else if (use_reserved_slot == TRUE)
352                 i = 1;
353         else
354                 i = 2;
355
356         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
357                 if (le_adv_slot[i].initialized == 0) {
358                         DBG("Slot to be allocated [%d] UUID to be registered [%s]",
359                                 i, btuuid2str(uuid->uu));
360                         le_adv_slot[i].initialized = 1;
361                         memcpy(&le_adv_slot[i].app_uuid.uu, &uuid->uu, sizeof(bt_uuid_t));
362                         return i;
363                 }
364         }
365
366         return -1;
367 }
368
369 void _bt_hal_get_gatt_server_instance_initialized(int *instance)
370 {
371         int i;
372         if (le_adv_slot == NULL) {
373                 ERR("le_adv_slot is NULL");
374                 return;
375         }
376
377         DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
378
379         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
380                 if (le_adv_slot[i].initialized == 0)
381                         continue;
382                 DBG("Initialized Slot found: UUID [%s] slot [%d]", le_adv_slot[i].app_uuid.uu, i);
383                 *instance = i;
384                 break;
385         }
386 }
387
388 gboolean _bt_is_advertising(void)
389 {
390         return FALSE;
391 }
392
393 int _bt_set_advertising(const char *sender, int adv_handle,
394                         gboolean enable, gboolean use_reserved_slot)
395 {
396         DBG("+");
397         return BT_STATUS_UNSUPPORTED;
398 }
399
400 static int __bt_hal_uuid_type(uint8_t* p_uuid)
401 {
402         int i = 0;
403         int match = 0;
404         int all_zero = 1;
405
406         for (i = 0; i != 16; ++i) {
407                 if (i == 12 || i == 13)
408                         continue;
409
410                 if (p_uuid[i] == BASE_UUID_CONVERTED[i])
411                         ++match;
412
413                 if (p_uuid[i] != 0)
414                         all_zero = 0;
415         }
416         if (all_zero)
417                 return 0;
418         if (match == 12)
419                 return BT_HAL_UUID_32;
420         if (match == 14)
421                 return BT_HAL_UUID_16;
422         return BT_HAL_UUID_128;
423 }
424
425 static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length, int is_solicit)
426 {
427         DBG("+");
428         int prev_byte_len = 0;
429         /* dest[index] will contain the length followed by AD Type
430            Move length only when different byte_len is found Ex) 2->4, 2->16, 4->16 etc */
431         int index = 0;
432
433         while (len >= 16) {
434
435                 /* Create Local buffer & copy source 16 bytes in sequence */
436                 int byte_len;
437                 bt_uuid_t uuid;
438                 memset(&uuid, 0, sizeof(bt_uuid_t));
439                 memcpy(&uuid.uu, src, 16);
440
441                 /* Compute current UUID's byte length */
442                 byte_len = __bt_hal_uuid_type(uuid.uu);
443
444                 switch (byte_len) {
445                 case 2: {
446                         if (prev_byte_len == byte_len) {
447                                 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);
448                                 *length += 2;
449                                 dest[index] += 2;
450                         } else {
451                                 if (dest[index] != 0)
452                                         index = dest[index] +1;
453                                 dest[index] = byte_len + 1;
454                                 if (is_solicit)
455                                         dest[index+1] = 0x14; /* AD Type */
456                                 else
457                                         dest[index+1] = 0x02; /* AD Type */
458                                 memcpy(&(dest[index + 2]), &src[12], byte_len);
459                                 *length += 4;
460                         }
461
462                         /* Update current type */
463                         prev_byte_len = byte_len;
464                         break;
465                 }
466                 case 4: {
467                         if (prev_byte_len == byte_len) {
468                                 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);;
469                                 *length += 4;
470                                 dest[index] += 4;
471                         } else {
472                                 if (dest[index] != 0)
473                                         index = dest[index] +1;
474                                 dest[index] = byte_len + 1;
475                                 if (is_solicit)
476                                         dest[index+1] = 0x1F; /* AD Type */
477                                 else
478                                         dest[index+1] = 0x04; /* AD Type */
479                                 memcpy(&(dest[index + 2]), &src[12], byte_len);
480                                 *length += 6;
481                         }
482                         /* Update current type */
483                         prev_byte_len = byte_len;
484                         break;
485                 }
486                 case 16: {
487                         if (dest[index] != 0)
488                                 index = dest[index] +1;
489                         dest[index] = byte_len + 1;
490                         if (is_solicit)
491                                 dest[index+1] = 0x15; /* AD Type */
492                         else
493                                 dest[index+1] = 0x06; /* AD Type */
494                         memcpy(&(dest[index + 2]), &src[12], byte_len);
495                         /* Update current type */
496                         prev_byte_len = byte_len;
497                         *length += 18;
498                         break;
499                 }
500                 default: {
501                         ERR("Abnormal Byte len [%d]", byte_len);
502                         break;
503                 }
504                 }
505
506                 /* Process Next 16 bytes of MW UUID */
507                 src += 16;
508                 len -= 16;
509         }
510         DBG("-");
511 }
512
513 static gboolean __bt_hal_is_factory_test_mode(void)
514 {
515         int mode = 0;
516
517         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
518                 ERR("Get the DUT Mode fail");
519                 return TRUE;
520         }
521
522         if (mode != FALSE) {
523                 INFO("DUT Test Mode !!");
524                 return TRUE;
525         }
526
527         return FALSE;
528 }
529
530 static gboolean __bt_hal_adv_event_cb(gpointer param)
531 {
532         bt_hal_adv_event_data_t *event = (bt_hal_adv_event_data_t*)param;
533         DBG("+");
534
535         if (!event)
536                 return FALSE;
537
538         if (!gatt_le_event_cb) {
539                 ERR("GATT event callback not registered!!!");
540                 return FALSE;
541         }
542
543         switch (event->event) {
544         case BT_HAL_MULTI_ADV_ENB_EVT: {
545                 INFO("BLE Advertising enabled slot [%d]", event->server_if);
546                 struct hal_ev_multi_adv_enable ev;
547                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_enable));
548                 ev.status = event->status;
549                 ev.server_instance = event->server_if;
550                 gatt_le_event_cb(HAL_EV_MULTI_ADV_ENABLE, (void *)&ev, sizeof(ev));
551                 break;
552         }
553         case BT_HAL_MULTI_ADV_DISABLE_EVT: {
554                 INFO("BLE Advertising disabled slot [%d]", event->server_if);
555                 struct hal_ev_multi_adv_disable ev;
556                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_disable));
557                 ev.status = event->status;
558                 ev.server_instance = event->server_if;
559                 gatt_le_event_cb(HAL_EV_MULTI_ADV_DISABLE, (void *)&ev, sizeof(ev));
560                 break;
561         }
562         case BT_HAL_MULTI_ADV_PARAM_EVT: {
563                 INFO("Unhandled event slot [%d]", event->server_if);
564                 break;
565         }
566         case BT_HAL_MULTI_ADV_UPDATE_EVT: {
567                 INFO("BLE Advertising Param update slot [%d]", event->server_if);
568                 struct hal_ev_multi_adv_update ev;
569                 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_update));
570                 ev.status = event->status;
571                 ev.server_instance = event->server_if;
572                 gatt_le_event_cb(HAL_EV_MULTI_ADV_UPDATE, (void *)&ev, sizeof(ev));
573                 break;
574         }
575         case BT_HAL_MULTI_ADV_DATA_EVT: {
576                 INFO("BLE Advertising data set slot [%d]", event->server_if);
577                 struct hal_ev_multi_adv_data_set ev_data_set;
578                 /* Copy data */
579                 memset(&ev_data_set, 0, sizeof(struct hal_ev_multi_adv_data_set));
580                 ev_data_set.status = event->status;
581                 ev_data_set.server_instance = event->server_if;
582                 gatt_le_event_cb(HAL_EV_MULTI_ADV_DATA_SET, (void *)&ev_data_set, sizeof(ev_data_set));
583                 break;
584         }
585         case BT_HAL_LEGACY_ADV_STATUS: {
586                 INFO("BLE Legacy Advertising [%d]", event->server_if);
587                 struct hal_ev_legacy_adv_status ev;
588                 /* Copy data */
589                 memset(&ev, 0, sizeof(struct hal_ev_legacy_adv_status));
590                 ev.status = event->status;
591                 ev.server_instance = event->server_if;
592                 gatt_le_event_cb(HAL_EV_LEGACY_ADV_ENABLE, (void *)&ev, sizeof(ev));
593                 break;
594         }
595         default:
596                 ERR("Unknown event");
597                 break;
598         }
599
600         g_free(event);
601
602         DBG("-");
603         return FALSE;
604 }
605
606 int _bt_hal_enable_advertising(int server_if, int adv_slot_id, bool enable, bool is_multi_adv)
607 {
608         DBG("+");
609         GError *error = NULL;
610         GVariant *ret;
611         GDBusProxy *proxy;
612
613         proxy = _bt_hal_get_adapter_proxy();
614         if (proxy == NULL)
615                 return BT_STATUS_FAIL;
616
617         if (le_adv_slot[adv_slot_id].is_advertising == TRUE && enable == TRUE)
618                 return BT_STATUS_BUSY;
619
620         if (le_adv_slot[adv_slot_id].initialized == TRUE &&
621                         le_adv_slot[adv_slot_id].is_advertising == FALSE &&
622                         enable == FALSE)
623                 return BT_STATUS_DONE;
624
625         if (le_adv_slot[adv_slot_id].hold_timer_id > 0) {
626                 g_source_remove(le_adv_slot[adv_slot_id].hold_timer_id);
627                 le_adv_slot[adv_slot_id].hold_timer_id = 0;
628         }
629
630         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
631                         g_variant_new("(bi)", enable, adv_slot_id),
632                         G_DBUS_CALL_FLAGS_NONE,
633                         -1,
634                         NULL,
635                         &error);
636
637         if (error) {
638                 ERR("SetAdvertising Fail: %s", error->message);
639                 g_clear_error(&error);
640                 return BT_STATUS_FAIL;
641         }
642
643         INFO("Enable advertising [%d] SLot Id [%d] gatt_server [%d] Is Multi? [%d]",
644                                 enable, adv_slot_id, server_if, is_multi_adv);
645         if (ret)
646                 g_variant_unref(ret);
647
648         le_adv_slot[adv_slot_id].is_multi_adv = is_multi_adv;
649         le_adv_slot[adv_slot_id].is_advertising = enable;
650         return BT_STATUS_SUCCESS;
651 }
652
653 int _bt_hal_set_advertising_params(int server_if, int min_interval,
654                 int max_interval, int adv_type,
655                 int chnl_map, int tx_power, int timeout_s)
656 {
657         DBG("+");
658         GDBusProxy *proxy;
659         GVariant *ret;
660         GError *error = NULL;
661         guint32 min = 0;
662         guint32 max = 0;
663         bt_hal_adv_event_data_t *event;
664         int slot_id = 0;
665
666
667         proxy = _bt_hal_get_adapter_proxy();
668         if (proxy == NULL)
669                 return BT_STATUS_FAIL;
670
671         if (min_interval > max_interval ||
672                         min_interval < BT_HAL_ADV_INTERVAL_MIN ||
673                         max_interval > BT_HAL_ADV_INTERVAL_MAX)
674                 return BT_STATUS_PARM_INVALID;
675
676
677         if (adv_type  == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
678                         adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
679                         adv_type == BT_HAL_ADV_NON_CONNECTABLE)
680                 return BT_STATUS_UNSUPPORTED;
681
682
683         min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
684         max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
685
686         slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(server_if);
687
688         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
689                         g_variant_new("(uuuuii)", min, max,
690                         BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
691                         tx_power, slot_id), G_DBUS_CALL_FLAGS_NONE,
692                         -1, NULL, &error);
693         if (error) {
694                 ERR("SetAdvertisingParameters Fail: %s", error->message);
695                 g_clear_error(&error);
696                 return BT_STATUS_FAIL;
697         }
698
699         INFO("Set advertising data");
700         if (ret)
701                 g_variant_unref(ret);
702
703         /*
704          * As we need to provide async callback to user from HAL, simply schedule a
705          * callback method which will carry actual result
706          */
707         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
708         event->event  = BT_HAL_MULTI_ADV_UPDATE_EVT;
709         event->server_if = server_if;
710         event->status = BT_STATUS_SUCCESS;
711         g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
712
713         return BT_STATUS_SUCCESS;
714 }
715
716 /* Takes care of both Scan Response and Advertising data */
717 int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
718 {
719         DBG("+");
720         uint8_t adv_data[31];
721         int index = 0;
722         GDBusProxy *proxy;
723         GError *error = NULL;
724         GVariant *ret = NULL;
725         GVariant *temp = NULL;
726         GVariantBuilder *builder;
727         bt_hal_adv_event_data_t *event;
728         int length = 0;
729         int i;
730         int slot_id = 0;
731
732         /* Parse data according to Bluez Interface */
733         if (__bt_hal_is_factory_test_mode()) {
734                 ERR("Unable to set advertising data in factory binary !!");
735                 return BT_STATUS_UNSUPPORTED;
736         }
737
738         /* TODO: Check adapter and LE adapter status */
739         proxy = _bt_hal_get_adapter_proxy();
740         if (proxy == NULL)
741                 return BT_STATUS_FAIL;
742
743         slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(adv_param_setup.server_if);
744
745         memset(&adv_data, 0, 31);
746
747         /* Service UUID */
748         DBG("Service UUID length [%d]", adv_param_setup.service_uuid_len);
749         if (adv_param_setup.service_uuid_len > 0) {
750                 __bt_hal_parse_uuid(adv_param_setup.service_uuid_len,
751                                 adv_param_setup.service_uuid, &adv_data[index], &length, FALSE);
752                 index = length;
753                 DBG("After Service UUID:Index [%d]", index);
754         }
755
756         /* Solicit UUID */
757         DBG("Solicit UUID length [%d]", adv_param_setup.solicit_uuid_len);
758         if (adv_param_setup.solicit_uuid_len > 0) {
759                 __bt_hal_parse_uuid(adv_param_setup.solicit_uuid_len,
760                                 adv_param_setup.solicit_uuid, &adv_data[index], &length, TRUE);
761                 index = length;
762                 DBG("After Solicit UUID: Index [%d]", index);
763         }
764
765         /* Service Data  UUID*/
766         DBG("Service Data length [%d]", adv_param_setup.service_data_len);
767         if (adv_param_setup.service_data_len > 0) {
768                 adv_data[index] = 1 + adv_param_setup.service_data_len;
769                 adv_data[index+1] = 0x16; /* Fixed */
770                 memcpy(&adv_data[index+2], adv_param_setup.service_data, adv_param_setup.service_data_len);
771                 index += (2 + adv_param_setup.service_data_len);
772                 length += (2 + adv_param_setup.service_data_len);
773                 DBG("After Service data: Index [%d]", index);
774         }
775
776         /* Set Apperance */
777         if (adv_param_setup.appearance > 0) {
778                 adv_data[index] = 0x03;
779                 adv_data[index+1] = 0x19;
780                 adv_data[index+2] = (uint8_t) (adv_param_setup.appearance & 0xFF);
781                 adv_data[index+3] = (uint8_t) ((adv_param_setup.appearance  >> 8) & 0xFF);
782                 index += 4;
783                 length += 4;
784                 DBG("After Apperance: Index [%d]", index);
785         }
786
787         /* TX Power */
788         if (adv_param_setup.include_txpower != 0) {
789                 adv_data[index] = 0x01;
790                 adv_data[index+1] = 0x0A;
791                 index += 2;
792                 length += 2;
793                 DBG("After TX Power: Index [%d]", index);
794         }
795
796         /* Device Name */
797         if (adv_param_setup.include_name != 0) {
798                 adv_data[index] = 0x01;
799                 adv_data[index+1] = 0x09;
800                 index += 2;
801                 length += 2;
802                 DBG("After Name: Index [%d]", index);
803         }
804
805         /* Manufacturer data */
806         if (adv_param_setup.manufacturer_data_len > 0) {
807                 adv_data[index] = 1 + adv_param_setup.manufacturer_data_len;
808                 adv_data[index+1] = 0xFF;
809                 memcpy(&adv_data[index+2], adv_param_setup.manufacturer_data, adv_param_setup.manufacturer_data_len);
810                 index += (2 + adv_param_setup.manufacturer_data_len);
811                 length += (2 + adv_param_setup.manufacturer_data_len);
812                 DBG("After Manuf Data: Index [%d]", index);
813         }
814
815         /* Create Builder */
816         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
817         for (i = 0; i < length; i++)
818                 g_variant_builder_add(builder, "y", adv_data[i]);
819
820         temp = g_variant_new("ay", builder);
821         g_variant_builder_unref(builder);
822
823         DBG("####Adv data length [%d] Index [%d]", length, index);
824         for (i = 0; i < length; i++)
825                 DBG("##Data[%d] [0x%x]", i, adv_data[i]);
826
827         if (adv_param_setup.set_scan_rsp == 0) {
828                 /* Set Advertising data to stack */
829                 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
830                                 g_variant_new("(@ayi)", temp, slot_id),
831                                 G_DBUS_CALL_FLAGS_NONE,
832                                 -1, NULL, &error);
833         } else {
834                 /* Set Scan response data to stack */
835                 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
836                                 g_variant_new("(@ayi)", temp, slot_id),
837                                 G_DBUS_CALL_FLAGS_NONE,
838                                 -1, NULL, &error);
839         }
840
841         if (error) {
842                 ERR("SetAdvertisingData Fail: %s", error->message);
843                 g_clear_error(&error);
844                 return BT_STATUS_FAIL;
845         }
846
847         INFO("Set advertising data");
848         if (ret)
849                 g_variant_unref(ret);
850
851         /*
852          * As we need to provide async callback to user from HAL, simply schedule a
853          * callback method which will carry actual result
854          */
855         event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
856         event->event  = BT_HAL_MULTI_ADV_DATA_EVT;
857         event->server_if = adv_param_setup.server_if;
858         event->status = BT_STATUS_SUCCESS;
859         memcpy(&event->data, adv_data, 31);
860         g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
861
862         return BT_STATUS_SUCCESS;
863 }
864
865 int _bt_hal_adapter_le_start_scan(void)
866 {
867         GDBusProxy *proxy;
868         GError *error = NULL;
869         GVariant *ret;
870
871         DBG("+");
872
873         /* TODO: Check adapter and LE adapter status */
874         proxy = _bt_hal_get_adapter_proxy();
875         if (proxy == NULL)
876                 return BT_STATUS_FAIL;
877
878         ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
879                         NULL, G_DBUS_CALL_FLAGS_NONE,
880                         -1, NULL, &error);
881         if (ret == NULL) {
882                 if (error) {
883                         ERR("StartLEDiscovery Fail: %s", error->message);
884                         g_clear_error(&error);
885                 }
886
887                 return BT_STATUS_FAIL;
888         }
889
890         g_variant_unref(ret);
891
892         DBG("-");
893         return BT_STATUS_SUCCESS;
894 }
895
896 int _bt_hal_adapter_le_stop_scan(void)
897 {
898         GDBusProxy *proxy;
899         GError *error = NULL;
900         GVariant *ret;
901
902         DBG("+");
903
904         /* TODO: Check adapter and LE adapter status */
905         proxy = _bt_hal_get_adapter_proxy();
906         if (proxy == NULL)
907                 return BT_STATUS_FAIL;
908
909         ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
910                         NULL, G_DBUS_CALL_FLAGS_NONE,
911                         -1, NULL, &error);
912         if (ret == NULL) {
913                 if (error) {
914                         g_dbus_error_strip_remote_error(error);
915                         ERR("StopLEDiscovery Fail: %s", error->message);
916
917                         /* Abnormal case for ARTIK530 */
918                         if (g_strrstr(error->message, "No discovery started") ||
919                                  g_strrstr(error->message, "Operation already in progress")) {
920                                 g_clear_error(&error);
921                                 return BT_STATUS_SUCCESS;
922                         }
923
924                         g_clear_error(&error);
925                         return BT_STATUS_FAIL;
926                 }
927         }
928
929         g_variant_unref(ret);
930
931         DBG("-");
932         return BT_STATUS_SUCCESS;
933 }
934
935 /*sets the privacy functionality of the adapter*/
936 int _bt_hal_adapter_le_set_privacy(uint8_t set_privacy)
937 {
938         GDBusProxy *proxy;
939         GError *error = NULL;
940         GVariant *result = NULL;
941         proxy = _bt_hal_get_adapter_proxy();
942         if (proxy == NULL)
943                 return BT_STATUS_FAIL;
944
945         result = g_dbus_proxy_call_sync(proxy,
946                                 "SetLePrivacy",
947                                 g_variant_new("(b)", set_privacy),
948                                 G_DBUS_CALL_FLAGS_NONE,
949                                 -1,
950                                 NULL,
951                                 &error);
952
953         if (!result) {
954                 if (error != NULL) {
955                         ERR("Failed to SetLePrivacy (Error: %s)", error->message);
956                         g_clear_error(&error);
957                 } else
958                         ERR("Failed to SetLePrivacy");
959                 return BT_STATUS_FAIL;
960         }
961
962         g_variant_unref(result);
963         INFO("SetLePrivacy as %d", set_privacy);
964         return BT_STATUS_SUCCESS;
965 }
966
967 int _bt_hal_adapter_le_set_scan_parameters(
968                 int scan_type, int scan_interval, int scan_window)
969 {
970         GDBusProxy *proxy;
971         GError *error = NULL;
972         GVariant *ret;
973
974         DBG("+");
975
976         /* TODO: Check adapter and LE adapter status */
977         proxy = _bt_hal_get_adapter_proxy();
978         if (proxy == NULL)
979                 return BT_STATUS_FAIL;
980
981         ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
982                         g_variant_new("(uuu)", scan_type, scan_interval, scan_window),
983                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
984         if (ret == NULL) {
985                 if (error) {
986                         ERR("SetScanParameters Fail: %s", error->message);
987                         g_clear_error(&error);
988                 }
989
990                 return BT_STATUS_FAIL;
991         }
992
993         g_variant_unref(ret);
994
995         DBG("-");
996         return BT_STATUS_SUCCESS;
997 }
998
999 /* To send stack event to hal-av handler */
1000 void _bt_hal_register_gatt_le_dbus_handler_cb(handle_stack_msg cb)
1001 {
1002         gatt_le_event_cb = cb;
1003 }
1004
1005 void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
1006 {
1007         gatt_le_event_cb = NULL;
1008 }
1009
1010 int _bt_hal_adapter_le_set_manufacturer_data(bt_manufacturer_data_t *m_data)
1011 {
1012         GDBusProxy *proxy;
1013         GError *error = NULL;
1014         int i;
1015         GVariant *val;
1016         GVariant *ret;
1017         GVariantBuilder *builder;
1018
1019         proxy = _bt_hal_get_adapter_proxy();
1020         if (proxy == NULL)
1021                 return BT_STATUS_FAIL;
1022
1023         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1024
1025         if (m_data->data_len + 2 >= BT_MANUFACTURER_DATA_LENGTH_MAX)
1026                 return BT_STATUS_PARM_INVALID;
1027         for (i = 0; i < (m_data->data_len) + 2; i++)
1028                 g_variant_builder_add(builder, "y", m_data->data[i]);
1029
1030         val = g_variant_new("(ay)", builder);
1031
1032         ret = g_dbus_proxy_call_sync(proxy,
1033                                 "SetManufacturerData",
1034                                 val,
1035                                 G_DBUS_CALL_FLAGS_NONE,
1036                                 -1,
1037                                 NULL,
1038                                 &error);
1039         g_variant_builder_unref(builder);
1040         if (!ret) {
1041                 if (error != NULL) {
1042                         ERR("Failed to SetManufacturerData (Error: %s)", error->message);
1043                         g_clear_error(&error);
1044                 } else {
1045                         ERR("Failed to SetManufacturerData");
1046                 }
1047                 return BT_STATUS_FAIL;
1048         }
1049
1050         INFO("Set manufacturer data");
1051         g_variant_unref(ret);
1052
1053         return BT_STATUS_SUCCESS;
1054 }
1055
1056
1057
1058 /*add/remove remote device address from white list*/
1059 int _bt_hal_adapter_le_set_white_list(bt_bdaddr_t *device_address, bt_dev_addr_type_t address_type, bool is_add)
1060 {
1061         GDBusProxy *proxy;
1062         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1063         GError *error = NULL;
1064         GVariant *ret;
1065
1066         if (address_type != BLUETOOTH_HAL_DEVICE_PUBLIC_ADDRESS &&
1067                 address_type != BLUETOOTH_HAL_DEVICE_RANDOM_ADDRESS)
1068                 return BT_STATUS_PARM_INVALID;
1069
1070         _bt_hal_convert_addr_type_to_string(address, device_address->address);
1071
1072         proxy = _bt_hal_get_adapter_proxy();
1073         if (proxy == NULL)
1074                 return BT_STATUS_FAIL;
1075         if (is_add)
1076                 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1077                                 g_variant_new("(su)", address, address_type),
1078                                 G_DBUS_CALL_FLAGS_NONE, -1,
1079                                 NULL, &error);
1080         else
1081                 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1082                                 g_variant_new("(su)", address, address_type),
1083                                 G_DBUS_CALL_FLAGS_NONE, -1,
1084                                 NULL, &error);
1085
1086         if (error) {
1087                 if (is_add)
1088                         ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1089                 else
1090                         ERR("AddDeviceWhiteList Fail: %s", error->message);
1091                 g_clear_error(&error);
1092                 return BT_STATUS_FAIL;
1093         }
1094
1095         if (ret)
1096                 g_variant_unref(ret);
1097         if (is_add)
1098                 INFO("Device Added to white list");
1099         else
1100                 INFO("Device Removed from white list");
1101         return BT_STATUS_SUCCESS;
1102 }