Fix LE stop scanning related bugs
[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
1159         proxy = _bt_get_adapter_proxy();
1160         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1161
1162         if (_bt_is_le_scanning()) {
1163                 if (scan_filter_enabled == TRUE) {
1164                         if (scanner->filter_list == NULL) {
1165                                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1166                                                 g_variant_new("(ib)", 0, FALSE),
1167                                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1168
1169                                 if (error) {
1170                                         BT_ERR("scan_filter_clear Fail: %s", error->message);
1171                                         g_clear_error(&error);
1172                                 }
1173
1174                                 if (ret)
1175                                         g_variant_unref(ret);
1176                                 BT_INFO("Disable LE Scan Filter");
1177                                 scan_filter_enabled = FALSE;
1178                         } else {
1179                                 BT_INFO("LE Filter Scan is continue");
1180                         }
1181                 } else {
1182                         BT_INFO("LE Full Scan is already on progress");
1183                 }
1184
1185                 scanner->is_scanning = TRUE;
1186                 return BLUETOOTH_ERROR_NONE;
1187         } else {
1188                 if (is_le_set_scan_parameter == FALSE) {
1189                         /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1190                         bluetooth_le_scan_params_t scan_params;
1191                         scan_params.type = 1;
1192                         scan_params.interval = 5000;
1193                         scan_params.window = 500;
1194                         _bt_set_scan_parameters(&scan_params);
1195                 }
1196
1197                 if (scanner->filter_list == NULL) {
1198                         BT_INFO("Start LE Full Scan");
1199                         scan_filter_enabled = FALSE;
1200                 } else {
1201                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1202                                         g_variant_new("(ib)", 0, TRUE),
1203                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1204
1205                         if (error) {
1206                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1207                                 g_clear_error(&error);
1208                         }
1209
1210                         if (ret)
1211                                 g_variant_unref(ret);
1212                         BT_INFO("Enable LE Scan Filter");
1213                         scan_filter_enabled = TRUE;
1214                 }
1215         }
1216
1217         ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1218                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1219                                 -1, NULL, &error);
1220
1221         if (error) {
1222                 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1223                 g_clear_error(&error);
1224                 return BLUETOOTH_ERROR_INTERNAL;
1225         }
1226
1227         if (ret)
1228                 g_variant_unref(ret);
1229
1230         scanner->is_scanning = TRUE;
1231         return BLUETOOTH_ERROR_NONE;
1232 }
1233
1234 int _bt_stop_le_scan(const char *sender)
1235 {
1236         GDBusProxy *proxy;
1237         GError *error = NULL;
1238         GVariant *ret;
1239         bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1240         GSList *l;
1241         gboolean next_scanning = FALSE;
1242         gboolean need_scan_filter = TRUE;
1243
1244         if (scanner == NULL || scanner->is_scanning == FALSE)
1245                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1246
1247         scanner->is_scanning = FALSE;
1248
1249         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1250                 scanner = l->data;
1251                 if (scanner->is_scanning == TRUE) {
1252                         next_scanning = TRUE;
1253                         if (scanner->filter_list == NULL)
1254                                 need_scan_filter = FALSE;
1255                 }
1256         }
1257
1258         proxy = _bt_get_adapter_proxy();
1259         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1260
1261         if (next_scanning == TRUE) {
1262                 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1263                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1264                                         g_variant_new("(ib)", 0, TRUE),
1265                                         G_DBUS_CALL_FLAGS_NONE,
1266                                         -1, NULL, &error);
1267
1268                         if (error) {
1269                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1270                                 g_clear_error(&error);
1271                         }
1272
1273                         if (ret)
1274                                 g_variant_unref(ret);
1275                         BT_INFO("Enable LE Scan Filter");
1276                         scan_filter_enabled = TRUE;
1277                 }
1278                 return BLUETOOTH_ERROR_NONE;
1279         } else {
1280                 if (scan_filter_enabled == TRUE) {
1281                         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1282                                         g_variant_new("(ib)", 0, FALSE),
1283                                         G_DBUS_CALL_FLAGS_NONE,
1284                                         -1, NULL, &error);
1285
1286                         if (error) {
1287                                 BT_ERR("scan_filter_clear Fail: %s", error->message);
1288                                 g_clear_error(&error);
1289                         }
1290
1291                         if (ret)
1292                                 g_variant_unref(ret);
1293                         BT_INFO("Disable LE Scan Filter");
1294                 } else {
1295                         BT_INFO("Just stop LE scan");
1296                 }
1297         }
1298
1299         ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1300                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1301                                 -1, NULL, &error);
1302         if (ret == NULL) {
1303                 BT_ERR("LE Scan stop failed");
1304                 return BLUETOOTH_ERROR_INTERNAL;
1305         }
1306
1307         scan_filter_enabled = FALSE;
1308         is_le_set_scan_parameter = FALSE;
1309         if (ret)
1310                 g_variant_unref(ret);
1311         return BLUETOOTH_ERROR_NONE;
1312 }
1313
1314 void _bt_disable_all_scanner_status(void)
1315 {
1316         GSList *l;
1317         bt_adapter_le_scanner_t *scanner;
1318
1319         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1320                 scanner = l->data;
1321                 scanner->is_scanning = FALSE;
1322         }
1323 }
1324
1325 void _bt_set_le_scan_status(gboolean mode)
1326 {
1327         is_le_scanning = mode;
1328 }
1329
1330 gboolean _bt_is_le_scanning(void)
1331 {
1332         return is_le_scanning;
1333 }
1334
1335 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1336 {
1337         le_scan_type = type;
1338 }
1339
1340 bt_le_scan_type_t _bt_get_le_scan_type(void)
1341 {
1342         return le_scan_type;
1343 }
1344
1345 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1346                 int adv_data_len, const char *svc_uuid, int uuid_len,
1347                 const char *uuid_mask, char ad_type)
1348 {
1349         char *data = NULL;
1350         int data_len = 0;
1351         int i;
1352
1353         __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1354                         ad_type, &data, &data_len);
1355         if (data != NULL) {
1356                 _bt_swap_byte_ordering(data, data_len);
1357                 for (i = 0; i < data_len; i += uuid_len) {
1358                         if (uuid_len > (data_len - i))
1359                                 break;
1360
1361                         if (_bt_byte_arr_cmp_with_mask(data + i,
1362                                 svc_uuid, uuid_mask, uuid_len) == 0) {
1363                                 g_free(data);
1364                                 return TRUE;
1365                         }
1366                 }
1367                 g_free(data);
1368         }
1369
1370         return FALSE;
1371 }
1372
1373 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1374                 const char *adv_data, int adv_data_len,
1375                 const char *scan_data, int scan_data_len,
1376                 const bt_adapter_le_scanner_t *scanner)
1377 {
1378         GSList *l;
1379         bluetooth_le_scan_filter_t *filter_data = NULL;
1380         char *data = NULL;
1381         int data_len = 0;
1382         gboolean is_matched = FALSE;
1383
1384         if (scanner->filter_list == NULL) {
1385                 BT_INFO("This scanner is on Full Scan.");
1386                 return TRUE;
1387         }
1388
1389         for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1390                 filter_data = l->data;
1391
1392                 if (filter_data->added_features &
1393                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1394                         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1395
1396                         _bt_convert_addr_type_to_string(address,
1397                                         filter_data->device_address.addr);
1398                         if (strncmp(address, device_address,
1399                                         BT_ADDRESS_STRING_SIZE) != 0)
1400                                 continue;
1401                 }
1402
1403                 if (filter_data->added_features &
1404                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1405                         is_matched = FALSE;
1406
1407                         if (__bt_check_scan_result_uuid(adv_data,
1408                                 adv_data_len,
1409                                 (char*)filter_data->service_uuid.data.data,
1410                                 filter_data->service_uuid.data_len,
1411                                 (char*)filter_data->service_uuid_mask.data.data,
1412                                 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1413                                 == TRUE)
1414                                 is_matched = TRUE;
1415                         if (__bt_check_scan_result_uuid(adv_data,
1416                                 adv_data_len,
1417                                 (char*)filter_data->service_uuid.data.data,
1418                                 filter_data->service_uuid.data_len,
1419                                 (char*)filter_data->service_uuid_mask.data.data,
1420                                 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1421                                 == TRUE)
1422                                 is_matched = TRUE;
1423                         if (__bt_check_scan_result_uuid(adv_data,
1424                                 adv_data_len,
1425                                 (char*)filter_data->service_uuid.data.data,
1426                                 filter_data->service_uuid.data_len,
1427                                 (char*)filter_data->service_uuid_mask.data.data,
1428                                 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1429                                 == TRUE)
1430                                 is_matched = TRUE;
1431                         if (__bt_check_scan_result_uuid(adv_data,
1432                                 adv_data_len,
1433                                 (char*)filter_data->service_uuid.data.data,
1434                                 filter_data->service_uuid.data_len,
1435                                 (char*)filter_data->service_uuid_mask.data.data,
1436                                 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1437                                 == TRUE)
1438                                 is_matched = TRUE;
1439                         if (__bt_check_scan_result_uuid(scan_data,
1440                                 scan_data_len,
1441                                 (char*)filter_data->service_uuid.data.data,
1442                                 filter_data->service_uuid.data_len,
1443                                 (char*)filter_data->service_uuid_mask.data.data,
1444                                 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1445                                 == TRUE)
1446                                 is_matched = TRUE;
1447                         if (__bt_check_scan_result_uuid(scan_data,
1448                                 scan_data_len,
1449                                 (char*)filter_data->service_uuid.data.data,
1450                                 filter_data->service_uuid.data_len,
1451                                 (char*)filter_data->service_uuid_mask.data.data,
1452                                 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1453                                 == TRUE)
1454                                 is_matched = TRUE;
1455                         if (__bt_check_scan_result_uuid(scan_data,
1456                                 scan_data_len,
1457                                 (char*)filter_data->service_uuid.data.data,
1458                                 filter_data->service_uuid.data_len,
1459                                 (char*)filter_data->service_uuid_mask.data.data,
1460                                 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1461                                 == TRUE)
1462                                 is_matched = TRUE;
1463                         if (__bt_check_scan_result_uuid(scan_data,
1464                                 scan_data_len,
1465                                 (char*)filter_data->service_uuid.data.data,
1466                                 filter_data->service_uuid.data_len,
1467                                 (char*)filter_data->service_uuid_mask.data.data,
1468                                 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1469                                 == TRUE)
1470                                 is_matched = TRUE;
1471
1472                         if (is_matched == FALSE)
1473                                 continue;
1474                 }
1475                 if (filter_data->added_features &
1476                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1477                         is_matched = FALSE;
1478
1479                         if (__bt_check_scan_result_uuid(adv_data,
1480                                 adv_data_len,
1481                                 (char*)filter_data->service_solicitation_uuid.data.data,
1482                                 filter_data->service_solicitation_uuid.data_len,
1483                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1484                                 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1485                                 == TRUE)
1486                                 is_matched = TRUE;
1487                         if (__bt_check_scan_result_uuid(adv_data,
1488                                 adv_data_len,
1489                                 (char*)filter_data->service_solicitation_uuid.data.data,
1490                                 filter_data->service_solicitation_uuid.data_len,
1491                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1492                                 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1493                                 == TRUE)
1494                                 is_matched = TRUE;
1495                         if (__bt_check_scan_result_uuid(scan_data,
1496                                 scan_data_len,
1497                                 (char*)filter_data->service_solicitation_uuid.data.data,
1498                                 filter_data->service_solicitation_uuid.data_len,
1499                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1500                                 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1501                                 == TRUE)
1502                                 is_matched = TRUE;
1503                         if (__bt_check_scan_result_uuid(scan_data,
1504                                 scan_data_len,
1505                                 (char*)filter_data->service_solicitation_uuid.data.data,
1506                                 filter_data->service_solicitation_uuid.data_len,
1507                                 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1508                                 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1509                                 == TRUE)
1510                                 is_matched = TRUE;
1511
1512                         if (is_matched == FALSE)
1513                                 continue;
1514                 }
1515                 if (filter_data->added_features &
1516                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1517                         char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1518                         data = NULL;
1519                         data_len = 0;
1520                         is_matched = FALSE;
1521
1522                         __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1523                                         BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1524                                         &data, &data_len);
1525                         if (data != NULL) {
1526                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1527                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1528                                 memcpy(name, data, data_len);
1529                                 name[data_len] = '\0';
1530                                 g_free(data);
1531                                 data = NULL;
1532                                 if (strncmp(filter_data->device_name,
1533                                                 name, data_len) == 0)
1534                                         is_matched = TRUE;
1535                         }
1536                         __bt_get_ad_data_by_type((char*)scan_data,
1537                                 scan_data_len,
1538                                 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1539                                 &data, &data_len);
1540                         if (data != NULL) {
1541                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1542                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1543                                 memcpy(name, data, data_len);
1544                                 name[data_len] = '\0';
1545                                 g_free(data);
1546                                 data = NULL;
1547                                 if (strncmp(filter_data->device_name,
1548                                                 name, data_len) == 0)
1549                                         is_matched = TRUE;
1550                         }
1551
1552                         if (is_matched == FALSE)
1553                                 continue;
1554                 }
1555                 if (filter_data->added_features &
1556                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1557                         data = NULL;
1558                         data_len = 0;
1559                         is_matched = FALSE;
1560
1561                         __bt_get_ad_data_by_type((char*)adv_data,
1562                                 adv_data_len,
1563                                 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1564                                 &data, &data_len);
1565                         if (data != NULL) {
1566                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1567                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1568                                 if (_bt_byte_arr_cmp_with_mask(data,
1569                                         (char*)filter_data->manufacturer_data.data.data,
1570                                         (char*)filter_data->manufacturer_data_mask.data.data,
1571                                         data_len) == 0) {
1572                                         is_matched = TRUE;
1573                                 }
1574                                 g_free(data);
1575                                 data = NULL;
1576                         }
1577                         __bt_get_ad_data_by_type((char*)scan_data,
1578                                 scan_data_len,
1579                                 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1580                                 &data, &data_len);
1581                         if (data != NULL) {
1582                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1583                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1584                                 if (_bt_byte_arr_cmp_with_mask(data,
1585                                         (char*)filter_data->manufacturer_data.data.data,
1586                                         (char*)filter_data->manufacturer_data_mask.data.data,
1587                                         data_len) == 0) {
1588                                         is_matched = TRUE;
1589                                 }
1590                                 g_free(data);
1591                                 data = NULL;
1592                         }
1593
1594                         if (is_matched == FALSE)
1595                                 continue;
1596                 }
1597                 if (filter_data->added_features &
1598                         BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1599                         data = NULL;
1600                         data_len = 0;
1601                         is_matched = FALSE;
1602
1603                         __bt_get_ad_data_by_type((char*)adv_data,
1604                                 adv_data_len,
1605                                 BT_LE_AD_TYPE_SERVICE_DATA,
1606                                 &data, &data_len);
1607                         if (data != NULL) {
1608                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1609                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1610                                 if (_bt_byte_arr_cmp_with_mask(data,
1611                                         (char*)filter_data->service_data.data.data,
1612                                         (char*)filter_data->service_data_mask.data.data,
1613                                         data_len) == 0) {
1614                                         is_matched = TRUE;
1615                                 }
1616                                 g_free(data);
1617                                 data = NULL;
1618                         }
1619                         __bt_get_ad_data_by_type((char*)scan_data,
1620                                 scan_data_len,
1621                                 BT_LE_AD_TYPE_SERVICE_DATA,
1622                                 &data, &data_len);
1623                         if (data != NULL) {
1624                                 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1625                                         data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1626                                 if (_bt_byte_arr_cmp_with_mask(data,
1627                                         (char*)filter_data->service_data.data.data,
1628                                         (char*)filter_data->service_data_mask.data.data,
1629                                         data_len) == 0) {
1630                                         is_matched = TRUE;
1631                                 }
1632                                 g_free(data);
1633                                 data = NULL;
1634                         }
1635
1636                         if (is_matched == FALSE)
1637                                 continue;
1638                 }
1639
1640                 BT_INFO("The scan result is conformable.");
1641                 return TRUE;
1642         }
1643
1644         BT_INFO("The scan result is NOT conformable.");
1645         return FALSE;
1646 }
1647
1648 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1649                                 const bt_le_adv_info_t *adv_info)
1650 {
1651         int result = BLUETOOTH_ERROR_NONE;
1652         GSList *l;
1653         GVariant *scan_data_param, *adv_data_param;
1654         GVariant *param;
1655         bt_adapter_le_scanner_t *scanner = NULL;
1656         const char *adv_data = NULL;
1657         int adv_data_len = 0;
1658         const char *scan_data = NULL;
1659         int scan_data_len = 0;
1660
1661         ret_if(le_dev_info == NULL);
1662         if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1663                 ret_if(adv_info == NULL);
1664
1665         if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1666                 adv_data = le_dev_info->adv_data;
1667                 adv_data_len = le_dev_info->adv_data_len;
1668                 scan_data = le_dev_info->adv_data;
1669                 scan_data_len = 0;
1670         } else {
1671                 adv_data = adv_info->data;
1672                 adv_data_len = adv_info->data_len;
1673                 scan_data = le_dev_info->adv_data;
1674                 scan_data_len = le_dev_info->adv_data_len;
1675         }
1676
1677         for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1678                 scanner = l->data;
1679                 if (scanner->is_scanning == FALSE)
1680                         continue;
1681
1682                 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1683                         adv_data, adv_data_len, scan_data, scan_data_len,
1684                         scanner) == FALSE)
1685                         continue;
1686
1687                 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1688                                                         adv_data, adv_data_len, TRUE, NULL, NULL);
1689                 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1690                                                         scan_data, scan_data_len, TRUE, NULL, NULL);
1691
1692                 param = g_variant_new("(isnnn@ayn@ay)",
1693                                         result,
1694                                         le_dev_info->address,
1695                                         le_dev_info->addr_type,
1696                                         le_dev_info->rssi,
1697                                         adv_data_len,
1698                                         adv_data_param,
1699                                         scan_data_len,
1700                                         scan_data_param);
1701
1702                 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1703                                 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1704         }
1705 }
1706
1707 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1708 {
1709         GDBusProxy *proxy;
1710         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1711         GError *error = NULL;
1712         GVariant *ret;
1713
1714         if (__bt_is_factory_test_mode()) {
1715                 BT_ERR("Unable to add white list in factory binary !!");
1716                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1717         }
1718
1719         BT_CHECK_PARAMETER(device_address, return);
1720
1721         if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1722                 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1723                 return BLUETOOTH_ERROR_INVALID_PARAM;
1724
1725         _bt_convert_addr_type_to_string(address, device_address->addr);
1726
1727         proxy = _bt_get_adapter_proxy();
1728         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1729
1730         ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1731                           g_variant_new("(su)", address, address_type),
1732                           G_DBUS_CALL_FLAGS_NONE, -1,
1733                           NULL, &error);
1734
1735         if (error) {
1736                 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1737                 g_clear_error(&error);
1738                 return BLUETOOTH_ERROR_INTERNAL;
1739         }
1740
1741         if (ret)
1742                 g_variant_unref(ret);
1743         BT_INFO("Add white list");
1744
1745         return BLUETOOTH_ERROR_NONE;
1746 }
1747
1748 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1749 {
1750         GDBusProxy *proxy;
1751         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1752         GError *error = NULL;
1753         GVariant *ret;
1754
1755         if (__bt_is_factory_test_mode()) {
1756                 BT_ERR("Unable to remove white list in factory binary !!");
1757                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1758         }
1759
1760         BT_CHECK_PARAMETER(device_address, return);
1761
1762         if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1763                 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1764                 return BLUETOOTH_ERROR_INVALID_PARAM;
1765
1766         _bt_convert_addr_type_to_string(address, device_address->addr);
1767
1768         proxy = _bt_get_adapter_proxy();
1769         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1770
1771         ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1772                           g_variant_new("(su)", address, address_type),
1773                           G_DBUS_CALL_FLAGS_NONE, -1,
1774                           NULL, &error);
1775
1776         if (error) {
1777                 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1778                 g_clear_error(&error);
1779                 return BLUETOOTH_ERROR_INTERNAL;
1780         }
1781
1782         if (ret)
1783                 g_variant_unref(ret);
1784         BT_INFO("Remove white list");
1785
1786         return BLUETOOTH_ERROR_NONE;
1787 }
1788
1789 int _bt_clear_white_list(void)
1790 {
1791         GDBusProxy *proxy;
1792         GError *error = NULL;
1793         GVariant *ret;
1794
1795         if (__bt_is_factory_test_mode()) {
1796                 BT_ERR("Unable to clear white list in factory binary !!");
1797                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1798         }
1799
1800         proxy = _bt_get_adapter_proxy();
1801         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1802
1803         ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1804                                 NULL,G_DBUS_CALL_FLAGS_NONE,
1805                                 -1, NULL, &error);
1806
1807         if (error) {
1808                 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1809                 g_clear_error(&error);
1810                 return BLUETOOTH_ERROR_INTERNAL;
1811         }
1812         if (ret)
1813                 g_variant_unref(ret);
1814
1815         BT_INFO("Clear white list");
1816
1817         return BLUETOOTH_ERROR_NONE;
1818 }
1819