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