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");
834 return UAM_ERROR_NONE;
837 int _uam_core_update_user(uam_user_info_s *user)
841 uam_db_user_info_t *user_info;
843 retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
845 /* Retrieve user from list */
846 l = g_slist_find_custom(users, user->account, __compare_user_account);
847 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
850 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
852 /* Update user to database */
853 if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
854 UAM_ERR("_uam_db_update_user_info failed");
855 return UAM_ERROR_DB_FAILED;
859 return UAM_ERROR_NONE;
862 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
867 uam_db_device_info_t *device;
868 uam_db_user_info_t *user;
870 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
871 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
873 l = g_slist_find_custom(users, account, __compare_user_account);
874 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
877 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
880 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
881 retv_if((dev_info->type & device->supported_techs),
882 UAM_ERROR_ALREADY_REGISTERED);
885 UAM_INFO("[%d]", user->user_id);
887 ret = _uam_pm_register_device(user->user_id, dev_info);
888 if (UAM_ERROR_NONE != ret) {
889 UAM_ERR("_uam_pm_register_device failed with %s",
890 _uam_manager_error_to_str(ret));
895 return UAM_ERROR_NONE;
898 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
901 uam_db_device_info_t *device;
904 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
905 retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
908 l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
913 if (!(device->supported_techs & dev->type))
916 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
917 uam_db_tech_info_t *tech = l->data;
923 if (dev->type != tech->tech_type)
926 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
927 uam_db_address_info_t *addr = l1->data;
932 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
933 UAM_ADDR_TYPE_BT == addr->addr_type ||
934 UAM_ADDR_TYPE_P2P == addr->addr_type ||
935 UAM_ADDR_TYPE_WIFI == addr->addr_type)
936 if (!strcasecmp(addr->address, dev->mac)) {
945 UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
947 return UAM_ERROR_NONE;
950 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
951 const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
957 ret = _uam_db_get_device_services_count(dev_info->device_id,
958 dev_info->type, dev_info->mac, &count);
959 if (UAM_ERROR_NONE != ret) {
960 UAM_ERR("_uam_db_get_device_services_count failed with %s",
961 _uam_manager_error_to_str(ret));
966 ret = UAM_ERROR_RESOURCE_BUSY;
967 UAM_WARN("other service uses this device ref:[%d]", count);
971 ret = _uam_pm_unregister_device(user_id, dev_info);
972 if (UAM_ERROR_NONE != ret) {
973 UAM_ERR("_uam_pm_unregister_device failed with %s",
974 _uam_manager_error_to_str(ret));
978 /* Send device removed event to application */
979 __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
981 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
982 /* Remove device from database */
983 ret = _uam_device_db_delete_device_info(
984 dev_info->device_id, dev_info->type, dev_info->mac);
985 if (UAM_ERROR_NONE != ret) {
986 UAM_ERR("_uam_device_db_delete_device_info failed");
987 __uam_db_end_transaction(0);
991 /* Remove device from service */
992 for (l = tech->svc_list; l; l = g_slist_next(l)) {
993 uam_db_service_info_t *svc = l->data;
995 if (!svc || !svc->name)
997 ret = _uam_core_service_remove_device(svc->name,
998 dev_info->device_id, dev_info->type);
999 if (UAM_ERROR_NONE != ret)
1000 UAM_ERR("_uam_device_db_delete_device_info failed");
1002 __uam_db_end_transaction(1);
1004 /* Remove tech info from device's tech list */
1005 device->tech_list = g_slist_remove(device->tech_list, tech);
1006 device->supported_techs &= ~(tech->tech_type);
1007 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1008 __free_dev_tech_info(tech);
1010 if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1011 /* Remove device from global device list */
1012 devices = g_slist_remove(devices, device);
1014 /* Remove device from user's device list */
1015 device->user->devices = g_slist_remove(device->user->devices, device);
1017 __free_user_device(device);
1020 /* Set/update registered device list to plugins */
1021 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1022 UAM_ERR("_uam_pm_set_registered_devices failed");
1024 /* Set/update registered device list to cloud plugin */
1025 _uam_cloud_update_registered_devices();
1028 return UAM_ERROR_NONE;
1031 int _uam_core_remove_device(const char *account,
1032 const uam_device_info_s *dev_info)
1037 uam_db_tech_info_t *tech;
1038 uam_db_device_info_t *device;
1039 uam_db_user_info_t *user;
1041 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1042 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1044 /* Retrieve user from list */
1045 l = g_slist_find_custom(users, account, __compare_user_account);
1046 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1049 /* Retrieve device from list */
1050 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1051 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1053 retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1054 retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1056 /* Retrieve tech info from list */
1057 l = g_slist_find_custom(device->tech_list,
1058 &(dev_info->type), __compare_tech_type);
1059 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1062 ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1068 int _uam_core_remove_device_by_device_id(const char *device_id,
1074 uam_device_info_s dev_info;
1075 uam_db_tech_info_t *tech;
1076 uam_db_device_info_t *device;
1078 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1079 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1080 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1082 /* Retrieve device from list */
1083 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1084 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1086 retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1088 /* Retrieve tech info from list */
1089 l = g_slist_find_custom(device->tech_list,
1090 &tech_type, __compare_tech_type);
1091 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1095 ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1096 retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1098 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1104 int _uam_core_remove_device_by_mac(const char *mac)
1107 uam_db_tech_info_t *tech;
1108 uam_db_device_info_t *device;
1109 uam_device_info_s dev_info;
1112 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1114 tech = __get_tech_info_by_mac(mac);
1115 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1116 device = tech->device;
1118 ret = __copy_tech_info_to_device_info(tech, &dev_info);
1119 if (UAM_ERROR_NONE != ret) {
1120 UAM_ERR("__copy_tech_info_to_device_info failed");
1124 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1130 int _uam_core_update_device(const uam_device_info_s *a_device)
1134 int ret = UAM_ERROR_NONE;
1135 GSList *l, *l1, *l2;
1137 uam_device_info_s temp;
1138 uam_db_user_info_t *user = NULL;
1139 uam_db_device_info_t *device = NULL;
1140 uam_db_tech_info_t *tech = NULL;
1142 /* Find all tech-devices in users' devices */
1143 for (l = users; NULL != l; l = g_slist_next(l)) {
1146 l1 = g_slist_find_custom(user->devices,
1147 a_device->device_id, __compare_device_id);
1149 UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1150 user->user_id, a_device->device_id);
1155 if (!(device->supported_techs & a_device->type)) {
1156 UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1157 device->device_id, a_device->type);
1161 /* Update discriminant for devices */
1162 device->discriminant = a_device->discriminant;
1163 device->os = a_device->operating_system;
1165 l2 = g_slist_find_custom(device->tech_list,
1166 &(a_device->type), __compare_tech_type);
1168 UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1174 UAM_DBG("Device tech is NULL");
1178 /* Update discriminant for device-tech */
1179 tech->discriminant = a_device->discriminant;
1181 /* Update device's updated information to database */
1182 ret = __copy_tech_info_to_device_info(tech, &temp);
1183 if (UAM_ERROR_NONE != ret) {
1184 UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1188 ret = _uam_device_db_update_device(temp.device_id, temp.type,
1189 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant);
1190 if (UAM_ERROR_NONE != ret) {
1191 UAM_ERR("_uam_device_db_update_device failed [%d]", ret);
1196 /* Set/update registered device list to plugins */
1197 ret = _uam_pm_set_registered_devices(devices);
1198 if (UAM_ERROR_NONE != ret) {
1199 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1203 /* Set/update registered device list to cloud plugin */
1204 _uam_cloud_update_registered_devices();
1210 int _uam_core_get_default_user(uam_user_info_s *user_info)
1216 uam_db_user_info_t *user;
1218 retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1220 ret = _uam_core_add_user(&user_id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1221 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1222 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1226 l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1227 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1230 memset(user_info, 0x00, sizeof(uam_user_info_s));
1231 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1232 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1235 return UAM_ERROR_NONE;
1238 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1244 size = g_slist_length(users);
1245 *user_list = g_new0(uam_user_info_s, size);
1248 /* fetch users list from DB */
1249 for (l = users; l; l = g_slist_next(l)) {
1250 uam_db_user_info_t *db_info = l->data;
1252 if (!db_info || !db_info->account)
1255 g_strlcpy((*user_list)[*count].account,
1256 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1258 g_strlcpy((*user_list)[*count].name,
1259 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1264 UAM_INFO("Count: %d", *count);
1266 return UAM_ERROR_NONE;
1269 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1272 uam_db_user_info_t *db_info;
1275 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1277 l = g_slist_find_custom(users, account, __compare_user_account);
1278 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1281 g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1283 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1287 return UAM_ERROR_NONE;
1290 int _uam_core_get_devcie_by_device_id(
1291 const char *device_id, int tech_type, uam_device_info_s *device)
1294 uam_db_device_info_t *db_info;
1298 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1299 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1300 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1302 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1303 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1305 retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1307 memset(device, 0x00, sizeof(uam_device_info_s));
1309 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1310 uam_db_tech_info_t *tech = l1->data;
1313 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1316 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1317 uam_db_address_info_t *addr = l2->data;
1322 __uam_core_copy_addr(device, addr);
1325 device->operating_system = db_info->os;
1326 g_strlcpy(device->device_id, db_info->device_id,
1327 UAM_DEVICE_ID_MAX_STRING_LEN);
1328 device->type = tech->tech_type;
1329 device->discriminant = tech->discriminant;
1332 retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1335 return UAM_ERROR_NONE;
1338 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1342 uam_db_tech_info_t *tech;
1344 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1346 tech = __get_tech_info_by_mac(mac);
1347 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1349 ret = __copy_tech_info_to_device_info(tech, device);
1350 if (UAM_ERROR_NONE != ret) {
1351 UAM_ERR("__copy_tech_info_to_device_info failed");
1359 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1362 uam_db_device_info_t *dev;
1365 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1367 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1368 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1371 g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1372 if (dev->user->name)
1373 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1376 return UAM_ERROR_NONE;
1379 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1382 uam_db_tech_info_t *tech;
1384 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1386 tech = __get_tech_info_by_mac(mac);
1387 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1389 g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1390 if (tech->device->user->name)
1391 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1394 return UAM_ERROR_NONE;
1397 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1400 int ret = UAM_ERROR_NONE;
1402 ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1408 int _uam_core_get_user_devices(const char *account,
1409 int *count, uam_device_info_s **device_list)
1412 uam_db_user_info_t *user;
1414 int ret = UAM_ERROR_NONE;
1416 l = g_slist_find_custom(users, account, __compare_user_account);
1417 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1420 ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1426 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1430 *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1433 return UAM_ERROR_NONE;
1436 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1441 is_ready = _uam_pm_is_sensor_ready(sensor);
1442 UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1448 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
1449 uam_tech_type_e tech_type, const char *svc_name)
1452 uam_svc_dev_info_t *svc_dev = NULL;
1455 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1458 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1461 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1462 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1463 (svc_dev->tech_type == tech_type)) {
1464 UAM_DBG("Service device found in list");
1473 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1474 const char *svc_name, gboolean discriminant, unsigned long long last_seen)
1477 uam_svc_dev_info_t *svc = NULL;
1479 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1480 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1481 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1482 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1484 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1486 svc = g_new0(uam_svc_dev_info_t, 1);
1487 svc->device_id = g_strdup(device_id);
1488 svc->tech_type = tech_type;
1489 svc->service = g_strdup(svc_name);
1490 svc_devs = g_slist_append(svc_devs, svc);
1493 svc->discriminant = discriminant;
1494 svc->last_seen = last_seen;
1496 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] last_seen[%llu]",
1497 svc->service, svc->device_id, svc->tech_type, svc->discriminant, svc->last_seen);
1500 return UAM_ERROR_NONE;
1503 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
1504 uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant)
1507 uam_svc_dev_info_t *svc = NULL;
1509 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1510 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1511 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1512 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1514 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1516 svc = g_new0(uam_svc_dev_info_t, 1);
1517 svc->device_id = g_strdup(device_id);
1518 svc->tech_type = tech_type;
1519 svc->service = g_strdup(svc_name);
1520 svc_devs = g_slist_append(svc_devs, svc);
1523 svc->discriminant = discriminant;
1525 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]]",
1526 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1529 return UAM_ERROR_NONE;
1532 int _uam_core_service_add_user(const char *svc_name, const char *account)
1536 int ret = UAM_ERROR_NONE;
1537 uam_db_user_info_t *user;
1538 uam_db_service_info_t *service;
1540 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1541 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1543 /* Retrieve user from list */
1544 l = g_slist_find_custom(users, account, __compare_user_account);
1545 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1548 /* Retrieve service from list */
1549 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1550 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1553 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1554 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1555 uam_db_device_info_t *device = l->data;
1561 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1562 uam_db_tech_info_t *tech = l1->data;
1569 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1570 __compare_svc_name);
1574 __add_service_to_dev_tech_mapping(tech, service);
1576 mac = __get_mac_addr(tech);
1577 /* Insert device service info to db */
1578 ret = _uam_db_insert_device_service_info(device->device_id,
1579 tech->tech_type, mac, service->name, service->cycle,
1580 device->discriminant, 0);
1581 if (UAM_ERROR_NONE != ret) {
1582 UAM_WARN("Device service addition to persistent DB failed");
1583 __uam_db_end_transaction(0);
1586 ret = _uam_core_update_svc_dev_info(device->device_id,
1587 tech->tech_type, service->name, device->discriminant, 0);
1588 if (UAM_ERROR_NONE != ret) {
1589 UAM_WARN("Device service addition to service device mapping failed");
1590 __uam_db_end_transaction(0);
1596 __uam_db_end_transaction(1);
1602 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1606 uam_db_user_info_t *user;
1609 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1610 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1612 /* Retrieve user from list */
1613 l = g_slist_find_custom(users, account, __compare_user_account);
1614 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1617 /* Retrieve service from list */
1618 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1619 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1621 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1622 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1623 uam_db_device_info_t *device = l->data;
1629 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1630 uam_db_tech_info_t *tech = l1->data;
1637 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1638 __compare_svc_name);
1642 UAM_DBG("Service %s found, remove it from list", svc_name);
1643 __remove_service_to_dev_tech_mapping(
1644 tech, (uam_db_service_info_t *)l2->data);
1646 mac = __get_mac_addr(tech);
1647 /* Remove service-device from DB */
1648 ret = _uam_db_delete_device_service_info(device->device_id,
1649 tech->tech_type, mac, svc_name);
1650 if (UAM_ERROR_NONE != ret) {
1651 UAM_WARN("Device service removal from persistent DB failed");
1652 __uam_db_end_transaction(0);
1657 __uam_db_end_transaction(1);
1660 return UAM_ERROR_NONE;
1663 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1666 uam_db_device_info_t *device;
1669 retv_if(NULL == device_id, NULL);
1670 retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1671 retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1673 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1675 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1680 if (!device || !(device->supported_techs & tech_type)) {
1681 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1682 tech_type, device_id);
1686 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1687 uam_db_tech_info_t *tech = l->data;
1692 if (tech_type == tech->tech_type) {
1693 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1694 device_id, tech_type);
1699 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1704 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
1710 int ret = UAM_ERROR_NONE;
1711 uam_db_tech_info_t *tech_info;
1712 uam_db_service_info_t *service;
1714 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1715 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1716 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1717 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1719 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1720 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1722 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1723 retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1725 /* Retrieve service from list */
1726 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1727 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1730 __add_service_to_dev_tech_mapping(tech_info, service);
1732 mac = __get_mac_addr(tech_info);
1733 /* Insert device service info to db */
1734 ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
1735 service->name, service->cycle, tech_info->discriminant, 0);
1736 if (UAM_ERROR_NONE != ret) {
1737 UAM_WARN("Device service addition to persistent DB failed");
1740 ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
1741 tech_info->discriminant, 0);
1742 if (UAM_ERROR_NONE != ret) {
1743 UAM_WARN("Device service addition to svc dev mapping failed");
1748 return UAM_ERROR_NONE;
1751 int _uam_core_service_remove_device(const char *svc_name,
1752 const char *device_id, int tech_type)
1757 uam_db_tech_info_t *tech_info;
1758 int ret = UAM_ERROR_NONE;
1760 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1761 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1762 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1763 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1765 /* Retrieve service from list */
1766 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1767 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1769 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1770 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1772 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1773 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1775 __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1777 mac = __get_mac_addr(tech_info);
1778 /* Remove service-device from DB */
1779 ret = _uam_db_delete_device_service_info(
1780 device_id, tech_type, mac, svc_name);
1781 if (UAM_ERROR_NONE != ret) {
1782 UAM_ERR("Device service removal from persistent DB failed");
1787 return UAM_ERROR_NONE;
1790 int _uam_core_service_set_device_discriminant(const char *svc_name,
1791 const char *device_id, int tech_type, gboolean discriminant)
1795 int ret = UAM_ERROR_NONE;
1797 uam_db_tech_info_t *tech_info;
1798 uam_db_service_info_t *service;
1800 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1801 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1802 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1803 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1805 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1806 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1808 /* Retrieve service from list */
1809 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1810 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1813 mac = __get_mac_addr(tech_info);
1814 /* Insert device service info to db */
1815 ret = _uam_db_update_device_service_discriminant(device_id,
1816 tech_type, mac, service->name, discriminant);
1817 if (UAM_ERROR_NONE != ret) {
1818 UAM_WARN("Device service discriminant update to persistent DB failed");
1821 ret = _uam_core_update_svc_dev_info_discriminant(device_id,
1822 tech_type, service->name, discriminant);
1823 if (UAM_ERROR_NONE != ret) {
1824 UAM_WARN("Device service discriminant mapping update failed");
1829 return UAM_ERROR_NONE;
1832 int _uam_core_service_get_device_discriminant(const char *svc_name,
1833 const char *device_id, int tech_type, gboolean *discriminant)
1836 uam_svc_dev_info_t *svc_dev;
1838 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1839 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1840 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1841 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1843 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1844 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1845 *discriminant = (gboolean)svc_dev->discriminant;
1848 return UAM_ERROR_NONE;
1851 int _uam_core_service_get_device_last_seen(const char *svc_name,
1852 const char *device_id, int tech_type, unsigned long long *last_seen)
1855 uam_svc_dev_info_t *svc_dev;
1857 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1858 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1859 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1860 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1862 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1863 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1864 *last_seen = svc_dev->last_seen;
1867 return UAM_ERROR_NONE;
1870 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1874 uam_db_service_info_t *service;
1875 unsigned int elapsed_time;
1877 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1878 retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1879 retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1881 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1882 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1885 elapsed_time = service->cycle - service->remaining_time;
1886 service->cycle = new_cycle;
1887 if (new_cycle < elapsed_time)
1888 service->remaining_time = 0;
1890 service->remaining_time = new_cycle - elapsed_time;
1892 /* Update service detection cycle in DB */
1893 if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1894 UAM_WARN("Service cycle updation to persistent DB failed");
1897 return UAM_ERROR_NONE;
1900 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1904 uam_db_service_info_t *service;
1906 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1907 retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1909 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1910 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1912 *cycle = service->cycle;
1915 return UAM_ERROR_NONE;
1918 int _uam_core_set_detection_threshold(unsigned int sensor,
1919 int presence_threshold, int absence_threshold)
1924 ret = _uam_pm_set_detection_threshold(sensor,
1925 presence_threshold, absence_threshold);
1926 if (UAM_ERROR_NONE != ret) {
1927 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
1928 _uam_manager_error_to_str(ret));
1933 return UAM_ERROR_NONE;
1936 static gboolean __start_detection(gpointer data)
1940 uam_db_service_info_t *service = NULL;
1941 unsigned int sensors;
1942 gboolean start_detection = FALSE;
1944 unsigned int presence_env_sensors;
1945 unsigned int absence_env_sensors;
1947 presence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE);
1948 UAM_DBG("Presence Envionmental sensors: 0x%8.8X", presence_env_sensors);
1950 absence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
1951 UAM_DBG("Absence Envionmental sensors: 0x%8.8X", absence_env_sensors);
1953 if (0 != presence_env_sensors) {
1954 /* Stop PRESENCE detection on active envionmental sensors*/
1955 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
1956 if (UAM_ERROR_NONE != ret)
1957 UAM_ERR("Failed with error: %s (0x%4.4X)",
1958 _uam_manager_error_to_str(ret), ret);
1960 if (0 != absence_env_sensors) {
1961 /* Stop ABSENCE detection on envionmental sensors*/
1962 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
1963 if (UAM_ERROR_NONE != ret)
1964 UAM_ERR("Failed with error: %s (0x%4.4X)",
1965 _uam_manager_error_to_str(ret), ret);
1968 for (l = services; NULL != l; l = g_slist_next(l)) {
1970 if (!service || !service->monitors)
1973 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
1974 UAM_DBG("service->remaining_time: %d", service->remaining_time);
1975 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
1976 if (0 >= service->remaining_time) {
1977 start_detection = TRUE;
1978 service->remaining_time = service->cycle;
1982 if (!start_detection)
1985 /* Get sensors on which PRESENCE detection to be started */
1986 sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
1987 UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
1989 /* Remove env sensors from active sensors */
1990 sensors &= ~presence_env_sensors;
1991 UAM_DBG("Presence Connectivity sensors: 0x%8.8X", sensors);
1994 /* Start PRESENCE detection */
1995 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
1996 if (UAM_ERROR_NONE != ret)
1997 UAM_ERR("Failed with error: %s (0x%4.4X)",
1998 _uam_manager_error_to_str(ret), ret);
2001 /* Get sensors on which ABSENCE detection to be started */
2002 sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2003 UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
2005 /* Remove env sensors from active sensors */
2006 sensors &= ~absence_env_sensors;
2007 UAM_DBG("ABSENCE Connectivity sensors: 0x%8.8X", sensors);
2010 /* Start ABSENCE detection */
2011 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
2012 if (UAM_ERROR_NONE != ret)
2013 UAM_ERR("Failed with error: %s (0x%4.4X)",
2014 _uam_manager_error_to_str(ret), ret);
2018 if (0 != presence_env_sensors) {
2019 /* Always Start PRESENCE detection on active envionmental sensors*/
2020 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2021 if (UAM_ERROR_NONE != ret)
2022 UAM_ERR("Failed with error: %s (0x%4.4X)",
2023 _uam_manager_error_to_str(ret), ret);
2025 if (0 != absence_env_sensors) {
2026 /* Always Start ABSENCE detection on active envionmental sensors*/
2027 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2028 if (UAM_ERROR_NONE != ret)
2029 UAM_ERR("Failed with error: %s (0x%4.4X)",
2030 _uam_manager_error_to_str(ret), ret);
2037 static int __uam_core_start_detection(int detection_type,
2038 const char *svc_name, char *sender, unsigned int sensors)
2041 uam_monitor_info_t *monitor;
2042 uam_db_service_info_t *service;
2043 gboolean is_monitor_added = TRUE;
2046 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2047 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2049 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2051 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
2052 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
2053 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2054 services = g_slist_append(services, default_svc);
2058 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2059 retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2062 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2064 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2066 monitor->name = g_strdup(sender);
2067 monitor->mode = detection_type;
2068 monitor->service = service;
2069 is_monitor_added = FALSE;
2071 UAM_ERR("Memory allocation error");
2072 return UAM_ERROR_OUT_OF_MEMORY;
2076 UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2078 monitor->sensors |= sensors;
2079 if (!is_monitor_added) {
2080 monitors = g_slist_append(monitors, monitor);
2081 service->monitors = g_slist_append(service->monitors, monitor);
2084 /* Start detection */
2085 if (0 == detection_timer) {
2086 __start_detection(NULL);
2087 UAM_INFO("Monitor started detection, start timer");
2088 detection_timer = g_timeout_add_seconds(
2089 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2093 return UAM_ERROR_NONE;
2096 static int __uam_core_stop_detection(int detection_type,
2097 const char *svc_name, char *sender, unsigned int sensors)
2100 int ret = UAM_ERROR_NONE;
2101 unsigned int remaining_sensors;
2102 unsigned int active_sensors;
2103 uam_monitor_info_t *monitor;
2104 uam_db_service_info_t *service;
2106 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2107 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2109 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2110 retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2111 service = monitor->service;
2112 retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2114 /* Find sensors which are already monitoring */
2115 active_sensors = _uam_core_get_active_sensors(detection_type);
2116 UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2117 sensors, active_sensors);
2119 /* Update monitor info for application */
2120 monitor->sensors &= ~sensors;
2121 if (0 == monitor->sensors) {
2123 * App requested to stop monitoring for all of its active sensors,
2124 * remove its monitor info from list.
2126 monitors = g_slist_remove(monitors, monitor);
2127 if ((NULL == monitors) && (0 != detection_timer)) {
2128 UAM_INFO("All monitors stopped detection, stop timer");
2129 g_source_remove(detection_timer);
2130 detection_timer = 0;
2133 service->monitors = g_slist_remove(service->monitors, monitor);
2134 if (NULL == service->monitors)
2135 service->remaining_time = 0;
2137 g_free(monitor->name);
2141 /* Find sensors which are already monitoring */
2142 remaining_sensors = _uam_core_get_active_sensors(detection_type);
2143 UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2145 if (active_sensors == remaining_sensors) {
2146 UAM_INFO("NO need to stop monitoring");
2147 return UAM_ERROR_NONE;
2150 /* Stop monitoring only for sensors which aren't required anymore */
2151 sensors = (active_sensors & ~remaining_sensors);
2152 ret = _uam_pm_stop_detection(detection_type, sensors);
2153 if (UAM_ERROR_NONE != ret)
2154 UAM_ERR("Failed with error: %s (0x%4.4X)",
2155 _uam_manager_error_to_str(ret), ret);
2161 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2166 ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2172 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2177 ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2183 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2188 ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2194 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2199 ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2205 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2210 UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2211 ret = _uam_pm_set_low_power_mode(bitmask, mode);
2212 if (UAM_ERROR_NONE != ret) {
2213 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2214 bitmask, _uam_manager_error_to_str(ret));
2219 return UAM_ERROR_NONE;
2222 int _uam_core_get_detection_window(unsigned int *window)
2226 retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2228 *window = detection_window;
2231 return UAM_ERROR_NONE;
2234 int _uam_core_set_detection_window(unsigned int window)
2238 retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2239 retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2240 retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2242 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2243 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2244 return UAM_ERROR_INTERNAL;
2247 detection_window = window;
2250 return UAM_ERROR_NONE;
2253 int _uam_core_init(void)
2258 GSList *db_svc_list;
2259 GSList *db_adv_list;
2260 GSList *db_svc_dev_list;
2264 _uam_db_initialize();
2266 /* Reset detecton window to default */
2267 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2268 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2269 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2271 /* Fetch user list */
2272 db_users = _uam_db_get_all_users();
2274 UAM_INFO_C("No users in database");
2275 return UAM_ERROR_NONE;
2278 for (l = db_users; NULL != l; l = g_slist_next(l)) {
2279 db_user_info_t *info = l->data;
2280 uam_db_user_info_t *user;
2285 user = g_new0(uam_db_user_info_t, 1);
2286 user->user_id = info->user_id;
2287 user->name = g_strdup(info->name);
2288 user->account = g_strdup(info->account);
2289 user->devices = NULL;
2291 users = g_slist_prepend(users, user);
2294 /* Fetch service list */
2295 db_svc_list = _uam_service_db_get_all_services();
2297 UAM_INFO_C("No services in database");
2298 return UAM_ERROR_NONE;
2301 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2302 db_service_info_t *db_svc = l->data;
2303 uam_db_service_info_t *service;
2309 l1 = g_slist_find_custom(services,
2310 db_svc->service_name, __compare_svc_name);
2312 service = g_new0(uam_db_service_info_t, 1);
2313 service->name = g_strdup(db_svc->service_name);
2314 service->cycle = db_svc->cycle;
2315 service->presence_threshold = db_svc->presence_threshold;
2316 service->absence_threshold = db_svc->absence_threshold;
2317 services = g_slist_append(services, service);
2321 /* Fetch device list */
2322 db_devices = _uam_device_db_get_all_devices();
2324 UAM_INFO_C("No Devices registered in database");
2325 return UAM_ERROR_NONE;
2328 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2329 db_device_info_t *db_info = l->data;
2330 uam_db_user_info_t *user;
2331 GSList *svc_list = NULL;
2337 l1 = g_slist_find_custom(users,
2338 &(db_info->user_id), __compare_user_id);
2340 UAM_ERR("Invalid user Id: %d", db_info->user_id);
2345 /* Fetch device services from DB */
2346 l1 = _uam_db_get_device_services(
2347 db_info->dev_info.device_id,
2348 db_info->dev_info.type,
2349 db_info->dev_info.mac);
2351 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2352 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2353 db_info->presence_state, db_info->last_seen, svc_list);
2356 /* Fetch iBeacon adv list */
2357 db_adv_list = _uam_db_get_all_advs();
2359 UAM_INFO_C("No iBeacon adv in database");
2361 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2362 db_adv_info_t *db_adv = l->data;
2363 _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2367 /* Fetch svc dev list */
2368 db_svc_dev_list = _uam_db_get_service_devices_info();
2369 if (!db_svc_dev_list) {
2370 UAM_INFO_C("No service devices in database");
2372 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2373 db_svc_dev_info_t *db_svc = l->data;
2375 _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
2376 db_svc->svc, db_svc->discriminant, db_svc->last_seen);
2380 g_slist_free_full(db_devices, g_free);
2381 g_slist_free_full(db_users, g_free);
2382 g_slist_free_full(db_svc_list, g_free);
2383 g_slist_free_full(db_adv_list, g_free);
2384 g_slist_free_full(db_svc_dev_list, g_free);
2386 /* Set/update registered device list to plugins */
2387 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2388 UAM_ERR("_uam_pm_set_registered_devices failed");
2390 /* Set/update registered device list to cloud plugin */
2391 _uam_cloud_update_registered_devices();
2394 return UAM_ERROR_NONE;
2397 void _uam_core_deinit(void)
2402 /* de-init database */
2403 _uam_db_deinitialize();
2405 /* Reset detecton window to default */
2406 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2408 /* Release allocated memory for devices */
2409 g_slist_free_full(devices, __free_user_device);
2412 /* Release allocated memory for users */
2413 for (l = users; NULL != l; l = g_slist_next(l)) {
2414 uam_db_user_info_t *user = l->data;
2420 g_free(user->account);
2424 g_slist_free(users);
2427 /* Release allocated memory for services */
2428 for (l = services; NULL != l; l = g_slist_next(l)) {
2429 uam_db_service_info_t *service = l->data;
2434 g_free(service->name);
2437 g_slist_free(services);
2440 /* Release allocated memory for service devices */
2441 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2442 uam_svc_dev_info_t *svc_dev = l->data;
2447 g_free(svc_dev->device_id);
2448 g_free(svc_dev->service);
2451 g_slist_free(svc_devs);
2457 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2461 /* Send sensor state changed event over dbus */
2463 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2464 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2466 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2467 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2472 int _uam_core_handle_device_added(int status,
2473 int user_id, const uam_device_info_s *dev_info)
2478 int ret = UAM_ERROR_NONE;
2479 GSList *svc_list = NULL;
2480 uam_db_user_info_t *user = NULL;
2482 UAM_INFO("[%d]", user_id);
2484 /* Send reply over dbus for add device API */
2485 l = _uam_manager_get_request_list();
2486 for (; NULL != l; l = g_slist_next(l)) {
2487 uam_request_context_t *info = l->data;
2488 uam_device_info_s *dev;
2491 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2496 UAM_WARN("info->data is NULL");
2500 if (dev->type != dev_info->type ||
2501 strcasecmp(dev->device_id, dev_info->device_id)) {
2502 UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2503 dev->device_id, dev_info->device_id);
2507 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2508 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2509 _uam_manager_method_return(info->context, out_param, status);
2511 _uam_remove_timer(info->tid);
2513 _uam_manager_remove_req_ctxt_from_list(info);
2518 if (UAM_ERROR_NONE != status) {
2519 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2525 l = g_slist_find_custom(users,
2526 USER_ACCOUNT_DEFAULT, __compare_user_account);
2528 ret = _uam_core_add_user(&id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2529 if (UAM_ERROR_NONE != ret) {
2530 UAM_ERR("_uam_core_add_user failed with %s",
2531 _uam_manager_error_to_str(ret));
2532 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2538 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2540 UAM_ERR("Invalid user Id: %d", user_id);
2541 ret = UAM_ERROR_NOT_FOUND;
2542 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2547 /* Get default service and add it to device's service list by default */
2548 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2550 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2551 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2552 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2553 services = g_slist_append(services, service);
2554 svc_list = g_slist_append(svc_list, service);
2556 uam_db_service_info_t *service = l->data;
2557 svc_list = g_slist_append(svc_list, service);
2560 __uam_core_add_dev_to_list(user, dev_info,
2561 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen, svc_list);
2563 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2565 /* Add device to database */
2566 ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
2567 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen);
2568 if (UAM_ERROR_NONE != ret) {
2569 UAM_WARN("Device addition to persistent DB failed");
2570 __uam_db_end_transaction(0);
2574 /* Insert device service info to db */
2575 ret = _uam_db_insert_device_service_info(
2576 dev_info->device_id, dev_info->type, dev_info->mac,
2577 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2578 dev_info->discriminant, 0);
2579 if (UAM_ERROR_NONE != ret) {
2580 UAM_WARN("Device service addition to persistent DB failed");
2581 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2582 __uam_db_end_transaction(0);
2585 __uam_db_end_transaction(1);
2587 ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
2588 UAM_SERVICE_DEFAULT, dev_info->discriminant, 0);
2589 if (UAM_ERROR_NONE != ret) {
2590 UAM_WARN("Device service mappiing update failed");
2591 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2595 /* Send device added event to application */
2596 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2598 /* Set/update registered device list to plugins */
2599 ret = _uam_pm_set_registered_devices(devices);
2600 if (UAM_ERROR_NONE != ret) {
2601 UAM_ERR("_uam_pm_set_registered_devices failed");
2605 _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2607 /* Set/update registered device list to cloud plugin */
2608 if (UAM_ERROR_NONE == status)
2609 _uam_cloud_update_registered_devices();
2615 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2619 unsigned long long timestamp;
2621 UAM_INFO("sensor 0x[%8.8X]", sensor);
2623 if (NULL == sensor_info) {
2624 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2625 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2626 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2631 timestamp = _uam_get_timestamp();
2633 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2634 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2635 g_variant_new("(utiidddd)", sensor, timestamp,
2636 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2637 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2638 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2643 // service specific light detection threshold
2644 for (l = services; NULL != l; l = g_slist_next(l)) {
2645 uam_db_service_info_t *svc = l->data;
2648 if (!svc || !svc->monitors)
2651 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2652 svc->name, sensor_info->values[0], svc->presence_threshold);
2654 if (sensor_info->values[0] < svc->presence_threshold)
2657 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2658 uam_monitor_info_t *mon = l1->data;
2663 UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2664 mon->name, mon->sensors);
2666 if (!(mon->sensors & sensor))
2669 if (UAM_DETECT_PRESENCE != mon->mode)
2672 _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2673 g_variant_new("(utiidddd)", sensor, timestamp,
2674 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2675 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2676 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2684 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
2685 unsigned int sensor)
2690 UAM_INFO("sensor 0x[%8.8X]", sensor);
2692 if (NULL == sensor_info) {
2693 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2694 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2695 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2700 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2701 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2702 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2703 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2704 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2705 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2710 // service specific light detection threshold
2711 for (l = services; NULL != l; l = g_slist_next(l)) {
2712 uam_db_service_info_t *svc = l->data;
2715 if (!svc || !svc->monitors)
2718 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2719 svc->name, sensor_info->values[0], svc->absence_threshold);
2721 if (sensor_info->values[0] > svc->absence_threshold)
2724 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2725 uam_monitor_info_t *mon = l1->data;
2730 if (!(mon->sensors & sensor))
2733 if (UAM_DETECT_PRESENCE != mon->mode)
2736 _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2737 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2738 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2739 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2740 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2747 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2748 uam_device_info_s *dev_info)
2753 uam_db_user_info_t *user;
2754 uam_svc_dev_info_t *svc_dev = NULL;
2755 gboolean live_monitoring = FALSE;
2756 unsigned long long timestamp;
2759 ret_if(NULL == tech);
2760 ret_if(NULL == tech->svc_list);
2761 ret_if(NULL == dev_info);
2763 user = tech->device->user;
2764 user->last_seen = tech->last_seen;
2766 for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2767 uam_db_service_info_t *svc = l->data;
2769 live_monitoring = FALSE;
2771 if (!svc || !svc->monitors)
2774 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2775 svc->name, svc->remaining_time, svc->cycle);
2777 if (!(svc->remaining_time == svc->cycle))
2780 UAM_DBG("Check service device discriminant");
2781 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2782 dev_info->type, svc->name);
2783 if (!svc_dev || !svc_dev->discriminant)
2786 UAM_DBG("Send event");
2787 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2788 uam_monitor_info_t *mon = l1->data;
2793 if (!(mon->sensors & sensor))
2796 if (UAM_DETECT_PRESENCE != mon->mode)
2800 * For current service, if any of its running monitor has same sensor
2801 * and detection_mode
2803 live_monitoring = TRUE;
2805 timestamp = _uam_get_timestamp();
2806 UAM_INFO("sensor [%d]", sensor);
2807 _uam_manager_send_event(mon->name,
2808 UAM_EVENT_USER_PRESENCE_DETECTED,
2809 g_variant_new("(utsss)", sensor, timestamp,
2810 user->account, svc->name, dev_info->device_id));
2811 UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2813 " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
2814 mon->name, dev_info->device_id,
2815 sensor, user->account,
2820 /* Update service specific device last_seen in svc_dev list and DB */
2821 if (live_monitoring) {
2822 svc_dev->last_seen = tech->last_seen;
2823 ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
2824 dev_info->type, dev_info->mac, svc->name, tech->last_seen);
2825 if (UAM_ERROR_NONE != ret)
2826 UAM_WARN("_uam_db_update_device_service_last_seen failed");
2833 int _uam_core_handle_presence_detected(unsigned int sensor,
2834 int user_id, void *info)
2837 int ret = UAM_ERROR_NONE;
2840 uam_db_user_info_t *user;
2841 uam_db_device_info_t *device;
2842 uam_db_tech_info_t *tech;
2844 uam_device_info_s *dev_info = NULL;
2845 uam_sensor_info_s *sensor_info = NULL;
2847 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2849 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2851 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2854 _uam_vpm_send_presence_detection_event(sensor);
2856 if (NULL == dev_info) {
2857 __send_sensor_presence_event(sensor_info, sensor);
2861 retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
2863 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2865 UAM_ERR("Invalid user_id [%d]", user_id);
2866 return UAM_ERROR_INVALID_PARAMETER;
2870 l = g_slist_find_custom(user->devices,
2871 dev_info->device_id, __compare_device_id);
2873 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2874 user_id, dev_info->device_id);
2875 return UAM_ERROR_INVALID_PARAMETER;
2878 if (!(device->supported_techs & dev_info->type)) {
2879 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2880 dev_info->device_id, dev_info->type);
2881 return UAM_ERROR_INVALID_PARAMETER;
2884 l = g_slist_find_custom(device->tech_list,
2885 &(dev_info->type), __compare_tech_type);
2887 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2888 return UAM_ERROR_INVALID_PARAMETER;
2892 tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2893 tech->last_seen = dev_info->last_seen;
2895 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
2897 /* Check if IP/MAC address was updated then update in DB */
2898 if (UAM_TECH_TYPE_WIFI == dev_info->type) {
2900 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2901 uam_db_address_info_t *addr = l->data;
2906 if (UAM_ADDR_TYPE_IPv4 == addr->addr_type) {
2908 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
2909 UAM_DBG("Old IPv4: %s, New IPv4: %s",
2910 addr->address, dev_info->ipv4_addr);
2912 g_free(addr->address);
2913 addr->addr_type = UAM_ADDR_TYPE_IPv4;
2914 addr->address = g_strdup(dev_info->ipv4_addr);
2916 /* Update IP address in DB */
2917 ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
2918 dev_info->type, dev_info->ipv4_addr);
2919 if (UAM_ERROR_NONE != ret) {
2920 UAM_WARN("_uam_device_db_update_device_ip_address failed");
2921 __uam_db_end_transaction(0);
2927 if (UAM_ADDR_TYPE_WIFI == addr->addr_type) {
2929 if (strcasecmp(addr->address, dev_info->mac)) {
2930 UAM_DBG("Old MAC: %s, New MAC: %s",
2931 addr->address, dev_info->mac);
2933 g_free(addr->address);
2934 addr->addr_type = UAM_ADDR_TYPE_WIFI;
2935 addr->address = g_strdup(dev_info->mac);
2937 /* Update address in DB */
2938 ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
2939 dev_info->type, dev_info->mac);
2940 if (UAM_ERROR_NONE != ret) {
2941 UAM_WARN("_uam_device_db_update_device_mac_address failed");
2942 __uam_db_end_transaction(0);
2950 /* Update database (presence state & timestamp) */
2951 ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
2952 dev_info->type, dev_info->mac, dev_info->last_seen);
2953 if (UAM_ERROR_NONE != ret) {
2954 UAM_WARN("_uam_device_db_update_device_last_seen failed");
2955 __uam_db_end_transaction(0);
2959 ret = _uam_device_db_update_device_presence(dev_info->device_id,
2960 dev_info->type, dev_info->mac, tech->presence_state);
2961 if (UAM_ERROR_NONE != ret) {
2962 UAM_WARN("_uam_device_db_update_device_presence failed");
2963 __uam_db_end_transaction(0);
2967 /* Send user presence event and update service_device timestamp */
2968 __send_user_presence_event(tech, sensor, dev_info);
2969 __uam_db_end_transaction(1);
2975 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
2981 * For each service, find users absent on given sensor. Then for each
2982 * monitor in serivce's monitor list, if it is monitoring ABSENCE on
2983 * given sensor, send user ABSENCE event.
2985 for (l = services; NULL != l; l = g_slist_next(l)) {
2986 uam_db_service_info_t *svc = l->data;
2987 GSList *absent_users = NULL;
2988 GSList *present_users = NULL;
2992 if (!svc || !svc->monitors || !svc->dev_techs)
2995 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
2996 uam_db_tech_info_t *tech = l1->data;
2998 if (!tech || (tech->tech_type != type)) {
2999 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
3003 if (!tech->device || !tech->device->user) {
3004 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
3008 l2 = g_slist_find_custom(present_users,
3009 &(tech->device->user->user_id), __compare_user_id);
3011 if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
3012 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
3014 tech->device->device_id,
3015 tech->device->user->account);
3016 /* Remove user from absent list */
3017 absent_users = g_slist_remove(absent_users, tech->device->user);
3019 /* If user not in present list, add user to the list */
3021 UAM_DBG("added present user [%s]", tech->device->user->account);
3022 present_users = g_slist_prepend(present_users, tech->device->user);
3025 /* If user not in the present list then only add it to absent list */
3026 if ((NULL == l2) && (NULL == g_slist_find_custom(
3027 absent_users, &(tech->device->user->user_id),
3028 __compare_user_id))) {
3029 UAM_DBG("added absent user [%s]", tech->device->user->account);
3030 absent_users = g_slist_prepend(absent_users, tech->device->user);
3035 g_slist_free(present_users);
3039 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
3040 uam_monitor_info_t *mon = l2->data;
3045 if (!(mon->sensors & sensor))
3048 if (UAM_DETECT_ABSENCE != mon->mode)
3051 for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
3052 uam_db_user_info_t *user = l1->data;
3057 user->last_seen = 0;
3059 _uam_manager_send_event(mon->name,
3060 UAM_EVENT_USER_ABSENCE_DETECTED,
3061 g_variant_new("(utss)", sensor, user->last_seen,
3062 user->account, svc->name));
3063 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
3064 " for 0x%8.8X, User: %s Service: %s",
3065 mon->name, sensor, user->account, svc->name);
3069 g_slist_free(absent_users);
3075 void _uam_core_handle_absence_detected(unsigned int sensor,
3076 int user_id, void *info)
3079 uam_db_user_info_t *user;
3080 uam_db_device_info_t *device;
3081 uam_db_tech_info_t *tech;
3083 uam_device_info_s *dev_info = NULL;
3084 uam_sensor_info_s *sensor_info = NULL;
3086 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3088 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3090 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3093 if (NULL == dev_info) {
3094 __send_sensor_absence_event(sensor_info, sensor);
3099 ret_if(0 > user_id);
3101 l = g_slist_find_custom(users, &user_id, __compare_user_id);
3103 UAM_ERR("Invalid user_id [%d]", user_id);
3108 l = g_slist_find_custom(user->devices,
3109 dev_info->device_id, __compare_device_id);
3111 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3112 user_id, dev_info->device_id);
3116 if (!(device->supported_techs & dev_info->type)) {
3117 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3118 dev_info->device_id, dev_info->type);
3122 l = g_slist_find_custom(device->tech_list,
3123 &(dev_info->type), __compare_tech_type);
3125 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3130 tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
3132 /* Update database (presence state) */
3133 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
3134 dev_info->type, dev_info->mac, tech->presence_state))
3135 UAM_WARN("_uam_device_db_update_device_presence failed");
3140 void _uam_core_cleanup_monitor(char *name)
3144 for (l = monitors; NULL != l; l = g_slist_next(l)) {
3145 uam_monitor_info_t *monitor = l->data;
3147 if (!monitor || !monitor->name || !monitor->service)
3150 if (0 != g_strcmp0(name, monitor->name))
3153 /* If there is a monitor that is not freed, stop detection
3154 * and free the monitor structure in the memory. */
3155 UAM_INFO("clear %s's monitor info.", monitor->name);
3156 __uam_core_stop_detection(monitor->mode,
3157 monitor->service->name, name, monitor->sensors);
3161 static void __free_user_info(gpointer data)
3164 uam_db_user_info_t *user = data;
3166 ret_if(NULL == user);
3169 g_free(user->account);
3174 static void __free_service_info(gpointer data)
3177 uam_db_service_info_t *svc = data;
3179 ret_if(NULL == svc);
3186 static void __free_monitor_info(gpointer data)
3189 uam_monitor_info_t *monitor = data;
3191 ret_if(NULL == monitor);
3193 g_free(monitor->name);
3198 static void __free_scanner_info(gpointer data)
3201 uam_scanner_info_t *scanner = data;
3203 ret_if(NULL == scanner);
3205 g_free(scanner->name);
3210 void _uam_core_reset_database(void)
3215 ret = _uam_db_clear();
3216 if (UAM_ERROR_NONE != ret) {
3217 UAM_ERR("_uam_db_clear failed with %s",
3218 _uam_manager_error_to_str(ret));
3219 unlink(DATABASE_FULL_PATH);
3223 g_slist_free_full(devices, __free_user_device);
3226 g_slist_free_full(users, __free_user_info);
3229 g_slist_free_full(services, __free_service_info);
3232 g_slist_free_full(monitors, __free_monitor_info);
3235 g_slist_free_full(scanners, __free_scanner_info);
3238 /* Set/update registered device list to plugins */
3239 ret = _uam_pm_set_registered_devices(devices);
3240 if (UAM_ERROR_NONE != ret)
3241 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3242 _uam_manager_error_to_str(ret));
3244 /* Set/update registered device list to cloud plugin */
3245 _uam_cloud_update_registered_devices();
3250 void _uam_core_handle_detection_started(unsigned int sensor)
3253 unsigned int active_sensors = 0;
3255 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3256 sensor, detecting_sensors);
3258 detecting_sensors |= sensor;
3259 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3260 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3261 if (active_sensors == detecting_sensors) {
3262 /* Send detection started event */
3263 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3269 void _uam_core_handle_detection_stopped(unsigned int sensor)
3273 uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3274 uam_cycle_state_e cycle_state;
3277 ret_if((detecting_sensors & sensor) == 0);
3278 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3279 sensor, detecting_sensors);
3280 detecting_sensors &= ~sensor;
3282 if (UAM_SENSOR_BITMASK_BLE == sensor)
3283 type = UAM_TECH_TYPE_BLE;
3284 else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3285 type = UAM_TECH_TYPE_WIFI;
3287 if (UAM_TECH_TYPE_NONE != type)
3288 __send_user_absence_event(type, sensor);
3290 if (0 == detecting_sensors) {
3291 /* Send detection stopped event */
3292 for (l = monitors; l; l = g_slist_next(l)) {
3293 uam_monitor_info_t *mon = l->data;
3295 if (!mon || !mon->name || !mon->service)
3297 uam_db_service_info_t *service = mon->service;
3298 cycle_state = UAM_DETECTION_CYCLE_END;
3300 UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d", mon->sensors, service->name, service->remaining_time);
3301 if (!(mon->sensors & _uam_core_get_env_sensors())) {
3302 if (service->remaining_time < service->cycle) {
3303 UAM_DBG("service->remaining_time < service->cycle, return");
3306 } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
3307 cycle_state = UAM_DETECTION_CYCLE_MID;
3310 _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
3311 g_variant_new("(si)", service->name, cycle_state));
3312 UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
3313 " cycle state:[%s]",
3314 mon->name, service->name, cycle_state ? "end" : "mid");
3320 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3324 retv_if(NULL == name, NULL);
3326 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3327 uam_scanner_info_t *scanner = l->data;
3329 if (!scanner || !scanner->name)
3332 if (0 == g_strcmp0(scanner->name, name)) {
3333 UAM_DBG("Scanning application found in list");
3341 static gboolean __scan_completed_cb(gpointer data)
3344 uam_scanner_info_t *scanner = data;
3346 retv_if(NULL == scanner, FALSE);
3348 if (UAM_ERROR_NONE != _uam_manager_send_event(
3349 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3350 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3352 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3355 scanners = g_slist_remove(scanners, scanner);
3356 g_free(scanner->name);
3363 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3367 uam_scanner_info_t *scanner;
3369 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3370 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3372 scanner = __uam_find_scanner(sender);
3373 retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3375 ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3376 if (UAM_ERROR_NONE != ret) {
3377 UAM_ERR("Failed with error: %s (0x%4.4X)",
3378 _uam_manager_error_to_str(ret), ret);
3382 scanner = g_malloc0(sizeof(uam_scanner_info_t));
3384 UAM_ERR("Failed to allocate memory");
3385 return UAM_ERROR_OUT_OF_MEMORY;
3387 scanner->name = g_strdup(sender);
3388 scanner->sensors |= sensors;
3389 scanner->timer = g_timeout_add_seconds(detection_period,
3390 __scan_completed_cb, scanner);
3391 scanners = g_slist_append(scanners, scanner);
3392 UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3395 return UAM_ERROR_NONE;
3398 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3402 uam_scanner_info_t *scanner;
3405 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3406 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3408 scanner = __uam_find_scanner(sender);
3409 retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3411 /* Trim sensors to a subset of active sensors for the scanner */
3412 sensors &= scanner->sensors;
3415 * modify scanner's active sensors and if active sensors are NULL
3416 * remove scanner from scanners list
3418 scanner->sensors &= ~sensors;
3419 if (0 == scanner->sensors) {
3420 scanners = g_slist_remove(scanners, scanner);
3421 g_source_remove(scanner->timer);
3422 g_free(scanner->name);
3426 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3427 uam_scanner_info_t *scanner_data = l->data;
3429 if (!scanner_data || !scanner_data->name)
3432 sensors &= ~(scanner_data->sensors);
3436 ret = _uam_pm_stop_active_device_scan(sensors);
3437 if (UAM_ERROR_NONE != ret) {
3438 UAM_ERR("Failed with error: %s (0x%4.4X)",
3439 _uam_manager_error_to_str(ret), ret);
3445 return UAM_ERROR_NONE;
3448 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3449 unsigned int sensor, const uam_device_info_s *dev_info)
3454 ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3456 for (l = scanners; NULL != l;) {
3457 uam_scanner_info_t *scanner = l->data;
3459 if (!scanner || !scanner->name) {
3460 l = g_slist_next(l);
3464 if (0 == (scanner->sensors & sensor)) {
3465 l = g_slist_next(l);
3469 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3470 scanner->sensors &= ~(sensor);
3471 UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3472 if (0 != scanner->sensors) {
3473 l = g_slist_next(l);
3477 if (UAM_ERROR_NONE != _uam_manager_send_event(
3478 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3479 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3481 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3484 l = g_slist_next(l);
3485 scanners = g_slist_remove(scanners, scanner);
3486 g_source_remove(scanner->timer);
3487 g_free(scanner->name);
3490 GVariant *param = g_variant_new("(iiisss)",
3492 dev_info->operating_system,
3495 dev_info->ipv4_addr,
3496 dev_info->device_id);
3497 if (UAM_ERROR_NONE != _uam_manager_send_event(
3498 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3499 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3501 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3503 l = g_slist_next(l);
3510 int _uam_core_register_service(uam_service_info_s *svc)
3514 uam_db_service_info_t *service;
3515 int service_number = 0;
3517 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3519 /* Retrieve service from list */
3520 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3521 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3523 service = g_new0(uam_db_service_info_t, 1);
3524 service->name = g_strdup(svc->name);
3525 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3526 service->presence_threshold = svc->presence_threshold;
3527 service->absence_threshold = svc->absence_threshold;
3529 /* Add service to database */
3530 if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3531 UAM_ERR("_uam_db_insert_service_info failed");
3533 return UAM_ERROR_DB_FAILED;
3536 services = g_slist_append(services, service);
3538 /* Send service registered event to application */
3539 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3540 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3541 UAM_ERROR_NONE, service->name)))
3542 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3545 return UAM_ERROR_NONE;
3548 int _uam_core_update_service(uam_service_info_s *svc)
3552 uam_db_service_info_t *service;
3554 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3556 /* Retrieve service from list */
3557 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3558 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3561 service->presence_threshold = svc->presence_threshold;
3562 service->absence_threshold = svc->absence_threshold;
3564 /* Update service to database */
3565 if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3566 UAM_ERR("_uam_db_update_service_info failed");
3567 return UAM_ERROR_DB_FAILED;
3571 return UAM_ERROR_NONE;
3574 int _uam_core_get_default_service(uam_service_info_s *service_info)
3579 uam_db_service_info_t *service;
3581 retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3583 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3586 // insert default service
3587 memset(service_info, 0x00, sizeof(uam_service_info_s));
3588 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3589 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3590 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3592 ret = _uam_core_register_service(service_info);
3593 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3594 UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3597 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3600 retv_if(NULL == l, UAM_ERROR_INTERNAL);
3603 memset(service_info, 0x00, sizeof(uam_service_info_s));
3604 g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3607 return UAM_ERROR_NONE;
3610 int _uam_core_unregister_service(const char *svc_name)
3614 uam_db_service_info_t *service;
3616 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3618 /* Retrieve service from list */
3619 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3620 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3623 /* Check if service is being used*/
3624 if (service->monitors) {
3625 UAM_ERR("service monitoring in progress");
3626 return UAM_ERROR_PERMISSION_DENIED;
3629 /* Remove service from database */
3630 if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3631 UAM_ERR("_uam_db_delete_service_info failed");
3632 return UAM_ERROR_DB_FAILED;
3635 /* Remove service mapping from devices*/
3636 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3637 uam_db_tech_info_t *tech = l->data;
3638 if (!tech || !tech->addresses)
3640 tech->svc_list = g_slist_remove(tech->svc_list, service);
3642 services = g_slist_remove(services, service);
3644 /* Send service unregistered event to application */
3645 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3646 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3647 UAM_ERROR_NONE, service->name)))
3648 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3651 return UAM_ERROR_NONE;
3654 static int __get_service_dev_list(
3655 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3661 int ret = UAM_ERROR_NONE;
3662 uam_svc_dev_info_t *svc_dev = NULL;
3663 uam_device_info_s *dev = NULL;
3666 /* Calculate number of devices */
3667 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3668 uam_db_tech_info_t *tech = l1->data;
3669 if (!tech || !tech->addresses)
3675 *device_list = g_new0(uam_device_info_s, *count);
3678 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3679 uam_db_tech_info_t *tech = l1->data;
3681 if (!tech || !tech->addresses)
3684 /* Copy tech info to device info */
3685 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
3686 if (UAM_ERROR_NONE != ret) {
3687 UAM_ERR("__copy_tech_info_to_device_info failed");
3691 (*device_list)[indx].last_seen = 0;
3695 UAM_INFO("Count = %d, indx = %d", *count, indx);
3697 /* Update service specific device last time */
3698 for (s = svc_devs; s; s = g_slist_next(s)) {
3701 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
3703 if (g_strcmp0(svc_dev->service, service->name))
3706 for (indx = 0; indx < *count; indx++) {
3707 dev = &((*device_list)[indx]);
3709 if (svc_dev->tech_type != dev->type ||
3710 g_strcmp0(svc_dev->device_id, dev->device_id))
3713 dev->last_seen = svc_dev->last_seen;
3721 int _uam_core_get_service_devices(const char *svc_name,
3722 int *count, uam_device_info_s **device_list)
3725 uam_db_service_info_t *service;
3727 int ret = UAM_ERROR_NONE;
3729 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3730 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3733 ret = __get_service_dev_list(service, device_list, count);
3739 static void __get_service_user_list(
3740 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3745 GSList *svc_user_list = NULL;
3748 /* Calculate number of users */
3749 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3750 uam_db_tech_info_t *tech = l->data;
3751 if (!tech || !tech->addresses)
3755 uam_db_user_info_t *db_info = tech->device->user;
3756 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3758 svc_user_list = g_slist_append(svc_user_list, db_info);
3761 *count = g_slist_length(svc_user_list);
3762 *user_list = g_new0(uam_user_info_s, *count);
3765 for (l = svc_user_list; l; l = g_slist_next(l)) {
3766 uam_db_user_info_t *db_info = l->data;
3768 if (!db_info || !db_info->account)
3771 g_strlcpy((*user_list)[indx].account,
3772 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3774 g_strlcpy((*user_list)[indx].name,
3775 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3780 UAM_INFO("Count = %d, indx = %d", *count, indx);
3784 int _uam_core_get_service_users(const char *svc_name,
3785 int *count, uam_user_info_s **user_list)
3788 uam_db_service_info_t *service;
3791 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3792 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3795 __get_service_user_list(service, user_list, count);
3798 return UAM_ERROR_NONE;
3801 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3807 size = g_slist_length(services);
3808 *service_list = g_new0(uam_service_info_s, size);
3811 /* fetch services list from DB */
3812 for (l = services; l; l = g_slist_next(l)) {
3813 uam_db_service_info_t *db_info = l->data;
3815 if (!db_info || !db_info->name)
3818 g_strlcpy((*service_list)[*count].name,
3819 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3820 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3821 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3825 UAM_INFO("Count: %d", *count);
3827 return UAM_ERROR_NONE;
3830 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3835 UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3836 iadv[0], iadv[1], iadv[2]);
3838 ret = _uam_db_insert_adv_info(adv_len, iadv);
3839 if (UAM_ERROR_NONE != ret) {
3840 UAM_ERR("_uam_db_insert_adv_info failed");
3844 ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3845 if (UAM_ERROR_NONE != ret) {
3846 UAM_ERR("Failed with error: %s (0x%4.4X)",
3847 _uam_manager_error_to_str(ret), ret);
3852 return UAM_ERROR_NONE;
3855 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
3859 uam_sensor_info_s *sensor_info = info;
3861 ret_if(NULL == info);
3863 UAM_DBG("%d %d %llu %d %d", sensor, sensor_info->status, sensor_info->timestamp,
3864 sensor_info->accuracy, sensor_info->count);
3866 UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
3867 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
3869 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3870 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
3871 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3872 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3877 int _uam_core_add_payload(uam_ble_payload_s *payload,
3878 const char *device_id, int tech_type)
3881 int ret = UAM_ERROR_NONE;
3882 uam_db_tech_info_t *tech_info;
3885 retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
3886 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
3887 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
3888 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
3890 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
3891 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
3892 mac = __get_mac_addr(tech_info);
3894 /*** Add payload to database ***/
3895 ret = _uam_db_insert_payload_info(device_id, tech_type, mac, payload);
3896 if (UAM_ERROR_NONE != ret) {
3897 UAM_ERR("_uam_db_insert_payload_info failed");
3902 return UAM_ERROR_NONE;
3905 int _uam_core_service_add_payload(uam_ble_payload_s *payload,
3906 const char *svc_name)
3909 int ret = UAM_ERROR_NONE;
3910 uam_db_service_info_t *service;
3913 retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
3914 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3916 /* Retrieve service from list */
3917 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3918 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3921 /*** Add payload to database ***/
3922 ret = _uam_db_update_device_service_payload_info(payload, service->name);
3923 if (UAM_ERROR_NONE != ret) {
3924 UAM_ERR("_uam_db_update_device_service_payload_info failed");
3929 return UAM_ERROR_NONE;