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 */
52 static GSList *payloads; /* List of payloads - uam_db_payload_info_t */
54 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
55 static GSList *scanners; /* List of scanning apps - uam_scanner_info_t */
57 static guint detection_timer = 0;
58 static unsigned int detection_window;
60 static unsigned int detecting_sensors = 0;
62 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
64 const uam_db_user_info_t *user = data;
65 const char *account = user_data;
67 retv_if(NULL == user, -1);
68 retv_if(NULL == user->account, -1);
69 retv_if(NULL == account, -1);
71 return g_strcmp0(user->account, account);
74 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
76 const uam_db_user_info_t *user = data;
77 const int *id = user_data;
79 UAM_INFO("[%d][%d]", *id, user->user_id);
81 retv_if(NULL == user, -1);
82 retv_if(NULL == user->account, -1);
83 retv_if(NULL == id, -1);
85 if (*id != user->user_id)
91 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
93 const uam_db_service_info_t *service = data;
94 const char *svc_name = user_data;
96 retv_if(NULL == service, -1);
97 retv_if(NULL == service->name, -1);
98 retv_if(NULL == svc_name, -1);
100 return g_strcmp0(service->name, svc_name);
103 static gint __compare_payload(gconstpointer data, gconstpointer user_data)
105 const uam_db_payload_info_t *db_payload = data;
106 const uam_ble_payload_s *payload = user_data;
108 retv_if(NULL == db_payload, -1);
109 retv_if(NULL == payload, -1);
111 if ((db_payload->primary_key == payload->primary_key) &&
112 (0 == g_strcmp0(db_payload->device_uid, payload->device_uid)))
117 static gint __compare_db_payload(gconstpointer data, gconstpointer user_data)
119 const uam_db_payload_info_t *db_payload = data;
120 const uam_ble_payload_s *payload = user_data;
122 retv_if(NULL == db_payload, -1);
123 retv_if(NULL == payload, -1);
125 if ((db_payload->primary_key == payload->primary_key) &&
126 (0 == g_strcmp0(db_payload->device_uid, payload->device_uid)))
131 static void __free_address_info(gpointer data)
134 uam_db_address_info_t *addr = data;
136 ret_if(NULL == addr);
138 g_free(addr->address);
144 static void __free_dev_tech_info(gpointer data)
147 uam_db_tech_info_t *tech_info = data;
150 ret_if(NULL == tech_info);
152 /* Delete the tech information from the service list that includes tech. */
153 for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
154 uam_db_service_info_t *svc_info = l->data;
156 if (!svc_info || !svc_info->dev_techs)
159 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
162 g_slist_free_full(tech_info->addresses, __free_address_info);
163 tech_info->addresses = NULL;
170 static void __free_user_device(gpointer data)
173 uam_db_device_info_t *device = data;
175 ret_if(NULL == device);
177 /* Remove device data from global device list */
178 devices = g_slist_remove(devices, device);
180 /* Free allocated memory */
181 g_free(device->device_id);
182 g_slist_free_full(device->tech_list, __free_dev_tech_info);
188 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
193 UAM_INFO_C("Send %s to applications", _uam_manager_event_to_str(event));
194 /* Send device event to application */
195 param = g_variant_new("(iiisss)",
197 dev_info->operating_system,
201 dev_info->device_id);
202 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL, event, param))
203 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
208 static void __print_service(gpointer data, gpointer user_data)
211 uam_db_service_info_t *service = data;
212 uam_db_tech_info_t *tech = user_data;
214 ret_if(NULL == tech);
215 ret_if(NULL == service);
217 UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
218 tech->device->device_id, tech->tech_type,
219 service->name, service->cycle);
224 static void __print_svc_dev(gpointer data, gpointer user_data)
227 uam_svc_dev_info_t *svc_dev = data;
229 ret_if(NULL == svc_dev);
231 UAM_DBG("DevId: %s, Svc: %s, payload primary key: %d",
232 svc_dev->device_id, svc_dev->service,
233 svc_dev->payload->primary_key);
238 static void __add_service_to_dev_tech_mapping(
239 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
243 ret_if(NULL == tech);
244 ret_if(NULL == service);
246 tech->svc_list = g_slist_append(tech->svc_list, service);
247 service->dev_techs = g_slist_append(service->dev_techs, tech);
248 g_slist_foreach(tech->svc_list, __print_service, tech);
253 static void __remove_service_to_dev_tech_mapping(
254 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
258 ret_if(NULL == tech);
259 ret_if(NULL == service);
261 tech->svc_list = g_slist_remove(tech->svc_list, service);
262 service->dev_techs = g_slist_remove(service->dev_techs, tech);
263 g_slist_foreach(tech->svc_list, __print_service, tech);
268 static char *__get_mac_addr(uam_db_tech_info_t *tech)
273 retv_if(NULL == tech, NULL);
275 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
276 uam_db_address_info_t *addr = l->data;
281 if (addr->addr_type == UAM_ADDR_TYPE_BT ||
282 addr->addr_type == UAM_ADDR_TYPE_BLE ||
283 addr->addr_type == UAM_ADDR_TYPE_WIFI ||
284 addr->addr_type == UAM_ADDR_TYPE_P2P)
285 return addr->address;
292 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
294 switch (addr->addr_type) {
295 case UAM_ADDR_TYPE_BLE:
296 case UAM_ADDR_TYPE_BT:
297 case UAM_ADDR_TYPE_P2P:
298 case UAM_ADDR_TYPE_WIFI:
299 g_strlcpy(device->mac, addr->address,
300 UAM_MAC_ADDRESS_STRING_LEN);
302 case UAM_ADDR_TYPE_IPv4:
303 g_strlcpy(device->ipv4_addr,
305 UAM_IP_ADDRESS_MAX_STRING_LEN);
308 UAM_WARN("Unknown address type %d", addr->addr_type);
312 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
317 retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
319 memset(device, 0x00, sizeof(uam_device_info_s));
320 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
321 uam_db_address_info_t *addr = l->data;
326 __uam_core_copy_addr(device, addr);
329 device->operating_system = tech->device->os;
330 g_strlcpy(device->device_id, tech->device->device_id,
331 UAM_DEVICE_ID_MAX_STRING_LEN);
332 device->type = tech->tech_type;
333 device->discriminant = tech->discriminant;
334 device->last_seen = tech->last_seen;
337 return UAM_ERROR_NONE;
340 static int _uam_remove_user_device(uam_db_device_info_t *device)
343 uam_device_info_s dev_info;
346 int ret = UAM_ERROR_NONE;
348 retv_if(NULL == device, UAM_ERROR_INVALID_PARAMETER);
349 user_id = device->user->user_id;
351 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
352 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
353 uam_db_tech_info_t *tech = l->data;
358 /* Copy tech info to device info */
359 ret = __copy_tech_info_to_device_info(tech, &dev_info);
360 if (UAM_ERROR_NONE != ret) {
361 UAM_ERR("__copy_tech_info_to_device_info failed");
362 __uam_db_end_transaction(0);
366 /* Unregister device from plugin */
367 ret = _uam_pm_unregister_device(user_id, &dev_info);
368 if (UAM_ERROR_NONE != ret)
369 UAM_ERR("_uam_pm_unregister_device failed with %s",
370 _uam_manager_error_to_str(ret));
372 /* Send device removed event to application */
373 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
375 /* Remove device from database */
376 ret = _uam_device_db_delete_device_info(
377 dev_info.device_id, dev_info.type, dev_info.mac);
378 if (UAM_ERROR_NONE != ret) {
379 UAM_ERR("_uam_device_db_delete_device_info failed");
380 __uam_db_end_transaction(0);
384 __uam_db_end_transaction(1);
390 static int __free_uam_db_user_info(gpointer data)
393 uam_db_user_info_t *user = data;
395 int ret = UAM_ERROR_NONE;
397 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
398 uam_db_device_info_t *device = l->data;
399 ret = _uam_remove_user_device(device);
400 if (UAM_ERROR_NONE != ret) {
401 UAM_ERR("_uam_remove_user_device failed");
406 g_slist_free_full(user->devices, __free_user_device);
408 /* Set/update registered device list to plugins */
409 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
410 UAM_ERR("_uam_pm_set_registered_devices failed");
412 /* Set/update registered device list to cloud plugin */
413 _uam_cloud_update_registered_devices();
416 g_free(user->account);
423 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
426 const uam_db_device_info_t *device = data;
427 const char *dev_id = user_data;
429 retv_if(NULL == device, -1);
430 retv_if(NULL == device->device_id, -1);
431 retv_if(NULL == dev_id, -1);
434 return g_strcmp0(device->device_id, dev_id);
437 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
440 const uam_db_tech_info_t *tech = data;
441 const int *type = user_data;
443 retv_if(NULL == tech, -1);
444 retv_if(NULL == type, -1);
447 return ((*type == tech->tech_type) ? 0 : 1);
450 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
455 for (l = devices; NULL != l; l = g_slist_next(l)) {
456 uam_db_device_info_t *dev = l->data;
462 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
463 uam_db_tech_info_t *tech = l1->data;
469 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
470 uam_db_address_info_t *addr = l2->data;
475 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
476 UAM_ADDR_TYPE_BT == addr->addr_type ||
477 UAM_ADDR_TYPE_P2P == addr->addr_type ||
478 UAM_ADDR_TYPE_WIFI == addr->addr_type)
479 if (!strcasecmp(addr->address, mac)) {
480 UAM_DBG("Device found Mac: %s, type: %d",
481 addr->address, addr->addr_type);
492 static int __get_uam_db_dev_list_to_uam_dev_list(
493 GSList *db_dev_list, uam_device_info_s **device_list, int *count)
498 int ret = UAM_ERROR_NONE;
501 /* Calculate num devices first */
502 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
503 uam_db_device_info_t *db_info = l->data;
506 if (!db_info || !db_info->device_id)
509 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
510 uam_db_tech_info_t *tech = l1->data;
512 if (!tech || !tech->addresses)
518 UAM_INFO("Count = %d", *count);
520 *device_list = g_new0(uam_device_info_s, *count);
523 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
524 uam_db_device_info_t *db_info = l->data;
527 if (!db_info || !db_info->device_id)
530 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
531 uam_db_tech_info_t *tech = l1->data;
533 if (!tech || !tech->addresses)
536 /* Copy tech info to device info */
537 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
538 if (UAM_ERROR_NONE != ret) {
539 UAM_ERR("__copy_tech_info_to_device_info failed");
546 UAM_INFO("Count = %d, indx = %d", *count, indx);
551 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
552 const char *name, const char *svc_name, uam_pm_detection_mode_e mode)
557 retv_if(NULL == name, NULL);
558 retv_if(NULL == monitor_list, NULL);
560 for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
561 uam_monitor_info_t *monitor = l->data;
563 if (!monitor || !monitor->name ||
564 !monitor->service || !monitor->service->name)
567 if ((mode == monitor->mode) &&
568 (0 == g_strcmp0(monitor->name, name)) &&
569 (0 == g_strcmp0(monitor->service->name, svc_name))) {
570 UAM_DBG("Monitoring application found in list");
579 unsigned int _uam_core_get_active_sensors(int detection_mode)
582 unsigned int sensors = 0;
585 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
586 (UAM_DETECT_ABSENCE != detection_mode), 0);
588 for (l = monitors; NULL != l; l = g_slist_next(l)) {
589 uam_monitor_info_t *monitor = l->data;
591 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
594 sensors |= monitor->sensors;
601 unsigned int _uam_core_get_env_sensors()
604 unsigned int sensors = 0;
606 sensors |= UAM_SENSOR_BITMASK_MOTION;
607 sensors |= UAM_SENSOR_BITMASK_LIGHT;
613 unsigned int _uam_core_get_active_env_sensors(int detection_mode)
616 unsigned int sensors = 0;
619 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
620 (UAM_DETECT_ABSENCE != detection_mode), 0);
622 for (l = monitors; NULL != l; l = g_slist_next(l)) {
623 uam_monitor_info_t *monitor = l->data;
625 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
628 sensors |= monitor->sensors & _uam_core_get_env_sensors();
635 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
639 GSList *svc_list = NULL;
641 retv_if(NULL == db_svc_list, NULL);
644 * Iterate over the db_svc_list and add each service to the global
645 * service list "services" if its not already inserted. Also append this
646 * uam_db_service_info_t to svc_list.
648 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
649 db_service_info_t *db_svc = l->data;
650 uam_db_service_info_t *service;
656 l1 = g_slist_find_custom(services,
657 db_svc->service_name, __compare_svc_name);
659 service = g_new0(uam_db_service_info_t, 1);
660 service->name = g_strdup(db_svc->service_name);
661 service->cycle = db_svc->cycle;
662 services = g_slist_append(services, service);
666 svc_list = g_slist_append(svc_list, service);
673 static void __uam_copy_db_payload_info(uam_ble_payload_s *dst_payload,
674 uam_db_payload_info_t *src_payload)
677 dst_payload->primary_key = src_payload->primary_key;
678 dst_payload->device_icon = src_payload->device_icon;
679 dst_payload->secondary_key = src_payload->secondary_key;
680 if (src_payload->device_uid)
681 memcpy(dst_payload->device_uid,
682 src_payload->device_uid, UAM_BLE_PAYLOAD_DEVICE_UID_LEN);
683 if (src_payload->bt_mac)
684 memcpy(dst_payload->bt_mac,
685 src_payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
689 static void __uam_copy_uam_payload_info(
690 uam_db_payload_info_t *dst_payload, uam_ble_payload_s *src_payload)
693 dst_payload->primary_key = src_payload->primary_key;
694 dst_payload->device_icon = src_payload->device_icon;
695 dst_payload->secondary_key = src_payload->secondary_key;
696 dst_payload->device_uid = g_memdup(&(src_payload->device_uid),
697 UAM_BLE_PAYLOAD_DEVICE_UID_LEN);
698 dst_payload->bt_mac = g_memdup(&(src_payload->bt_mac),
699 UAM_BT_MAC_ADDRESS_STRING_LEN);
703 static GSList *_uam_core_find_svc_dev_list(uam_device_info_s *dev_info)
706 uam_svc_dev_info_t *svc_dev = NULL;
708 GSList *svc_dev_list = NULL;
710 retv_if(NULL == dev_info, NULL);
713 * Iterate over the svc_devs and find each service device information
715 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
718 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
721 if ((0 == g_strcmp0(svc_dev->device_id, dev_info->device_id)) &&
722 (svc_dev->tech_type == dev_info->type)) {
723 svc_dev_list = g_slist_append(svc_dev_list, svc_dev);
724 UAM_DBG("Service found for device in list");
732 static void __uam_core_add_dev_to_list(
733 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
734 int presence_state, unsigned long long last_seen, GSList *svc_list,
735 GSList *svc_dev_list)
738 uam_db_tech_info_t *tech;
739 uam_db_device_info_t *device;
742 ret_if(NULL == dev_info);
743 ret_if(NULL == user);
745 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
748 ret_if(user != device->user);
749 ret_if(device->supported_techs & dev_info->type);
751 if (device->os != dev_info->operating_system) {
752 UAM_INFO("device->os: %d, dev_info->operating_system: %d",
753 device->os, dev_info->operating_system);
754 /* Update device OS type */
755 if (UAM_OS_TYPE_INVALID == device->os || UAM_OS_TYPE_UNDEFINED == device->os)
756 device->os = dev_info->operating_system;
758 UAM_WARN("Strange - OS types did not match, need to check");
761 device = g_new0(uam_db_device_info_t, 1);
762 device->device_id = g_strdup(dev_info->device_id);
763 device->os = dev_info->operating_system;
764 device->discriminant = dev_info->discriminant;
767 /* Add device to global device list */
768 devices = g_slist_append(devices, device);
770 /* Add same device to user's device list */
771 user->devices = g_slist_append(user->devices, device);
774 tech = g_new0(uam_db_tech_info_t, 1);
775 tech->tech_type = dev_info->type;
776 tech->presence_state = presence_state;
777 tech->last_seen = last_seen;
778 tech->device = device;
779 tech->discriminant = dev_info->discriminant;
781 tech->svc_list = svc_list;
782 g_slist_foreach(tech->svc_list, __print_service, tech);
783 for (l = svc_list; NULL != l; l = g_slist_next(l)) {
784 uam_db_service_info_t *service = l->data;
789 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
791 tech->svc_dev_list = svc_dev_list;
792 g_slist_foreach(tech->svc_dev_list, __print_svc_dev, NULL);
794 /* Add tech info to tech list */
795 device->tech_list = g_slist_append(device->tech_list, tech);
796 device->supported_techs |= tech->tech_type;
797 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
799 if (0 < strlen(dev_info->mac)) {
800 uam_db_address_info_t *addr;
802 addr = g_new0(uam_db_address_info_t, 1);
803 addr->address = g_strdup(dev_info->mac);
805 switch (dev_info->type) {
806 case UAM_TECH_TYPE_BLE:
807 addr->addr_type = UAM_ADDR_TYPE_BLE;
809 case UAM_TECH_TYPE_BT:
810 addr->addr_type = UAM_ADDR_TYPE_BT;
812 case UAM_TECH_TYPE_P2P:
813 addr->addr_type = UAM_ADDR_TYPE_P2P;
815 case UAM_TECH_TYPE_WIFI:
816 addr->addr_type = UAM_ADDR_TYPE_WIFI;
819 UAM_ERR("Unknown tech type: %d", dev_info->type);
820 g_free(addr->address);
826 UAM_DBG("MAC address %s added for tech type: %d",
827 dev_info->mac, dev_info->type);
828 tech->addresses = g_slist_append(tech->addresses, addr);
832 if (0 < strlen(dev_info->ipv4_addr)) {
833 uam_db_address_info_t *addr;
835 if (UAM_TECH_TYPE_BLE == dev_info->type ||
836 UAM_TECH_TYPE_BT == dev_info->type)
837 UAM_WARN("IPv4 address %s added for tech type: %d",
838 dev_info->ipv4_addr, dev_info->type);
840 UAM_DBG("IPv4 address %s added for tech type: %d",
841 dev_info->ipv4_addr, dev_info->type);
843 addr = g_new0(uam_db_address_info_t, 1);
844 addr->addr_type = UAM_ADDR_TYPE_IPv4;
845 addr->address = g_strdup(dev_info->ipv4_addr);
847 tech->addresses = g_slist_append(tech->addresses, addr);
853 int _uam_core_add_user(int *user_id, const char *account, const char *name)
857 uam_db_user_info_t *user;
858 int ret = UAM_ERROR_NONE;
860 l = g_slist_find_custom(users, account, __compare_user_account);
861 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
863 user = g_new0(uam_db_user_info_t, 1);
865 /* Add user to database */
866 ret = _uam_db_insert_user_info(&(user->user_id), name, account);
867 if (UAM_ERROR_NONE != ret) {
868 UAM_ERR("_uam_db_insert_user_info failed [%d]", ret);
873 user->name = g_strdup(name);
874 user->account = g_strdup(account);
875 user->devices = NULL;
877 *user_id = user->user_id;
879 users = g_slist_append(users, user);
881 /* Send user added event to application */
882 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
883 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
884 UAM_ERROR_NONE, user->account, user->name)))
885 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
888 return UAM_ERROR_NONE;
891 int _uam_core_remove_user(const char *account)
895 uam_db_user_info_t *user;
896 int ret = UAM_ERROR_NONE;
898 l = g_slist_find_custom(users, account, __compare_user_account);
899 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
902 /* Remove user from database */
903 ret = _uam_db_delete_by_user_id(user->user_id);
904 if (UAM_ERROR_NONE != ret) {
905 UAM_ERR("_uam_db_delete_by_user_id failed");
909 users = g_slist_remove(users, user);
911 /* Send user removed event to application */
912 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
913 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
914 UAM_ERROR_NONE, user->account, user->name)))
915 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
917 ret = __free_uam_db_user_info((gpointer)user);
918 if (UAM_ERROR_NONE != ret)
919 UAM_WARN("_free_uam_db_user_info failed");
922 return UAM_ERROR_NONE;
925 int _uam_core_update_user(uam_user_info_s *user)
929 uam_db_user_info_t *user_info;
931 retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
933 /* Retrieve user from list */
934 l = g_slist_find_custom(users, user->account, __compare_user_account);
935 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
938 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
940 /* Update user to database */
941 if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
942 UAM_ERR("_uam_db_update_user_info failed");
943 return UAM_ERROR_DB_FAILED;
947 return UAM_ERROR_NONE;
950 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
955 uam_db_device_info_t *device;
956 uam_db_user_info_t *user;
958 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
959 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
961 l = g_slist_find_custom(users, account, __compare_user_account);
962 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
965 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
968 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
969 retv_if((dev_info->type & device->supported_techs),
970 UAM_ERROR_ALREADY_REGISTERED);
973 UAM_INFO("[%d]", user->user_id);
975 ret = _uam_pm_register_device(user->user_id, dev_info);
976 if (UAM_ERROR_NONE != ret) {
977 UAM_ERR("_uam_pm_register_device failed with %s",
978 _uam_manager_error_to_str(ret));
983 return UAM_ERROR_NONE;
986 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
989 uam_db_device_info_t *device;
992 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
993 retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
996 l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
1001 if (!(device->supported_techs & dev->type))
1004 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1005 uam_db_tech_info_t *tech = l->data;
1011 if (dev->type != tech->tech_type)
1014 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
1015 uam_db_address_info_t *addr = l1->data;
1020 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
1021 UAM_ADDR_TYPE_BT == addr->addr_type ||
1022 UAM_ADDR_TYPE_P2P == addr->addr_type ||
1023 UAM_ADDR_TYPE_WIFI == addr->addr_type)
1024 if (!strcasecmp(addr->address, dev->mac)) {
1033 UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
1035 return UAM_ERROR_NONE;
1038 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
1039 const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
1045 ret = _uam_db_get_device_services_count(dev_info->device_id,
1046 dev_info->type, dev_info->mac, &count);
1047 if (UAM_ERROR_NONE != ret) {
1048 UAM_ERR("_uam_db_get_device_services_count failed with %s",
1049 _uam_manager_error_to_str(ret));
1054 ret = UAM_ERROR_RESOURCE_BUSY;
1055 UAM_WARN("other service uses this device ref:[%d]", count);
1059 ret = _uam_pm_unregister_device(user_id, dev_info);
1060 if (UAM_ERROR_NONE != ret) {
1061 UAM_ERR("_uam_pm_unregister_device failed with %s",
1062 _uam_manager_error_to_str(ret));
1066 /* Send device removed event to application */
1067 __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
1069 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1070 /* Remove device from database */
1071 ret = _uam_device_db_delete_device_info(
1072 dev_info->device_id, dev_info->type, dev_info->mac);
1073 if (UAM_ERROR_NONE != ret) {
1074 UAM_ERR("_uam_device_db_delete_device_info failed");
1075 __uam_db_end_transaction(0);
1079 /* Remove device from service */
1080 for (l = tech->svc_list; l; l = g_slist_next(l)) {
1081 uam_db_service_info_t *svc = l->data;
1083 if (!svc || !svc->name)
1085 ret = _uam_core_service_remove_device(svc->name,
1086 dev_info->device_id, dev_info->type);
1087 if (UAM_ERROR_NONE != ret)
1088 UAM_ERR("_uam_device_db_delete_device_info failed");
1090 __uam_db_end_transaction(1);
1092 /* Remove tech info from device's tech list */
1093 device->tech_list = g_slist_remove(device->tech_list, tech);
1094 device->supported_techs &= ~(tech->tech_type);
1095 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1096 __free_dev_tech_info(tech);
1098 if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1099 /* Remove device from global device list */
1100 devices = g_slist_remove(devices, device);
1102 /* Remove device from user's device list */
1103 device->user->devices = g_slist_remove(device->user->devices, device);
1105 __free_user_device(device);
1108 /* Set/update registered device list to plugins */
1109 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1110 UAM_ERR("_uam_pm_set_registered_devices failed");
1112 /* Set/update registered device list to cloud plugin */
1113 _uam_cloud_update_registered_devices();
1116 return UAM_ERROR_NONE;
1119 int _uam_core_remove_device(const char *account,
1120 const uam_device_info_s *dev_info)
1125 uam_db_tech_info_t *tech;
1126 uam_db_device_info_t *device;
1127 uam_db_user_info_t *user;
1129 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1130 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1132 /* Retrieve user from list */
1133 l = g_slist_find_custom(users, account, __compare_user_account);
1134 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1137 /* Retrieve device from list */
1138 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1139 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1141 retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1142 retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1144 /* Retrieve tech info from list */
1145 l = g_slist_find_custom(device->tech_list,
1146 &(dev_info->type), __compare_tech_type);
1147 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1150 ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1156 int _uam_core_remove_device_by_device_id(const char *device_id,
1162 uam_device_info_s dev_info;
1163 uam_db_tech_info_t *tech;
1164 uam_db_device_info_t *device;
1166 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1167 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1168 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1170 /* Retrieve device from list */
1171 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1172 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1174 retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1176 /* Retrieve tech info from list */
1177 l = g_slist_find_custom(device->tech_list,
1178 &tech_type, __compare_tech_type);
1179 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1183 ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1184 retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1186 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1192 int _uam_core_remove_device_by_mac(const char *mac)
1195 uam_db_tech_info_t *tech;
1196 uam_db_device_info_t *device;
1197 uam_device_info_s dev_info;
1200 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1202 tech = __get_tech_info_by_mac(mac);
1203 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1204 device = tech->device;
1206 ret = __copy_tech_info_to_device_info(tech, &dev_info);
1207 if (UAM_ERROR_NONE != ret) {
1208 UAM_ERR("__copy_tech_info_to_device_info failed");
1212 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1218 int _uam_core_update_device(const uam_device_info_s *a_device)
1222 int ret = UAM_ERROR_NONE;
1223 GSList *l, *l1, *l2;
1225 uam_device_info_s temp;
1226 uam_db_user_info_t *user = NULL;
1227 uam_db_device_info_t *device = NULL;
1228 uam_db_tech_info_t *tech = NULL;
1230 /* Find all tech-devices in users' devices */
1231 for (l = users; NULL != l; l = g_slist_next(l)) {
1234 l1 = g_slist_find_custom(user->devices,
1235 a_device->device_id, __compare_device_id);
1237 UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1238 user->user_id, a_device->device_id);
1243 if (!(device->supported_techs & a_device->type)) {
1244 UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1245 device->device_id, a_device->type);
1249 /* Update discriminant for devices */
1250 device->discriminant = a_device->discriminant;
1251 device->os = a_device->operating_system;
1253 l2 = g_slist_find_custom(device->tech_list,
1254 &(a_device->type), __compare_tech_type);
1256 UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1262 UAM_DBG("Device tech is NULL");
1266 /* Update discriminant for device-tech */
1267 tech->discriminant = a_device->discriminant;
1269 /* Update device's updated information to database */
1270 ret = __copy_tech_info_to_device_info(tech, &temp);
1271 if (UAM_ERROR_NONE != ret) {
1272 UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1276 ret = _uam_device_db_update_device(temp.device_id, temp.type,
1277 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant);
1278 if (UAM_ERROR_NONE != ret) {
1279 UAM_ERR("_uam_device_db_update_device failed [%d]", ret);
1284 /* Set/update registered device list to plugins */
1285 ret = _uam_pm_set_registered_devices(devices);
1286 if (UAM_ERROR_NONE != ret) {
1287 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1291 /* Set/update registered device list to cloud plugin */
1292 _uam_cloud_update_registered_devices();
1298 int _uam_core_get_default_user(uam_user_info_s *user_info)
1304 uam_db_user_info_t *user;
1306 retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1308 ret = _uam_core_add_user(&user_id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1309 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1310 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1314 l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1315 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1318 memset(user_info, 0x00, sizeof(uam_user_info_s));
1319 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1320 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1323 return UAM_ERROR_NONE;
1326 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1332 size = g_slist_length(users);
1333 *user_list = g_new0(uam_user_info_s, size);
1336 /* fetch users list from DB */
1337 for (l = users; l; l = g_slist_next(l)) {
1338 uam_db_user_info_t *db_info = l->data;
1340 if (!db_info || !db_info->account)
1343 g_strlcpy((*user_list)[*count].account,
1344 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1346 g_strlcpy((*user_list)[*count].name,
1347 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1352 UAM_INFO("Count: %d", *count);
1354 return UAM_ERROR_NONE;
1357 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1360 uam_db_user_info_t *db_info;
1363 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1365 l = g_slist_find_custom(users, account, __compare_user_account);
1366 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1369 g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1371 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1375 return UAM_ERROR_NONE;
1378 int _uam_core_get_devcie_by_device_id(
1379 const char *device_id, int tech_type, uam_device_info_s *device)
1382 uam_db_device_info_t *db_info;
1386 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1387 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1388 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1390 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1391 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1393 retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1395 memset(device, 0x00, sizeof(uam_device_info_s));
1397 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1398 uam_db_tech_info_t *tech = l1->data;
1401 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1404 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1405 uam_db_address_info_t *addr = l2->data;
1410 __uam_core_copy_addr(device, addr);
1413 device->operating_system = db_info->os;
1414 g_strlcpy(device->device_id, db_info->device_id,
1415 UAM_DEVICE_ID_MAX_STRING_LEN);
1416 device->type = tech->tech_type;
1417 device->discriminant = tech->discriminant;
1420 retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1423 return UAM_ERROR_NONE;
1426 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1430 uam_db_tech_info_t *tech;
1432 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1434 tech = __get_tech_info_by_mac(mac);
1435 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1437 ret = __copy_tech_info_to_device_info(tech, device);
1438 if (UAM_ERROR_NONE != ret) {
1439 UAM_ERR("__copy_tech_info_to_device_info failed");
1447 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1450 uam_db_device_info_t *dev;
1453 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1455 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1456 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1459 g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1460 if (dev->user->name)
1461 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1464 return UAM_ERROR_NONE;
1467 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1470 uam_db_tech_info_t *tech;
1472 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1474 tech = __get_tech_info_by_mac(mac);
1475 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1477 g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1478 if (tech->device->user->name)
1479 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1482 return UAM_ERROR_NONE;
1485 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1488 int ret = UAM_ERROR_NONE;
1490 ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1496 int _uam_core_get_user_devices(const char *account,
1497 int *count, uam_device_info_s **device_list)
1500 uam_db_user_info_t *user;
1502 int ret = UAM_ERROR_NONE;
1504 l = g_slist_find_custom(users, account, __compare_user_account);
1505 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1508 ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1514 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1518 *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1521 return UAM_ERROR_NONE;
1524 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1529 is_ready = _uam_pm_is_sensor_ready(sensor);
1530 UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1536 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
1537 uam_tech_type_e tech_type, const char *svc_name)
1540 uam_svc_dev_info_t *svc_dev = NULL;
1543 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1546 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1549 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1550 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1551 (svc_dev->tech_type == tech_type)) {
1552 UAM_DBG("Service device found in list");
1561 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1562 const char *svc_name, gboolean discriminant, unsigned long long last_seen,
1563 uam_ble_payload_s *payload_info)
1566 uam_svc_dev_info_t *svc = NULL;
1568 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1569 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1570 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1571 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1573 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1575 svc = g_new0(uam_svc_dev_info_t, 1);
1576 svc->device_id = g_strdup(device_id);
1577 svc->tech_type = tech_type;
1578 svc->service = g_strdup(svc_name);
1579 svc->payload = g_new0(uam_db_payload_info_t, 1);
1580 __uam_copy_uam_payload_info(svc->payload, payload_info);
1581 svc_devs = g_slist_append(svc_devs, svc);
1584 if (discriminant >= 0)
1585 svc->discriminant = discriminant;
1587 svc->last_seen = last_seen;
1589 __uam_copy_uam_payload_info(svc->payload, payload_info);
1591 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] " \
1592 "last_seen [%llu] payload primary key [%d]",
1593 svc->service, svc->device_id, svc->tech_type, svc->discriminant,
1594 svc->last_seen, svc->payload->primary_key);
1597 return UAM_ERROR_NONE;
1600 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
1601 uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant)
1604 uam_svc_dev_info_t *svc = NULL;
1606 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1607 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1608 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1609 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1611 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1613 svc = g_new0(uam_svc_dev_info_t, 1);
1614 svc->device_id = g_strdup(device_id);
1615 svc->tech_type = tech_type;
1616 svc->service = g_strdup(svc_name);
1617 svc_devs = g_slist_append(svc_devs, svc);
1620 svc->discriminant = discriminant;
1622 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]]",
1623 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1626 return UAM_ERROR_NONE;
1629 int _uam_core_service_add_user(const char *svc_name, const char *account)
1633 int ret = UAM_ERROR_NONE;
1634 uam_db_user_info_t *user;
1635 uam_db_service_info_t *service;
1637 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1638 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1640 /* Retrieve user from list */
1641 l = g_slist_find_custom(users, account, __compare_user_account);
1642 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1645 /* Retrieve service from list */
1646 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1647 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1650 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1651 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1652 uam_db_device_info_t *device = l->data;
1658 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1659 uam_db_tech_info_t *tech = l1->data;
1666 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1667 __compare_svc_name);
1671 __add_service_to_dev_tech_mapping(tech, service);
1673 mac = __get_mac_addr(tech);
1674 /* Insert device service info to db */
1675 ret = _uam_db_insert_device_service_info(device->device_id,
1676 tech->tech_type, mac, service->name, service->cycle,
1677 device->discriminant, 0);
1678 if (UAM_ERROR_NONE != ret) {
1679 UAM_WARN("Device service addition to persistent DB failed");
1680 __uam_db_end_transaction(0);
1683 ret = _uam_core_update_svc_dev_info(device->device_id, tech->tech_type,
1684 service->name, device->discriminant, 0, NULL);
1685 if (UAM_ERROR_NONE != ret) {
1686 UAM_WARN("Device service addition to service device mapping failed");
1687 __uam_db_end_transaction(0);
1693 __uam_db_end_transaction(1);
1699 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1703 uam_db_user_info_t *user;
1706 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1707 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1709 /* Retrieve user from list */
1710 l = g_slist_find_custom(users, account, __compare_user_account);
1711 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1714 /* Retrieve service from list */
1715 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1716 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1718 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1719 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1720 uam_db_device_info_t *device = l->data;
1726 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1727 uam_db_tech_info_t *tech = l1->data;
1734 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1735 __compare_svc_name);
1739 UAM_DBG("Service %s found, remove it from list", svc_name);
1740 __remove_service_to_dev_tech_mapping(
1741 tech, (uam_db_service_info_t *)l2->data);
1743 mac = __get_mac_addr(tech);
1744 /* Remove service-device from DB */
1745 ret = _uam_db_delete_device_service_info(device->device_id,
1746 tech->tech_type, mac, svc_name);
1747 if (UAM_ERROR_NONE != ret) {
1748 UAM_WARN("Device service removal from persistent DB failed");
1749 __uam_db_end_transaction(0);
1754 __uam_db_end_transaction(1);
1757 return UAM_ERROR_NONE;
1760 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1763 uam_db_device_info_t *device;
1766 retv_if(NULL == device_id, NULL);
1767 retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1768 retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1770 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1772 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1777 if (!device || !(device->supported_techs & tech_type)) {
1778 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1779 tech_type, device_id);
1783 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1784 uam_db_tech_info_t *tech = l->data;
1789 if (tech_type == tech->tech_type) {
1790 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1791 device_id, tech_type);
1796 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1801 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
1807 int ret = UAM_ERROR_NONE;
1808 uam_db_tech_info_t *tech_info;
1809 uam_db_service_info_t *service;
1811 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1812 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1813 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1814 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1816 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1817 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1819 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1820 retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1822 /* Retrieve service from list */
1823 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1824 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1827 __add_service_to_dev_tech_mapping(tech_info, service);
1829 mac = __get_mac_addr(tech_info);
1830 /* Insert device service info to db */
1831 ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
1832 service->name, service->cycle, tech_info->discriminant, 0);
1833 if (UAM_ERROR_NONE != ret) {
1834 UAM_WARN("Device service addition to persistent DB failed");
1837 ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
1838 tech_info->discriminant, 0, NULL);
1839 if (UAM_ERROR_NONE != ret) {
1840 UAM_WARN("Device service addition to svc dev mapping failed");
1845 return UAM_ERROR_NONE;
1848 int _uam_core_service_remove_device(const char *svc_name,
1849 const char *device_id, int tech_type)
1854 uam_db_tech_info_t *tech_info;
1855 int ret = UAM_ERROR_NONE;
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 /* Retrieve service from list */
1863 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1864 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1866 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1867 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1869 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1870 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1872 __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1874 mac = __get_mac_addr(tech_info);
1875 /* Remove service-device from DB */
1876 ret = _uam_db_delete_device_service_info(
1877 device_id, tech_type, mac, svc_name);
1878 if (UAM_ERROR_NONE != ret) {
1879 UAM_ERR("Device service removal from persistent DB failed");
1884 return UAM_ERROR_NONE;
1887 int _uam_core_service_set_device_discriminant(const char *svc_name,
1888 const char *device_id, int tech_type, gboolean discriminant)
1892 int ret = UAM_ERROR_NONE;
1894 uam_db_tech_info_t *tech_info;
1895 uam_db_service_info_t *service;
1897 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1898 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1899 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1900 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1902 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1903 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1905 /* Retrieve service from list */
1906 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1907 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1910 mac = __get_mac_addr(tech_info);
1911 /* Insert device service info to db */
1912 ret = _uam_db_update_device_service_discriminant(device_id,
1913 tech_type, mac, service->name, discriminant);
1914 if (UAM_ERROR_NONE != ret) {
1915 UAM_WARN("Device service discriminant update to persistent DB failed");
1918 ret = _uam_core_update_svc_dev_info_discriminant(device_id,
1919 tech_type, service->name, discriminant);
1920 if (UAM_ERROR_NONE != ret) {
1921 UAM_WARN("Device service discriminant mapping update failed");
1926 return UAM_ERROR_NONE;
1929 int _uam_core_service_get_device_discriminant(const char *svc_name,
1930 const char *device_id, int tech_type, gboolean *discriminant)
1933 uam_svc_dev_info_t *svc_dev;
1935 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1936 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1937 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1938 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1940 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1941 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1942 *discriminant = (gboolean)svc_dev->discriminant;
1945 return UAM_ERROR_NONE;
1948 int _uam_core_service_get_device_last_seen(const char *svc_name,
1949 const char *device_id, int tech_type, unsigned long long *last_seen)
1952 uam_svc_dev_info_t *svc_dev;
1954 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1955 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1956 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1957 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1959 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1960 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1961 *last_seen = svc_dev->last_seen;
1964 return UAM_ERROR_NONE;
1967 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1971 uam_db_service_info_t *service;
1972 unsigned int elapsed_time;
1974 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1975 retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1976 retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1978 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1979 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1982 elapsed_time = service->cycle - service->remaining_time;
1983 service->cycle = new_cycle;
1984 if (new_cycle < elapsed_time)
1985 service->remaining_time = 0;
1987 service->remaining_time = new_cycle - elapsed_time;
1989 /* Update service detection cycle in DB */
1990 if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1991 UAM_WARN("Service cycle updation to persistent DB failed");
1994 return UAM_ERROR_NONE;
1997 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
2001 uam_db_service_info_t *service;
2003 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2004 retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
2006 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2007 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2009 *cycle = service->cycle;
2012 return UAM_ERROR_NONE;
2015 int _uam_core_set_detection_threshold(unsigned int sensor,
2016 int presence_threshold, int absence_threshold)
2021 ret = _uam_pm_set_detection_threshold(sensor,
2022 presence_threshold, absence_threshold);
2023 if (UAM_ERROR_NONE != ret) {
2024 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
2025 _uam_manager_error_to_str(ret));
2030 return UAM_ERROR_NONE;
2033 static gboolean __start_detection(gpointer data)
2037 uam_db_service_info_t *service = NULL;
2038 unsigned int sensors;
2039 gboolean start_detection = FALSE;
2041 unsigned int presence_env_sensors;
2042 unsigned int absence_env_sensors;
2044 presence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE);
2045 UAM_DBG("Presence Envionmental sensors: 0x%8.8X", presence_env_sensors);
2047 absence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
2048 UAM_DBG("Absence Envionmental sensors: 0x%8.8X", absence_env_sensors);
2050 if (0 != presence_env_sensors) {
2051 /* Stop PRESENCE detection on active envionmental sensors*/
2052 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2053 if (UAM_ERROR_NONE != ret)
2054 UAM_ERR("Failed with error: %s (0x%4.4X)",
2055 _uam_manager_error_to_str(ret), ret);
2057 if (0 != absence_env_sensors) {
2058 /* Stop ABSENCE detection on envionmental sensors*/
2059 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2060 if (UAM_ERROR_NONE != ret)
2061 UAM_ERR("Failed with error: %s (0x%4.4X)",
2062 _uam_manager_error_to_str(ret), ret);
2065 for (l = services; NULL != l; l = g_slist_next(l)) {
2067 if (!service || !service->monitors)
2070 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
2071 UAM_DBG("service->remaining_time: %d", service->remaining_time);
2072 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
2073 if (0 >= service->remaining_time) {
2074 start_detection = TRUE;
2075 service->remaining_time = service->cycle;
2079 if (!start_detection)
2082 /* Get sensors on which PRESENCE detection to be started */
2083 sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
2084 UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
2086 /* Remove env sensors from active sensors */
2087 sensors &= ~presence_env_sensors;
2088 UAM_DBG("Presence Connectivity sensors: 0x%8.8X", sensors);
2091 /* Start PRESENCE detection */
2092 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
2093 if (UAM_ERROR_NONE != ret)
2094 UAM_ERR("Failed with error: %s (0x%4.4X)",
2095 _uam_manager_error_to_str(ret), ret);
2098 /* Get sensors on which ABSENCE detection to be started */
2099 sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2100 UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
2102 /* Remove env sensors from active sensors */
2103 sensors &= ~absence_env_sensors;
2104 UAM_DBG("ABSENCE Connectivity sensors: 0x%8.8X", sensors);
2107 /* Start ABSENCE detection */
2108 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
2109 if (UAM_ERROR_NONE != ret)
2110 UAM_ERR("Failed with error: %s (0x%4.4X)",
2111 _uam_manager_error_to_str(ret), ret);
2115 if (0 != presence_env_sensors) {
2116 /* Always Start PRESENCE detection on active envionmental sensors*/
2117 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2118 if (UAM_ERROR_NONE != ret)
2119 UAM_ERR("Failed with error: %s (0x%4.4X)",
2120 _uam_manager_error_to_str(ret), ret);
2122 if (0 != absence_env_sensors) {
2123 /* Always Start ABSENCE detection on active envionmental sensors*/
2124 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2125 if (UAM_ERROR_NONE != ret)
2126 UAM_ERR("Failed with error: %s (0x%4.4X)",
2127 _uam_manager_error_to_str(ret), ret);
2134 static int __uam_core_start_detection(int detection_type,
2135 const char *svc_name, char *sender, unsigned int sensors)
2138 uam_monitor_info_t *monitor;
2139 uam_db_service_info_t *service;
2140 gboolean is_monitor_added = TRUE;
2143 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2144 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2146 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2148 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
2149 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
2150 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2151 services = g_slist_append(services, default_svc);
2155 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2156 retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2159 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2161 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2163 monitor->name = g_strdup(sender);
2164 monitor->mode = detection_type;
2165 monitor->service = service;
2166 is_monitor_added = FALSE;
2168 UAM_ERR("Memory allocation error");
2169 return UAM_ERROR_OUT_OF_MEMORY;
2173 UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2175 monitor->sensors |= sensors;
2176 if (!is_monitor_added) {
2177 monitors = g_slist_append(monitors, monitor);
2178 service->monitors = g_slist_append(service->monitors, monitor);
2181 /* Start detection */
2182 if (0 == detection_timer) {
2183 __start_detection(NULL);
2184 UAM_INFO("Monitor started detection, start timer");
2185 detection_timer = g_timeout_add_seconds(
2186 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2190 return UAM_ERROR_NONE;
2193 static int __uam_core_stop_detection(int detection_type,
2194 const char *svc_name, char *sender, unsigned int sensors)
2197 int ret = UAM_ERROR_NONE;
2198 unsigned int remaining_sensors;
2199 unsigned int active_sensors;
2200 uam_monitor_info_t *monitor;
2201 uam_db_service_info_t *service;
2203 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2204 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2206 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2207 retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2208 service = monitor->service;
2209 retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2211 /* Find sensors which are already monitoring */
2212 active_sensors = _uam_core_get_active_sensors(detection_type);
2213 UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2214 sensors, active_sensors);
2216 /* Update monitor info for application */
2217 monitor->sensors &= ~sensors;
2218 if (0 == monitor->sensors) {
2220 * App requested to stop monitoring for all of its active sensors,
2221 * remove its monitor info from list.
2223 monitors = g_slist_remove(monitors, monitor);
2224 if ((NULL == monitors) && (0 != detection_timer)) {
2225 UAM_INFO("All monitors stopped detection, stop timer");
2226 g_source_remove(detection_timer);
2227 detection_timer = 0;
2230 service->monitors = g_slist_remove(service->monitors, monitor);
2231 if (NULL == service->monitors)
2232 service->remaining_time = 0;
2234 g_free(monitor->name);
2238 /* Find sensors which are already monitoring */
2239 remaining_sensors = _uam_core_get_active_sensors(detection_type);
2240 UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2242 if (active_sensors == remaining_sensors) {
2243 UAM_INFO("NO need to stop monitoring");
2244 return UAM_ERROR_NONE;
2247 /* Stop monitoring only for sensors which aren't required anymore */
2248 sensors = (active_sensors & ~remaining_sensors);
2249 ret = _uam_pm_stop_detection(detection_type, sensors);
2250 if (UAM_ERROR_NONE != ret)
2251 UAM_ERR("Failed with error: %s (0x%4.4X)",
2252 _uam_manager_error_to_str(ret), ret);
2258 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2263 ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2269 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2274 ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2280 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2285 ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2291 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2296 ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2302 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2307 UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2308 ret = _uam_pm_set_low_power_mode(bitmask, mode);
2309 if (UAM_ERROR_NONE != ret) {
2310 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2311 bitmask, _uam_manager_error_to_str(ret));
2316 return UAM_ERROR_NONE;
2319 int _uam_core_get_detection_window(unsigned int *window)
2323 retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2325 *window = detection_window;
2328 return UAM_ERROR_NONE;
2331 int _uam_core_set_detection_window(unsigned int window)
2335 retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2336 retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2337 retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2339 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2340 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2341 return UAM_ERROR_INTERNAL;
2344 detection_window = window;
2347 return UAM_ERROR_NONE;
2350 int _uam_core_init(void)
2355 GSList *db_svc_list;
2356 GSList *db_adv_list;
2357 GSList *db_svc_dev_list;
2358 GSList *db_payload_list;
2362 _uam_db_initialize();
2364 /* Reset detecton window to default */
2365 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2366 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2367 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2369 /* Fetch user list */
2370 db_users = _uam_db_get_all_users();
2372 UAM_INFO_C("No users in database");
2375 for (l = db_users; NULL != l; l = g_slist_next(l)) {
2376 db_user_info_t *info = l->data;
2377 uam_db_user_info_t *user;
2382 user = g_new0(uam_db_user_info_t, 1);
2383 user->user_id = info->user_id;
2384 user->name = g_strdup(info->name);
2385 user->account = g_strdup(info->account);
2386 user->devices = NULL;
2388 users = g_slist_prepend(users, user);
2392 /* Fetch service list */
2393 db_svc_list = _uam_service_db_get_all_services();
2395 UAM_INFO_C("No services in database");
2398 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2399 db_service_info_t *db_svc = l->data;
2400 uam_db_service_info_t *service;
2406 l1 = g_slist_find_custom(services,
2407 db_svc->service_name, __compare_svc_name);
2409 service = g_new0(uam_db_service_info_t, 1);
2410 service->name = g_strdup(db_svc->service_name);
2411 service->cycle = db_svc->cycle;
2412 service->presence_threshold = db_svc->presence_threshold;
2413 service->absence_threshold = db_svc->absence_threshold;
2414 services = g_slist_append(services, service);
2419 /* Fetch payload list */
2420 db_payload_list = _uam_db_get_all_payloads();
2421 if (!db_payload_list) {
2422 UAM_INFO_C("No device payload in database");
2424 for (l = db_payload_list; NULL != l; l = g_slist_next(l)) {
2425 db_payload_info_t *db_payload = l->data;
2426 uam_db_payload_info_t *payload = g_new0(uam_db_payload_info_t, 1);
2432 l1 = g_slist_find_custom(payloads, db_payload, __compare_db_payload);
2434 payload = g_new0(uam_db_payload_info_t, 1);
2435 __uam_copy_uam_payload_info(payload, &(db_payload->payload_info));
2436 payload->device_id = g_strdup(db_payload->device_id);
2437 payload->tech_type = db_payload->type;
2438 payloads = g_slist_append(payloads, payload);
2443 /* Fetch svc dev list */
2444 db_svc_dev_list = _uam_db_get_service_devices_info();
2445 if (!db_svc_dev_list) {
2446 UAM_INFO_C("No service devices in database");
2448 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2449 db_svc_dev_info_t *db_svc = l->data;
2451 _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
2452 db_svc->svc, db_svc->discriminant, db_svc->last_seen,
2453 &(db_svc->payload_info));
2457 /* Fetch device list */
2458 db_devices = _uam_device_db_get_all_devices();
2460 UAM_INFO_C("No Devices registered in database");
2463 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2464 db_device_info_t *db_info = l->data;
2465 uam_db_user_info_t *user;
2466 GSList *svc_list = NULL;
2467 GSList *svc_dev_list = NULL;
2473 l1 = g_slist_find_custom(users,
2474 &(db_info->user_id), __compare_user_id);
2476 UAM_ERR("Invalid user Id: %d", db_info->user_id);
2481 /* Fetch device services from DB */
2482 l1 = _uam_db_get_device_services(
2483 db_info->dev_info.device_id,
2484 db_info->dev_info.type,
2485 db_info->dev_info.mac);
2487 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2489 svc_dev_list = _uam_core_find_svc_dev_list(&(db_info->dev_info));
2490 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2491 db_info->presence_state, db_info->last_seen,
2492 svc_list, svc_dev_list);
2496 /* Fetch iBeacon adv list */
2497 db_adv_list = _uam_db_get_all_advs();
2499 UAM_INFO_C("No iBeacon adv in database");
2501 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2502 db_adv_info_t *db_adv = l->data;
2503 _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2507 g_slist_free_full(db_devices, g_free);
2508 g_slist_free_full(db_users, g_free);
2509 g_slist_free_full(db_svc_list, g_free);
2510 g_slist_free_full(db_adv_list, g_free);
2511 g_slist_free_full(db_svc_dev_list, g_free);
2512 g_slist_free_full(db_payload_list, g_free);
2515 /* Set/update registered device list to plugins */
2516 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2517 UAM_ERR("_uam_pm_set_registered_devices failed");
2519 /* Set/update registered device list to cloud plugin */
2520 _uam_cloud_update_registered_devices();
2524 return UAM_ERROR_NONE;
2527 void _uam_core_deinit(void)
2532 /* de-init database */
2533 _uam_db_deinitialize();
2535 /* Reset detecton window to default */
2536 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2538 /* Release allocated memory for devices */
2539 g_slist_free_full(devices, __free_user_device);
2542 /* Release allocated memory for users */
2543 for (l = users; NULL != l; l = g_slist_next(l)) {
2544 uam_db_user_info_t *user = l->data;
2550 g_free(user->account);
2554 g_slist_free(users);
2557 /* Release allocated memory for services */
2558 for (l = services; NULL != l; l = g_slist_next(l)) {
2559 uam_db_service_info_t *service = l->data;
2564 g_free(service->name);
2567 g_slist_free(services);
2570 /* Release allocated memory for service devices */
2571 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2572 uam_svc_dev_info_t *svc_dev = l->data;
2577 g_free(svc_dev->device_id);
2578 g_free(svc_dev->service);
2579 g_free(svc_dev->payload);
2582 g_slist_free(svc_devs);
2585 /* Release allocated memory for payloads */
2586 for (l = payloads; NULL != l; l = g_slist_next(l)) {
2587 uam_db_payload_info_t *payload = l->data;
2591 g_free(payload->device_uid);
2592 g_free(payload->bt_mac);
2595 g_slist_free(payloads);
2601 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2605 /* Send sensor state changed event over dbus */
2607 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2608 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2610 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2611 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2616 int _uam_core_handle_device_added(int status,
2617 int user_id, const uam_device_info_s *dev_info)
2622 int ret = UAM_ERROR_NONE;
2623 GSList *svc_list = NULL;
2624 GSList *svc_dev_list = NULL;
2625 uam_db_user_info_t *user = NULL;
2626 uam_svc_dev_info_t *svc_dev = NULL;
2628 UAM_INFO("[%d]", user_id);
2630 /* Send reply over dbus for add device API */
2631 l = _uam_manager_get_request_list();
2632 for (; NULL != l; l = g_slist_next(l)) {
2633 uam_request_context_t *info = l->data;
2634 uam_device_info_s *dev;
2637 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2642 UAM_WARN("info->data is NULL");
2646 if (dev->type != dev_info->type ||
2647 strcasecmp(dev->device_id, dev_info->device_id)) {
2648 UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2649 dev->device_id, dev_info->device_id);
2653 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2654 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2655 _uam_manager_method_return(info->context, out_param, status);
2657 _uam_remove_timer(info->tid);
2659 _uam_manager_remove_req_ctxt_from_list(info);
2664 if (UAM_ERROR_NONE != status) {
2665 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2671 l = g_slist_find_custom(users,
2672 USER_ACCOUNT_DEFAULT, __compare_user_account);
2674 ret = _uam_core_add_user(&id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2675 if (UAM_ERROR_NONE != ret) {
2676 UAM_ERR("_uam_core_add_user failed with %s",
2677 _uam_manager_error_to_str(ret));
2678 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2684 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2686 UAM_ERR("Invalid user Id: %d", user_id);
2687 ret = UAM_ERROR_NOT_FOUND;
2688 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2693 /* Get default service and add it to device's service list by default */
2694 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2696 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2697 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2698 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2699 services = g_slist_append(services, service);
2700 svc_list = g_slist_append(svc_list, service);
2702 uam_db_service_info_t *service = l->data;
2703 svc_list = g_slist_append(svc_list, service);
2706 /** updates for svc dev*/
2707 ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
2708 UAM_SERVICE_DEFAULT, dev_info->discriminant, 0, NULL);
2709 if (UAM_ERROR_NONE != ret) {
2710 UAM_WARN("Device service mappiing update failed");
2711 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2715 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2716 dev_info->type, UAM_SERVICE_DEFAULT);
2717 svc_dev_list = g_slist_append(svc_dev_list, svc_dev);
2718 __uam_core_add_dev_to_list(user, dev_info, UAM_PRESENCE_STATE_PRESENT,
2719 dev_info->last_seen, svc_list, svc_dev_list);
2721 /** Start database transaction */
2722 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2724 /* Add device to database */
2725 ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
2726 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen);
2727 if (UAM_ERROR_NONE != ret) {
2728 UAM_WARN("Device addition to persistent DB failed");
2729 __uam_db_end_transaction(0);
2733 /* Insert device service info to db */
2734 ret = _uam_db_insert_device_service_info(
2735 dev_info->device_id, dev_info->type, dev_info->mac,
2736 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2737 dev_info->discriminant, 0);
2738 if (UAM_ERROR_NONE != ret) {
2739 UAM_WARN("Device service addition to persistent DB failed");
2740 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2741 __uam_db_end_transaction(0);
2744 __uam_db_end_transaction(1);
2745 /** End database transaction */
2747 /* Send device added event to application */
2748 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2750 /* Set/update registered device list to plugins */
2751 ret = _uam_pm_set_registered_devices(devices);
2752 if (UAM_ERROR_NONE != ret) {
2753 UAM_ERR("_uam_pm_set_registered_devices failed");
2757 _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2759 /* Set/update registered device list to cloud plugin */
2760 if (UAM_ERROR_NONE == status)
2761 _uam_cloud_update_registered_devices();
2767 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2771 unsigned long long timestamp;
2773 UAM_INFO("sensor 0x[%8.8X]", sensor);
2775 if (NULL == sensor_info) {
2776 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2777 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2778 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2783 timestamp = _uam_get_timestamp();
2785 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2786 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2787 g_variant_new("(utiidddd)", sensor, timestamp,
2788 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2789 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2790 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2795 // service specific light detection threshold
2796 for (l = services; NULL != l; l = g_slist_next(l)) {
2797 uam_db_service_info_t *svc = l->data;
2800 if (!svc || !svc->monitors)
2803 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2804 svc->name, sensor_info->values[0], svc->presence_threshold);
2806 if (sensor_info->values[0] < svc->presence_threshold)
2809 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2810 uam_monitor_info_t *mon = l1->data;
2815 UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2816 mon->name, mon->sensors);
2818 if (!(mon->sensors & sensor))
2821 if (UAM_DETECT_PRESENCE != mon->mode)
2824 _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2825 g_variant_new("(utiidddd)", sensor, timestamp,
2826 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2827 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2828 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2836 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
2837 unsigned int sensor)
2842 UAM_INFO("sensor 0x[%8.8X]", sensor);
2844 if (NULL == sensor_info) {
2845 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2846 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2847 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2852 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2853 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2854 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2855 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2856 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2857 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2862 // service specific light detection threshold
2863 for (l = services; NULL != l; l = g_slist_next(l)) {
2864 uam_db_service_info_t *svc = l->data;
2867 if (!svc || !svc->monitors)
2870 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2871 svc->name, sensor_info->values[0], svc->absence_threshold);
2873 if (sensor_info->values[0] > svc->absence_threshold)
2876 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2877 uam_monitor_info_t *mon = l1->data;
2882 if (!(mon->sensors & sensor))
2885 if (UAM_DETECT_PRESENCE != mon->mode)
2888 _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2889 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2890 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2891 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2892 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2899 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2900 uam_device_info_s *dev_info)
2905 uam_db_user_info_t *user;
2906 uam_svc_dev_info_t *svc_dev = NULL;
2907 gboolean live_monitoring = FALSE;
2908 unsigned long long timestamp;
2911 ret_if(NULL == tech);
2912 ret_if(NULL == tech->svc_list);
2913 ret_if(NULL == dev_info);
2915 user = tech->device->user;
2916 user->last_seen = tech->last_seen;
2918 for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2919 uam_db_service_info_t *svc = l->data;
2921 live_monitoring = FALSE;
2923 if (!svc || !svc->monitors)
2926 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2927 svc->name, svc->remaining_time, svc->cycle);
2929 if (!(svc->remaining_time == svc->cycle))
2932 UAM_DBG("Check service device discriminant");
2933 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2934 dev_info->type, svc->name);
2935 if (!svc_dev || !svc_dev->discriminant)
2938 UAM_DBG("Send event");
2939 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2940 uam_monitor_info_t *mon = l1->data;
2945 if (!(mon->sensors & sensor))
2948 if (UAM_DETECT_PRESENCE != mon->mode)
2952 * For current service, if any of its running monitor has same sensor
2953 * and detection_mode
2955 live_monitoring = TRUE;
2957 timestamp = _uam_get_timestamp();
2958 UAM_INFO("sensor [%d]", sensor);
2959 _uam_manager_send_event(mon->name,
2960 UAM_EVENT_USER_PRESENCE_DETECTED,
2961 g_variant_new("(utsss)", sensor, timestamp,
2962 user->account, svc->name, dev_info->device_id));
2963 UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2965 " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
2966 mon->name, dev_info->device_id,
2967 sensor, user->account,
2972 /* Update service specific device last_seen in svc_dev list and DB */
2973 if (live_monitoring) {
2974 svc_dev->last_seen = tech->last_seen;
2975 ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
2976 dev_info->type, dev_info->mac, svc->name, tech->last_seen);
2977 if (UAM_ERROR_NONE != ret)
2978 UAM_WARN("_uam_db_update_device_service_last_seen failed");
2985 int _uam_core_handle_presence_detected(unsigned int sensor,
2986 int user_id, void *info)
2989 int ret = UAM_ERROR_NONE;
2992 uam_db_user_info_t *user;
2993 uam_db_device_info_t *device;
2994 uam_db_tech_info_t *tech;
2996 uam_device_info_s *dev_info = NULL;
2997 uam_sensor_info_s *sensor_info = NULL;
2999 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3001 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3003 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3006 _uam_vpm_send_presence_detection_event(sensor);
3008 if (NULL == dev_info) {
3009 __send_sensor_presence_event(sensor_info, sensor);
3013 retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
3015 l = g_slist_find_custom(users, &user_id, __compare_user_id);
3017 UAM_ERR("Invalid user_id [%d]", user_id);
3018 return UAM_ERROR_INVALID_PARAMETER;
3022 l = g_slist_find_custom(user->devices,
3023 dev_info->device_id, __compare_device_id);
3025 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3026 user_id, dev_info->device_id);
3027 return UAM_ERROR_INVALID_PARAMETER;
3030 if (!(device->supported_techs & dev_info->type)) {
3031 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3032 dev_info->device_id, dev_info->type);
3033 return UAM_ERROR_INVALID_PARAMETER;
3036 l = g_slist_find_custom(device->tech_list,
3037 &(dev_info->type), __compare_tech_type);
3039 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3040 return UAM_ERROR_INVALID_PARAMETER;
3044 tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
3045 tech->last_seen = dev_info->last_seen;
3047 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
3049 /* Check if IP/MAC address was updated then update in DB */
3050 if (UAM_TECH_TYPE_WIFI == dev_info->type) {
3052 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
3053 uam_db_address_info_t *addr = l->data;
3058 if (UAM_ADDR_TYPE_IPv4 == addr->addr_type) {
3060 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
3061 UAM_DBG("Old IPv4: %s, New IPv4: %s",
3062 addr->address, dev_info->ipv4_addr);
3064 g_free(addr->address);
3065 addr->addr_type = UAM_ADDR_TYPE_IPv4;
3066 addr->address = g_strdup(dev_info->ipv4_addr);
3068 /* Update IP address in DB */
3069 ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
3070 dev_info->type, dev_info->ipv4_addr);
3071 if (UAM_ERROR_NONE != ret) {
3072 UAM_WARN("_uam_device_db_update_device_ip_address failed");
3073 __uam_db_end_transaction(0);
3079 if (UAM_ADDR_TYPE_WIFI == addr->addr_type) {
3081 if (strcasecmp(addr->address, dev_info->mac)) {
3082 UAM_DBG("Old MAC: %s, New MAC: %s",
3083 addr->address, dev_info->mac);
3085 g_free(addr->address);
3086 addr->addr_type = UAM_ADDR_TYPE_WIFI;
3087 addr->address = g_strdup(dev_info->mac);
3089 /* Update address in DB */
3090 ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
3091 dev_info->type, dev_info->mac);
3092 if (UAM_ERROR_NONE != ret) {
3093 UAM_WARN("_uam_device_db_update_device_mac_address failed");
3094 __uam_db_end_transaction(0);
3102 /* Update database (presence state & timestamp) */
3103 ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
3104 dev_info->type, dev_info->mac, dev_info->last_seen);
3105 if (UAM_ERROR_NONE != ret) {
3106 UAM_WARN("_uam_device_db_update_device_last_seen failed");
3107 __uam_db_end_transaction(0);
3111 ret = _uam_device_db_update_device_presence(dev_info->device_id,
3112 dev_info->type, dev_info->mac, tech->presence_state);
3113 if (UAM_ERROR_NONE != ret) {
3114 UAM_WARN("_uam_device_db_update_device_presence failed");
3115 __uam_db_end_transaction(0);
3119 /* Send user presence event and update service_device timestamp */
3120 __send_user_presence_event(tech, sensor, dev_info);
3121 __uam_db_end_transaction(1);
3127 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
3133 * For each service, find users absent on given sensor. Then for each
3134 * monitor in serivce's monitor list, if it is monitoring ABSENCE on
3135 * given sensor, send user ABSENCE event.
3137 for (l = services; NULL != l; l = g_slist_next(l)) {
3138 uam_db_service_info_t *svc = l->data;
3139 GSList *absent_users = NULL;
3140 GSList *present_users = NULL;
3144 if (!svc || !svc->monitors || !svc->dev_techs)
3147 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3148 uam_db_tech_info_t *tech = l1->data;
3150 if (!tech || (tech->tech_type != type)) {
3151 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
3155 if (!tech->device || !tech->device->user) {
3156 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
3160 l2 = g_slist_find_custom(present_users,
3161 &(tech->device->user->user_id), __compare_user_id);
3163 if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
3164 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
3166 tech->device->device_id,
3167 tech->device->user->account);
3168 /* Remove user from absent list */
3169 absent_users = g_slist_remove(absent_users, tech->device->user);
3171 /* If user not in present list, add user to the list */
3173 UAM_DBG("added present user [%s]", tech->device->user->account);
3174 present_users = g_slist_prepend(present_users, tech->device->user);
3177 /* If user not in the present list then only add it to absent list */
3178 if ((NULL == l2) && (NULL == g_slist_find_custom(
3179 absent_users, &(tech->device->user->user_id),
3180 __compare_user_id))) {
3181 UAM_DBG("added absent user [%s]", tech->device->user->account);
3182 absent_users = g_slist_prepend(absent_users, tech->device->user);
3187 g_slist_free(present_users);
3191 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
3192 uam_monitor_info_t *mon = l2->data;
3197 if (!(mon->sensors & sensor))
3200 if (UAM_DETECT_ABSENCE != mon->mode)
3203 for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
3204 uam_db_user_info_t *user = l1->data;
3209 user->last_seen = 0;
3211 _uam_manager_send_event(mon->name,
3212 UAM_EVENT_USER_ABSENCE_DETECTED,
3213 g_variant_new("(utss)", sensor, user->last_seen,
3214 user->account, svc->name));
3215 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
3216 " for 0x%8.8X, User: %s Service: %s",
3217 mon->name, sensor, user->account, svc->name);
3221 g_slist_free(absent_users);
3227 void _uam_core_handle_absence_detected(unsigned int sensor,
3228 int user_id, void *info)
3231 uam_db_user_info_t *user;
3232 uam_db_device_info_t *device;
3233 uam_db_tech_info_t *tech;
3235 uam_device_info_s *dev_info = NULL;
3236 uam_sensor_info_s *sensor_info = NULL;
3238 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3240 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3242 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3245 if (NULL == dev_info) {
3246 __send_sensor_absence_event(sensor_info, sensor);
3251 ret_if(0 > user_id);
3253 l = g_slist_find_custom(users, &user_id, __compare_user_id);
3255 UAM_ERR("Invalid user_id [%d]", user_id);
3260 l = g_slist_find_custom(user->devices,
3261 dev_info->device_id, __compare_device_id);
3263 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3264 user_id, dev_info->device_id);
3268 if (!(device->supported_techs & dev_info->type)) {
3269 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3270 dev_info->device_id, dev_info->type);
3274 l = g_slist_find_custom(device->tech_list,
3275 &(dev_info->type), __compare_tech_type);
3277 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3282 tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
3284 /* Update database (presence state) */
3285 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
3286 dev_info->type, dev_info->mac, tech->presence_state))
3287 UAM_WARN("_uam_device_db_update_device_presence failed");
3292 void _uam_core_cleanup_monitor(char *name)
3296 for (l = monitors; NULL != l; l = g_slist_next(l)) {
3297 uam_monitor_info_t *monitor = l->data;
3299 if (!monitor || !monitor->name || !monitor->service)
3302 if (0 != g_strcmp0(name, monitor->name))
3305 /* If there is a monitor that is not freed, stop detection
3306 * and free the monitor structure in the memory. */
3307 UAM_INFO("clear %s's monitor info.", monitor->name);
3308 __uam_core_stop_detection(monitor->mode,
3309 monitor->service->name, name, monitor->sensors);
3313 static void __free_user_info(gpointer data)
3316 uam_db_user_info_t *user = data;
3318 ret_if(NULL == user);
3321 g_free(user->account);
3326 static void __free_service_info(gpointer data)
3329 uam_db_service_info_t *svc = data;
3331 ret_if(NULL == svc);
3338 static void __free_monitor_info(gpointer data)
3341 uam_monitor_info_t *monitor = data;
3343 ret_if(NULL == monitor);
3345 g_free(monitor->name);
3350 static void __free_scanner_info(gpointer data)
3353 uam_scanner_info_t *scanner = data;
3355 ret_if(NULL == scanner);
3357 g_free(scanner->name);
3362 void _uam_core_reset_database(void)
3367 ret = _uam_db_clear();
3368 if (UAM_ERROR_NONE != ret) {
3369 UAM_ERR("_uam_db_clear failed with %s",
3370 _uam_manager_error_to_str(ret));
3371 unlink(DATABASE_FULL_PATH);
3375 g_slist_free_full(devices, __free_user_device);
3378 g_slist_free_full(users, __free_user_info);
3381 g_slist_free_full(services, __free_service_info);
3384 g_slist_free_full(monitors, __free_monitor_info);
3387 g_slist_free_full(scanners, __free_scanner_info);
3390 /* Set/update registered device list to plugins */
3391 ret = _uam_pm_set_registered_devices(devices);
3392 if (UAM_ERROR_NONE != ret)
3393 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3394 _uam_manager_error_to_str(ret));
3396 /* Set/update registered device list to cloud plugin */
3397 _uam_cloud_update_registered_devices();
3402 void _uam_core_handle_detection_started(unsigned int sensor)
3405 unsigned int active_sensors = 0;
3407 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3408 sensor, detecting_sensors);
3410 detecting_sensors |= sensor;
3411 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3412 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3413 if (active_sensors == detecting_sensors) {
3414 /* Send detection started event */
3415 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3421 void _uam_core_handle_detection_stopped(unsigned int sensor)
3425 uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3426 uam_cycle_state_e cycle_state;
3429 ret_if((detecting_sensors & sensor) == 0);
3430 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3431 sensor, detecting_sensors);
3432 detecting_sensors &= ~sensor;
3434 if (UAM_SENSOR_BITMASK_BLE == sensor)
3435 type = UAM_TECH_TYPE_BLE;
3436 else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3437 type = UAM_TECH_TYPE_WIFI;
3439 if (UAM_TECH_TYPE_NONE != type)
3440 __send_user_absence_event(type, sensor);
3442 if (0 == detecting_sensors) {
3443 /* Send detection stopped event */
3444 for (l = monitors; l; l = g_slist_next(l)) {
3445 uam_monitor_info_t *mon = l->data;
3447 if (!mon || !mon->name || !mon->service)
3449 uam_db_service_info_t *service = mon->service;
3450 cycle_state = UAM_DETECTION_CYCLE_END;
3452 UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d", mon->sensors, service->name, service->remaining_time);
3453 if (!(mon->sensors & _uam_core_get_env_sensors())) {
3454 if (service->remaining_time < service->cycle) {
3455 UAM_DBG("service->remaining_time < service->cycle, return");
3458 } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
3459 cycle_state = UAM_DETECTION_CYCLE_MID;
3462 _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
3463 g_variant_new("(si)", service->name, cycle_state));
3464 UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
3465 " cycle state:[%s]",
3466 mon->name, service->name, cycle_state ? "end" : "mid");
3472 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3476 retv_if(NULL == name, NULL);
3478 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3479 uam_scanner_info_t *scanner = l->data;
3481 if (!scanner || !scanner->name)
3484 if (0 == g_strcmp0(scanner->name, name)) {
3485 UAM_DBG("Scanning application found in list");
3493 static gboolean __scan_completed_cb(gpointer data)
3496 uam_scanner_info_t *scanner = data;
3498 retv_if(NULL == scanner, FALSE);
3500 if (UAM_ERROR_NONE != _uam_manager_send_event(
3501 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3502 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3504 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3507 scanners = g_slist_remove(scanners, scanner);
3508 g_free(scanner->name);
3515 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3519 uam_scanner_info_t *scanner;
3521 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3522 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3524 scanner = __uam_find_scanner(sender);
3525 retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3527 ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3528 if (UAM_ERROR_NONE != ret) {
3529 UAM_ERR("Failed with error: %s (0x%4.4X)",
3530 _uam_manager_error_to_str(ret), ret);
3534 scanner = g_malloc0(sizeof(uam_scanner_info_t));
3536 UAM_ERR("Failed to allocate memory");
3537 return UAM_ERROR_OUT_OF_MEMORY;
3539 scanner->name = g_strdup(sender);
3540 scanner->sensors |= sensors;
3541 scanner->timer = g_timeout_add_seconds(detection_period,
3542 __scan_completed_cb, scanner);
3543 scanners = g_slist_append(scanners, scanner);
3544 UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3547 return UAM_ERROR_NONE;
3550 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3554 uam_scanner_info_t *scanner;
3557 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3558 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3560 scanner = __uam_find_scanner(sender);
3561 retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3563 /* Trim sensors to a subset of active sensors for the scanner */
3564 sensors &= scanner->sensors;
3567 * modify scanner's active sensors and if active sensors are NULL
3568 * remove scanner from scanners list
3570 scanner->sensors &= ~sensors;
3571 if (0 == scanner->sensors) {
3572 scanners = g_slist_remove(scanners, scanner);
3573 g_source_remove(scanner->timer);
3574 g_free(scanner->name);
3578 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3579 uam_scanner_info_t *scanner_data = l->data;
3581 if (!scanner_data || !scanner_data->name)
3584 sensors &= ~(scanner_data->sensors);
3588 ret = _uam_pm_stop_active_device_scan(sensors);
3589 if (UAM_ERROR_NONE != ret) {
3590 UAM_ERR("Failed with error: %s (0x%4.4X)",
3591 _uam_manager_error_to_str(ret), ret);
3597 return UAM_ERROR_NONE;
3600 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3601 unsigned int sensor, const uam_device_info_s *dev_info)
3606 ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3608 for (l = scanners; NULL != l;) {
3609 uam_scanner_info_t *scanner = l->data;
3611 if (!scanner || !scanner->name) {
3612 l = g_slist_next(l);
3616 if (0 == (scanner->sensors & sensor)) {
3617 l = g_slist_next(l);
3621 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3622 scanner->sensors &= ~(sensor);
3623 UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3624 if (0 != scanner->sensors) {
3625 l = g_slist_next(l);
3629 if (UAM_ERROR_NONE != _uam_manager_send_event(
3630 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3631 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3633 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3636 l = g_slist_next(l);
3637 scanners = g_slist_remove(scanners, scanner);
3638 g_source_remove(scanner->timer);
3639 g_free(scanner->name);
3642 GVariant *param = g_variant_new("(iiisss)",
3644 dev_info->operating_system,
3647 dev_info->ipv4_addr,
3648 dev_info->device_id);
3649 if (UAM_ERROR_NONE != _uam_manager_send_event(
3650 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3651 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3653 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3655 l = g_slist_next(l);
3662 int _uam_core_register_service(uam_service_info_s *svc)
3666 uam_db_service_info_t *service;
3667 int service_number = 0;
3669 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3671 /* Retrieve service from list */
3672 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3673 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3675 service = g_new0(uam_db_service_info_t, 1);
3676 service->name = g_strdup(svc->name);
3677 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3678 service->presence_threshold = svc->presence_threshold;
3679 service->absence_threshold = svc->absence_threshold;
3681 /* Add service to database */
3682 if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3683 UAM_ERR("_uam_db_insert_service_info failed");
3685 return UAM_ERROR_DB_FAILED;
3688 services = g_slist_append(services, service);
3690 /* Send service registered event to application */
3691 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3692 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3693 UAM_ERROR_NONE, service->name)))
3694 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3697 return UAM_ERROR_NONE;
3700 int _uam_core_update_service(uam_service_info_s *svc)
3704 uam_db_service_info_t *service;
3706 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3708 /* Retrieve service from list */
3709 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3710 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3713 service->presence_threshold = svc->presence_threshold;
3714 service->absence_threshold = svc->absence_threshold;
3716 /* Update service to database */
3717 if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3718 UAM_ERR("_uam_db_update_service_info failed");
3719 return UAM_ERROR_DB_FAILED;
3723 return UAM_ERROR_NONE;
3726 int _uam_core_get_default_service(uam_service_info_s *service_info)
3731 uam_db_service_info_t *service;
3733 retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3735 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3738 // insert default service
3739 memset(service_info, 0x00, sizeof(uam_service_info_s));
3740 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3741 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3742 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3744 ret = _uam_core_register_service(service_info);
3745 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3746 UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3749 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3752 retv_if(NULL == l, UAM_ERROR_INTERNAL);
3755 memset(service_info, 0x00, sizeof(uam_service_info_s));
3756 g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3759 return UAM_ERROR_NONE;
3762 int _uam_core_unregister_service(const char *svc_name)
3766 uam_db_service_info_t *service;
3768 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3770 /* Retrieve service from list */
3771 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3772 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3775 /* Check if service is being used*/
3776 if (service->monitors) {
3777 UAM_ERR("service monitoring in progress");
3778 return UAM_ERROR_PERMISSION_DENIED;
3781 /* Remove service from database */
3782 if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3783 UAM_ERR("_uam_db_delete_service_info failed");
3784 return UAM_ERROR_DB_FAILED;
3787 /* Remove service mapping from devices*/
3788 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3789 uam_db_tech_info_t *tech = l->data;
3790 if (!tech || !tech->addresses)
3792 tech->svc_list = g_slist_remove(tech->svc_list, service);
3794 services = g_slist_remove(services, service);
3796 /* Send service unregistered event to application */
3797 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3798 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3799 UAM_ERROR_NONE, service->name)))
3800 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3803 return UAM_ERROR_NONE;
3806 static int __get_service_dev_list(
3807 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3813 int ret = UAM_ERROR_NONE;
3814 uam_svc_dev_info_t *svc_dev = NULL;
3815 uam_device_info_s *dev = NULL;
3818 /* Calculate number of devices */
3819 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3820 uam_db_tech_info_t *tech = l1->data;
3821 if (!tech || !tech->addresses)
3827 *device_list = g_new0(uam_device_info_s, *count);
3830 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3831 uam_db_tech_info_t *tech = l1->data;
3833 if (!tech || !tech->addresses)
3836 /* Copy tech info to device info */
3837 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
3838 if (UAM_ERROR_NONE != ret) {
3839 UAM_ERR("__copy_tech_info_to_device_info failed");
3843 (*device_list)[indx].last_seen = 0;
3847 UAM_INFO("Count = %d, indx = %d", *count, indx);
3849 /* Update service specific device last time */
3850 for (s = svc_devs; s; s = g_slist_next(s)) {
3853 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
3855 if (g_strcmp0(svc_dev->service, service->name))
3858 for (indx = 0; indx < *count; indx++) {
3859 dev = &((*device_list)[indx]);
3861 if (svc_dev->tech_type != dev->type ||
3862 g_strcmp0(svc_dev->device_id, dev->device_id))
3865 dev->last_seen = svc_dev->last_seen;
3873 int _uam_core_get_service_devices(const char *svc_name,
3874 int *count, uam_device_info_s **device_list)
3877 uam_db_service_info_t *service;
3879 int ret = UAM_ERROR_NONE;
3881 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3882 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3885 ret = __get_service_dev_list(service, device_list, count);
3891 static void __get_service_user_list(
3892 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3897 GSList *svc_user_list = NULL;
3900 /* Calculate number of users */
3901 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3902 uam_db_tech_info_t *tech = l->data;
3903 if (!tech || !tech->addresses)
3907 uam_db_user_info_t *db_info = tech->device->user;
3908 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3910 svc_user_list = g_slist_append(svc_user_list, db_info);
3913 *count = g_slist_length(svc_user_list);
3914 *user_list = g_new0(uam_user_info_s, *count);
3917 for (l = svc_user_list; l; l = g_slist_next(l)) {
3918 uam_db_user_info_t *db_info = l->data;
3920 if (!db_info || !db_info->account)
3923 g_strlcpy((*user_list)[indx].account,
3924 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3926 g_strlcpy((*user_list)[indx].name,
3927 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3932 UAM_INFO("Count = %d, indx = %d", *count, indx);
3936 int _uam_core_get_service_users(const char *svc_name,
3937 int *count, uam_user_info_s **user_list)
3940 uam_db_service_info_t *service;
3943 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3944 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3947 __get_service_user_list(service, user_list, count);
3950 return UAM_ERROR_NONE;
3953 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3959 size = g_slist_length(services);
3960 *service_list = g_new0(uam_service_info_s, size);
3963 /* fetch services list from DB */
3964 for (l = services; l; l = g_slist_next(l)) {
3965 uam_db_service_info_t *db_info = l->data;
3967 if (!db_info || !db_info->name)
3970 g_strlcpy((*service_list)[*count].name,
3971 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3972 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3973 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3977 UAM_INFO("Count: %d", *count);
3979 return UAM_ERROR_NONE;
3982 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3987 UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3988 iadv[0], iadv[1], iadv[2]);
3990 ret = _uam_db_insert_adv_info(adv_len, iadv);
3991 if (UAM_ERROR_NONE != ret) {
3992 UAM_ERR("_uam_db_insert_adv_info failed");
3996 ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3997 if (UAM_ERROR_NONE != ret) {
3998 UAM_ERR("Failed with error: %s (0x%4.4X)",
3999 _uam_manager_error_to_str(ret), ret);
4004 return UAM_ERROR_NONE;
4007 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
4011 uam_sensor_info_s *sensor_info = info;
4013 ret_if(NULL == info);
4015 UAM_DBG("%d %d %llu %d %d", sensor, sensor_info->status, sensor_info->timestamp,
4016 sensor_info->accuracy, sensor_info->count);
4018 UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
4019 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
4021 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
4022 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
4023 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
4024 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
4029 int _uam_core_add_payload(uam_ble_payload_s *payload,
4030 const char *device_id, int tech_type)
4033 int ret = UAM_ERROR_NONE;
4034 uam_db_tech_info_t *tech_info;
4035 uam_db_payload_info_t *db_payload = g_new0(uam_db_payload_info_t, 1);
4038 retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
4039 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
4040 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
4041 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
4043 // <TO-DO> check if payload already exist
4045 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
4046 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
4047 mac = __get_mac_addr(tech_info);
4049 __uam_copy_uam_payload_info(db_payload, payload);
4050 db_payload->device_id = g_strdup(device_id);
4051 db_payload->tech_type = tech_type;
4052 payloads = g_slist_append(payloads, db_payload);
4054 /*** Add payload to database ***/
4055 ret = _uam_db_insert_payload_info(device_id, tech_type, mac, payload);
4056 if (UAM_ERROR_NONE != ret) {
4057 UAM_ERR("_uam_db_insert_payload_info failed");
4062 return UAM_ERROR_NONE;
4065 int _uam_core_service_add_payload(uam_ble_payload_s *payload,
4066 const char *svc_name)
4069 int ret = UAM_ERROR_NONE;
4070 uam_db_service_info_t *service;
4071 uam_db_payload_info_t *db_payload;
4072 uam_svc_dev_info_t *svc_dev;
4073 uam_db_device_info_t *device;
4076 retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
4077 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
4079 /* Retrieve service from list */
4080 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
4081 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
4084 /* Retrieve payload from list */
4085 l = g_slist_find_custom(payloads, payload, __compare_payload);
4086 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
4087 db_payload = l->data;
4089 // <TO-DO> check if this device-service pair exist
4092 _uam_core_update_svc_dev_info(db_payload->device_id, db_payload->tech_type,
4093 service->name, -1, -1, payload);
4094 svc_dev = _uam_core_find_svc_dev_info(db_payload->device_id,
4095 db_payload->tech_type, service->name);
4096 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
4098 /**Update svc_dev list for device*/
4099 l = g_slist_find_custom(devices, db_payload->device_id, __compare_device_id);
4102 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
4103 uam_db_tech_info_t *tech = l->data;
4108 if (db_payload->tech_type != tech->tech_type)
4111 tech->svc_dev_list = g_slist_append(tech->svc_dev_list, svc_dev);
4114 /* Set/update registered device list to plugins */
4115 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
4116 UAM_ERR("_uam_pm_set_registered_devices failed");
4119 /*** Add payload service mapping to database ***/
4120 ret = _uam_db_update_device_service_payload_info(payload, service->name);
4121 if (UAM_ERROR_NONE != ret) {
4122 UAM_ERR("_uam_db_update_device_service_payload_info failed");
4127 return UAM_ERROR_NONE;
4130 int _uam_core_get_payloads(int *count, uam_ble_payload_s **payload_list)
4136 size = g_slist_length(payloads);
4137 *payload_list = g_new0(uam_ble_payload_s, size);
4140 /* fetch payloads list from DB */
4141 for (l = payloads; l; l = g_slist_next(l)) {
4142 uam_db_payload_info_t *db_info = l->data;
4146 __uam_copy_db_payload_info(&((*payload_list)[*count]), db_info);
4150 UAM_INFO("Count: %d", *count);
4152 return UAM_ERROR_NONE;