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