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