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