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