Fix memory leak
[platform/core/connectivity/ua-manager.git] / ua-daemon / src / pm / ua-plugin-manager.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License")
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <dlfcn.h>
21 #include <ua-plugin.h>
22 #include <ua-plugin-manager.h>
23 #include <tzplatform_config.h>
24
25 #include "ua-pm-util.h"
26
27 static unsigned int available_sensors = 0;
28
29 extern const uas_callbacks_t ble_cbs;
30 extern const uas_callbacks_t wifi_cbs;
31 extern const uas_callbacks_t light_cbs;
32 extern const uas_callbacks_t motion_cbs;
33
34 static int ble_detection_type = 0;
35 static int wifi_detection_type = 0;
36
37 typedef struct {
38         void *handle;
39         uas_module_t *module;
40         uas_api_t *api;
41         uas_capability_e capability;
42 } uam_sensor_plugin_info_t;
43
44 uam_sensor_plugin_info_t* plugins[UAS_PLUGIN_ID_MAX];
45
46 static gboolean __add_plugin(void *handle, uas_module_t *module)
47 {
48         FUNC_ENTRY;
49         uas_api_t *api = NULL;
50         uam_sensor_plugin_info_t *plugin;
51
52         UAM_DBG("Plugin [id: %d, name: %s, version: %s]",
53                         module->id, module->name, module->version);
54
55         if (UAS_PLUGIN_ID_MAX <= module->id ||
56                         UAS_PLUGIN_ID_BLE > module->id) {
57                 UAM_ERR("Unknown Id %d for %s", module->id, module->name);
58                 return FALSE;
59         }
60
61         if (NULL != plugins[module->id]) {
62                 UAM_ERR("Plugin %s already added",
63                                 plugins[module->id]->module->name);
64                 return FALSE;
65         }
66
67         if (g_str_equal(module->version, UAM_VERSION) == FALSE) {
68                 UAM_ERR("Version (%s) mismatch for %s",
69                                 module->version, module->name);
70                 return FALSE;
71         }
72
73         plugin = g_try_new0(uam_sensor_plugin_info_t, 1);
74         if (NULL == plugin) {
75                 UAM_ERR("Memory allocation failed");
76                 return FALSE;
77         }
78         if (NULL == module->init) {
79                 UAM_ERR("module->init is NULL");
80                 g_free(plugin);
81                 return FALSE;
82         }
83
84         module->init(&api);
85         if (NULL == api) {
86                 UAM_ERR("API returned is NULL");
87                 g_free(plugin);
88                 return FALSE;
89         }
90
91         plugin->handle = handle;
92         plugin->module = module;
93         plugin->api = api;
94
95         plugins[module->id] = plugin;
96
97         FUNC_EXIT;
98         return TRUE;
99 }
100
101 static int __load_plugin(const char *path, const char *name, const char *symbol)
102 {
103         FUNC_ENTRY;
104         char *filename;
105         void *handle;
106         uas_module_t *module;
107
108         retv_if(NULL == path, UAM_ERROR_INVALID_PARAMETER);
109         retv_if(NULL == name, UAM_ERROR_INVALID_PARAMETER);
110         retv_if(NULL == symbol, UAM_ERROR_INVALID_PARAMETER);
111
112         filename = g_build_filename(path, name, NULL);
113         UAM_DBG("Loading [%s]", filename);
114
115         handle = dlopen(filename, RTLD_NOW);
116         g_free(filename);
117         if (handle == NULL) {
118                 UAM_ERR("Can't load plugin %s", dlerror());
119                 return UAM_ERROR_INTERNAL;
120         }
121
122         module = (uas_module_t *)dlsym(handle, symbol);
123         if (module == NULL) {
124                 UAM_ERR("Can't load plugin module: %s", dlerror());
125                 dlclose(handle);
126                 return UAM_ERROR_INTERNAL;
127         }
128
129         retv_if(FALSE == __add_plugin(handle, module), UAM_ERROR_INTERNAL);
130
131         FUNC_EXIT;
132         return UAM_ERROR_NONE;
133 }
134
135 static int __load_sensor_plugins(void)
136 {
137         FUNC_ENTRY;
138
139         GDir *dir;
140         const char *filename;
141         int ret = UAM_ERROR_INTERNAL;
142
143         retv_if(0 == strlen(SENSOR_PLUGIN_DIR), UAM_ERROR_INVALID_PARAMETER);
144
145         UAM_DBG("Loading plugins from %s", SENSOR_PLUGIN_DIR);
146
147         dir = g_dir_open(SENSOR_PLUGIN_DIR, 0, NULL);
148         if (!dir) {
149                 UAM_ERR("Unable to open directory");
150                 return UAM_ERROR_INTERNAL;
151         }
152
153         while ((filename = g_dir_read_name(dir)) != NULL) {
154
155                 if (g_str_has_suffix(filename, ".so") == FALSE)
156                         continue;
157
158                 /* If atleast one plugin is loaded, return value is UAM_ERROR_NONE */
159                 if (UAM_ERROR_NONE == __load_plugin(
160                                         SENSOR_PLUGIN_DIR, filename, "uas_module"))
161                         ret = UAM_ERROR_NONE;
162
163         }
164
165         g_dir_close(dir);
166
167         FUNC_EXIT;
168         return ret;
169 }
170
171 static int __init_sensor_plugins(void)
172 {
173         FUNC_ENTRY;
174         int ret = UAM_ERROR_INTERNAL;
175         int id;
176
177         retv_if(UAM_ERROR_NONE != __load_sensor_plugins(), UAM_ERROR_INTERNAL);
178
179         /* Initialize loaded sensor plugins */
180         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
181                 uam_sensor_plugin_info_t *plugin = plugins[id];
182                 int status;
183
184                 if (!plugin || !plugin->api) {
185                         UAM_WARN("Plugin with ID: %s is NULL", _uam_get_sensor_str(id));
186                         continue;
187                 }
188
189                 switch (id) {
190                 case UAS_PLUGIN_ID_BLE:
191                         status = plugin->api->init(&ble_cbs);
192                         if (UAS_STATUS_SUCCESS != status) {
193                                 /* Deinit plugin */
194                                 continue;
195                         }
196
197                         plugin->capability = UAS_NOT_SUPPORT_USER;
198                         if (UAS_STATUS_SUCCESS != plugin->api->get_capability(
199                                                 &plugin->capability))
200                                 plugin->capability = UAS_NOT_SUPPORT_USER;
201
202                         available_sensors |= UAM_SENSOR_BITMASK_BLE;
203                         break;
204                 case UAS_PLUGIN_ID_WIFI:
205                         status = plugin->api->init(&wifi_cbs);
206                         if (UAS_STATUS_SUCCESS != status) {
207                                 /* Deinit plugin */
208                                 continue;
209                         }
210
211                         plugin->capability = UAS_NOT_SUPPORT_USER;
212                         if (UAS_STATUS_SUCCESS != plugin->api->get_capability(
213                                                 &plugin->capability))
214                                 plugin->capability = UAS_NOT_SUPPORT_USER;
215
216                         available_sensors |= UAM_SENSOR_BITMASK_WIFI;
217                         break;
218
219                 case UAS_PLUGIN_ID_LIGHT:
220                         status = plugin->api->init(&light_cbs);
221                         if (UAS_STATUS_SUCCESS != status) {
222                                 /* Deinit plugin */
223                                 continue;
224                         }
225
226                         available_sensors |= UAM_SENSOR_BITMASK_LIGHT;
227                         break;
228                 case UAS_PLUGIN_ID_MOTION:
229                         status = plugin->api->init(&motion_cbs);
230                         if (UAS_STATUS_SUCCESS != status) {
231                                 /* Deinit plugin */
232                                 continue;
233                         }
234
235                         available_sensors |= UAM_SENSOR_BITMASK_MOTION;
236                         break;
237                 }
238
239                 /* If atleast one sensor init is success, return success */
240                 ret = UAM_ERROR_NONE;
241         }
242
243         FUNC_EXIT;
244         return ret;
245 }
246
247 static void __deinit_sensor_plugins(void)
248 {
249         FUNC_ENTRY;
250         int id;
251
252         /* Deinitialize and unload sensor plugins */
253         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
254                 uam_sensor_plugin_info_t *plugin = plugins[id];
255
256                 if (!plugin)
257                         continue;
258
259                 if (plugin->api && plugin->api->deinit)
260                         plugin->api->deinit();
261
262                 if (plugin->module && plugin->module->deinit)
263                         plugin->module->deinit();
264
265                 if (plugin->handle)
266                         dlclose(plugin->handle);
267
268                 g_free(plugin);
269                 plugin = NULL;
270         }
271
272         available_sensors = 0;
273         FUNC_EXIT;
274 }
275
276 static void __uas_device_list_free(int count, uas_device_info_t *devices)
277 {
278         FUNC_ENTRY;
279         int i;
280         int j;
281
282         for (i = 0; i < count; i++) {
283                 uas_device_info_t *device = &(devices[i]);
284
285                 g_free(device->device_id);
286
287                 for (j = 0; j < device->num_addr; j++)
288                         g_free(device->addr_list[j].address);
289
290                 g_free(device->addr_list);
291
292                 if(device->payload) {
293                         g_free(device->payload->duid);
294                         g_free(device->payload->bt_mac);
295                         g_free(device->payload);
296                 }
297         }
298
299         g_free(devices);
300
301         FUNC_EXIT;
302 }
303
304 static uas_device_info_t *__get_uas_device_list(int id, GSList *devices, int *num_devices)
305 {
306         FUNC_ENTRY;
307         uas_device_info_t *dev_list;
308         GSList *l;
309         int len;
310         int count = 0;
311         unsigned int tech_type;
312
313         retv_if(NULL == devices, NULL);
314
315         tech_type = _pm_util_uas_plugin_id_to_tech_type(id);
316         retv_if(UAM_TECH_TYPE_NONE == tech_type, NULL);
317
318         len = g_slist_length(devices);
319         dev_list = g_new0(uas_device_info_t, len);
320
321         for (l = devices; NULL != l; l = g_slist_next(l)) {
322                 uam_db_device_info_t *dev = l->data;
323                 uas_device_info_t *device = &(dev_list[count]);
324
325                 if (!dev)
326                         continue;
327
328                 if (dev->supported_techs & tech_type) {
329                         _pm_util_uam_db_dev_to_uas_dev(tech_type, dev, &device);
330                         device->supported_techs = dev->supported_techs;
331                         count++;
332                 }
333         }
334
335         *num_devices = count;
336         FUNC_EXIT;
337
338         return dev_list;
339 }
340
341 int _uam_pm_init(void)
342 {
343         FUNC_ENTRY;
344         int ret;
345
346         ret = __init_sensor_plugins();
347         if (UAM_ERROR_NONE != ret)
348                 return ret;
349
350         FUNC_EXIT;
351         return UAM_ERROR_NONE;
352 }
353
354 void _uam_pm_deinit(void)
355 {
356         FUNC_ENTRY;
357
358         __deinit_sensor_plugins();
359
360         FUNC_EXIT;
361 }
362
363 unsigned int _uam_pm_get_avaliable_sensors(void)
364 {
365         FUNC_ENTRY;
366
367         UAM_DBG("Available sensors: 0x%8.8X", available_sensors);
368
369         FUNC_EXIT;
370         return available_sensors;
371 }
372
373 gboolean _uam_pm_is_sensor_ready(unsigned int sensor_bitmask)
374 {
375         FUNC_ENTRY;
376         int id;
377         int state;
378         uam_sensor_plugin_info_t *plugin;
379
380         id = _pm_util_sensor_bitmask_to_plugin_id(sensor_bitmask);
381         retv_if(UAS_PLUGIN_ID_MAX <= id, FALSE);
382
383         plugin = plugins[id];
384         retv_if(!plugin || !plugin->api, FALSE);
385
386         if (UAS_STATUS_SUCCESS != plugin->api->get_state(&state))
387                 state = UAS_STATE_NOT_READY;
388
389         UAM_DBG("Sensor: 0x%8.8X, State: %d", sensor_bitmask, state);
390
391         FUNC_EXIT;
392         return (UAS_STATE_READY == state ? TRUE : FALSE);
393 }
394
395 int _uam_pm_register_device(int user_id, const uam_device_info_s *dev)
396 {
397         FUNC_ENTRY;
398         int id;
399         uam_sensor_plugin_info_t *plugin;
400         uas_device_info_t *device = NULL;
401
402         retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
403
404         id = _pm_util_uam_tech_type_to_plugin_id(dev->type);
405         retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
406
407         plugin = plugins[id];
408         retv_if(!plugin || !plugin->api, UAM_ERROR_NOT_SUPPORTED);
409         retv_if(UAS_SUPPORT_USER != plugin->capability, UAM_ERROR_NOT_SUPPORTED);
410
411         device = _pm_util_uam_dev_info_to_uas_dev_info(dev);
412         retv_if(NULL == device, UAM_ERROR_INTERNAL);
413
414         device->user_id = user_id;
415         if (UAS_STATUS_SUCCESS != plugin->api->add_device(device)) {
416                 UAM_ERR("plugin->add_device() failed");
417                 return UAM_ERROR_INTERNAL;
418         }
419         _pm_util_uas_device_info_free(device);
420
421         FUNC_EXIT;
422         return UAM_ERROR_NONE;
423 }
424
425 int _uam_pm_unregister_device(int user_id, const uam_device_info_s *dev)
426 {
427         FUNC_ENTRY;
428         int id;
429         uam_sensor_plugin_info_t *plugin;
430         uas_device_info_t *device = NULL;
431         int ret;
432
433         retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
434
435         id = _pm_util_uam_tech_type_to_plugin_id(dev->type);
436         retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
437
438         plugin = plugins[id];
439         retv_if(!plugin || !plugin->api, UAM_ERROR_NOT_SUPPORTED);
440         retv_if(UAS_SUPPORT_USER != plugin->capability, UAM_ERROR_NOT_SUPPORTED);
441
442         device = _pm_util_uam_dev_info_to_uas_dev_info(dev);
443         retv_if(NULL == device, UAM_ERROR_INTERNAL);
444         device->user_id = user_id;
445
446         ret = plugin->api->remove_device(device);
447         if (UAS_STATUS_SUCCESS != ret && UAS_STATUS_ALREADY_DONE != ret) {
448                 UAM_ERR("plugin->remove_device() failed");
449         }
450
451         _pm_util_uas_device_info_free(device);
452
453         FUNC_EXIT;
454         return UAM_ERROR_NONE;
455 }
456
457 int _uam_pm_set_registered_devices(GSList *devices)
458 {
459         FUNC_ENTRY;
460         int id;
461         uas_device_info_t *dev_list = NULL;
462         int num_devices = 0;
463
464         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
465                 uam_sensor_plugin_info_t *plugin = plugins[id];
466
467                 if (!plugin || !plugin->api)
468                         continue;
469
470                 if (UAS_SUPPORT_USER != plugin->capability)
471                         continue;
472
473                 dev_list = __get_uas_device_list(id, devices, &num_devices);
474                 if (!dev_list)
475                         UAM_INFO("No devices for Plugin %d", id);
476
477                 if (UAS_STATUS_SUCCESS != plugin->api->set_registered_devices(
478                                         num_devices, dev_list))
479                         UAM_ERR("plugin->set_registered_devices() failed for %d", id);
480
481                 __uas_device_list_free(num_devices, dev_list);
482         }
483
484         FUNC_EXIT;
485         return UAM_ERROR_NONE;
486 }
487
488 int _uam_pm_start_detection(unsigned int detection_mode, unsigned int bitmask)
489 {
490         FUNC_ENTRY;
491         int id;
492         int status;
493         int ret = UAM_ERROR_INTERNAL;
494         uas_detection_type_e type;
495
496         switch (detection_mode) {
497         case UAM_DETECT_PRESENCE:
498                 type = UAS_PRESENCE;
499                 break;
500         case UAM_DETECT_ABSENCE:
501                 type = UAS_ABSENCE;
502                 break;
503         default:
504                 type = UAS_PRESENCE | UAS_ABSENCE;
505         }
506
507         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
508                 uam_sensor_plugin_info_t *plugin = plugins[id];
509                 unsigned int sensor = _pm_util_uas_plugin_id_to_sensor_bitmask(id);
510
511                 if (!(sensor & bitmask))
512                         continue;
513
514                 if (!plugin || !plugin->api)
515                         continue;
516
517                 /*
518                  * For User/device detection capable plugins, need to start both, PRESENCE
519                  * as well as ABSENCE detection, to keep UA database updated.
520                  */
521                 if (UAS_PLUGIN_ID_BLE == id || UAS_PLUGIN_ID_WIFI == id)
522                         status = plugin->api->start_detection(UAS_PRESENCE | UAS_ABSENCE);
523                 else
524                         status = plugin->api->start_detection(type);
525
526                 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
527                         UAM_ERR("plugin->start_detection(%d) failed for %d", type, id);
528                         continue;
529                 }
530
531                 if (UAS_PLUGIN_ID_BLE == id)
532                         ble_detection_type |= type;
533                 if (UAS_PLUGIN_ID_WIFI == id)
534                         wifi_detection_type |= type;
535
536                 /* Result success if detection started for atleast 1 of the sensor */
537                 ret = UAM_ERROR_NONE;
538         }
539
540         FUNC_EXIT;
541         return ret;
542 }
543
544 int _uam_pm_stop_detection(unsigned int detection_mode, unsigned int bitmask)
545 {
546         FUNC_ENTRY;
547         int id;
548         int status;
549         int ret = UAM_ERROR_INTERNAL;
550         uas_detection_type_e type;
551
552         switch (detection_mode) {
553         case UAM_DETECT_PRESENCE:
554                 type = UAS_PRESENCE;
555                 break;
556         case UAM_DETECT_ABSENCE:
557                 type = UAS_ABSENCE;
558                 break;
559         default:
560                 type = UAS_PRESENCE | UAS_ABSENCE;
561         }
562
563         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
564                 uam_sensor_plugin_info_t *plugin = plugins[id];
565                 unsigned int sensor = _pm_util_uas_plugin_id_to_sensor_bitmask(id);
566
567                 if (!(sensor & bitmask))
568                         continue;
569
570                 if (!plugin || !plugin->api)
571                         continue;
572
573                 if (UAS_PLUGIN_ID_BLE == id) {
574                         ble_detection_type &= ~type;
575                         ret = UAM_ERROR_NONE;
576                         if (0 != ble_detection_type)
577                                 continue;
578                 }
579
580                 if (UAS_PLUGIN_ID_WIFI == id) {
581                         wifi_detection_type &= ~type;
582                         ret = UAM_ERROR_NONE;
583                         if (0 != wifi_detection_type)
584                                 continue;
585                 }
586
587                 if (UAS_PLUGIN_ID_BLE == id || UAS_PLUGIN_ID_WIFI == id)
588                         status = plugin->api->stop_detection(UAS_PRESENCE | UAS_ABSENCE);
589                 else
590                         status = plugin->api->stop_detection(type);
591
592                 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
593                         UAM_ERR("plugin->stop_detection(%d) failed for %d", type, id);
594                         continue;
595                 }
596
597                 /* Result success if detection stopped for atleast 1 of the sensor */
598                 ret = UAM_ERROR_NONE;
599         }
600
601         FUNC_EXIT;
602         return ret;
603 }
604
605 int _uam_pm_set_low_power_mode(unsigned int bitmask, gboolean mode)
606 {
607         FUNC_ENTRY;
608         int id;
609
610         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
611                 uam_sensor_plugin_info_t *plugin = plugins[id];
612                 unsigned int sensor = _pm_util_uas_plugin_id_to_sensor_bitmask(id);
613
614                 if (!(sensor & bitmask))
615                         continue;
616
617                 if (!plugin || !plugin->api || !plugin->api->set_low_power_mode)
618                         continue;
619
620                 if (UAS_STATUS_SUCCESS !=
621                                 plugin->api->set_low_power_mode(mode ? 1 : 0))
622                         UAM_ERR("plugin->set_low_power_mode() failed for %d", id);
623         }
624
625         FUNC_EXIT;
626         return UAM_ERROR_NONE;
627 }
628
629 int _uam_pm_set_detection_window(unsigned int detection_window)
630 {
631         FUNC_ENTRY;
632         int id;
633         int ret = UAM_ERROR_INTERNAL;
634
635         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
636                 uam_sensor_plugin_info_t *plugin = plugins[id];
637
638                 if (!plugin || !plugin->api || !plugin->api->set_detection_window)
639                         continue;
640
641                 if (UAS_STATUS_SUCCESS != plugin->api->set_detection_window(detection_window)) {
642                         UAM_ERR("plugin->set_detection_window() failed");
643                         continue;
644                 }
645
646                 /* Result success if detection params set for atleast 1 of the sensors */
647                 ret = UAM_ERROR_NONE;
648         }
649
650         FUNC_EXIT;
651         return ret;
652 }
653
654 int _uam_pm_set_detection_threshold(unsigned int sensor,
655                 int presence_threshold, int absence_threshold)
656 {
657         FUNC_ENTRY;
658         int id;
659         uam_sensor_plugin_info_t *plugin;
660
661         id = _pm_util_sensor_bitmask_to_plugin_id(sensor);
662         retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
663
664         plugin = plugins[id];
665         retv_if(!plugin || !plugin->api, UAM_ERROR_NOT_SUPPORTED);
666
667         if (UAS_STATUS_SUCCESS != plugin->api->set_detection_threshold(
668                                 presence_threshold, absence_threshold)) {
669                 UAM_ERR("plugin->set_detection_threshold() failed");
670                 return UAM_ERROR_INTERNAL;
671         }
672
673         FUNC_EXIT;
674         return UAM_ERROR_NONE;
675 }
676
677 int _uam_pm_start_active_device_scan(unsigned int* bitmask, int detection_period)
678 {
679         FUNC_ENTRY;
680         int id;
681         int status;
682         int ret = UAM_ERROR_INTERNAL;
683
684         unsigned int scanning_sensor = 0;
685
686         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
687                 uam_sensor_plugin_info_t *plugin = plugins[id];
688                 unsigned int sensor = _pm_util_uas_plugin_id_to_sensor_bitmask(id);
689
690                 if (!(sensor & (*bitmask)))
691                         continue;
692
693                 if (!plugin || !plugin->api || !plugin->api->scan_active_devices)
694                         continue;
695
696                 status = plugin->api->scan_active_devices(detection_period);
697
698                 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
699                         UAM_ERR("plugin->search_active_devices(%d) failed for %d", detection_period, id);
700                         continue;
701                 }
702
703                 scanning_sensor |= sensor;
704                 /* Result success if scanning started for atleast 1 of the sensor */
705                 ret = UAM_ERROR_NONE;
706         }
707
708         (*bitmask) &= scanning_sensor;
709
710         FUNC_EXIT;
711         return ret;
712 }
713
714 int _uam_pm_stop_active_device_scan(unsigned int bitmask)
715 {
716         FUNC_ENTRY;
717         int id;
718         int status;
719         int ret = UAM_ERROR_INTERNAL;
720
721         for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
722                 uam_sensor_plugin_info_t *plugin = plugins[id];
723                 unsigned int sensor = _pm_util_uas_plugin_id_to_sensor_bitmask(id);
724
725                 if (!(sensor & bitmask))
726                         continue;
727
728                 if (!plugin || !plugin->api || !plugin->api->cancel_active_device_scan)
729                         continue;
730
731                 status = plugin->api->cancel_active_device_scan();
732
733                 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
734                         UAM_ERR("plugin->stop_search_active_devices() failed for %d", id);
735                         continue;
736                 }
737
738                 ret = UAM_ERROR_NONE;
739         }
740
741         FUNC_EXIT;
742         return ret;
743 }
744
745 int _uam_pm_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
746 {
747         FUNC_ENTRY;
748         int id;
749         int status;
750         int ret = UAM_ERROR_INTERNAL;
751
752         id = UAS_PLUGIN_ID_BLE;
753         uam_sensor_plugin_info_t *plugin = plugins[id];
754
755         if (!plugin || !plugin->api || !plugin->api->add_ibeacon_adv) {
756                 ret = UAM_ERROR_NOT_SUPPORTED;
757                 goto done;
758         }
759
760         status = plugin->api->add_ibeacon_adv(adv_len, iadv);
761         if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
762                 UAM_ERR("plugin->add_ibeacon_adv failed for %d", id);
763                 goto done;
764         }
765         ret = UAM_ERROR_NONE;
766
767 done:
768         FUNC_EXIT;
769         return ret;
770 }