Remove journal related codes
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter-le.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <stdio.h>
25 //#include <dbus/dbus-glib.h>
26 //#include <dbus/dbus.h>
27 #include <gio/gio.h>
28 #include <glib.h>
29 #include <dlog.h>
30 #include <string.h>
31 #include <vconf.h>
32 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
33 #include <syspopup_caller.h>
34 #endif
35 #include <aul.h>
36
37 #include "bt-internal-types.h"
38 #include "bt-service-common.h"
39 #include "bt-service-event.h"
40 #include "bt-service-adapter.h"
41 #include "bt-service-adapter-le.h"
42
43
44 #define BT_ADV_INTERVAL_MIN 20 /* msec */
45 #define BT_ADV_INTERVAL_MAX 10240
46 #define BT_ADV_INTERVAL_SPLIT 0.625
47 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
48 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
49 #define BT_ADV_FILTER_POLICY_DEFAULT    0x00
50 #define BT_ADV_TYPE_DEFAULT     0x00
51 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY    0x03
52
53 typedef struct {
54         int adv_inst_max;
55         int rpa_offloading;
56         int max_filter;
57 } bt_adapter_le_feature_info_t;
58
59 typedef struct {
60         char *sender;
61         int adv_handle;
62         gboolean is_advertising;
63 } bt_adapter_le_adv_slot_t;
64
65 typedef struct {
66         char *sender;
67         GSList *filter_list;
68         gboolean is_scanning;
69 } bt_adapter_le_scanner_t;
70
71 static bluetooth_advertising_params_t adv_params = {
72         BT_DEFAULT_ADV_MIN_INTERVAL,
73         BT_DEFAULT_ADV_MAX_INTERVAL,
74         BT_ADV_FILTER_POLICY_DEFAULT,
75         BT_ADV_TYPE_DEFAULT};
76 static bluetooth_advertising_data_t adv_data = { {0} };
77 static int adv_data_len;
78 static bluetooth_scan_resp_data_t resp_data = { {0} };
79 static int resp_data_len;
80
81 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
82 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
83
84 GSList *scanner_list = NULL;
85 static gboolean is_le_set_scan_parameter = FALSE;
86 static gboolean is_le_scanning = FALSE;
87 static gboolean scan_filter_enabled = FALSE;
88 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
89
90 void __bt_free_le_adv_slot(void)
91 {
92         int i;
93
94         if (le_adv_slot == NULL)
95                 return;
96
97         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
98                 if (le_adv_slot[i].sender)
99                         g_free(le_adv_slot[i].sender);
100         }
101         g_free(le_adv_slot);
102         le_adv_slot = NULL;
103 }
104
105 int _bt_service_adapter_le_init(void)
106 {
107         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
108
109         return BLUETOOTH_ERROR_NONE;
110 }
111
112 void _bt_service_adapter_le_deinit(void)
113 {
114         __bt_free_le_adv_slot();
115 }
116
117 gboolean _bt_update_le_feature_support(const char *item, const char *value)
118 {
119         if (item== NULL || value == NULL)
120                 return FALSE;
121
122         if (g_strcmp0(item, "adv_inst_max") == 0) {
123                 if (atoi(value) != le_feature_info.adv_inst_max) {
124                         __bt_free_le_adv_slot();
125                         le_feature_info.adv_inst_max = atoi(value);
126                         le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
127                 }
128         } else if (g_strcmp0(item, "rpa_offloading") == 0) {
129                 le_feature_info.rpa_offloading = atoi(value);
130         } else if (g_strcmp0(item, "max_filter") == 0) {
131                 le_feature_info.max_filter = atoi(value);
132         } else {
133                 BT_DBG("No registered item");
134                 return FALSE;
135         }
136
137         return TRUE;
138 }
139
140 static gboolean __bt_is_factory_test_mode(void)
141 {
142         int mode = 0;
143 #ifdef ENABLE_TIZEN_2_4
144         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
145                 BT_ERR("Get the DUT Mode fail");
146                 return TRUE;
147         }
148 #endif
149         if (mode != FALSE) {
150                 BT_INFO("DUT Test Mode !!");
151                 return TRUE;
152         }
153
154         return FALSE;
155 }
156
157 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
158 {
159         int i;
160
161         if (le_adv_slot == NULL)
162                 return -1;
163
164         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
165                 if (le_adv_slot[i].sender == NULL)
166                         continue;
167                 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
168                         return i;
169         }
170
171         if (le_feature_info.adv_inst_max <= 2)
172                 i = 0;
173         else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
174                 i = 0;
175         else
176                 i = 2;
177
178         for (; i < le_feature_info.adv_inst_max; i++) {
179                 if (le_adv_slot[i].sender == NULL)
180                         return i;
181         }
182
183         return -1;
184 }
185
186 void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
187 {
188         if (le_adv_slot[slot_id].sender == NULL) {
189                 le_adv_slot[slot_id].sender = strdup(sender);
190                 le_adv_slot[slot_id].adv_handle = adv_handle;
191         }
192 }
193
194 void __bt_unregister_adv_slot_owner(int slot_id)
195 {
196         g_free(le_adv_slot[slot_id].sender);
197         le_adv_slot[slot_id].sender = NULL;
198         le_adv_slot[slot_id].adv_handle = 0;
199 }
200
201 const char* _bt_get_adv_slot_owner(int slot_id)
202 {
203         if (le_adv_slot == NULL)
204                 return NULL;
205
206         return le_adv_slot[slot_id].sender;
207 }
208
209 int _bt_get_adv_slot_adv_handle(int slot_id)
210 {
211         if (le_adv_slot == NULL)
212                 return 0;
213
214         return le_adv_slot[slot_id].adv_handle;
215 }
216
217 void _bt_set_advertising_status(int slot_id, gboolean mode)
218 {
219         le_adv_slot[slot_id].is_advertising = mode;
220 }
221
222 gboolean _bt_is_advertising(void)
223 {
224         gboolean status = FALSE;
225         int i;
226
227         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
228                 if (le_adv_slot[i].is_advertising == TRUE)
229                         status = TRUE;
230         }
231
232         return status;
233 }
234
235 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
236 {
237         int i;
238
239         if (le_adv_slot == NULL)
240                 return;
241
242         for (i = 0; i < le_feature_info.adv_inst_max; i++) {
243                 if (le_adv_slot[i].sender != NULL) {
244                         if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
245                                 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
246                                 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
247                         }
248                 }
249         }
250 }
251
252 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
253 {
254         if (params == NULL)
255                 return FALSE;
256
257         memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
258
259         return TRUE;
260 }
261
262 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
263 {
264         GDBusProxy *proxy;
265         GError *error = NULL;
266         GVariant *ret;
267         int slot_id;
268
269         if (__bt_is_factory_test_mode()) {
270                 BT_ERR("Unable to start advertising in factory binary !!");
271                 return BLUETOOTH_ERROR_NOT_SUPPORT;
272         }
273
274         if (_bt_adapter_get_status() != BT_ACTIVATED &&
275                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
276                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
277         }
278
279         slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
280         if (slot_id == -1) {
281                 BT_ERR("There is NO available slot!!");
282                 return BLUETOOTH_ERROR_NO_RESOURCES;
283         }
284
285         if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
286                 return BLUETOOTH_ERROR_IN_PROGRESS;
287
288         if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
289                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
290
291         proxy = _bt_get_adapter_proxy();
292         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
293
294         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
295                                 g_variant_new("(bi)", enable, slot_id),
296                                 G_DBUS_CALL_FLAGS_NONE,
297                                 -1,
298                                 NULL,
299                                 &error);
300
301         if (error) {
302                 BT_ERR("SetAdvertising Fail: %s", error->message);
303                 g_clear_error(&error);
304                 return BLUETOOTH_ERROR_INTERNAL;
305         }
306
307         if (enable == TRUE)
308                 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
309
310         le_adv_slot[slot_id].is_advertising = enable;
311         BT_INFO("Set advertising [%d]", enable);
312
313         if (ret)
314                 g_variant_unref(ret);
315
316         return BLUETOOTH_ERROR_NONE;
317 }
318
319 int _bt_set_custom_advertising(const char *sender, int adv_handle,
320                                 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
321 {
322         GDBusProxy *proxy;
323         GVariant *ret;
324         GError *error = NULL;
325         guint32 min = 0;
326         guint32 max = 0;
327         int slot_id;
328
329         BT_CHECK_PARAMETER(params, return);
330
331         if (__bt_is_factory_test_mode()) {
332                 BT_ERR("Unable to start advertising in factory binary !!");
333                 return BLUETOOTH_ERROR_NOT_SUPPORT;
334         }
335
336         if (_bt_adapter_get_status() != BT_ACTIVATED &&
337                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
338                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
339         }
340
341         slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
342         if (slot_id == -1) {
343                 BT_ERR("There is NO available slot!!");
344                 return BLUETOOTH_ERROR_NO_RESOURCES;
345         }
346
347         if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
348                 return BLUETOOTH_ERROR_IN_PROGRESS;
349
350         if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
351                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
352
353         proxy = _bt_get_adapter_proxy();
354         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
355
356         if (params->interval_min > params->interval_max ||
357                         params->interval_min < BT_ADV_INTERVAL_MIN ||
358                         params->interval_max > BT_ADV_INTERVAL_MAX)
359                 return BLUETOOTH_ERROR_INVALID_PARAM;
360
361         if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
362                 return BLUETOOTH_ERROR_INVALID_PARAM;
363
364         if (params->type  == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
365                         params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
366                         params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
367                 return BLUETOOTH_ERROR_NOT_SUPPORT;
368
369         min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
370         max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
371
372         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
373                         g_variant_new("(uuuui)", min, max, 
374                         params->filter_policy, params->type,
375                         slot_id), G_DBUS_CALL_FLAGS_NONE,
376                         -1, NULL, &error);
377
378         if (error) {
379                 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
380                 g_clear_error(&error);
381                 return BLUETOOTH_ERROR_INTERNAL;
382         }
383
384         adv_params.interval_min = params->interval_min;
385         adv_params.interval_max = params->interval_max;
386         adv_params.filter_policy = params->filter_policy;
387         adv_params.type= params->type;
388
389         if (ret)
390                 g_variant_unref(ret);
391
392         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
393                                 g_variant_new("(bi)", enable, slot_id),
394                                 G_DBUS_CALL_FLAGS_NONE,
395                                 -1,
396                                 NULL,
397                                 &error);
398
399         if (error) {
400                 BT_ERR("SetAdvertising Fail: %s", error->message);
401                 g_clear_error(&error);
402                 return BLUETOOTH_ERROR_INTERNAL;
403         }
404
405         if (enable == TRUE)
406                 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
407         else
408                 __bt_unregister_adv_slot_owner(slot_id);
409
410         le_adv_slot[slot_id].is_advertising = enable;
411         BT_INFO_C("Set advertising [%d]", enable);
412         if (ret)
413                 g_variant_unref(ret);
414
415         return BLUETOOTH_ERROR_NONE;
416 }
417
418 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
419                 char in_type, char **data, int *data_len)
420 {
421         if (in_data == NULL || data == NULL || data_len == NULL)
422                 return BLUETOOTH_ERROR_INTERNAL;
423
424         if (in_len < 0)
425                 return BLUETOOTH_ERROR_INTERNAL;
426
427         int i;
428         int len = 0;
429         int type = 0;
430
431         for (i = 0; i < in_len; i++) {
432                 len = in_data[i];
433                 if (len <= 0 || i + 1 >= in_len) {
434                         BT_ERR("Invalid advertising data");
435                         return BLUETOOTH_ERROR_INTERNAL;
436                 }
437
438                 type = in_data[i + 1];
439                 if (type == in_type) {
440                         i = i + 2;
441                         len--;
442                         break;
443                 }
444
445                 i += len;
446                 len = 0;
447         }
448
449         if (i + len > in_len) {
450                 BT_ERR("Invalid advertising data");
451                 return BLUETOOTH_ERROR_INTERNAL;
452         } else if (len == 0) {
453                 BT_DBG("AD Type 0x%02x data is not set", in_type);
454                 *data = NULL;
455                 *data_len = 0;
456                 return BLUETOOTH_ERROR_NONE;
457         }
458
459         *data = g_memdup(&in_data[i], len);
460         if (*data == NULL)
461                 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
462         *data_len = len;
463
464         return BLUETOOTH_ERROR_NONE;
465 }
466
467 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
468 {
469         BT_CHECK_PARAMETER(adv, return);
470         BT_CHECK_PARAMETER(length, return);
471
472         memcpy(adv, &adv_data, sizeof(adv_data));
473         *length = adv_data_len;
474
475         return BLUETOOTH_ERROR_NONE;
476 }
477
478 int _bt_set_advertising_data(const char *sender, int adv_handle,
479                                 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
480 {
481         GDBusProxy *proxy;
482         GError *error = NULL;
483         GVariant *ret, *ad_data, *param = NULL;
484         GVariant *temp = NULL;
485         GVariantBuilder *builder;
486         int i;
487         char *old_mdata = NULL;
488         char *new_mdata = NULL;
489         int old_len = 0;
490         int new_len = 0;
491         int slot_id;
492
493         if (__bt_is_factory_test_mode()) {
494                 BT_ERR("Unable to set advertising data in factory binary !!");
495                 return BLUETOOTH_ERROR_NOT_SUPPORT;
496         }
497
498         BT_CHECK_PARAMETER(adv, return);
499
500         if (_bt_adapter_get_status() != BT_ACTIVATED &&
501                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
502                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
503         }
504
505         proxy = _bt_get_adapter_proxy();
506         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
507
508         slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
509         if (slot_id == -1) {
510                 BT_ERR("There is NO available slot!!");
511                 return BLUETOOTH_ERROR_NO_RESOURCES;
512         }
513
514         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
515         for (i = 0; i < length; i++) {
516                 g_variant_builder_add(builder, "y", adv->data[i]);
517         }
518
519         temp = g_variant_new("ay", builder);
520         g_variant_builder_unref(builder);
521         ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
522                                 g_variant_new("(@ayi)", temp, slot_id),
523                                 G_DBUS_CALL_FLAGS_NONE,
524                                 -1, NULL, &error);
525
526         if (error) {
527                 BT_ERR("SetAdvertisingData Fail: %s", error->message);
528                 g_clear_error(&error);
529                 return BLUETOOTH_ERROR_INTERNAL;
530         }
531
532         __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
533
534         __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
535                         &old_mdata, &old_len);
536         __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
537                         &new_mdata, &new_len);
538         if (old_len != new_len ||
539                         (old_mdata && new_mdata &&
540                          memcmp(old_mdata, new_mdata, new_len))) {
541                ad_data = g_variant_new_from_data((const GVariantType *)"ay",
542                                             new_mdata, new_len, TRUE, NULL, NULL);
543                 param = g_variant_new("(@ay)", ad_data);
544                 _bt_send_event(BT_ADAPTER_EVENT,
545                                 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
546                                 param);
547         }
548         g_free(new_mdata);
549         g_free(old_mdata);
550
551         memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
552         memcpy(&adv_data, adv, length);
553         adv_data_len = length;
554
555         BT_INFO("Set advertising data");
556         if (ret)
557                 g_variant_unref(ret);
558
559         return BLUETOOTH_ERROR_NONE;
560 }
561
562 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
563 {
564         BT_CHECK_PARAMETER(response, return);
565         BT_CHECK_PARAMETER(length, return);
566
567         memcpy(response, &resp_data, sizeof(resp_data));
568         *length = resp_data_len;
569
570         return BLUETOOTH_ERROR_NONE;
571 }
572
573 int _bt_set_scan_response_data(const char *sender, int adv_handle,
574                                 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
575 {
576         GDBusProxy *proxy;
577         GError *error = NULL;
578         GVariant *ret, *scan_data,  *param = NULL;
579         GVariant *temp = NULL;
580         GVariantBuilder *builder;
581         int i;
582         char *old_mdata = NULL;
583         char *new_mdata = NULL;
584         int old_len = 0;
585         int new_len = 0;
586         int slot_id;
587
588         if (__bt_is_factory_test_mode()) {
589                 BT_ERR("Unable to set scan response list in factory binary !!");
590                 return BLUETOOTH_ERROR_NOT_SUPPORT;
591         }
592
593         BT_CHECK_PARAMETER(response, return);
594
595         if (_bt_adapter_get_status() != BT_ACTIVATED &&
596                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
597                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
598         }
599
600         proxy = _bt_get_adapter_proxy();
601         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
602
603         slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
604         if (slot_id == -1) {
605                 BT_ERR("There is NO available slot!!");
606                 return BLUETOOTH_ERROR_NO_RESOURCES;
607         }
608         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
609         for (i = 0; i < length; i++) {
610                 g_variant_builder_add(builder, "y", response->data[i]);
611         }
612
613         temp = g_variant_new("ay", builder);
614         g_variant_builder_unref(builder);
615         ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
616                                 g_variant_new("(@ayi)", temp, slot_id),
617                                 G_DBUS_CALL_FLAGS_NONE,
618                                 -1, NULL, &error);
619
620         if (error) {
621                 BT_ERR("SetScanRespData Fail: %s", error->message);
622                 g_clear_error(&error);
623                 return BLUETOOTH_ERROR_INTERNAL;
624         }
625
626         __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
627
628         /* Compare with previous scan resp data */
629         __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
630                         &old_mdata, &old_len);
631         __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
632                         &new_mdata, &new_len);
633         if (old_len != new_len ||
634                         (old_mdata && new_mdata &&
635                          memcmp(old_mdata, new_mdata, new_len))) {
636                 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
637                                             new_mdata, new_len, TRUE, NULL, NULL);
638                 param = g_variant_new("(@ay)", scan_data);
639                 _bt_send_event(BT_ADAPTER_EVENT,
640                                 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
641                                 param);
642         }
643         g_free(new_mdata);
644         g_free(old_mdata);
645
646         memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
647         memcpy(&resp_data, response, length);
648         resp_data_len = length;
649
650         if (ret)
651                 g_variant_unref(ret);
652         BT_INFO("Set scan response data");
653         return BLUETOOTH_ERROR_NONE;
654 }
655
656 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
657 {
658         GDBusProxy *proxy;
659         GError *error = NULL;
660         GVariant *ret;
661         guint32 itv = 0;
662         guint32 win = 0;
663
664         BT_CHECK_PARAMETER(params, return);
665
666         if (_bt_adapter_get_status() != BT_ACTIVATED &&
667                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
668                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
669         }
670
671         proxy = _bt_get_adapter_proxy();
672         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
673
674         if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
675                 return BLUETOOTH_ERROR_INVALID_PARAM;
676
677         if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
678                 return BLUETOOTH_ERROR_INVALID_PARAM;
679
680         if (params->window > params->interval)
681                 return BLUETOOTH_ERROR_INVALID_PARAM;
682
683         itv = params->interval / BT_ADV_INTERVAL_SPLIT;
684         win = params->window / BT_ADV_INTERVAL_SPLIT;
685
686         ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
687                         g_variant_new("(uuu)", params->type, itv, win),
688                         G_DBUS_CALL_FLAGS_NONE, -1,
689                         NULL, &error);
690
691         if (error) {
692                 BT_ERR("SetScanParameters Fail: %s", error->message);
693                 g_clear_error(&error);
694                 return BLUETOOTH_ERROR_INTERNAL;
695         }
696
697         _bt_set_le_scan_type(params->type);
698
699         is_le_set_scan_parameter = TRUE;
700
701         if (ret)
702                 g_variant_unref(ret);
703         BT_INFO("Set scan parameters");
704         return BLUETOOTH_ERROR_NONE;
705 }
706
707 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
708 {
709         GSList *l;
710         bt_adapter_le_scanner_t *scanner;
711
712         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
713                 scanner = l->data;
714                 if (g_strcmp0(scanner->sender, sender) == 0)
715                         return scanner;
716         }
717
718         return NULL;
719 }
720
721 int __bt_get_available_scan_filter_slot_id(void)
722 {
723         GSList *l;
724         bt_adapter_le_scanner_t *scanner;
725         GSList *fl;
726         bluetooth_le_scan_filter_t *filter_data;
727         gboolean *slot_check_list;
728         int i;
729
730         if (le_feature_info.max_filter == 0) {
731                 BT_ERR("Scan filter is NOT Supported");
732                 return -1;
733         }
734         slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
735
736         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
737                 scanner = l->data;
738                 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
739                         filter_data = fl->data;
740                         if (filter_data->slot_id < le_feature_info.max_filter) {
741                                 slot_check_list[filter_data->slot_id] = TRUE;
742                         }
743                 }
744         }
745
746         for (i = 0; i < le_feature_info.max_filter; i++) {
747                 if (slot_check_list[i] == FALSE) {
748                         g_free(slot_check_list);
749                         return i;
750                 }
751         }
752
753         BT_ERR("There is NO available slot for scan filter.");
754         g_free(slot_check_list);
755         return -1;
756 }
757
758 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
759 {
760         GDBusProxy *proxy;
761         GError *error = NULL;
762         GVariant *ret, *param;
763         GVariant *arr_uuid_param, *arr_uuid_mask_param;
764         GVariant *arr_data_param, *arr_data_mask_param;
765         GArray *arr_uuid;
766         GArray *arr_uuid_mask;
767         GArray *arr_data;
768         GArray *arr_data_mask;
769         bt_adapter_le_scanner_t *scanner = NULL;
770         bluetooth_le_scan_filter_t *filter_data = NULL;
771         int feature_selection = 0;
772
773         *slot_id = __bt_get_available_scan_filter_slot_id();
774         if (*slot_id == -1)
775                 return BLUETOOTH_ERROR_NO_RESOURCES;
776
777         proxy = _bt_get_adapter_proxy();
778         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
779
780         arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
781         arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
782         arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
783         arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
784
785         arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
786                                             arr_uuid, filter->service_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL);
787         arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
788                                             arr_uuid_mask, filter->service_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
789         arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
790                                             arr_data, filter->service_data.data_len * sizeof(guint8), TRUE, NULL, NULL);
791         arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
792                                             arr_data_mask, filter->service_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
793
794         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
795                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
796                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
797
798                 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
799
800                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
801                                         0,      // client_if
802                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
803                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS,        // filter_type
804                                         slot_id,        // filter_index
805                                         0,      // company_id
806                                         0,      // company_id_mask
807                                         arr_uuid_param, // p_uuid
808                                         arr_uuid_mask_param,    // p_uuid_mask
809                                         address,        // string
810                                         0,      // address_type
811                                         arr_data_param, // p_data
812                                         arr_data_mask_param);   // p_mask
813
814                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
815                                                         param, G_DBUS_CALL_FLAGS_NONE,
816                                                         -1, NULL, &error);
817
818                 if (error) {
819                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
820                         g_clear_error(&error);
821                 }
822                 if (ret)
823                         g_variant_unref(ret);
824         }
825
826         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
827                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
828
829                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
830                                         0,      // client_if
831                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
832                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME,   // filter_type
833                                         slot_id,        // filter_index
834                                         0,      // company_id
835                                         0,      // company_id_mask
836                                         arr_uuid_param, // p_uuid
837                                         arr_uuid_mask_param,    // p_uuid_mask
838                                         filter->device_name,    // string
839                                         0,      // address_type
840                                         arr_data_param, // p_data
841                                         arr_data_mask_param);
842
843                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
844                                                 param, G_DBUS_CALL_FLAGS_NONE,
845                                                 -1, NULL, &error);
846
847                 if (error) {
848                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
849                         g_clear_error(&error);
850                 }
851                 if (ret)
852                         g_variant_unref(ret);
853         }
854
855         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
856                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
857
858                 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
859                 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
860
861                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
862                                             arr_uuid, filter->service_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL);
863                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
864                                             arr_uuid, filter->service_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
865
866                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
867                                         0,      // client_if
868                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
869                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID,  // filter_type
870                                         slot_id,        // filter_index
871                                         0,      // company_id
872                                         0,      // company_id_mask
873                                         arr_uuid_param, // p_uuid
874                                         arr_uuid_mask_param,    // p_uuid_mask
875                                         NULL,   // string
876                                         0,      // address_type
877                                         arr_data_param, // p_data
878                                         arr_data_mask_param);
879
880                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
881                                                 param, G_DBUS_CALL_FLAGS_NONE,
882                                                 -1, NULL, &error);
883
884                 if (error) {
885                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
886                         g_clear_error(&error);
887                 }
888                 if (ret)
889                         g_variant_unref(ret);
890         }
891
892         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
893                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
894
895                 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
896                 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
897
898                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
899                                             arr_uuid, filter->service_solicitation_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL);
900                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
901                                             arr_uuid, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
902
903                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
904                                         0,      // client_if
905                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
906                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID,     // filter_type
907                                         slot_id,        // filter_index
908                                         0,      // company_id
909                                         0,      // company_id_mask
910                                         arr_uuid_param, // p_uuid
911                                         arr_uuid_mask_param,    // p_uuid_mask
912                                         NULL,   // string
913                                         0,      // address_type
914                                         arr_data_param, // p_data
915                                         arr_data_mask_param);
916
917                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
918                                 G_DBUS_CALL_FLAGS_NONE,
919                                 -1, NULL, &error);
920
921                 if (error) {
922                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
923                         g_clear_error(&error);
924                 }
925                 if (ret)
926                         g_variant_unref(ret);
927         }
928
929         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
930                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
931
932                 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
933                 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
934
935                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
936                                             arr_uuid, filter->service_data.data_len * sizeof(guint8), TRUE, NULL, NULL);
937                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
938                                             arr_uuid, filter->service_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
939
940                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
941                                         0,      // client_if
942                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
943                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA,  // filter_type
944                                         slot_id,        // filter_index
945                                         0,      // company_id
946                                         0,      // company_id_mask
947                                         arr_uuid_param, // p_uuid
948                                         arr_uuid_mask_param,    // p_uuid_mask
949                                         NULL,   // string
950                                         0,      // address_type
951                                         arr_data_param, // p_data
952                                         arr_data_mask_param);
953
954                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
955                                 G_DBUS_CALL_FLAGS_NONE,
956                                 -1, NULL, &error);
957
958                 if (error) {
959                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
960                         g_clear_error(&error);
961                 }
962                 if (ret)
963                         g_variant_unref(ret);
964         }
965
966         if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
967                 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
968
969                 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
970                 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
971
972                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
973                                             arr_uuid, filter->manufacturer_data.data_len * sizeof(guint8), TRUE, NULL, NULL);
974                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
975                                             arr_uuid, filter->manufacturer_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL);
976
977                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
978                                         0,      // client_if
979                                         0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
980                                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA,     // filter_type
981                                         slot_id,        // filter_index
982                                         filter->manufacturer_id,        // company_id
983                                         0xFFFF, // company_id_mask
984                                         arr_uuid_param, // p_uuid
985                                         arr_uuid_mask_param,    // p_uuid_mask
986                                         NULL,   // string
987                                         0,      // address_type
988                                         arr_data_param, // p_data
989                                         arr_data_mask_param);
990
991                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
992                                 G_DBUS_CALL_FLAGS_NONE,
993                                 -1, NULL, &error);
994
995                 if (error) {
996                         BT_ERR("scan_filter_add_remove Fail: %s", error->message);
997                         g_clear_error(&error);
998                 }
999                 if (ret)
1000                         g_variant_unref(ret);
1001         }
1002
1003         g_array_free(arr_uuid, TRUE);
1004         g_array_free(arr_uuid_mask, TRUE);
1005         g_array_free(arr_data, TRUE);
1006         g_array_free(arr_data_mask, TRUE);
1007
1008         BT_DBG("Filter selection %.2x", feature_selection);
1009
1010         param = g_variant_new("(iiiiiiiiiiii)",
1011                                 0,      // client_if
1012                                 0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1013                                 slot_id,        // filter_index
1014                                 feature_selection,      // feat_seln
1015                                 0,      // list_logic_type (OR - 0x00, AND - 0x01)
1016                                 1,      // filt_logic_type (OR - 0x00, AND - 0x01)
1017                                 -127,   // rssi_high_thres
1018                                 -127,   // rssi_low_thres
1019                                 0,      // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1020                                 0,      // found_timeout
1021                                 0,      // lost_timeout
1022                                 0);     // found_timeout_cnt
1023         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1024                                 param, G_DBUS_CALL_FLAGS_NONE,
1025                                 -1, NULL, &error);
1026
1027         if (error) {
1028                 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1029                 g_clear_error(&error);
1030         }
1031
1032         scanner = __bt_find_scanner_from_list(sender);
1033         if (scanner == NULL) {
1034                 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1035                 scanner->sender = strdup(sender);
1036                 scanner_list = g_slist_append(scanner_list, scanner);
1037         }
1038
1039         filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1040         memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1041         filter_data->slot_id = *slot_id;
1042
1043         scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1044
1045         if (ret)
1046                 g_variant_unref(ret);
1047         return BLUETOOTH_ERROR_NONE;
1048 }
1049
1050 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1051 {
1052         GDBusProxy *proxy;
1053         GError *error = NULL;
1054         GVariant *ret;
1055         bt_adapter_le_scanner_t *scanner = NULL;
1056         bluetooth_le_scan_filter_t *filter_data = NULL;
1057         GSList *l;
1058         gboolean is_slot_id_found = FALSE;
1059
1060         scanner = __bt_find_scanner_from_list(sender);
1061         if (scanner == NULL) {
1062                 BT_ERR("There is NO available scanner.");
1063                 return BLUETOOTH_ERROR_NOT_FOUND;
1064         }
1065
1066         for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1067                 filter_data = l->data;
1068                 if (filter_data->slot_id == slot_id) {
1069                         is_slot_id_found = TRUE;
1070                         break;
1071                 }
1072         }
1073         if (is_slot_id_found == FALSE) {
1074                 BT_ERR("There is NO registered slot.");
1075                 return BLUETOOTH_ERROR_NOT_FOUND;
1076         }
1077
1078         proxy = _bt_get_adapter_proxy();
1079         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1080
1081         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1082                                 g_variant_new("(ii)", 0, slot_id),
1083                                 G_DBUS_CALL_FLAGS_NONE,
1084                                 -1, NULL, &error);
1085
1086         if (error) {
1087                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1088                 g_clear_error(&error);
1089         }
1090
1091         scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1092         g_free(filter_data);
1093
1094         if (ret)
1095                 g_variant_unref(ret);
1096         return BLUETOOTH_ERROR_NONE;
1097 }
1098
1099 int _bt_unregister_all_scan_filters(const char *sender)
1100 {
1101         GDBusProxy *proxy;
1102         GError *error = NULL;
1103         GVariant *ret;
1104         bt_adapter_le_scanner_t *scanner = NULL;
1105         bluetooth_le_scan_filter_t *filter_data = NULL;
1106         GSList *l;
1107
1108         scanner = __bt_find_scanner_from_list(sender);
1109         if (scanner == NULL) {
1110                 BT_ERR("There is NO available scanner.");
1111                 return BLUETOOTH_ERROR_NOT_FOUND;
1112         }
1113
1114         proxy = _bt_get_adapter_proxy();
1115         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1116
1117         for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1118                 filter_data = l->data;
1119
1120                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1121                                         g_variant_new("(ii)", 0, filter_data->slot_id),
1122                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1123
1124                 if (error) {
1125                         BT_ERR("scan_filter_clear Fail: %s", error->message);
1126                         g_clear_error(&error);
1127                 }
1128                 if (ret)
1129                         g_variant_unref(ret);
1130         }
1131
1132         g_slist_free_full(scanner->filter_list, g_free);
1133         scanner->filter_list = NULL;
1134
1135         return BLUETOOTH_ERROR_NONE;
1136 }
1137
1138 int _bt_start_le_scan(const char *sender)
1139 {
1140         GDBusProxy *proxy;
1141         GError *error = NULL;
1142         GVariant *ret;
1143         bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1144
1145         if (scanner == NULL) {
1146                 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1147                 scanner->sender = strdup(sender);
1148                 scanner_list = g_slist_append(scanner_list, scanner);
1149         }
1150
1151         if (scanner->is_scanning == TRUE) {
1152                 BT_ERR("BT is already in LE scanning");
1153                 return BLUETOOTH_ERROR_IN_PROGRESS;
1154         }
1155
1156         proxy = _bt_get_adapter_proxy();
1157         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1158
1159         if (_bt_is_le_scanning()) {
1160                 if (scan_filter_enabled == TRUE) {
1161                         if (scanner->filter_list == NULL) {
1162                                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1163                                                 g_variant_new("(ib)", 0, FALSE),
1164                                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1165
1166                                 if (error) {
1167                                         BT_ERR("scan_filter_clear Fail: %s", error->message);
1168                                         g_clear_error(&error);
1169                                 }
1170
1171                                 if (ret)
1172                                         g_variant_unref(ret);
1173                                 BT_INFO("Disable LE Scan Filter");
1174                                 scan_filter_enabled = FALSE;
1175                         } else {
1176                                 BT_INFO("LE Filter Scan is continue");
1177                         }
1178                 } else {
1179                         BT_INFO("LE Full Scan is already on progress");
1180                 }
1181
1182                 scanner->is_scanning = TRUE;
1183                 return BLUETOOTH_ERROR_NONE;
1184         } else {
1185                 if (is_le_set_scan_parameter == FALSE) {
1186                         /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1187                         bluetooth_le_scan_params_t scan_params;
1188                         scan_params.type = 1;
1189                         scan_params.interval = 5000;
1190                         scan_params.window = 500;
1191                         _bt_set_scan_parameters(&scan_params);
1192                 }
1193
1194                 if (scanner->filter_list == NULL) {
1195                         BT_INFO("Start LE Full Scan");
1196                         scan_filter_enabled = FALSE;
1197                 } else {
1198                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1199                                         g_variant_new("(ib)", 0, TRUE),
1200                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1201
1202                         if (error) {
1203                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1204                                 g_clear_error(&error);
1205                         }
1206
1207                         if (ret)
1208                                 g_variant_unref(ret);
1209                         BT_INFO("Enable LE Scan Filter");
1210                         scan_filter_enabled = TRUE;
1211                 }
1212         }
1213
1214         ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1215                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1216                                 -1, NULL, &error);
1217
1218         if (error) {
1219                 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1220                 g_clear_error(&error);
1221                 return BLUETOOTH_ERROR_INTERNAL;
1222         }
1223
1224         if (ret)
1225                 g_variant_unref(ret);
1226
1227         scanner->is_scanning = TRUE;
1228         return BLUETOOTH_ERROR_NONE;
1229 }
1230
1231 int _bt_stop_le_scan(const char *sender)
1232 {
1233         GDBusProxy *proxy;
1234         GError *error = NULL;
1235         GVariant *ret;
1236         bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1237         GSList *l;
1238         gboolean next_scanning = FALSE;
1239         gboolean need_scan_filter = TRUE;
1240
1241         if (scanner == NULL || scanner->is_scanning == FALSE)
1242                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1243
1244         scanner->is_scanning = FALSE;
1245
1246         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1247                 scanner = l->data;
1248                 if (scanner->is_scanning == TRUE) {
1249                         next_scanning = TRUE;
1250                         if (scanner->filter_list == NULL)
1251                                 need_scan_filter = FALSE;
1252                 }
1253         }
1254
1255         proxy = _bt_get_adapter_proxy();
1256         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1257
1258         if (next_scanning == TRUE) {
1259                 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1260                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1261                                         g_variant_new("(ib)", 0, TRUE),
1262                                         G_DBUS_CALL_FLAGS_NONE,
1263                                         -1, NULL, &error);
1264
1265                         if (error) {
1266                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1267                                 g_clear_error(&error);
1268                         }
1269
1270                         if (ret)
1271                                 g_variant_unref(ret);
1272                         BT_INFO("Enable LE Scan Filter");
1273                         scan_filter_enabled = TRUE;
1274                 }
1275                 return BLUETOOTH_ERROR_NONE;
1276         } else {
1277                 if (scan_filter_enabled == TRUE) {
1278                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1279                                         g_variant_new("(ib)", 0, FALSE),
1280                                         G_DBUS_CALL_FLAGS_NONE,
1281                                         -1, NULL, &error);
1282
1283                         if (error) {
1284                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1285                                 g_clear_error(&error);
1286                         }
1287
1288                         if (ret)
1289                                 g_variant_unref(ret);
1290                         BT_INFO("Disable LE Scan Filter");
1291                 } else {
1292                         BT_INFO("Just stop LE scan");
1293                 }
1294         }
1295
1296         ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1297                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1298                                 -1, NULL, &error);
1299         if (ret == NULL) {
1300                 BT_ERR("LE Scan stop failed");
1301                 return BLUETOOTH_ERROR_INTERNAL;
1302         }
1303
1304         scan_filter_enabled = FALSE;
1305         is_le_set_scan_parameter = FALSE;
1306         if (ret)
1307                 g_variant_unref(ret);
1308         return BLUETOOTH_ERROR_NONE;
1309 }
1310
1311 void _bt_disable_all_scanner_status(void)
1312 {
1313         GSList *l;
1314         bt_adapter_le_scanner_t *scanner;
1315
1316         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1317                 scanner = l->data;
1318                 scanner->is_scanning = FALSE;
1319         }
1320 }
1321
1322 void _bt_set_le_scan_status(gboolean mode)
1323 {
1324         is_le_scanning = mode;
1325 }
1326
1327 gboolean _bt_is_le_scanning(void)
1328 {
1329         return is_le_scanning;
1330 }
1331
1332 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1333 {
1334         le_scan_type = type;
1335 }
1336
1337 bt_le_scan_type_t _bt_get_le_scan_type(void)
1338 {
1339         return le_scan_type;
1340 }
1341
1342 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1343                 int adv_data_len, const char *svc_uuid, int uuid_len,
1344                 const char *uuid_mask, char ad_type)
1345 {
1346         char *data = NULL;
1347         int data_len = 0;
1348         int i;
1349
1350         __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1351                         ad_type, &data, &data_len);
1352         if (data != NULL) {
1353                 _bt_swap_byte_ordering(data, data_len);
1354                 for (i = 0; i < data_len; i += uuid_len) {
1355                         if (uuid_len > (data_len - i))
1356                                 break;
1357
1358                         if (_bt_byte_arr_cmp_with_mask(data + i,
1359                                 svc_uuid, uuid_mask, uuid_len) == 0) {
1360                                 g_free(data);
1361                                 return TRUE;
1362                         }
1363                 }
1364                 g_free(data);
1365         }
1366
1367         return FALSE;
1368 }
1369
1370 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1371                 const char *adv_data, int adv_data_len,
1372                 const char *scan_data, int scan_data_len,
1373                 const bt_adapter_le_scanner_t *scanner)
1374 {
1375         GSList *l;
1376         bluetooth_le_scan_filter_t *filter_data = NULL;
1377         char *data = NULL;
1378         int data_len = 0;
1379         gboolean is_matched = FALSE;
1380
1381         if (scanner->filter_list == NULL) {
1382                 BT_INFO("This scanner is on Full Scan.");
1383                 return TRUE;
1384         }
1385
1386         for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1387                 filter_data = l->data;
1388
1389                 if (filter_data->added_features &
1390                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1391                         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1392
1393                         _bt_convert_addr_type_to_string(address,
1394                                         filter_data->device_address.addr);
1395                         if (strncmp(address, device_address,
1396                                         BT_ADDRESS_STRING_SIZE) != 0)
1397                                 continue;
1398                 }
1399
1400                 if (filter_data->added_features &
1401                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1402                         is_matched = FALSE;
1403
1404                         if (__bt_check_scan_result_uuid(adv_data,
1405                                 adv_data_len,
1406                                 (char*)filter_data->service_uuid.data.data,
1407                                 filter_data->service_uuid.data_len,
1408                                 (char*)filter_data->service_uuid_mask.data.data,
1409                                 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1410                                 == TRUE)
1411                                 is_matched = TRUE;
1412                         if (__bt_check_scan_result_uuid(adv_data,
1413                                 adv_data_len,
1414                                 (char*)filter_data->service_uuid.data.data,
1415                                 filter_data->service_uuid.data_len,
1416                                 (char*)filter_data->service_uuid_mask.data.data,
1417                                 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1418                                 == TRUE)
1419                                 is_matched = TRUE;
1420                         if (__bt_check_scan_result_uuid(adv_data,
1421                                 adv_data_len,
1422                                 (char*)filter_data->service_uuid.data.data,
1423                                 filter_data->service_uuid.data_len,
1424                                 (char*)filter_data->service_uuid_mask.data.data,
1425                                 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1426                                 == TRUE)
1427                                 is_matched = TRUE;
1428                         if (__bt_check_scan_result_uuid(adv_data,
1429                                 adv_data_len,
1430                                 (char*)filter_data->service_uuid.data.data,
1431                                 filter_data->service_uuid.data_len,
1432                                 (char*)filter_data->service_uuid_mask.data.data,
1433                                 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1434                                 == TRUE)
1435                                 is_matched = TRUE;
1436                         if (__bt_check_scan_result_uuid(scan_data,
1437                                 scan_data_len,
1438                                 (char*)filter_data->service_uuid.data.data,
1439                                 filter_data->service_uuid.data_len,
1440                                 (char*)filter_data->service_uuid_mask.data.data,
1441                                 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1442                                 == TRUE)
1443                                 is_matched = TRUE;
1444                         if (__bt_check_scan_result_uuid(scan_data,
1445                                 scan_data_len,
1446                                 (char*)filter_data->service_uuid.data.data,
1447                                 filter_data->service_uuid.data_len,
1448                                 (char*)filter_data->service_uuid_mask.data.data,
1449                                 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1450                                 == TRUE)
1451                                 is_matched = TRUE;
1452                         if (__bt_check_scan_result_uuid(scan_data,
1453                                 scan_data_len,
1454                                 (char*)filter_data->service_uuid.data.data,
1455                                 filter_data->service_uuid.data_len,
1456                                 (char*)filter_data->service_uuid_mask.data.data,
1457                                 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1458                                 == TRUE)
1459                                 is_matched = TRUE;
1460                         if (__bt_check_scan_result_uuid(scan_data,
1461                                 scan_data_len,
1462                                 (char*)filter_data->service_uuid.data.data,
1463                                 filter_data->service_uuid.data_len,
1464                                 (char*)filter_data->service_uuid_mask.data.data,
1465                                 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1466                                 == TRUE)
1467                                 is_matched = TRUE;
1468
1469                         if (is_matched == FALSE)
1470                                 continue;
1471                 }
1472                 if (filter_data->added_features &
1473                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1474                         is_matched = FALSE;
1475
1476                         if (__bt_check_scan_result_uuid(adv_data,
1477                                 adv_data_len,
1478                                 (char*)filter_data->service_solicitation_uuid.data.data,
1479                                 filter_data->service_solicitation_uuid.data_len,
1480                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1481                                 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1482                                 == TRUE)
1483                                 is_matched = TRUE;
1484                         if (__bt_check_scan_result_uuid(adv_data,
1485                                 adv_data_len,
1486                                 (char*)filter_data->service_solicitation_uuid.data.data,
1487                                 filter_data->service_solicitation_uuid.data_len,
1488                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1489                                 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1490                                 == TRUE)
1491                                 is_matched = TRUE;
1492                         if (__bt_check_scan_result_uuid(scan_data,
1493                                 scan_data_len,
1494                                 (char*)filter_data->service_solicitation_uuid.data.data,
1495                                 filter_data->service_solicitation_uuid.data_len,
1496                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1497                                 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1498                                 == TRUE)
1499                                 is_matched = TRUE;
1500                         if (__bt_check_scan_result_uuid(scan_data,
1501                                 scan_data_len,
1502                                 (char*)filter_data->service_solicitation_uuid.data.data,
1503                                 filter_data->service_solicitation_uuid.data_len,
1504                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1505                                 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1506                                 == TRUE)
1507                                 is_matched = TRUE;
1508
1509                         if (is_matched == FALSE)
1510                                 continue;
1511                 }
1512                 if (filter_data->added_features &
1513                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1514                         char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1515                         data = NULL;
1516                         data_len = 0;
1517                         is_matched = FALSE;
1518
1519                         __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1520                                         BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1521                                         &data, &data_len);
1522                         if (data != NULL) {
1523                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1524                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1525                                 memcpy(name, data, data_len);
1526                                 name[data_len] = '\0';
1527                                 g_free(data);
1528                                 data = NULL;
1529                                 if (strncmp(filter_data->device_name,
1530                                                 name, data_len) == 0)
1531                                         is_matched = TRUE;
1532                         }
1533                         __bt_get_ad_data_by_type((char*)scan_data,
1534                                 scan_data_len,
1535                                 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1536                                 &data, &data_len);
1537                         if (data != NULL) {
1538                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1539                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1540                                 memcpy(name, data, data_len);
1541                                 name[data_len] = '\0';
1542                                 g_free(data);
1543                                 data = NULL;
1544                                 if (strncmp(filter_data->device_name,
1545                                                 name, data_len) == 0)
1546                                         is_matched = TRUE;
1547                         }
1548
1549                         if (is_matched == FALSE)
1550                                 continue;
1551                 }
1552                 if (filter_data->added_features &
1553                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1554                         data = NULL;
1555                         data_len = 0;
1556                         is_matched = FALSE;
1557
1558                         __bt_get_ad_data_by_type((char*)adv_data,
1559                                 adv_data_len,
1560                                 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1561                                 &data, &data_len);
1562                         if (data != NULL) {
1563                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1564                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1565                                 if (_bt_byte_arr_cmp_with_mask(data,
1566                                         (char*)filter_data->manufacturer_data.data.data,
1567                                         (char*)filter_data->manufacturer_data_mask.data.data,
1568                                         data_len) == 0) {
1569                                         is_matched = TRUE;
1570                                 }
1571                                 g_free(data);
1572                                 data = NULL;
1573                         }
1574                         __bt_get_ad_data_by_type((char*)scan_data,
1575                                 scan_data_len,
1576                                 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1577                                 &data, &data_len);
1578                         if (data != NULL) {
1579                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1580                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1581                                 if (_bt_byte_arr_cmp_with_mask(data,
1582                                         (char*)filter_data->manufacturer_data.data.data,
1583                                         (char*)filter_data->manufacturer_data_mask.data.data,
1584                                         data_len) == 0) {
1585                                         is_matched = TRUE;
1586                                 }
1587                                 g_free(data);
1588                                 data = NULL;
1589                         }
1590
1591                         if (is_matched == FALSE)
1592                                 continue;
1593                 }
1594                 if (filter_data->added_features &
1595                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1596                         data = NULL;
1597                         data_len = 0;
1598                         is_matched = FALSE;
1599
1600                         __bt_get_ad_data_by_type((char*)adv_data,
1601                                 adv_data_len,
1602                                 BT_LE_AD_TYPE_SERVICE_DATA,
1603                                 &data, &data_len);
1604                         if (data != NULL) {
1605                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1606                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1607                                 if (_bt_byte_arr_cmp_with_mask(data,
1608                                         (char*)filter_data->service_data.data.data,
1609                                         (char*)filter_data->service_data_mask.data.data,
1610                                         data_len) == 0) {
1611                                         is_matched = TRUE;
1612                                 }
1613                                 g_free(data);
1614                                 data = NULL;
1615                         }
1616                         __bt_get_ad_data_by_type((char*)scan_data,
1617                                 scan_data_len,
1618                                 BT_LE_AD_TYPE_SERVICE_DATA,
1619                                 &data, &data_len);
1620                         if (data != NULL) {
1621                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1622                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1623                                 if (_bt_byte_arr_cmp_with_mask(data,
1624                                         (char*)filter_data->service_data.data.data,
1625                                         (char*)filter_data->service_data_mask.data.data,
1626                                         data_len) == 0) {
1627                                         is_matched = TRUE;
1628                                 }
1629                                 g_free(data);
1630                                 data = NULL;
1631                         }
1632
1633                         if (is_matched == FALSE)
1634                                 continue;
1635                 }
1636
1637                 BT_INFO("The scan result is conformable.");
1638                 return TRUE;
1639         }
1640
1641         BT_INFO("The scan result is NOT conformable.");
1642         return FALSE;
1643 }
1644
1645 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1646                                 const bt_le_adv_info_t *adv_info)
1647 {
1648         int result = BLUETOOTH_ERROR_NONE;
1649         GSList *l;
1650         GVariant *scan_data_param, *adv_data_param;
1651         GVariant *param;
1652         bt_adapter_le_scanner_t *scanner = NULL;
1653         const char *adv_data = NULL;
1654         int adv_data_len = 0;
1655         const char *scan_data = NULL;
1656         int scan_data_len = 0;
1657
1658         ret_if(le_dev_info == NULL);
1659         if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1660                 ret_if(adv_info == NULL);
1661
1662         if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1663                 adv_data = le_dev_info->adv_data;
1664                 adv_data_len = le_dev_info->adv_data_len;
1665                 scan_data = le_dev_info->adv_data;
1666                 scan_data_len = 0;
1667         } else {
1668                 adv_data = adv_info->data;
1669                 adv_data_len = adv_info->data_len;
1670                 scan_data = le_dev_info->adv_data;
1671                 scan_data_len = le_dev_info->adv_data_len;
1672         }
1673
1674         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1675                 scanner = l->data;
1676                 if (scanner->is_scanning == FALSE)
1677                         continue;
1678
1679                 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1680                         adv_data, adv_data_len, scan_data, scan_data_len,
1681                         scanner) == FALSE)
1682                         continue;
1683
1684                 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1685                                                         adv_data, adv_data_len, TRUE, NULL, NULL);
1686                 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1687                                                         scan_data, scan_data_len, TRUE, NULL, NULL);
1688
1689                 param = g_variant_new("(isnnn@ayn@ay)",
1690                                         result,
1691                                         le_dev_info->address,
1692                                         le_dev_info->addr_type,
1693                                         le_dev_info->rssi,
1694                                         adv_data_len,
1695                                         adv_data_param,
1696                                         scan_data_len,
1697                                         scan_data_param);
1698
1699                 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1700                                 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1701         }
1702 }
1703
1704 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1705 {
1706         GDBusProxy *proxy;
1707         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1708         GError *error = NULL;
1709         GVariant *ret;
1710
1711         if (__bt_is_factory_test_mode()) {
1712                 BT_ERR("Unable to add white list in factory binary !!");
1713                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1714         }
1715
1716         BT_CHECK_PARAMETER(device_address, return);
1717
1718         if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1719                 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1720                 return BLUETOOTH_ERROR_INVALID_PARAM;
1721
1722         _bt_convert_addr_type_to_string(address, device_address->addr);
1723
1724         proxy = _bt_get_adapter_proxy();
1725         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1726
1727         ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1728                           g_variant_new("(su)", address, address_type),
1729                           G_DBUS_CALL_FLAGS_NONE, -1,
1730                           NULL, &error);
1731
1732         if (error) {
1733                 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1734                 g_clear_error(&error);
1735                 return BLUETOOTH_ERROR_INTERNAL;
1736         }
1737
1738         if (ret)
1739                 g_variant_unref(ret);
1740         BT_INFO("Add white list");
1741
1742         return BLUETOOTH_ERROR_NONE;
1743 }
1744
1745 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1746 {
1747         GDBusProxy *proxy;
1748         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1749         GError *error = NULL;
1750         GVariant *ret;
1751
1752         if (__bt_is_factory_test_mode()) {
1753                 BT_ERR("Unable to remove white list in factory binary !!");
1754                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1755         }
1756
1757         BT_CHECK_PARAMETER(device_address, return);
1758
1759         if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1760                 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1761                 return BLUETOOTH_ERROR_INVALID_PARAM;
1762
1763         _bt_convert_addr_type_to_string(address, device_address->addr);
1764
1765         proxy = _bt_get_adapter_proxy();
1766         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1767
1768         ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1769                           g_variant_new("(su)", address, address_type),
1770                           G_DBUS_CALL_FLAGS_NONE, -1,
1771                           NULL, &error);
1772
1773         if (error) {
1774                 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1775                 g_clear_error(&error);
1776                 return BLUETOOTH_ERROR_INTERNAL;
1777         }
1778
1779         if (ret)
1780                 g_variant_unref(ret);
1781         BT_INFO("Remove white list");
1782
1783         return BLUETOOTH_ERROR_NONE;
1784 }
1785
1786 int _bt_clear_white_list(void)
1787 {
1788         GDBusProxy *proxy;
1789         GError *error = NULL;
1790         GVariant *ret;
1791
1792         if (__bt_is_factory_test_mode()) {
1793                 BT_ERR("Unable to clear white list in factory binary !!");
1794                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1795         }
1796
1797         proxy = _bt_get_adapter_proxy();
1798         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1799
1800         ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1801                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1802                                 -1, NULL, &error);
1803
1804         if (error) {
1805                 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1806                 g_clear_error(&error);
1807                 return BLUETOOTH_ERROR_INTERNAL;
1808         }
1809         if (ret)
1810                 g_variant_unref(ret);
1811
1812         BT_INFO("Clear white list");
1813
1814         return BLUETOOTH_ERROR_NONE;
1815 }
1816