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