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-internal.h"
23 #include "ua-manager-common.h"
24 #include "ua-plugin-manager.h"
26 #include "ua-manager-database.h"
27 #include "ua-cloud-plugin-handler.h"
29 #include "ua-vendor-plugin-manager.h"
31 #define UAM_MAX_USERS 255
32 #define USER_ACCOUNT_DEFAULT "default@default.com"
33 #define USER_NAME_DEFAULT "default"
38 uam_pm_detection_mode_e mode;
39 uam_db_service_info_t *service;
48 static GSList *users; /* List of users - uam_db_user_info_t */
49 static GSList *devices; /* List of devices - uam_db_device_info_t */
50 static GSList *services; /* List of services - uam_db_service_info_t */
51 static GSList *svc_devs; /* List of service device mapping - uam_svc_dev_info_t */
53 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
54 static GSList *scanners; /* List of scanning apps - uam_scanner_info_t */
56 static guint detection_timer = 0;
57 static unsigned int detection_window;
59 static unsigned int detecting_sensors = 0;
61 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
63 const uam_db_user_info_t *user = data;
64 const char *account = user_data;
66 retv_if(NULL == user, -1);
67 retv_if(NULL == user->account, -1);
68 retv_if(NULL == account, -1);
70 return g_strcmp0(user->account, account);
73 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
75 const uam_db_user_info_t *user = data;
76 const int *id = user_data;
78 UAM_INFO("[%d][%d]", *id, user->user_id);
80 retv_if(NULL == user, -1);
81 retv_if(NULL == user->account, -1);
82 retv_if(NULL == id, -1);
84 if (*id != user->user_id)
90 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
92 const uam_db_service_info_t *service = data;
93 const char *svc_name = user_data;
95 retv_if(NULL == service, -1);
96 retv_if(NULL == service->name, -1);
97 retv_if(NULL == svc_name, -1);
99 return g_strcmp0(service->name, svc_name);
102 static void __free_address_info(gpointer data)
105 uam_db_address_info_t *addr = data;
107 ret_if(NULL == addr);
109 g_free(addr->address);
115 static void __free_dev_tech_info(gpointer data)
118 uam_db_tech_info_t *tech_info = data;
121 ret_if(NULL == tech_info);
123 /* Delete the tech information from the service list that includes tech. */
124 for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
125 uam_db_service_info_t *svc_info = l->data;
127 if (!svc_info || !svc_info->dev_techs)
130 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
133 g_slist_free_full(tech_info->addresses, __free_address_info);
134 tech_info->addresses = NULL;
141 static void __free_user_device(gpointer data)
144 uam_db_device_info_t *device = data;
146 ret_if(NULL == device);
148 /* Remove device data from global device list */
149 devices = g_slist_remove(devices, device);
151 /* Free allocated memory */
152 g_free(device->device_id);
153 g_slist_free_full(device->tech_list, __free_dev_tech_info);
159 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
164 UAM_INFO_C("Send %s to applications", _uam_manager_event_to_str(event));
165 /* Send device event to application */
166 param = g_variant_new("(iiisss)",
168 dev_info->operating_system,
172 dev_info->device_id);
173 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL, event, param))
174 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
179 static void __print_service(gpointer data, gpointer user_data)
182 uam_db_service_info_t *service = data;
183 uam_db_tech_info_t *tech = user_data;
185 ret_if(NULL == tech);
186 ret_if(NULL == service);
188 UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
189 tech->device->device_id, tech->tech_type,
190 service->name, service->cycle);
195 static void __add_service_to_dev_tech_mapping(
196 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
200 ret_if(NULL == tech);
201 ret_if(NULL == service);
203 tech->svc_list = g_slist_append(tech->svc_list, service);
204 service->dev_techs = g_slist_append(service->dev_techs, tech);
205 g_slist_foreach(tech->svc_list, __print_service, tech);
210 static void __remove_service_to_dev_tech_mapping(
211 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
215 ret_if(NULL == tech);
216 ret_if(NULL == service);
218 tech->svc_list = g_slist_remove(tech->svc_list, service);
219 service->dev_techs = g_slist_remove(service->dev_techs, tech);
220 g_slist_foreach(tech->svc_list, __print_service, tech);
225 static char *__get_mac_addr(uam_db_tech_info_t *tech)
230 retv_if(NULL == tech, NULL);
232 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
233 uam_db_address_info_t *addr = l->data;
238 if (addr->addr_type == UAM_ADDR_TYPE_BT ||
239 addr->addr_type == UAM_ADDR_TYPE_BLE ||
240 addr->addr_type == UAM_ADDR_TYPE_WIFI ||
241 addr->addr_type == UAM_ADDR_TYPE_P2P)
242 return addr->address;
249 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
251 switch (addr->addr_type) {
252 case UAM_ADDR_TYPE_BLE:
253 case UAM_ADDR_TYPE_BT:
254 case UAM_ADDR_TYPE_P2P:
255 case UAM_ADDR_TYPE_WIFI:
256 g_strlcpy(device->mac, addr->address,
257 UAM_MAC_ADDRESS_STRING_LEN);
259 case UAM_ADDR_TYPE_IPv4:
260 g_strlcpy(device->ipv4_addr,
262 UAM_IP_ADDRESS_MAX_STRING_LEN);
265 UAM_WARN("Unknown address type %d", addr->addr_type);
270 static void __uam_copy_payload_info(uam_ble_payload_s *dev_payload, uam_db_ble_payload_t *payload)
273 dev_payload->primary_key = payload->primary_key;
274 dev_payload->device_icon = payload->device_icon;
275 dev_payload->secondary_key = payload->secondary_key;
276 if (payload->device_uid)
277 memcpy(dev_payload->device_uid,
278 payload->device_uid, UAM_BLE_PAYLOAD_DEVICE_UID_LEN);
280 memcpy(dev_payload->bt_mac,
281 payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
286 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
291 retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
293 memset(device, 0x00, sizeof(uam_device_info_s));
294 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
295 uam_db_address_info_t *addr = l->data;
300 __uam_core_copy_addr(device, addr);
303 device->operating_system = tech->device->os;
304 g_strlcpy(device->device_id, tech->device->device_id,
305 UAM_DEVICE_ID_MAX_STRING_LEN);
306 device->type = tech->tech_type;
307 device->discriminant = tech->discriminant;
308 device->last_seen = tech->last_seen;
311 return UAM_ERROR_NONE;
314 static int _uam_remove_user_device(uam_db_device_info_t *device)
317 uam_device_info_s dev_info;
320 int ret = UAM_ERROR_NONE;
322 retv_if(NULL == device, UAM_ERROR_INVALID_PARAMETER);
323 user_id = device->user->user_id;
325 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
326 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
327 uam_db_tech_info_t *tech = l->data;
332 /* Copy tech info to device info */
333 ret = __copy_tech_info_to_device_info(tech, &dev_info);
334 if (UAM_ERROR_NONE != ret) {
335 UAM_ERR("__copy_tech_info_to_device_info failed");
336 __uam_db_end_transaction(0);
340 /* Unregister device from plugin */
341 ret = _uam_pm_unregister_device(user_id, &dev_info);
342 if (UAM_ERROR_NONE != ret)
343 UAM_ERR("_uam_pm_unregister_device failed with %s",
344 _uam_manager_error_to_str(ret));
346 /* Send device removed event to application */
347 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
349 /* Remove device from database */
350 ret = _uam_device_db_delete_device_info(
351 dev_info.device_id, dev_info.type, dev_info.mac);
352 if (UAM_ERROR_NONE != ret) {
353 UAM_ERR("_uam_device_db_delete_device_info failed");
354 __uam_db_end_transaction(0);
358 __uam_db_end_transaction(1);
364 static int __free_uam_db_user_info(gpointer data)
367 uam_db_user_info_t *user = data;
369 int ret = UAM_ERROR_NONE;
371 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
372 uam_db_device_info_t *device = l->data;
373 ret = _uam_remove_user_device(device);
374 if (UAM_ERROR_NONE != ret) {
375 UAM_ERR("_uam_remove_user_device failed");
380 g_slist_free_full(user->devices, __free_user_device);
382 /* Set/update registered device list to plugins */
383 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
384 UAM_ERR("_uam_pm_set_registered_devices failed");
386 /* Set/update registered device list to cloud plugin */
387 _uam_cloud_update_registered_devices();
390 g_free(user->account);
397 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
400 const uam_db_device_info_t *device = data;
401 const char *dev_id = user_data;
403 retv_if(NULL == device, -1);
404 retv_if(NULL == device->device_id, -1);
405 retv_if(NULL == dev_id, -1);
408 return g_strcmp0(device->device_id, dev_id);
411 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
414 const uam_db_tech_info_t *tech = data;
415 const int *type = user_data;
417 retv_if(NULL == tech, -1);
418 retv_if(NULL == type, -1);
421 return ((*type == tech->tech_type) ? 0 : 1);
424 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
429 for (l = devices; NULL != l; l = g_slist_next(l)) {
430 uam_db_device_info_t *dev = l->data;
436 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
437 uam_db_tech_info_t *tech = l1->data;
443 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
444 uam_db_address_info_t *addr = l2->data;
449 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
450 UAM_ADDR_TYPE_BT == addr->addr_type ||
451 UAM_ADDR_TYPE_P2P == addr->addr_type ||
452 UAM_ADDR_TYPE_WIFI == addr->addr_type)
453 if (!strcasecmp(addr->address, mac)) {
454 UAM_DBG("Device found Mac: %s, type: %d",
455 addr->address, addr->addr_type);
466 static int __get_uam_db_dev_list_to_uam_dev_list(
467 GSList *db_dev_list, uam_device_info_s **device_list, int *count)
472 int ret = UAM_ERROR_NONE;
475 /* Calculate num devices first */
476 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
477 uam_db_device_info_t *db_info = l->data;
480 if (!db_info || !db_info->device_id)
483 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
484 uam_db_tech_info_t *tech = l1->data;
486 if (!tech || !tech->addresses)
492 UAM_INFO("Count = %d", *count);
494 *device_list = g_new0(uam_device_info_s, *count);
497 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
498 uam_db_device_info_t *db_info = l->data;
501 if (!db_info || !db_info->device_id)
504 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
505 uam_db_tech_info_t *tech = l1->data;
507 if (!tech || !tech->addresses)
510 /* Copy tech info to device info */
511 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
512 if (UAM_ERROR_NONE != ret) {
513 UAM_ERR("__copy_tech_info_to_device_info failed");
520 UAM_INFO("Count = %d, indx = %d", *count, indx);
525 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
526 const char *name, const char *svc_name, uam_pm_detection_mode_e mode)
531 retv_if(NULL == name, NULL);
532 retv_if(NULL == monitor_list, NULL);
534 for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
535 uam_monitor_info_t *monitor = l->data;
537 if (!monitor || !monitor->name ||
538 !monitor->service || !monitor->service->name)
541 if ((mode == monitor->mode) &&
542 (0 == g_strcmp0(monitor->name, name)) &&
543 (0 == g_strcmp0(monitor->service->name, svc_name))) {
544 UAM_DBG("Monitoring application found in list");
553 unsigned int _uam_core_get_active_sensors(int detection_mode)
556 unsigned int sensors = 0;
559 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
560 (UAM_DETECT_ABSENCE != detection_mode), 0);
562 for (l = monitors; NULL != l; l = g_slist_next(l)) {
563 uam_monitor_info_t *monitor = l->data;
565 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
568 sensors |= monitor->sensors;
575 unsigned int _uam_core_get_env_sensors()
578 unsigned int sensors = 0;
580 sensors |= UAM_SENSOR_BITMASK_MOTION;
581 sensors |= UAM_SENSOR_BITMASK_LIGHT;
587 unsigned int _uam_core_get_active_env_sensors(int detection_mode)
590 unsigned int sensors = 0;
593 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
594 (UAM_DETECT_ABSENCE != detection_mode), 0);
596 for (l = monitors; NULL != l; l = g_slist_next(l)) {
597 uam_monitor_info_t *monitor = l->data;
599 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
602 sensors |= monitor->sensors & _uam_core_get_env_sensors();
609 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
613 GSList *svc_list = NULL;
615 retv_if(NULL == db_svc_list, NULL);
618 * Iterate over the db_svc_list and add each service to the global
619 * service list "services" if its not already inserted. Also append this
620 * uam_db_service_info_t to svc_list.
622 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
623 db_service_info_t *db_svc = l->data;
624 uam_db_service_info_t *service;
630 l1 = g_slist_find_custom(services,
631 db_svc->service_name, __compare_svc_name);
633 service = g_new0(uam_db_service_info_t, 1);
634 service->name = g_strdup(db_svc->service_name);
635 service->cycle = db_svc->cycle;
636 services = g_slist_append(services, service);
640 svc_list = g_slist_append(svc_list, service);
647 static void __uam_core_add_dev_to_list(
648 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
649 int presence_state, unsigned long long last_seen, GSList *svc_list)
652 uam_db_tech_info_t *tech;
653 uam_db_device_info_t *device;
656 ret_if(NULL == dev_info);
657 ret_if(NULL == user);
659 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
662 ret_if(user != device->user);
663 ret_if(device->supported_techs & dev_info->type);
665 if (device->os != dev_info->operating_system) {
666 UAM_INFO("device->os: %d, dev_info->operating_system: %d",
667 device->os, dev_info->operating_system);
668 /* Update device OS type */
669 if (UAM_OS_TYPE_INVALID == device->os || UAM_OS_TYPE_UNDEFINED == device->os)
670 device->os = dev_info->operating_system;
672 UAM_WARN("Strange - OS types did not match, need to check");
675 device = g_new0(uam_db_device_info_t, 1);
676 device->device_id = g_strdup(dev_info->device_id);
677 device->os = dev_info->operating_system;
678 device->discriminant = dev_info->discriminant;
681 /* Add device to global device list */
682 devices = g_slist_append(devices, device);
684 /* Add same device to user's device list */
685 user->devices = g_slist_append(user->devices, device);
688 tech = g_new0(uam_db_tech_info_t, 1);
689 tech->tech_type = dev_info->type;
690 tech->presence_state = presence_state;
691 tech->last_seen = last_seen;
692 tech->device = device;
693 tech->discriminant = dev_info->discriminant;
695 tech->svc_list = svc_list;
696 g_slist_foreach(tech->svc_list, __print_service, tech);
697 for (l = svc_list; NULL != l; l = g_slist_next(l)) {
698 uam_db_service_info_t *service = l->data;
703 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
706 /* Add tech info to tech list */
707 device->tech_list = g_slist_append(device->tech_list, tech);
708 device->supported_techs |= tech->tech_type;
709 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
711 if (0 < strlen(dev_info->mac)) {
712 uam_db_address_info_t *addr;
714 addr = g_new0(uam_db_address_info_t, 1);
715 addr->address = g_strdup(dev_info->mac);
717 switch (dev_info->type) {
718 case UAM_TECH_TYPE_BLE:
719 addr->addr_type = UAM_ADDR_TYPE_BLE;
721 case UAM_TECH_TYPE_BT:
722 addr->addr_type = UAM_ADDR_TYPE_BT;
724 case UAM_TECH_TYPE_P2P:
725 addr->addr_type = UAM_ADDR_TYPE_P2P;
727 case UAM_TECH_TYPE_WIFI:
728 addr->addr_type = UAM_ADDR_TYPE_WIFI;
731 UAM_ERR("Unknown tech type: %d", dev_info->type);
732 g_free(addr->address);
738 UAM_DBG("MAC address %s added for tech type: %d",
739 dev_info->mac, dev_info->type);
740 tech->addresses = g_slist_append(tech->addresses, addr);
744 if (0 < strlen(dev_info->ipv4_addr)) {
745 uam_db_address_info_t *addr;
747 if (UAM_TECH_TYPE_BLE == dev_info->type ||
748 UAM_TECH_TYPE_BT == dev_info->type)
749 UAM_WARN("IPv4 address %s added for tech type: %d",
750 dev_info->ipv4_addr, dev_info->type);
752 UAM_DBG("IPv4 address %s added for tech type: %d",
753 dev_info->ipv4_addr, dev_info->type);
755 addr = g_new0(uam_db_address_info_t, 1);
756 addr->addr_type = UAM_ADDR_TYPE_IPv4;
757 addr->address = g_strdup(dev_info->ipv4_addr);
759 tech->addresses = g_slist_append(tech->addresses, addr);
765 int _uam_core_add_user(int *user_id, const char *account, const char *name)
769 uam_db_user_info_t *user;
770 int ret = UAM_ERROR_NONE;
772 l = g_slist_find_custom(users, account, __compare_user_account);
773 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
775 user = g_new0(uam_db_user_info_t, 1);
777 /* Add user to database */
778 ret = _uam_db_insert_user_info(&(user->user_id), name, account);
779 if (UAM_ERROR_NONE != ret) {
780 UAM_ERR("_uam_db_insert_user_info failed [%d]", ret);
785 user->name = g_strdup(name);
786 user->account = g_strdup(account);
787 user->devices = NULL;
789 *user_id = user->user_id;
791 users = g_slist_append(users, user);
793 /* Send user added event to application */
794 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
795 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
796 UAM_ERROR_NONE, user->account, user->name)))
797 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
800 return UAM_ERROR_NONE;
803 int _uam_core_remove_user(const char *account)
807 uam_db_user_info_t *user;
808 int ret = UAM_ERROR_NONE;
810 l = g_slist_find_custom(users, account, __compare_user_account);
811 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
814 /* Remove user from database */
815 ret = _uam_db_delete_by_user_id(user->user_id);
816 if (UAM_ERROR_NONE != ret) {
817 UAM_ERR("_uam_db_delete_by_user_id failed");
821 users = g_slist_remove(users, user);
823 /* Send user removed event to application */
824 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
825 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
826 UAM_ERROR_NONE, user->account, user->name)))
827 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
829 ret = __free_uam_db_user_info((gpointer)user);
830 if (UAM_ERROR_NONE != ret) {
831 UAM_WARN("_free_uam_db_user_info failed");
835 return UAM_ERROR_NONE;
838 int _uam_core_update_user(uam_user_info_s *user)
842 uam_db_user_info_t *user_info;
844 retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
846 /* Retrieve user from list */
847 l = g_slist_find_custom(users, user->account, __compare_user_account);
848 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
851 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
853 /* Update user to database */
854 if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
855 UAM_ERR("_uam_db_update_user_info failed");
856 return UAM_ERROR_DB_FAILED;
860 return UAM_ERROR_NONE;
863 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
868 uam_db_device_info_t *device;
869 uam_db_user_info_t *user;
871 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
872 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
874 l = g_slist_find_custom(users, account, __compare_user_account);
875 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
878 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
881 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
882 retv_if((dev_info->type & device->supported_techs),
883 UAM_ERROR_ALREADY_REGISTERED);
886 UAM_INFO("[%d]", user->user_id);
888 ret = _uam_pm_register_device(user->user_id, dev_info);
889 if (UAM_ERROR_NONE != ret) {
890 UAM_ERR("_uam_pm_register_device failed with %s",
891 _uam_manager_error_to_str(ret));
896 return UAM_ERROR_NONE;
899 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
902 uam_db_device_info_t *device;
905 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
906 retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
909 l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
914 if (!(device->supported_techs & dev->type))
917 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
918 uam_db_tech_info_t *tech = l->data;
924 if (dev->type != tech->tech_type)
927 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
928 uam_db_address_info_t *addr = l1->data;
933 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
934 UAM_ADDR_TYPE_BT == addr->addr_type ||
935 UAM_ADDR_TYPE_P2P == addr->addr_type ||
936 UAM_ADDR_TYPE_WIFI == addr->addr_type)
937 if (!strcasecmp(addr->address, dev->mac)) {
946 UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
948 return UAM_ERROR_NONE;
951 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
952 const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
958 ret = _uam_db_get_device_services_count(dev_info->device_id,
959 dev_info->type, dev_info->mac, &count);
960 if (UAM_ERROR_NONE != ret) {
961 UAM_ERR("_uam_db_get_device_services_count failed with %s",
962 _uam_manager_error_to_str(ret));
967 ret = UAM_ERROR_RESOURCE_BUSY;
968 UAM_WARN("other service uses this device ref:[%d]", count);
972 ret = _uam_pm_unregister_device(user_id, dev_info);
973 if (UAM_ERROR_NONE != ret) {
974 UAM_ERR("_uam_pm_unregister_device failed with %s",
975 _uam_manager_error_to_str(ret));
979 /* Send device removed event to application */
980 __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
982 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
983 /* Remove device from database */
984 ret = _uam_device_db_delete_device_info(
985 dev_info->device_id, dev_info->type, dev_info->mac);
986 if (UAM_ERROR_NONE != ret) {
987 UAM_ERR("_uam_device_db_delete_device_info failed");
988 __uam_db_end_transaction(0);
992 /* Remove device from service */
993 for (l = tech->svc_list; l; l = g_slist_next(l)) {
994 uam_db_service_info_t *svc = l->data;
996 if (!svc || !svc->name)
998 ret = _uam_core_service_remove_device(svc->name,
999 dev_info->device_id, dev_info->type);
1000 if (UAM_ERROR_NONE != ret) {
1001 UAM_ERR("_uam_device_db_delete_device_info failed");
1004 __uam_db_end_transaction(1);
1006 /* Remove tech info from device's tech list */
1007 device->tech_list = g_slist_remove(device->tech_list, tech);
1008 device->supported_techs &= ~(tech->tech_type);
1009 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1010 __free_dev_tech_info(tech);
1012 if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1013 /* Remove device from global device list */
1014 devices = g_slist_remove(devices, device);
1016 /* Remove device from user's device list */
1017 device->user->devices = g_slist_remove(device->user->devices, device);
1019 __free_user_device(device);
1022 /* Set/update registered device list to plugins */
1023 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1024 UAM_ERR("_uam_pm_set_registered_devices failed");
1026 /* Set/update registered device list to cloud plugin */
1027 _uam_cloud_update_registered_devices();
1030 return UAM_ERROR_NONE;
1033 int _uam_core_remove_device(const char *account,
1034 const uam_device_info_s *dev_info)
1039 uam_db_tech_info_t *tech;
1040 uam_db_device_info_t *device;
1041 uam_db_user_info_t *user;
1043 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1044 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1046 /* Retrieve user from list */
1047 l = g_slist_find_custom(users, account, __compare_user_account);
1048 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1051 /* Retrieve device from list */
1052 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1053 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1055 retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1056 retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1058 /* Retrieve tech info from list */
1059 l = g_slist_find_custom(device->tech_list,
1060 &(dev_info->type), __compare_tech_type);
1061 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1064 ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1070 int _uam_core_remove_device_by_device_id(const char *device_id,
1076 uam_device_info_s dev_info;
1077 uam_db_tech_info_t *tech;
1078 uam_db_device_info_t *device;
1080 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1081 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1082 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1084 /* Retrieve device from list */
1085 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1086 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1088 retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1090 /* Retrieve tech info from list */
1091 l = g_slist_find_custom(device->tech_list,
1092 &tech_type, __compare_tech_type);
1093 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1097 ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1098 retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1100 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1106 int _uam_core_remove_device_by_mac(const char *mac)
1109 uam_db_tech_info_t *tech;
1110 uam_db_device_info_t *device;
1111 uam_device_info_s dev_info;
1114 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1116 tech = __get_tech_info_by_mac(mac);
1117 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1118 device = tech->device;
1120 ret = __copy_tech_info_to_device_info(tech, &dev_info);
1121 if (UAM_ERROR_NONE != ret) {
1122 UAM_ERR("__copy_tech_info_to_device_info failed");
1126 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1132 int _uam_core_update_device(const uam_device_info_s *a_device)
1136 int ret = UAM_ERROR_NONE;
1137 GSList *l, *l1, *l2;
1139 uam_device_info_s temp;
1140 uam_db_user_info_t *user = NULL;
1141 uam_db_device_info_t *device = NULL;
1142 uam_db_tech_info_t *tech = NULL;
1144 /* Find all tech-devices in users' devices */
1145 for (l = users; NULL != l; l = g_slist_next(l)) {
1148 l1 = g_slist_find_custom(user->devices,
1149 a_device->device_id, __compare_device_id);
1151 UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1152 user->user_id, a_device->device_id);
1157 if (!(device->supported_techs & a_device->type)) {
1158 UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1159 device->device_id, a_device->type);
1163 /* Update discriminant for devices */
1164 device->discriminant = a_device->discriminant;
1165 device->os = a_device->operating_system;
1167 l2 = g_slist_find_custom(device->tech_list,
1168 &(a_device->type), __compare_tech_type);
1170 UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1176 UAM_DBG("Device tech is NULL");
1180 /* Update discriminant for device-tech */
1181 tech->discriminant = a_device->discriminant;
1183 /* Update device's updated information to database */
1184 ret = __copy_tech_info_to_device_info(tech, &temp);
1185 if (UAM_ERROR_NONE != ret) {
1186 UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1190 ret = _uam_device_db_update_device(temp.device_id, temp.type,
1191 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant);
1192 if (UAM_ERROR_NONE != ret) {
1193 UAM_ERR("_uam_device_db_update_device failed [%d]", ret);
1198 /* Set/update registered device list to plugins */
1199 ret = _uam_pm_set_registered_devices(devices);
1200 if (UAM_ERROR_NONE != ret) {
1201 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1205 /* Set/update registered device list to cloud plugin */
1206 _uam_cloud_update_registered_devices();
1212 int _uam_core_get_default_user(uam_user_info_s *user_info)
1218 uam_db_user_info_t *user;
1220 retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1222 ret = _uam_core_add_user(&user_id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1223 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1224 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1228 l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1229 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1232 memset(user_info, 0x00, sizeof(uam_user_info_s));
1233 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1234 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1237 return UAM_ERROR_NONE;
1240 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1246 size = g_slist_length(users);
1247 *user_list = g_new0(uam_user_info_s, size);
1250 /* fetch users list from DB */
1251 for (l = users; l; l = g_slist_next(l)) {
1252 uam_db_user_info_t *db_info = l->data;
1254 if (!db_info || !db_info->account)
1257 g_strlcpy((*user_list)[*count].account,
1258 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1260 g_strlcpy((*user_list)[*count].name,
1261 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1266 UAM_INFO("Count: %d", *count);
1268 return UAM_ERROR_NONE;
1271 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1274 uam_db_user_info_t *db_info;
1277 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1279 l = g_slist_find_custom(users, account, __compare_user_account);
1280 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1283 g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1285 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1289 return UAM_ERROR_NONE;
1292 int _uam_core_get_devcie_by_device_id(
1293 const char *device_id, int tech_type, uam_device_info_s *device)
1296 uam_db_device_info_t *db_info;
1300 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1301 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1302 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1304 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1305 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1307 retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1309 memset(device, 0x00, sizeof(uam_device_info_s));
1311 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1312 uam_db_tech_info_t *tech = l1->data;
1315 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1318 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1319 uam_db_address_info_t *addr = l2->data;
1324 __uam_core_copy_addr(device, addr);
1327 device->operating_system = db_info->os;
1328 g_strlcpy(device->device_id, db_info->device_id,
1329 UAM_DEVICE_ID_MAX_STRING_LEN);
1330 device->type = tech->tech_type;
1331 device->discriminant = tech->discriminant;
1334 retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1337 return UAM_ERROR_NONE;
1340 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1344 uam_db_tech_info_t *tech;
1346 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1348 tech = __get_tech_info_by_mac(mac);
1349 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1351 ret = __copy_tech_info_to_device_info(tech, device);
1352 if (UAM_ERROR_NONE != ret) {
1353 UAM_ERR("__copy_tech_info_to_device_info failed");
1361 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1364 uam_db_device_info_t *dev;
1367 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1369 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1370 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1373 g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1374 if (dev->user->name)
1375 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1378 return UAM_ERROR_NONE;
1381 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1384 uam_db_tech_info_t *tech;
1386 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1388 tech = __get_tech_info_by_mac(mac);
1389 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1391 g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1392 if (tech->device->user->name)
1393 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1396 return UAM_ERROR_NONE;
1399 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1402 int ret = UAM_ERROR_NONE;
1404 ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1410 int _uam_core_get_user_devices(const char *account,
1411 int *count, uam_device_info_s **device_list)
1414 uam_db_user_info_t *user;
1416 int ret = UAM_ERROR_NONE;
1418 l = g_slist_find_custom(users, account, __compare_user_account);
1419 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1422 ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1428 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1432 *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1435 return UAM_ERROR_NONE;
1438 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1443 is_ready = _uam_pm_is_sensor_ready(sensor);
1444 UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1450 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
1451 uam_tech_type_e tech_type, const char *svc_name)
1454 uam_svc_dev_info_t *svc_dev = NULL;
1457 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1460 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1463 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1464 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1465 (svc_dev->tech_type == tech_type)) {
1466 UAM_DBG("Service device found in list");
1475 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1476 const char *svc_name, gboolean discriminant, unsigned long long last_seen)
1479 uam_svc_dev_info_t *svc = NULL;
1481 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1482 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1483 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1484 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1486 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1488 svc = g_new0(uam_svc_dev_info_t, 1);
1489 svc->device_id = g_strdup(device_id);
1490 svc->tech_type = tech_type;
1491 svc->service = g_strdup(svc_name);
1492 svc_devs = g_slist_append(svc_devs, svc);
1495 svc->discriminant = discriminant;
1496 svc->last_seen = last_seen;
1498 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] last_seen[%llu]",
1499 svc->service, svc->device_id, svc->tech_type, svc->discriminant, svc->last_seen);
1502 return UAM_ERROR_NONE;
1505 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
1506 uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant)
1509 uam_svc_dev_info_t *svc = NULL;
1511 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1512 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1513 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1514 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1516 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1518 svc = g_new0(uam_svc_dev_info_t, 1);
1519 svc->device_id = g_strdup(device_id);
1520 svc->tech_type = tech_type;
1521 svc->service = g_strdup(svc_name);
1522 svc_devs = g_slist_append(svc_devs, svc);
1525 svc->discriminant = discriminant;
1527 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]]",
1528 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1531 return UAM_ERROR_NONE;
1534 int _uam_core_service_add_user(const char *svc_name, const char *account)
1538 int ret = UAM_ERROR_NONE;
1539 uam_db_user_info_t *user;
1540 uam_db_service_info_t *service;
1542 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1543 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1545 /* Retrieve user from list */
1546 l = g_slist_find_custom(users, account, __compare_user_account);
1547 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1550 /* Retrieve service from list */
1551 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1552 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1555 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1556 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1557 uam_db_device_info_t *device = l->data;
1563 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1564 uam_db_tech_info_t *tech = l1->data;
1571 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1572 __compare_svc_name);
1576 __add_service_to_dev_tech_mapping(tech, service);
1578 mac = __get_mac_addr(tech);
1579 /* Insert device service info to db */
1580 ret = _uam_db_insert_device_service_info(device->device_id,
1581 tech->tech_type, mac, service->name, service->cycle,
1582 device->discriminant, 0);
1583 if (UAM_ERROR_NONE != ret) {
1584 UAM_WARN("Device service addition to persistent DB failed");
1585 __uam_db_end_transaction(0);
1588 ret = _uam_core_update_svc_dev_info(device->device_id,
1589 tech->tech_type, service->name, device->discriminant, 0);
1590 if (UAM_ERROR_NONE != ret) {
1591 UAM_WARN("Device service addition to service device mapping failed");
1592 __uam_db_end_transaction(0);
1598 __uam_db_end_transaction(1);
1604 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1608 uam_db_user_info_t *user;
1611 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1612 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1614 /* Retrieve user from list */
1615 l = g_slist_find_custom(users, account, __compare_user_account);
1616 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1619 /* Retrieve service from list */
1620 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1621 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1623 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1624 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1625 uam_db_device_info_t *device = l->data;
1631 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1632 uam_db_tech_info_t *tech = l1->data;
1639 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1640 __compare_svc_name);
1644 UAM_DBG("Service %s found, remove it from list", svc_name);
1645 __remove_service_to_dev_tech_mapping(
1646 tech, (uam_db_service_info_t *)l2->data);
1648 mac = __get_mac_addr(tech);
1649 /* Remove service-device from DB */
1650 ret = _uam_db_delete_device_service_info(device->device_id,
1651 tech->tech_type, mac, svc_name);
1652 if (UAM_ERROR_NONE != ret) {
1653 UAM_WARN("Device service removal from persistent DB failed");
1654 __uam_db_end_transaction(0);
1659 __uam_db_end_transaction(1);
1662 return UAM_ERROR_NONE;
1665 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1668 uam_db_device_info_t *device;
1671 retv_if(NULL == device_id, NULL);
1672 retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1673 retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1675 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1677 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1682 if (!device || !(device->supported_techs & tech_type)) {
1683 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1684 tech_type, device_id);
1688 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1689 uam_db_tech_info_t *tech = l->data;
1694 if (tech_type == tech->tech_type) {
1695 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1696 device_id, tech_type);
1701 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1706 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
1712 int ret = UAM_ERROR_NONE;
1713 uam_db_tech_info_t *tech_info;
1714 uam_db_service_info_t *service;
1716 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1717 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1718 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1719 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1721 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1722 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1724 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1725 retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1727 /* Retrieve service from list */
1728 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1729 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1732 __add_service_to_dev_tech_mapping(tech_info, service);
1734 mac = __get_mac_addr(tech_info);
1735 /* Insert device service info to db */
1736 ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
1737 service->name, service->cycle, tech_info->discriminant, 0);
1738 if (UAM_ERROR_NONE != ret) {
1739 UAM_WARN("Device service addition to persistent DB failed");
1742 ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
1743 tech_info->discriminant, 0);
1744 if (UAM_ERROR_NONE != ret) {
1745 UAM_WARN("Device service addition to svc dev mapping failed");
1750 return UAM_ERROR_NONE;
1753 int _uam_core_service_remove_device(const char *svc_name,
1754 const char *device_id, int tech_type)
1759 uam_db_tech_info_t *tech_info;
1760 int ret = UAM_ERROR_NONE;
1762 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1763 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1764 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1765 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1767 /* Retrieve service from list */
1768 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1769 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1771 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1772 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1774 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1775 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1777 __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1779 mac = __get_mac_addr(tech_info);
1780 /* Remove service-device from DB */
1781 ret = _uam_db_delete_device_service_info(
1782 device_id, tech_type, mac, svc_name);
1783 if (UAM_ERROR_NONE != ret) {
1784 UAM_ERR("Device service removal from persistent DB failed");
1789 return UAM_ERROR_NONE;
1792 int _uam_core_service_set_device_discriminant(const char *svc_name,
1793 const char *device_id, int tech_type, gboolean discriminant)
1797 int ret = UAM_ERROR_NONE;
1799 uam_db_tech_info_t *tech_info;
1800 uam_db_service_info_t *service;
1802 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1803 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1804 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1805 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1807 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1808 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1810 /* Retrieve service from list */
1811 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1812 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1815 mac = __get_mac_addr(tech_info);
1816 /* Insert device service info to db */
1817 ret = _uam_db_update_device_service_discriminant(device_id,
1818 tech_type, mac, service->name, discriminant);
1819 if (UAM_ERROR_NONE != ret) {
1820 UAM_WARN("Device service discriminant update to persistent DB failed");
1823 ret = _uam_core_update_svc_dev_info_discriminant(device_id,
1824 tech_type, service->name, discriminant);
1825 if (UAM_ERROR_NONE != ret) {
1826 UAM_WARN("Device service discriminant mapping update failed");
1831 return UAM_ERROR_NONE;
1834 int _uam_core_service_get_device_discriminant(const char *svc_name,
1835 const char *device_id, int tech_type, gboolean *discriminant)
1838 uam_svc_dev_info_t *svc_dev;
1840 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1841 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1842 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1843 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1845 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1846 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1847 *discriminant = (gboolean)svc_dev->discriminant;
1850 return UAM_ERROR_NONE;
1853 int _uam_core_service_get_device_last_seen(const char *svc_name,
1854 const char *device_id, int tech_type, unsigned long long *last_seen)
1857 uam_svc_dev_info_t *svc_dev;
1859 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1860 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1861 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1862 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1864 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1865 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1866 *last_seen = svc_dev->last_seen;
1869 return UAM_ERROR_NONE;
1872 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1876 uam_db_service_info_t *service;
1877 unsigned int elapsed_time;
1879 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1880 retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1881 retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1883 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1884 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1887 elapsed_time = service->cycle - service->remaining_time;
1888 service->cycle = new_cycle;
1889 if (new_cycle < elapsed_time)
1890 service->remaining_time = 0;
1892 service->remaining_time = new_cycle - elapsed_time;
1894 /* Update service detection cycle in DB */
1895 if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1896 UAM_WARN("Service cycle updation to persistent DB failed");
1899 return UAM_ERROR_NONE;
1902 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1906 uam_db_service_info_t *service;
1908 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1909 retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1911 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1912 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1914 *cycle = service->cycle;
1917 return UAM_ERROR_NONE;
1920 int _uam_core_set_detection_threshold(unsigned int sensor,
1921 int presence_threshold, int absence_threshold)
1926 ret = _uam_pm_set_detection_threshold(sensor,
1927 presence_threshold, absence_threshold);
1928 if (UAM_ERROR_NONE != ret) {
1929 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
1930 _uam_manager_error_to_str(ret));
1935 return UAM_ERROR_NONE;
1938 static gboolean __start_detection(gpointer data)
1942 uam_db_service_info_t *service = NULL;
1943 unsigned int sensors;
1944 gboolean start_detection = FALSE;
1946 unsigned int presence_env_sensors;
1947 unsigned int absence_env_sensors;
1949 presence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE);
1950 UAM_DBG("Presence Envionmental sensors: 0x%8.8X", presence_env_sensors);
1952 absence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
1953 UAM_DBG("Absence Envionmental sensors: 0x%8.8X", absence_env_sensors);
1955 if (0 != presence_env_sensors) {
1956 /* Stop PRESENCE detection on active envionmental sensors*/
1957 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
1958 if (UAM_ERROR_NONE != ret)
1959 UAM_ERR("Failed with error: %s (0x%4.4X)",
1960 _uam_manager_error_to_str(ret), ret);
1962 if (0 != absence_env_sensors) {
1963 /* Stop ABSENCE detection on envionmental sensors*/
1964 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
1965 if (UAM_ERROR_NONE != ret)
1966 UAM_ERR("Failed with error: %s (0x%4.4X)",
1967 _uam_manager_error_to_str(ret), ret);
1970 for (l = services; NULL != l; l = g_slist_next(l)) {
1972 if (!service || !service->monitors)
1975 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
1976 UAM_DBG("service->remaining_time: %d", service->remaining_time);
1977 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
1978 if (0 >= service->remaining_time) {
1979 start_detection = TRUE;
1980 service->remaining_time = service->cycle;
1984 if (!start_detection)
1987 /* Get sensors on which PRESENCE detection to be started */
1988 sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
1989 UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
1991 /* Remove env sensors from active sensors */
1992 sensors &= ~presence_env_sensors;
1993 UAM_DBG("Presence Connectivity sensors: 0x%8.8X", sensors);
1996 /* Start PRESENCE detection */
1997 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
1998 if (UAM_ERROR_NONE != ret)
1999 UAM_ERR("Failed with error: %s (0x%4.4X)",
2000 _uam_manager_error_to_str(ret), ret);
2003 /* Get sensors on which ABSENCE detection to be started */
2004 sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2005 UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
2007 /* Remove env sensors from active sensors */
2008 sensors &= ~absence_env_sensors;
2009 UAM_DBG("ABSENCE Connectivity sensors: 0x%8.8X", sensors);
2012 /* Start ABSENCE detection */
2013 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
2014 if (UAM_ERROR_NONE != ret)
2015 UAM_ERR("Failed with error: %s (0x%4.4X)",
2016 _uam_manager_error_to_str(ret), ret);
2020 if (0 != presence_env_sensors) {
2021 /* Always Start PRESENCE detection on active envionmental sensors*/
2022 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2023 if (UAM_ERROR_NONE != ret)
2024 UAM_ERR("Failed with error: %s (0x%4.4X)",
2025 _uam_manager_error_to_str(ret), ret);
2027 if (0 != absence_env_sensors) {
2028 /* Always Start ABSENCE detection on active envionmental sensors*/
2029 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2030 if (UAM_ERROR_NONE != ret)
2031 UAM_ERR("Failed with error: %s (0x%4.4X)",
2032 _uam_manager_error_to_str(ret), ret);
2039 static int __uam_core_start_detection(int detection_type,
2040 const char *svc_name, char *sender, unsigned int sensors)
2043 uam_monitor_info_t *monitor;
2044 uam_db_service_info_t *service;
2045 gboolean is_monitor_added = TRUE;
2048 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2049 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2051 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2053 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
2054 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
2055 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2056 services = g_slist_append(services, default_svc);
2060 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2061 retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2064 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2066 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2068 monitor->name = g_strdup(sender);
2069 monitor->mode = detection_type;
2070 monitor->service = service;
2071 is_monitor_added = FALSE;
2073 UAM_ERR("Memory allocation error");
2074 return UAM_ERROR_OUT_OF_MEMORY;
2078 UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2080 monitor->sensors |= sensors;
2081 if (!is_monitor_added) {
2082 monitors = g_slist_append(monitors, monitor);
2083 service->monitors = g_slist_append(service->monitors, monitor);
2086 /* Start detection */
2087 if (0 == detection_timer) {
2088 __start_detection(NULL);
2089 UAM_INFO("Monitor started detection, start timer");
2090 detection_timer = g_timeout_add_seconds(
2091 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2095 return UAM_ERROR_NONE;
2098 static int __uam_core_stop_detection(int detection_type,
2099 const char *svc_name, char *sender, unsigned int sensors)
2102 int ret = UAM_ERROR_NONE;
2103 unsigned int remaining_sensors;
2104 unsigned int active_sensors;
2105 uam_monitor_info_t *monitor;
2106 uam_db_service_info_t *service;
2108 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2109 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2111 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2112 retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2113 service = monitor->service;
2114 retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2116 /* Find sensors which are already monitoring */
2117 active_sensors = _uam_core_get_active_sensors(detection_type);
2118 UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2119 sensors, active_sensors);
2121 /* Update monitor info for application */
2122 monitor->sensors &= ~sensors;
2123 if (0 == monitor->sensors) {
2125 * App requested to stop monitoring for all of its active sensors,
2126 * remove its monitor info from list.
2128 monitors = g_slist_remove(monitors, monitor);
2129 if ((NULL == monitors) && (0 != detection_timer)) {
2130 UAM_INFO("All monitors stopped detection, stop timer");
2131 g_source_remove(detection_timer);
2132 detection_timer = 0;
2135 service->monitors = g_slist_remove(service->monitors, monitor);
2136 if (NULL == service->monitors)
2137 service->remaining_time = 0;
2139 g_free(monitor->name);
2143 /* Find sensors which are already monitoring */
2144 remaining_sensors = _uam_core_get_active_sensors(detection_type);
2145 UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2147 if (active_sensors == remaining_sensors) {
2148 UAM_INFO("NO need to stop monitoring");
2149 return UAM_ERROR_NONE;
2152 /* Stop monitoring only for sensors which aren't required anymore */
2153 sensors = (active_sensors & ~remaining_sensors);
2154 ret = _uam_pm_stop_detection(detection_type, sensors);
2155 if (UAM_ERROR_NONE != ret)
2156 UAM_ERR("Failed with error: %s (0x%4.4X)",
2157 _uam_manager_error_to_str(ret), ret);
2163 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2168 ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2174 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2179 ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2185 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2190 ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2196 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2201 ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2207 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2212 UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2213 ret = _uam_pm_set_low_power_mode(bitmask, mode);
2214 if (UAM_ERROR_NONE != ret) {
2215 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2216 bitmask, _uam_manager_error_to_str(ret));
2221 return UAM_ERROR_NONE;
2224 int _uam_core_get_detection_window(unsigned int *window)
2228 retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2230 *window = detection_window;
2233 return UAM_ERROR_NONE;
2236 int _uam_core_set_detection_window(unsigned int window)
2240 retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2241 retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2242 retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2244 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2245 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2246 return UAM_ERROR_INTERNAL;
2249 detection_window = window;
2252 return UAM_ERROR_NONE;
2255 int _uam_core_init(void)
2260 GSList *db_svc_list;
2261 GSList *db_adv_list;
2262 GSList *db_svc_dev_list;
2266 _uam_db_initialize();
2268 /* Reset detecton window to default */
2269 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2270 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2271 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2273 /* Fetch user list */
2274 db_users = _uam_db_get_all_users();
2276 UAM_INFO_C("No users in database");
2277 return UAM_ERROR_NONE;
2280 for (l = db_users; NULL != l; l = g_slist_next(l)) {
2281 db_user_info_t *info = l->data;
2282 uam_db_user_info_t *user;
2287 user = g_new0(uam_db_user_info_t, 1);
2288 user->user_id = info->user_id;
2289 user->name = g_strdup(info->name);
2290 user->account = g_strdup(info->account);
2291 user->devices = NULL;
2293 users = g_slist_prepend(users, user);
2296 /* Fetch service list */
2297 db_svc_list = _uam_service_db_get_all_services();
2299 UAM_INFO_C("No services in database");
2300 return UAM_ERROR_NONE;
2303 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2304 db_service_info_t *db_svc = l->data;
2305 uam_db_service_info_t *service;
2311 l1 = g_slist_find_custom(services,
2312 db_svc->service_name, __compare_svc_name);
2314 service = g_new0(uam_db_service_info_t, 1);
2315 service->name = g_strdup(db_svc->service_name);
2316 service->cycle = db_svc->cycle;
2317 service->presence_threshold = db_svc->presence_threshold;
2318 service->absence_threshold = db_svc->absence_threshold;
2319 services = g_slist_append(services, service);
2323 /* Fetch device list */
2324 db_devices = _uam_device_db_get_all_devices();
2326 UAM_INFO_C("No Devices registered in database");
2327 return UAM_ERROR_NONE;
2330 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2331 db_device_info_t *db_info = l->data;
2332 uam_db_user_info_t *user;
2333 GSList *svc_list = NULL;
2339 l1 = g_slist_find_custom(users,
2340 &(db_info->user_id), __compare_user_id);
2342 UAM_ERR("Invalid user Id: %d", db_info->user_id);
2347 /* Fetch device services from DB */
2348 l1 = _uam_db_get_device_services(
2349 db_info->dev_info.device_id,
2350 db_info->dev_info.type,
2351 db_info->dev_info.mac);
2353 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2354 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2355 db_info->presence_state, db_info->last_seen, svc_list);
2358 /* Fetch iBeacon adv list */
2359 db_adv_list = _uam_db_get_all_advs();
2361 UAM_INFO_C("No iBeacon adv in database");
2363 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2364 db_adv_info_t *db_adv = l->data;
2365 _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2369 /* Fetch svc dev list */
2370 db_svc_dev_list = _uam_db_get_service_devices_info();
2371 if (!db_svc_dev_list) {
2372 UAM_INFO_C("No service devices in database");
2374 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2375 db_svc_dev_info_t *db_svc = l->data;
2377 _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
2378 db_svc->svc, db_svc->discriminant, db_svc->last_seen);
2382 g_slist_free_full(db_devices, g_free);
2383 g_slist_free_full(db_users, g_free);
2384 g_slist_free_full(db_svc_list, g_free);
2385 g_slist_free_full(db_adv_list, g_free);
2386 g_slist_free_full(db_svc_dev_list, g_free);
2388 /* Set/update registered device list to plugins */
2389 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2390 UAM_ERR("_uam_pm_set_registered_devices failed");
2392 /* Set/update registered device list to cloud plugin */
2393 _uam_cloud_update_registered_devices();
2396 return UAM_ERROR_NONE;
2399 void _uam_core_deinit(void)
2404 /* de-init database */
2405 _uam_db_deinitialize();
2407 /* Reset detecton window to default */
2408 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2410 /* Release allocated memory for devices */
2411 g_slist_free_full(devices, __free_user_device);
2414 /* Release allocated memory for users */
2415 for (l = users; NULL != l; l = g_slist_next(l)) {
2416 uam_db_user_info_t *user = l->data;
2422 g_free(user->account);
2426 g_slist_free(users);
2429 /* Release allocated memory for services */
2430 for (l = services; NULL != l; l = g_slist_next(l)) {
2431 uam_db_service_info_t *service = l->data;
2436 g_free(service->name);
2439 g_slist_free(services);
2442 /* Release allocated memory for service devices */
2443 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2444 uam_svc_dev_info_t *svc_dev = l->data;
2449 g_free(svc_dev->device_id);
2450 g_free(svc_dev->service);
2453 g_slist_free(svc_devs);
2459 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2463 /* Send sensor state changed event over dbus */
2465 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2466 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2468 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2469 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2474 int _uam_core_handle_device_added(int status,
2475 int user_id, const uam_device_info_s *dev_info)
2480 int ret = UAM_ERROR_NONE;
2481 GSList *svc_list = NULL;
2482 uam_db_user_info_t *user = NULL;
2484 UAM_INFO("[%d]", user_id);
2486 /* Send reply over dbus for add device API */
2487 l = _uam_manager_get_request_list();
2488 for (; NULL != l; l = g_slist_next(l)) {
2489 uam_request_context_t *info = l->data;
2490 uam_device_info_s *dev;
2493 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2498 UAM_WARN("info->data is NULL");
2502 if (dev->type != dev_info->type ||
2503 strcasecmp(dev->device_id, dev_info->device_id)) {
2504 UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2505 dev->device_id, dev_info->device_id);
2509 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2510 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2511 _uam_manager_method_return(info->context, out_param, status);
2513 _uam_remove_timer(info->tid);
2515 _uam_manager_remove_req_ctxt_from_list(info);
2520 if (UAM_ERROR_NONE != status) {
2521 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2527 l = g_slist_find_custom(users,
2528 USER_ACCOUNT_DEFAULT, __compare_user_account);
2530 ret = _uam_core_add_user(&id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2531 if (UAM_ERROR_NONE != ret) {
2532 UAM_ERR("_uam_core_add_user failed with %s",
2533 _uam_manager_error_to_str(ret));
2534 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2540 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2542 UAM_ERR("Invalid user Id: %d", user_id);
2543 ret = UAM_ERROR_NOT_FOUND;
2544 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2549 /* Get default service and add it to device's service list by default */
2550 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2552 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2553 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2554 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2555 services = g_slist_append(services, service);
2556 svc_list = g_slist_append(svc_list, service);
2558 uam_db_service_info_t *service = l->data;
2559 svc_list = g_slist_append(svc_list, service);
2562 __uam_core_add_dev_to_list(user, dev_info,
2563 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen, svc_list);
2565 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2567 /* Add device to database */
2568 ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
2569 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen);
2570 if (UAM_ERROR_NONE != ret) {
2571 UAM_WARN("Device addition to persistent DB failed");
2572 __uam_db_end_transaction(0);
2576 /* Insert device service info to db */
2577 ret = _uam_db_insert_device_service_info(
2578 dev_info->device_id, dev_info->type, dev_info->mac,
2579 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2580 dev_info->discriminant, 0);
2581 if (UAM_ERROR_NONE != ret) {
2582 UAM_WARN("Device service addition to persistent DB failed");
2583 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2584 __uam_db_end_transaction(0);
2587 __uam_db_end_transaction(1);
2589 ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
2590 UAM_SERVICE_DEFAULT, dev_info->discriminant, 0);
2591 if (UAM_ERROR_NONE != ret) {
2592 UAM_WARN("Device service mappiing update failed");
2593 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2597 /* Send device added event to application */
2598 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2600 /* Set/update registered device list to plugins */
2601 ret = _uam_pm_set_registered_devices(devices);
2602 if (UAM_ERROR_NONE != ret) {
2603 UAM_ERR("_uam_pm_set_registered_devices failed");
2607 _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2609 /* Set/update registered device list to cloud plugin */
2610 if (UAM_ERROR_NONE == status)
2611 _uam_cloud_update_registered_devices();
2617 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2621 unsigned long long timestamp;
2623 UAM_INFO("sensor 0x[%8.8X]", sensor);
2625 if (NULL == sensor_info) {
2626 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2627 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2628 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2633 timestamp = _uam_get_timestamp();
2635 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2636 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2637 g_variant_new("(utiidddd)", sensor, timestamp,
2638 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2639 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2640 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2645 // service specific light detection threshold
2646 for (l = services; NULL != l; l = g_slist_next(l)) {
2647 uam_db_service_info_t *svc = l->data;
2650 if (!svc || !svc->monitors)
2653 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2654 svc->name, sensor_info->values[0], svc->presence_threshold);
2656 if (sensor_info->values[0] < svc->presence_threshold)
2659 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2660 uam_monitor_info_t *mon = l1->data;
2665 UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2666 mon->name, mon->sensors);
2668 if (!(mon->sensors & sensor))
2671 if (UAM_DETECT_PRESENCE != mon->mode)
2674 _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2675 g_variant_new("(utiidddd)", sensor, timestamp,
2676 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2677 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2678 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2686 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
2687 unsigned int sensor)
2692 UAM_INFO("sensor 0x[%8.8X]", sensor);
2694 if (NULL == sensor_info) {
2695 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2696 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2697 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2702 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2703 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2704 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2705 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2706 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2707 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2712 // service specific light detection threshold
2713 for (l = services; NULL != l; l = g_slist_next(l)) {
2714 uam_db_service_info_t *svc = l->data;
2717 if (!svc || !svc->monitors)
2720 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2721 svc->name, sensor_info->values[0], svc->absence_threshold);
2723 if (sensor_info->values[0] > svc->absence_threshold)
2726 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2727 uam_monitor_info_t *mon = l1->data;
2732 if (!(mon->sensors & sensor))
2735 if (UAM_DETECT_PRESENCE != mon->mode)
2738 _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2739 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2740 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2741 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2742 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2749 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2750 uam_device_info_s *dev_info)
2755 uam_db_user_info_t *user;
2756 uam_svc_dev_info_t *svc_dev = NULL;
2757 gboolean live_monitoring = FALSE;
2758 unsigned long long timestamp;
2761 ret_if(NULL == tech);
2762 ret_if(NULL == tech->svc_list);
2763 ret_if(NULL == dev_info);
2765 user = tech->device->user;
2766 user->last_seen = tech->last_seen;
2768 for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2769 uam_db_service_info_t *svc = l->data;
2771 live_monitoring = FALSE;
2773 if (!svc || !svc->monitors)
2776 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2777 svc->name, svc->remaining_time, svc->cycle);
2779 if (!(svc->remaining_time == svc->cycle))
2782 UAM_DBG("Check service device discriminant");
2783 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2784 dev_info->type, svc->name);
2785 if (!svc_dev || !svc_dev->discriminant)
2788 UAM_DBG("Send event");
2789 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2790 uam_monitor_info_t *mon = l1->data;
2795 if (!(mon->sensors & sensor))
2798 if (UAM_DETECT_PRESENCE != mon->mode)
2802 * For current service, if any of its running monitor has same sensor
2803 * and detection_mode
2805 live_monitoring = TRUE;
2807 timestamp = _uam_get_timestamp();
2808 UAM_INFO("sensor [%d]", sensor);
2809 _uam_manager_send_event(mon->name,
2810 UAM_EVENT_USER_PRESENCE_DETECTED,
2811 g_variant_new("(utsss)", sensor, timestamp,
2812 user->account, svc->name, dev_info->device_id));
2813 UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2815 " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
2816 mon->name, dev_info->device_id,
2817 sensor, user->account,
2822 /* Update service specific device last_seen in svc_dev list and DB */
2823 if (live_monitoring) {
2824 svc_dev->last_seen = tech->last_seen;
2825 ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
2826 dev_info->type, dev_info->mac, svc->name, tech->last_seen);
2827 if (UAM_ERROR_NONE != ret)
2828 UAM_WARN("_uam_db_update_device_service_last_seen failed");
2835 int _uam_core_handle_presence_detected(unsigned int sensor,
2836 int user_id, void *info)
2839 int ret = UAM_ERROR_NONE;
2842 uam_db_user_info_t *user;
2843 uam_db_device_info_t *device;
2844 uam_db_tech_info_t *tech;
2846 uam_device_info_s *dev_info = NULL;
2847 uam_sensor_info_s *sensor_info = NULL;
2849 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2851 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2853 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2856 _uam_vpm_send_presence_detection_event(sensor);
2858 if (NULL == dev_info) {
2859 __send_sensor_presence_event(sensor_info, sensor);
2863 retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
2865 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2867 UAM_ERR("Invalid user_id [%d]", user_id);
2868 return UAM_ERROR_INVALID_PARAMETER;
2872 l = g_slist_find_custom(user->devices,
2873 dev_info->device_id, __compare_device_id);
2875 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2876 user_id, dev_info->device_id);
2877 return UAM_ERROR_INVALID_PARAMETER;
2880 if (!(device->supported_techs & dev_info->type)) {
2881 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2882 dev_info->device_id, dev_info->type);
2883 return UAM_ERROR_INVALID_PARAMETER;
2886 l = g_slist_find_custom(device->tech_list,
2887 &(dev_info->type), __compare_tech_type);
2889 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2890 return UAM_ERROR_INVALID_PARAMETER;
2894 tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2895 tech->last_seen = dev_info->last_seen;
2897 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
2899 /* Check if IP/MAC address was updated then update in DB */
2900 if (UAM_TECH_TYPE_WIFI == dev_info->type) {
2902 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2903 uam_db_address_info_t *addr = l->data;
2908 if (UAM_ADDR_TYPE_IPv4 == addr->addr_type) {
2910 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
2911 UAM_DBG("Old IPv4: %s, New IPv4: %s",
2912 addr->address, dev_info->ipv4_addr);
2914 g_free(addr->address);
2915 addr->addr_type = UAM_ADDR_TYPE_IPv4;
2916 addr->address = g_strdup(dev_info->ipv4_addr);
2918 /* Update IP address in DB */
2919 ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
2920 dev_info->type, dev_info->ipv4_addr);
2921 if (UAM_ERROR_NONE != ret) {
2922 UAM_WARN("_uam_device_db_update_device_ip_address failed");
2923 __uam_db_end_transaction(0);
2929 if (UAM_ADDR_TYPE_WIFI == addr->addr_type) {
2931 if (strcasecmp(addr->address, dev_info->mac)) {
2932 UAM_DBG("Old MAC: %s, New MAC: %s",
2933 addr->address, dev_info->mac);
2935 g_free(addr->address);
2936 addr->addr_type = UAM_ADDR_TYPE_WIFI;
2937 addr->address = g_strdup(dev_info->mac);
2939 /* Update address in DB */
2940 ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
2941 dev_info->type, dev_info->mac);
2942 if (UAM_ERROR_NONE != ret) {
2943 UAM_WARN("_uam_device_db_update_device_mac_address failed");
2944 __uam_db_end_transaction(0);
2952 /* Update database (presence state & timestamp) */
2953 ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
2954 dev_info->type, dev_info->mac, dev_info->last_seen);
2955 if (UAM_ERROR_NONE != ret) {
2956 UAM_WARN("_uam_device_db_update_device_last_seen failed");
2957 __uam_db_end_transaction(0);
2961 ret = _uam_device_db_update_device_presence(dev_info->device_id,
2962 dev_info->type, dev_info->mac, tech->presence_state);
2963 if (UAM_ERROR_NONE != ret) {
2964 UAM_WARN("_uam_device_db_update_device_presence failed");
2965 __uam_db_end_transaction(0);
2969 /* Send user presence event and update service_device timestamp */
2970 __send_user_presence_event(tech, sensor, dev_info);
2971 __uam_db_end_transaction(1);
2977 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
2983 * For each service, find users absent on given sensor. Then for each
2984 * monitor in serivce's monitor list, if it is monitoring ABSENCE on
2985 * given sensor, send user ABSENCE event.
2987 for (l = services; NULL != l; l = g_slist_next(l)) {
2988 uam_db_service_info_t *svc = l->data;
2989 GSList *absent_users = NULL;
2990 GSList *present_users = NULL;
2994 if (!svc || !svc->monitors || !svc->dev_techs)
2997 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
2998 uam_db_tech_info_t *tech = l1->data;
3000 if (!tech || (tech->tech_type != type)) {
3001 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
3005 if (!tech->device || !tech->device->user) {
3006 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
3010 l2 = g_slist_find_custom(present_users,
3011 &(tech->device->user->user_id), __compare_user_id);
3013 if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
3014 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
3016 tech->device->device_id,
3017 tech->device->user->account);
3018 /* Remove user from absent list */
3019 absent_users = g_slist_remove(absent_users, tech->device->user);
3021 /* If user not in present list, add user to the list */
3023 UAM_DBG("added present user [%s]", tech->device->user->account);
3024 present_users = g_slist_prepend(present_users, tech->device->user);
3027 /* If user not in the present list then only add it to absent list */
3028 if ((NULL == l2) && (NULL == g_slist_find_custom(
3029 absent_users, &(tech->device->user->user_id),
3030 __compare_user_id))) {
3031 UAM_DBG("added absent user [%s]", tech->device->user->account);
3032 absent_users = g_slist_prepend(absent_users, tech->device->user);
3037 g_slist_free(present_users);
3041 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
3042 uam_monitor_info_t *mon = l2->data;
3047 if (!(mon->sensors & sensor))
3050 if (UAM_DETECT_ABSENCE != mon->mode)
3053 for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
3054 uam_db_user_info_t *user = l1->data;
3059 user->last_seen = 0;
3061 _uam_manager_send_event(mon->name,
3062 UAM_EVENT_USER_ABSENCE_DETECTED,
3063 g_variant_new("(utss)", sensor, user->last_seen,
3064 user->account, svc->name));
3065 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
3066 " for 0x%8.8X, User: %s Service: %s",
3067 mon->name, sensor, user->account, svc->name);
3071 g_slist_free(absent_users);
3077 void _uam_core_handle_absence_detected(unsigned int sensor,
3078 int user_id, void *info)
3081 uam_db_user_info_t *user;
3082 uam_db_device_info_t *device;
3083 uam_db_tech_info_t *tech;
3085 uam_device_info_s *dev_info = NULL;
3086 uam_sensor_info_s *sensor_info = NULL;
3088 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3090 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3092 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3095 if (NULL == dev_info) {
3096 __send_sensor_absence_event(sensor_info, sensor);
3101 ret_if(0 > user_id);
3103 l = g_slist_find_custom(users, &user_id, __compare_user_id);
3105 UAM_ERR("Invalid user_id [%d]", user_id);
3110 l = g_slist_find_custom(user->devices,
3111 dev_info->device_id, __compare_device_id);
3113 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3114 user_id, dev_info->device_id);
3118 if (!(device->supported_techs & dev_info->type)) {
3119 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3120 dev_info->device_id, dev_info->type);
3124 l = g_slist_find_custom(device->tech_list,
3125 &(dev_info->type), __compare_tech_type);
3127 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3132 tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
3134 /* Update database (presence state) */
3135 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
3136 dev_info->type, dev_info->mac, tech->presence_state))
3137 UAM_WARN("_uam_device_db_update_device_presence failed");
3142 void _uam_core_cleanup_monitor(char *name)
3146 for (l = monitors; NULL != l; l = g_slist_next(l)) {
3147 uam_monitor_info_t *monitor = l->data;
3149 if (!monitor || !monitor->name || !monitor->service)
3152 if (0 != g_strcmp0(name, monitor->name))
3155 /* If there is a monitor that is not freed, stop detection
3156 * and free the monitor structure in the memory. */
3157 UAM_INFO("clear %s's monitor info.", monitor->name);
3158 __uam_core_stop_detection(monitor->mode,
3159 monitor->service->name, name, monitor->sensors);
3163 static void __free_user_info(gpointer data)
3166 uam_db_user_info_t *user = data;
3168 ret_if(NULL == user);
3171 g_free(user->account);
3176 static void __free_service_info(gpointer data)
3179 uam_db_service_info_t *svc = data;
3181 ret_if(NULL == svc);
3188 static void __free_monitor_info(gpointer data)
3191 uam_monitor_info_t *monitor = data;
3193 ret_if(NULL == monitor);
3195 g_free(monitor->name);
3200 static void __free_scanner_info(gpointer data)
3203 uam_scanner_info_t *scanner = data;
3205 ret_if(NULL == scanner);
3207 g_free(scanner->name);
3212 void _uam_core_reset_database(void)
3217 ret = _uam_db_clear();
3218 if (UAM_ERROR_NONE != ret) {
3219 UAM_ERR("_uam_db_clear failed with %s",
3220 _uam_manager_error_to_str(ret));
3221 unlink(DATABASE_FULL_PATH);
3225 g_slist_free_full(devices, __free_user_device);
3228 g_slist_free_full(users, __free_user_info);
3231 g_slist_free_full(services, __free_service_info);
3234 g_slist_free_full(monitors, __free_monitor_info);
3237 g_slist_free_full(scanners, __free_scanner_info);
3240 /* Set/update registered device list to plugins */
3241 ret = _uam_pm_set_registered_devices(devices);
3242 if (UAM_ERROR_NONE != ret)
3243 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3244 _uam_manager_error_to_str(ret));
3246 /* Set/update registered device list to cloud plugin */
3247 _uam_cloud_update_registered_devices();
3252 void _uam_core_handle_detection_started(unsigned int sensor)
3255 unsigned int active_sensors = 0;
3257 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3258 sensor, detecting_sensors);
3260 detecting_sensors |= sensor;
3261 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3262 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3263 if (active_sensors == detecting_sensors) {
3264 /* Send detection started event */
3265 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3271 void _uam_core_handle_detection_stopped(unsigned int sensor)
3275 uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3276 uam_cycle_state_e cycle_state;
3279 ret_if((detecting_sensors & sensor) == 0);
3280 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3281 sensor, detecting_sensors);
3282 detecting_sensors &= ~sensor;
3284 if (UAM_SENSOR_BITMASK_BLE == sensor)
3285 type = UAM_TECH_TYPE_BLE;
3286 else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3287 type = UAM_TECH_TYPE_WIFI;
3289 if (UAM_TECH_TYPE_NONE != type)
3290 __send_user_absence_event(type, sensor);
3292 if (0 == detecting_sensors) {
3293 /* Send detection stopped event */
3294 for (l = monitors; l; l = g_slist_next(l)) {
3295 uam_monitor_info_t *mon = l->data;
3297 if (!mon || !mon->name || !mon->service)
3299 uam_db_service_info_t *service = mon->service;
3300 cycle_state = UAM_DETECTION_CYCLE_END;
3302 UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d", mon->sensors, service->name, service->remaining_time);
3303 if (!(mon->sensors & _uam_core_get_env_sensors())) {
3304 if (service->remaining_time < service->cycle) {
3305 UAM_DBG("service->remaining_time < service->cycle, return");
3308 } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
3309 cycle_state = UAM_DETECTION_CYCLE_MID;
3312 _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
3313 g_variant_new("(si)", service->name, cycle_state));
3314 UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
3315 " cycle state:[%s]",
3316 mon->name, service->name, cycle_state ? "end" : "mid");
3322 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3326 retv_if(NULL == name, NULL);
3328 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3329 uam_scanner_info_t *scanner = l->data;
3331 if (!scanner || !scanner->name)
3334 if (0 == g_strcmp0(scanner->name, name)) {
3335 UAM_DBG("Scanning application found in list");
3343 static gboolean __scan_completed_cb(gpointer data)
3346 uam_scanner_info_t *scanner = data;
3348 retv_if(NULL == scanner, FALSE);
3350 if (UAM_ERROR_NONE != _uam_manager_send_event(
3351 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3352 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3354 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3357 scanners = g_slist_remove(scanners, scanner);
3358 g_free(scanner->name);
3365 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3369 uam_scanner_info_t *scanner;
3371 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3372 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3374 scanner = __uam_find_scanner(sender);
3375 retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3377 ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3378 if (UAM_ERROR_NONE != ret) {
3379 UAM_ERR("Failed with error: %s (0x%4.4X)",
3380 _uam_manager_error_to_str(ret), ret);
3384 scanner = g_malloc0(sizeof(uam_scanner_info_t));
3386 UAM_ERR("Failed to allocate memory");
3387 return UAM_ERROR_OUT_OF_MEMORY;
3389 scanner->name = g_strdup(sender);
3390 scanner->sensors |= sensors;
3391 scanner->timer = g_timeout_add_seconds(detection_period,
3392 __scan_completed_cb, scanner);
3393 scanners = g_slist_append(scanners, scanner);
3394 UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3397 return UAM_ERROR_NONE;
3400 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3404 uam_scanner_info_t *scanner;
3407 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3408 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3410 scanner = __uam_find_scanner(sender);
3411 retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3413 /* Trim sensors to a subset of active sensors for the scanner */
3414 sensors &= scanner->sensors;
3417 * modify scanner's active sensors and if active sensors are NULL
3418 * remove scanner from scanners list
3420 scanner->sensors &= ~sensors;
3421 if (0 == scanner->sensors) {
3422 scanners = g_slist_remove(scanners, scanner);
3423 g_source_remove(scanner->timer);
3424 g_free(scanner->name);
3428 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3429 uam_scanner_info_t *scanner_data = l->data;
3431 if (!scanner_data || !scanner_data->name)
3434 sensors &= ~(scanner_data->sensors);
3438 ret = _uam_pm_stop_active_device_scan(sensors);
3439 if (UAM_ERROR_NONE != ret) {
3440 UAM_ERR("Failed with error: %s (0x%4.4X)",
3441 _uam_manager_error_to_str(ret), ret);
3447 return UAM_ERROR_NONE;
3450 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3451 unsigned int sensor, const uam_device_info_s *dev_info)
3456 ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3458 for (l = scanners; NULL != l;) {
3459 uam_scanner_info_t *scanner = l->data;
3461 if (!scanner || !scanner->name) {
3462 l = g_slist_next(l);
3466 if (0 == (scanner->sensors & sensor)) {
3467 l = g_slist_next(l);
3471 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3472 scanner->sensors &= ~(sensor);
3473 UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3474 if (0 != scanner->sensors) {
3475 l = g_slist_next(l);
3479 if (UAM_ERROR_NONE != _uam_manager_send_event(
3480 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3481 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3483 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3486 l = g_slist_next(l);
3487 scanners = g_slist_remove(scanners, scanner);
3488 g_source_remove(scanner->timer);
3489 g_free(scanner->name);
3492 GVariant *param = g_variant_new("(iiisss)",
3494 dev_info->operating_system,
3497 dev_info->ipv4_addr,
3498 dev_info->device_id);
3499 if (UAM_ERROR_NONE != _uam_manager_send_event(
3500 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3501 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3503 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3505 l = g_slist_next(l);
3512 int _uam_core_register_service(uam_service_info_s *svc)
3516 uam_db_service_info_t *service;
3517 int service_number = 0;
3519 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3521 /* Retrieve service from list */
3522 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3523 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3525 service = g_new0(uam_db_service_info_t, 1);
3526 service->name = g_strdup(svc->name);
3527 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3528 service->presence_threshold = svc->presence_threshold;
3529 service->absence_threshold = svc->absence_threshold;
3531 /* Add service to database */
3532 if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3533 UAM_ERR("_uam_db_insert_service_info failed");
3535 return UAM_ERROR_DB_FAILED;
3538 services = g_slist_append(services, service);
3540 /* Send service registered event to application */
3541 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3542 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3543 UAM_ERROR_NONE, service->name)))
3544 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3547 return UAM_ERROR_NONE;
3550 int _uam_core_update_service(uam_service_info_s *svc)
3554 uam_db_service_info_t *service;
3556 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3558 /* Retrieve service from list */
3559 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3560 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3563 service->presence_threshold = svc->presence_threshold;
3564 service->absence_threshold = svc->absence_threshold;
3566 /* Update service to database */
3567 if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3568 UAM_ERR("_uam_db_update_service_info failed");
3569 return UAM_ERROR_DB_FAILED;
3573 return UAM_ERROR_NONE;
3576 int _uam_core_get_default_service(uam_service_info_s *service_info)
3581 uam_db_service_info_t *service;
3583 retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3585 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3588 // insert default service
3589 memset(service_info, 0x00, sizeof(uam_service_info_s));
3590 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3591 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3592 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3594 ret = _uam_core_register_service(service_info);
3595 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3596 UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3599 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3602 retv_if(NULL == l, UAM_ERROR_INTERNAL);
3605 memset(service_info, 0x00, sizeof(uam_service_info_s));
3606 g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3609 return UAM_ERROR_NONE;
3612 int _uam_core_unregister_service(const char *svc_name)
3616 uam_db_service_info_t *service;
3618 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3620 /* Retrieve service from list */
3621 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3622 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3625 /* Check if service is being used*/
3626 if (service->monitors) {
3627 UAM_ERR("service monitoring in progress");
3628 return UAM_ERROR_PERMISSION_DENIED;
3631 /* Remove service from database */
3632 if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3633 UAM_ERR("_uam_db_delete_service_info failed");
3634 return UAM_ERROR_DB_FAILED;
3637 /* Remove service mapping from devices*/
3638 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3639 uam_db_tech_info_t *tech = l->data;
3640 if (!tech || !tech->addresses)
3642 tech->svc_list = g_slist_remove(tech->svc_list, service);
3644 services = g_slist_remove(services, service);
3646 /* Send service unregistered event to application */
3647 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3648 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3649 UAM_ERROR_NONE, service->name)))
3650 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3653 return UAM_ERROR_NONE;
3656 static int __get_service_dev_list(
3657 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3663 int ret = UAM_ERROR_NONE;
3664 uam_svc_dev_info_t *svc_dev = NULL;
3665 uam_device_info_s *dev = NULL;
3668 /* Calculate number of devices */
3669 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3670 uam_db_tech_info_t *tech = l1->data;
3671 if (!tech || !tech->addresses)
3677 *device_list = g_new0(uam_device_info_s, *count);
3680 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3681 uam_db_tech_info_t *tech = l1->data;
3683 if (!tech || !tech->addresses)
3686 /* Copy tech info to device info */
3687 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
3688 if (UAM_ERROR_NONE != ret) {
3689 UAM_ERR("__copy_tech_info_to_device_info failed");
3693 (*device_list)[indx].last_seen = 0;
3697 UAM_INFO("Count = %d, indx = %d", *count, indx);
3699 /* Update service specific device last time */
3700 for (s = svc_devs; s; s = g_slist_next(s)) {
3703 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
3705 if (g_strcmp0(svc_dev->service, service->name))
3708 for (indx = 0; indx < *count; indx++) {
3709 dev = &((*device_list)[indx]);
3711 if (svc_dev->tech_type != dev->type ||
3712 g_strcmp0(svc_dev->device_id, dev->device_id))
3715 dev->last_seen = svc_dev->last_seen;
3723 int _uam_core_get_service_devices(const char *svc_name,
3724 int *count, uam_device_info_s **device_list)
3727 uam_db_service_info_t *service;
3729 int ret = UAM_ERROR_NONE;
3731 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3732 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3735 ret = __get_service_dev_list(service, device_list, count);
3741 static void __get_service_user_list(
3742 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3747 GSList *svc_user_list = NULL;
3750 /* Calculate number of users */
3751 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3752 uam_db_tech_info_t *tech = l->data;
3753 if (!tech || !tech->addresses)
3757 uam_db_user_info_t *db_info = tech->device->user;
3758 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3760 svc_user_list = g_slist_append(svc_user_list, db_info);
3763 *count = g_slist_length(svc_user_list);
3764 *user_list = g_new0(uam_user_info_s, *count);
3767 for (l = svc_user_list; l; l = g_slist_next(l)) {
3768 uam_db_user_info_t *db_info = l->data;
3770 if (!db_info || !db_info->account)
3773 g_strlcpy((*user_list)[indx].account,
3774 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3776 g_strlcpy((*user_list)[indx].name,
3777 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3782 UAM_INFO("Count = %d, indx = %d", *count, indx);
3786 int _uam_core_get_service_users(const char *svc_name,
3787 int *count, uam_user_info_s **user_list)
3790 uam_db_service_info_t *service;
3793 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3794 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3797 __get_service_user_list(service, user_list, count);
3800 return UAM_ERROR_NONE;
3803 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3809 size = g_slist_length(services);
3810 *service_list = g_new0(uam_service_info_s, size);
3813 /* fetch services list from DB */
3814 for (l = services; l; l = g_slist_next(l)) {
3815 uam_db_service_info_t *db_info = l->data;
3817 if (!db_info || !db_info->name)
3820 g_strlcpy((*service_list)[*count].name,
3821 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3822 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3823 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3827 UAM_INFO("Count: %d", *count);
3829 return UAM_ERROR_NONE;
3832 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3837 UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3838 iadv[0], iadv[1], iadv[2]);
3840 ret = _uam_db_insert_adv_info(adv_len, iadv);
3841 if (UAM_ERROR_NONE != ret) {
3842 UAM_ERR("_uam_db_insert_adv_info failed");
3846 ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3847 if (UAM_ERROR_NONE != ret) {
3848 UAM_ERR("Failed with error: %s (0x%4.4X)",
3849 _uam_manager_error_to_str(ret), ret);
3854 return UAM_ERROR_NONE;
3857 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
3861 uam_sensor_info_s *sensor_info = info;
3863 ret_if(NULL == info);
3865 UAM_DBG("%d %d %llu %d %d", sensor, sensor_info->status, sensor_info->timestamp,
3866 sensor_info->accuracy, sensor_info->count);
3868 UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
3869 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
3871 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3872 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
3873 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3874 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3879 int _uam_core_add_payload(uam_ble_payload_s *payload,
3880 const char *device_id, int tech_type)
3883 int ret = UAM_ERROR_NONE;
3884 uam_db_tech_info_t *tech_info;
3887 retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
3888 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
3889 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
3890 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
3892 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
3893 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
3894 // mac = __get_mac_addr(tech_info);
3896 /*** Add payload to database ***/
3897 // ret = _uam_db_insert_payload(payload, device_id, tech_type, mac);
3898 if (UAM_ERROR_NONE != ret) {
3899 UAM_ERR("_uam_db_insert_adv_info failed");
3904 return UAM_ERROR_NONE;