2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <ua-plugin.h>
22 #include <ua-plugin-manager.h>
23 #include <tzplatform_config.h>
25 #include "ua-pm-util.h"
27 static unsigned int available_sensors = 0;
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;
34 static int ble_detection_type = 0;
35 static int wifi_detection_type = 0;
41 uas_capability_e capability;
42 } uam_sensor_plugin_info_t;
44 uam_sensor_plugin_info_t* plugins[UAS_PLUGIN_ID_MAX];
46 static gboolean __add_plugin(void *handle, uas_module_t *module)
49 uas_api_t *api = NULL;
50 uam_sensor_plugin_info_t *plugin;
52 UAM_DBG("Plugin [id: %d, name: %s, version: %s]",
53 module->id, module->name, module->version);
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);
61 if (NULL != plugins[module->id]) {
62 UAM_ERR("Plugin %s already added",
63 plugins[module->id]->module->name);
67 if (g_str_equal(module->version, UAM_VERSION) == FALSE) {
68 UAM_ERR("Version (%s) mismatch for %s",
69 module->version, module->name);
73 plugin = g_try_new0(uam_sensor_plugin_info_t, 1);
75 UAM_ERR("Memory allocation failed");
78 if (NULL == module->init) {
79 UAM_ERR("module->init is NULL");
86 UAM_ERR("API returned is NULL");
91 plugin->handle = handle;
92 plugin->module = module;
95 plugins[module->id] = plugin;
101 static int __load_plugin(const char *path, const char *name, const char *symbol)
106 uas_module_t *module;
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);
112 filename = g_build_filename(path, name, NULL);
113 UAM_DBG("Loading [%s]", filename);
115 handle = dlopen(filename, RTLD_NOW);
117 if (handle == NULL) {
118 UAM_ERR("Can't load plugin %s", dlerror());
119 return UAM_ERROR_INTERNAL;
122 module = (uas_module_t *)dlsym(handle, symbol);
123 if (module == NULL) {
124 UAM_ERR("Can't load plugin module: %s", dlerror());
126 return UAM_ERROR_INTERNAL;
129 retv_if(FALSE == __add_plugin(handle, module), UAM_ERROR_INTERNAL);
132 return UAM_ERROR_NONE;
135 static int __load_sensor_plugins(void)
140 const char *filename;
141 int ret = UAM_ERROR_INTERNAL;
143 retv_if(0 == strlen(SENSOR_PLUGIN_DIR), UAM_ERROR_INVALID_PARAMETER);
145 UAM_DBG("Loading plugins from %s", SENSOR_PLUGIN_DIR);
147 dir = g_dir_open(SENSOR_PLUGIN_DIR, 0, NULL);
149 UAM_ERR("Unable to open directory");
150 return UAM_ERROR_INTERNAL;
153 while ((filename = g_dir_read_name(dir)) != NULL) {
155 if (g_str_has_suffix(filename, ".so") == FALSE)
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;
171 static int __init_sensor_plugins(void)
174 int ret = UAM_ERROR_INTERNAL;
177 retv_if(UAM_ERROR_NONE != __load_sensor_plugins(), UAM_ERROR_INTERNAL);
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];
184 if (!plugin || !plugin->api) {
185 UAM_WARN("Plugin with ID: %s is NULL", _uam_get_sensor_str(id));
190 case UAS_PLUGIN_ID_BLE:
191 status = plugin->api->init(&ble_cbs);
192 if (UAS_STATUS_SUCCESS != status) {
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;
202 available_sensors |= UAM_SENSOR_BITMASK_BLE;
204 case UAS_PLUGIN_ID_WIFI:
205 status = plugin->api->init(&wifi_cbs);
206 if (UAS_STATUS_SUCCESS != status) {
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;
216 available_sensors |= UAM_SENSOR_BITMASK_WIFI;
219 case UAS_PLUGIN_ID_LIGHT:
220 status = plugin->api->init(&light_cbs);
221 if (UAS_STATUS_SUCCESS != status) {
226 available_sensors |= UAM_SENSOR_BITMASK_LIGHT;
228 case UAS_PLUGIN_ID_MOTION:
229 status = plugin->api->init(&motion_cbs);
230 if (UAS_STATUS_SUCCESS != status) {
235 available_sensors |= UAM_SENSOR_BITMASK_MOTION;
239 /* If atleast one sensor init is success, return success */
240 ret = UAM_ERROR_NONE;
247 static void __deinit_sensor_plugins(void)
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];
259 if (plugin->api && plugin->api->deinit)
260 plugin->api->deinit();
262 if (plugin->module && plugin->module->deinit)
263 plugin->module->deinit();
266 dlclose(plugin->handle);
272 available_sensors = 0;
276 static void __uas_device_list_free(int count, uas_device_info_t *devices)
282 for (i = 0; i < count; i++) {
283 uas_device_info_t *device = &(devices[i]);
285 g_free(device->device_id);
287 for (j = 0; j < device->num_addr; j++)
288 g_free(device->addr_list[j].address);
290 g_free(device->addr_list);
292 if(device->payload) {
293 g_free(device->payload->duid);
294 g_free(device->payload->bt_mac);
295 g_free(device->payload);
304 static uas_device_info_t *__get_uas_device_list(int id, GSList *devices, int *num_devices)
307 uas_device_info_t *dev_list;
311 unsigned int tech_type;
313 retv_if(NULL == devices, NULL);
315 tech_type = _pm_util_uas_plugin_id_to_tech_type(id);
316 retv_if(UAM_TECH_TYPE_NONE == tech_type, NULL);
318 len = g_slist_length(devices);
319 dev_list = g_new0(uas_device_info_t, len);
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]);
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;
335 *num_devices = count;
341 int _uam_pm_init(void)
346 ret = __init_sensor_plugins();
347 if (UAM_ERROR_NONE != ret)
351 return UAM_ERROR_NONE;
354 void _uam_pm_deinit(void)
358 __deinit_sensor_plugins();
363 unsigned int _uam_pm_get_avaliable_sensors(void)
367 UAM_DBG("Available sensors: 0x%8.8X", available_sensors);
370 return available_sensors;
373 gboolean _uam_pm_is_sensor_ready(unsigned int sensor_bitmask)
378 uam_sensor_plugin_info_t *plugin;
380 id = _pm_util_sensor_bitmask_to_plugin_id(sensor_bitmask);
381 retv_if(UAS_PLUGIN_ID_MAX <= id, FALSE);
383 plugin = plugins[id];
384 retv_if(!plugin || !plugin->api, FALSE);
386 if (UAS_STATUS_SUCCESS != plugin->api->get_state(&state))
387 state = UAS_STATE_NOT_READY;
389 UAM_DBG("Sensor: 0x%8.8X, State: %d", sensor_bitmask, state);
392 return (UAS_STATE_READY == state ? TRUE : FALSE);
395 int _uam_pm_register_device(int user_id, const uam_device_info_s *dev)
399 uam_sensor_plugin_info_t *plugin;
400 uas_device_info_t *device = NULL;
402 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
404 id = _pm_util_uam_tech_type_to_plugin_id(dev->type);
405 retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
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);
411 device = _pm_util_uam_dev_info_to_uas_dev_info(dev);
412 retv_if(NULL == device, UAM_ERROR_INTERNAL);
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;
419 _pm_util_uas_device_info_free(device);
422 return UAM_ERROR_NONE;
425 int _uam_pm_unregister_device(int user_id, const uam_device_info_s *dev)
429 uam_sensor_plugin_info_t *plugin;
430 uas_device_info_t *device = NULL;
433 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
435 id = _pm_util_uam_tech_type_to_plugin_id(dev->type);
436 retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
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);
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;
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");
451 _pm_util_uas_device_info_free(device);
454 return UAM_ERROR_NONE;
457 int _uam_pm_set_registered_devices(GSList *devices)
461 uas_device_info_t *dev_list = NULL;
464 for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
465 uam_sensor_plugin_info_t *plugin = plugins[id];
467 if (!plugin || !plugin->api)
470 if (UAS_SUPPORT_USER != plugin->capability)
473 dev_list = __get_uas_device_list(id, devices, &num_devices);
475 UAM_INFO("No devices for Plugin %d", id);
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);
481 __uas_device_list_free(num_devices, dev_list);
485 return UAM_ERROR_NONE;
488 int _uam_pm_start_detection(unsigned int detection_mode, unsigned int bitmask)
493 int ret = UAM_ERROR_INTERNAL;
494 uas_detection_type_e type;
496 switch (detection_mode) {
497 case UAM_DETECT_PRESENCE:
500 case UAM_DETECT_ABSENCE:
504 type = UAS_PRESENCE | UAS_ABSENCE;
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);
511 if (!(sensor & bitmask))
514 if (!plugin || !plugin->api)
518 * For User/device detection capable plugins, need to start both, PRESENCE
519 * as well as ABSENCE detection, to keep UA database updated.
521 if (UAS_PLUGIN_ID_BLE == id || UAS_PLUGIN_ID_WIFI == id)
522 status = plugin->api->start_detection(UAS_PRESENCE | UAS_ABSENCE);
524 status = plugin->api->start_detection(type);
526 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
527 UAM_ERR("plugin->start_detection(%d) failed for %d", type, id);
531 if (UAS_PLUGIN_ID_BLE == id)
532 ble_detection_type |= type;
533 if (UAS_PLUGIN_ID_WIFI == id)
534 wifi_detection_type |= type;
536 /* Result success if detection started for atleast 1 of the sensor */
537 ret = UAM_ERROR_NONE;
544 int _uam_pm_stop_detection(unsigned int detection_mode, unsigned int bitmask)
549 int ret = UAM_ERROR_INTERNAL;
550 uas_detection_type_e type;
552 switch (detection_mode) {
553 case UAM_DETECT_PRESENCE:
556 case UAM_DETECT_ABSENCE:
560 type = UAS_PRESENCE | UAS_ABSENCE;
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);
567 if (!(sensor & bitmask))
570 if (!plugin || !plugin->api)
573 if (UAS_PLUGIN_ID_BLE == id) {
574 ble_detection_type &= ~type;
575 ret = UAM_ERROR_NONE;
576 if (0 != ble_detection_type)
580 if (UAS_PLUGIN_ID_WIFI == id) {
581 wifi_detection_type &= ~type;
582 ret = UAM_ERROR_NONE;
583 if (0 != wifi_detection_type)
587 if (UAS_PLUGIN_ID_BLE == id || UAS_PLUGIN_ID_WIFI == id)
588 status = plugin->api->stop_detection(UAS_PRESENCE | UAS_ABSENCE);
590 status = plugin->api->stop_detection(type);
592 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
593 UAM_ERR("plugin->stop_detection(%d) failed for %d", type, id);
597 /* Result success if detection stopped for atleast 1 of the sensor */
598 ret = UAM_ERROR_NONE;
605 int _uam_pm_set_low_power_mode(unsigned int bitmask, gboolean mode)
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);
614 if (!(sensor & bitmask))
617 if (!plugin || !plugin->api || !plugin->api->set_low_power_mode)
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);
626 return UAM_ERROR_NONE;
629 int _uam_pm_set_detection_window(unsigned int detection_window)
633 int ret = UAM_ERROR_INTERNAL;
635 for (id = UAS_PLUGIN_ID_BLE; id < UAS_PLUGIN_ID_MAX; id++) {
636 uam_sensor_plugin_info_t *plugin = plugins[id];
638 if (!plugin || !plugin->api || !plugin->api->set_detection_window)
641 if (UAS_STATUS_SUCCESS != plugin->api->set_detection_window(detection_window)) {
642 UAM_ERR("plugin->set_detection_window() failed");
646 /* Result success if detection params set for atleast 1 of the sensors */
647 ret = UAM_ERROR_NONE;
654 int _uam_pm_set_detection_threshold(unsigned int sensor,
655 int presence_threshold, int absence_threshold)
659 uam_sensor_plugin_info_t *plugin;
661 id = _pm_util_sensor_bitmask_to_plugin_id(sensor);
662 retv_if(UAS_PLUGIN_ID_MAX <= id, UAM_ERROR_INVALID_PARAMETER);
664 plugin = plugins[id];
665 retv_if(!plugin || !plugin->api, UAM_ERROR_NOT_SUPPORTED);
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;
674 return UAM_ERROR_NONE;
677 int _uam_pm_start_active_device_scan(unsigned int* bitmask, int detection_period)
682 int ret = UAM_ERROR_INTERNAL;
684 unsigned int scanning_sensor = 0;
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);
690 if (!(sensor & (*bitmask)))
693 if (!plugin || !plugin->api || !plugin->api->scan_active_devices)
696 status = plugin->api->scan_active_devices(detection_period);
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);
703 scanning_sensor |= sensor;
704 /* Result success if scanning started for atleast 1 of the sensor */
705 ret = UAM_ERROR_NONE;
708 (*bitmask) &= scanning_sensor;
714 int _uam_pm_stop_active_device_scan(unsigned int bitmask)
719 int ret = UAM_ERROR_INTERNAL;
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);
725 if (!(sensor & bitmask))
728 if (!plugin || !plugin->api || !plugin->api->cancel_active_device_scan)
731 status = plugin->api->cancel_active_device_scan();
733 if (UAS_STATUS_SUCCESS != status && UAS_STATUS_ALREADY_DONE != status) {
734 UAM_ERR("plugin->stop_search_active_devices() failed for %d", id);
738 ret = UAM_ERROR_NONE;
745 int _uam_pm_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
750 int ret = UAM_ERROR_INTERNAL;
752 id = UAS_PLUGIN_ID_BLE;
753 uam_sensor_plugin_info_t *plugin = plugins[id];
755 if (!plugin || !plugin->api || !plugin->api->add_ibeacon_adv) {
756 ret = UAM_ERROR_NOT_SUPPORTED;
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);
765 ret = UAM_ERROR_NONE;