2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "ua-plugin.h"
22 #include "ua-internal.h"
23 #include "ua-manager-common.h"
24 #include "ua-plugin-manager.h"
26 #include "ua-manager-database.h"
27 #include "ua-cloud-plugin-handler.h"
29 #include "ua-vendor-plugin-manager.h"
31 #define UAM_MAX_USERS 255
32 #define USER_ACCOUNT_DEFAULT "default@default.com"
33 #define USER_NAME_DEFAULT "default"
38 uam_pm_detection_mode_e mode;
39 uam_db_service_info_t *service;
48 static GSList *users; /* List of users - uam_db_user_info_t */
49 static GSList *devices; /* List of devices - uam_db_device_info_t */
50 static GSList *services; /* List of services - uam_db_service_info_t */
51 static GSList *svc_devs; /* List of service device mapping - uam_svc_dev_info_t */
53 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
54 static GSList *scanners; /* List of scanning apps - uam_scanner_info_t */
56 static guint detection_timer = 0;
57 static unsigned int detection_window;
59 static unsigned int detecting_sensors = 0;
61 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
63 const uam_db_user_info_t *user = data;
64 const char *account = user_data;
66 retv_if(NULL == user, -1);
67 retv_if(NULL == user->account, -1);
68 retv_if(NULL == account, -1);
70 return g_strcmp0(user->account, account);
73 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
75 const uam_db_user_info_t *user = data;
76 const int *id = user_data;
78 UAM_INFO("[%d][%d]", *id, user->user_id);
80 retv_if(NULL == user, -1);
81 retv_if(NULL == user->account, -1);
82 retv_if(NULL == id, -1);
84 if (*id != user->user_id)
90 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
92 const uam_db_service_info_t *service = data;
93 const char *svc_name = user_data;
95 retv_if(NULL == service, -1);
96 retv_if(NULL == service->name, -1);
97 retv_if(NULL == svc_name, -1);
99 return g_strcmp0(service->name, svc_name);
102 static void __free_address_info(gpointer data)
105 uam_db_address_info_t *addr = data;
107 ret_if(NULL == addr);
109 g_free(addr->address);
115 static void __free_dev_tech_info(gpointer data)
118 uam_db_tech_info_t *tech_info = data;
121 ret_if(NULL == tech_info);
123 /* Delete the tech information from the service list that includes tech. */
124 for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
125 uam_db_service_info_t *svc_info = l->data;
127 if (!svc_info || !svc_info->dev_techs)
130 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
133 g_slist_free_full(tech_info->addresses, __free_address_info);
134 tech_info->addresses = NULL;
136 if (tech_info->payload) {
137 g_free(tech_info->payload->duid);
138 g_free(tech_info->payload->bt_mac);
139 g_free(tech_info->payload);
147 static void __free_user_device(gpointer data)
150 uam_db_device_info_t *device = data;
152 ret_if(NULL == device);
154 /* Remove device data from global device list */
155 devices = g_slist_remove(devices, device);
157 /* Free allocated memory */
158 g_free(device->device_id);
159 g_slist_free_full(device->tech_list, __free_dev_tech_info);
165 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
170 UAM_INFO_C("Send %s to applications", _uam_manager_event_to_str(event));
171 /* Send device event to application */
172 param = g_variant_new("(iiisss)",
174 dev_info->operating_system,
178 dev_info->device_id);
179 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL, event, param))
180 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
185 static void __print_service(gpointer data, gpointer user_data)
188 uam_db_service_info_t *service = data;
189 uam_db_tech_info_t *tech = user_data;
191 ret_if(NULL == tech);
192 ret_if(NULL == service);
194 UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
195 tech->device->device_id, tech->tech_type,
196 service->name, service->cycle);
201 static void __add_service_to_dev_tech_mapping(
202 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
206 ret_if(NULL == tech);
207 ret_if(NULL == service);
209 tech->svc_list = g_slist_append(tech->svc_list, service);
210 service->dev_techs = g_slist_append(service->dev_techs, tech);
211 g_slist_foreach(tech->svc_list, __print_service, tech);
216 static void __remove_service_to_dev_tech_mapping(
217 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
221 ret_if(NULL == tech);
222 ret_if(NULL == service);
224 tech->svc_list = g_slist_remove(tech->svc_list, service);
225 service->dev_techs = g_slist_remove(service->dev_techs, tech);
226 g_slist_foreach(tech->svc_list, __print_service, tech);
231 static char *__get_mac_addr(uam_db_tech_info_t *tech)
236 retv_if(NULL == tech, NULL);
238 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
239 uam_db_address_info_t *addr = l->data;
244 if (addr->addr_type == UAM_ADDR_TYPE_BT ||
245 addr->addr_type == UAM_ADDR_TYPE_BLE ||
246 addr->addr_type == UAM_ADDR_TYPE_WIFI ||
247 addr->addr_type == UAM_ADDR_TYPE_P2P)
248 return addr->address;
255 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
257 switch (addr->addr_type) {
258 case UAM_ADDR_TYPE_BLE:
259 case UAM_ADDR_TYPE_BT:
260 case UAM_ADDR_TYPE_P2P:
261 case UAM_ADDR_TYPE_WIFI:
262 g_strlcpy(device->mac, addr->address,
263 UAM_MAC_ADDRESS_STRING_LEN);
265 case UAM_ADDR_TYPE_IPv4:
266 g_strlcpy(device->ipv4_addr,
268 UAM_IP_ADDRESS_MAX_STRING_LEN);
271 UAM_WARN("Unknown address type %d", addr->addr_type);
275 static void __uam_copy_payload_info(uam_ble_payload_s *dev_payload, uam_db_ble_payload_t *payload)
278 dev_payload->service_id = payload->service_id;
279 dev_payload->device_icon = payload->device_icon;
280 dev_payload->purpose = payload->purpose;
282 memcpy(dev_payload->duid,
283 payload->duid, UAM_BLE_PAYLOAD_DUID_LEN);
285 memcpy(dev_payload->bt_mac,
286 payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
290 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
295 retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
297 memset(device, 0x00, sizeof(uam_device_info_s));
298 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
299 uam_db_address_info_t *addr = l->data;
304 __uam_core_copy_addr(device, addr);
307 device->operating_system = tech->device->os;
308 g_strlcpy(device->device_id, tech->device->device_id,
309 UAM_DEVICE_ID_MAX_STRING_LEN);
310 device->type = tech->tech_type;
311 device->discriminant = tech->discriminant;
312 memset(device->payload.duid, 0, UAM_BLE_PAYLOAD_DUID_LEN + 1);
313 memset(device->payload.bt_mac, 0, UAM_BT_MAC_ADDRESS_STRING_LEN);
314 device->last_seen = tech->last_seen;
315 __uam_copy_payload_info(&(device->payload), tech->payload);
318 return UAM_ERROR_NONE;
321 static int _uam_remove_user_device(uam_db_device_info_t *device)
324 uam_device_info_s dev_info;
327 int ret = UAM_ERROR_NONE;
329 retv_if(NULL == device, UAM_ERROR_INVALID_PARAMETER);
330 user_id = device->user->user_id;
332 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
333 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
334 uam_db_tech_info_t *tech = l->data;
339 /* Copy tech info to device info */
340 ret = __copy_tech_info_to_device_info(tech, &dev_info);
341 if (UAM_ERROR_NONE != ret) {
342 UAM_ERR("__copy_tech_info_to_device_info failed");
343 __uam_db_end_transaction(0);
347 /* Unregister device from plugin */
348 ret = _uam_pm_unregister_device(user_id, &dev_info);
349 if (UAM_ERROR_NONE != ret)
350 UAM_ERR("_uam_pm_unregister_device failed with %s",
351 _uam_manager_error_to_str(ret));
353 /* Send device removed event to application */
354 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
356 /* Remove device from database */
357 ret = _uam_device_db_delete_device_info(
358 dev_info.device_id, dev_info.type, dev_info.mac);
359 if (UAM_ERROR_NONE != ret) {
360 UAM_ERR("_uam_device_db_delete_device_info failed");
361 __uam_db_end_transaction(0);
365 __uam_db_end_transaction(1);
371 static int __free_uam_db_user_info(gpointer data)
374 uam_db_user_info_t *user = data;
376 int ret = UAM_ERROR_NONE;
378 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
379 uam_db_device_info_t *device = l->data;
380 ret = _uam_remove_user_device(device);
381 if (UAM_ERROR_NONE != ret) {
382 UAM_ERR("_uam_remove_user_device failed");
387 g_slist_free_full(user->devices, __free_user_device);
389 /* Set/update registered device list to plugins */
390 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
391 UAM_ERR("_uam_pm_set_registered_devices failed");
393 /* Set/update registered device list to cloud plugin */
394 _uam_cloud_update_registered_devices();
397 g_free(user->account);
404 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
407 const uam_db_device_info_t *device = data;
408 const char *dev_id = user_data;
410 retv_if(NULL == device, -1);
411 retv_if(NULL == device->device_id, -1);
412 retv_if(NULL == dev_id, -1);
415 return g_strcmp0(device->device_id, dev_id);
418 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
421 const uam_db_tech_info_t *tech = data;
422 const int *type = user_data;
424 retv_if(NULL == tech, -1);
425 retv_if(NULL == type, -1);
428 return ((*type == tech->tech_type) ? 0 : 1);
431 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
436 for (l = devices; NULL != l; l = g_slist_next(l)) {
437 uam_db_device_info_t *dev = l->data;
443 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
444 uam_db_tech_info_t *tech = l1->data;
450 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
451 uam_db_address_info_t *addr = l2->data;
456 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
457 UAM_ADDR_TYPE_BT == addr->addr_type ||
458 UAM_ADDR_TYPE_P2P == addr->addr_type ||
459 UAM_ADDR_TYPE_WIFI == addr->addr_type)
460 if (!strcasecmp(addr->address, mac)) {
461 UAM_DBG("Device found Mac: %s, type: %d",
462 addr->address, addr->addr_type);
473 static int __get_uam_db_dev_list_to_uam_dev_list(
474 GSList *db_dev_list, uam_device_info_s **device_list, int *count)
479 int ret = UAM_ERROR_NONE;
482 /* Calculate num devices first */
483 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
484 uam_db_device_info_t *db_info = l->data;
487 if (!db_info || !db_info->device_id)
490 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
491 uam_db_tech_info_t *tech = l1->data;
493 if (!tech || !tech->addresses)
499 UAM_INFO("Count = %d", *count);
501 *device_list = g_new0(uam_device_info_s, *count);
504 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
505 uam_db_device_info_t *db_info = l->data;
508 if (!db_info || !db_info->device_id)
511 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
512 uam_db_tech_info_t *tech = l1->data;
514 if (!tech || !tech->addresses)
517 /* Copy tech info to device info */
518 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
519 if (UAM_ERROR_NONE != ret) {
520 UAM_ERR("__copy_tech_info_to_device_info failed");
527 UAM_INFO("Count = %d, indx = %d", *count, indx);
532 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
533 const char *name, const char *svc_name, uam_pm_detection_mode_e mode)
538 retv_if(NULL == name, NULL);
539 retv_if(NULL == monitor_list, NULL);
541 for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
542 uam_monitor_info_t *monitor = l->data;
544 if (!monitor || !monitor->name ||
545 !monitor->service || !monitor->service->name)
548 if ((mode == monitor->mode) &&
549 (0 == g_strcmp0(monitor->name, name)) &&
550 (0 == g_strcmp0(monitor->service->name, svc_name))) {
551 UAM_DBG("Monitoring application found in list");
560 unsigned int _uam_core_get_active_sensors(int detection_mode)
563 unsigned int sensors = 0;
566 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
567 (UAM_DETECT_ABSENCE != detection_mode), 0);
569 for (l = monitors; NULL != l; l = g_slist_next(l)) {
570 uam_monitor_info_t *monitor = l->data;
572 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
575 sensors |= monitor->sensors;
582 unsigned int _uam_core_get_env_sensors()
585 unsigned int sensors = 0;
587 sensors |= UAM_SENSOR_BITMASK_MOTION;
588 sensors |= UAM_SENSOR_BITMASK_LIGHT;
594 unsigned int _uam_core_get_active_env_sensors(int detection_mode)
597 unsigned int sensors = 0;
600 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
601 (UAM_DETECT_ABSENCE != detection_mode), 0);
603 for (l = monitors; NULL != l; l = g_slist_next(l)) {
604 uam_monitor_info_t *monitor = l->data;
606 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
609 sensors |= monitor->sensors & _uam_core_get_env_sensors();
616 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
620 GSList *svc_list = NULL;
622 retv_if(NULL == db_svc_list, NULL);
625 * Iterate over the db_svc_list and add each service to the global
626 * service list "services" if its not already inserted. Also append this
627 * uam_db_service_info_t to svc_list.
629 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
630 db_service_info_t *db_svc = l->data;
631 uam_db_service_info_t *service;
637 l1 = g_slist_find_custom(services,
638 db_svc->service_name, __compare_svc_name);
640 service = g_new0(uam_db_service_info_t, 1);
641 service->name = g_strdup(db_svc->service_name);
642 service->cycle = db_svc->cycle;
643 services = g_slist_append(services, service);
647 svc_list = g_slist_append(svc_list, service);
654 static void __uam_core_add_dev_to_list(
655 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
656 int presence_state, unsigned long long last_seen, GSList *svc_list)
659 uam_db_tech_info_t *tech;
660 uam_db_device_info_t *device;
663 ret_if(NULL == dev_info);
664 ret_if(NULL == user);
666 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
669 ret_if(user != device->user);
670 ret_if(device->supported_techs & dev_info->type);
672 if (device->os != dev_info->operating_system) {
673 UAM_INFO("device->os: %d, dev_info->operating_system: %d",
674 device->os, dev_info->operating_system);
675 /* Update device OS type */
676 if (UAM_OS_TYPE_INVALID == device->os || UAM_OS_TYPE_UNDEFINED == device->os)
677 device->os = dev_info->operating_system;
679 UAM_WARN("Strange - OS types did not match, need to check");
682 device = g_new0(uam_db_device_info_t, 1);
683 device->device_id = g_strdup(dev_info->device_id);
684 device->os = dev_info->operating_system;
685 device->discriminant = dev_info->discriminant;
688 /* Add device to global device list */
689 devices = g_slist_append(devices, device);
691 /* Add same device to user's device list */
692 user->devices = g_slist_append(user->devices, device);
695 tech = g_new0(uam_db_tech_info_t, 1);
696 tech->tech_type = dev_info->type;
697 tech->presence_state = presence_state;
698 tech->last_seen = last_seen;
699 tech->device = device;
700 tech->discriminant = dev_info->discriminant;
702 tech->payload = g_new0(uam_db_ble_payload_t, 1);
703 tech->payload->service_id = dev_info->payload.service_id;
704 tech->payload->purpose = dev_info->payload.purpose;
705 tech->payload->device_icon = dev_info->payload.device_icon;
706 tech->payload->duid = g_memdup(&(dev_info->payload.duid), UAM_BLE_PAYLOAD_DUID_LEN);
707 tech->payload->bt_mac = g_memdup(&(dev_info->payload.bt_mac), UAM_BT_MAC_ADDRESS_STRING_LEN);
709 tech->svc_list = svc_list;
710 g_slist_foreach(tech->svc_list, __print_service, tech);
711 for (l = svc_list; NULL != l; l = g_slist_next(l)) {
712 uam_db_service_info_t *service = l->data;
717 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
720 /* Add tech info to tech list */
721 device->tech_list = g_slist_append(device->tech_list, tech);
722 device->supported_techs |= tech->tech_type;
723 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
725 if (0 < strlen(dev_info->mac)) {
726 uam_db_address_info_t *addr;
728 addr = g_new0(uam_db_address_info_t, 1);
729 addr->address = g_strdup(dev_info->mac);
731 switch (dev_info->type) {
732 case UAM_TECH_TYPE_BLE:
733 addr->addr_type = UAM_ADDR_TYPE_BLE;
735 case UAM_TECH_TYPE_BT:
736 addr->addr_type = UAM_ADDR_TYPE_BT;
738 case UAM_TECH_TYPE_P2P:
739 addr->addr_type = UAM_ADDR_TYPE_P2P;
741 case UAM_TECH_TYPE_WIFI:
742 addr->addr_type = UAM_ADDR_TYPE_WIFI;
745 UAM_ERR("Unknown tech type: %d", dev_info->type);
746 g_free(addr->address);
752 UAM_DBG("MAC address %s added for tech type: %d",
753 dev_info->mac, dev_info->type);
754 tech->addresses = g_slist_append(tech->addresses, addr);
758 if (0 < strlen(dev_info->ipv4_addr)) {
759 uam_db_address_info_t *addr;
761 if (UAM_TECH_TYPE_BLE == dev_info->type ||
762 UAM_TECH_TYPE_BT == dev_info->type)
763 UAM_WARN("IPv4 address %s added for tech type: %d",
764 dev_info->ipv4_addr, dev_info->type);
766 UAM_DBG("IPv4 address %s added for tech type: %d",
767 dev_info->ipv4_addr, dev_info->type);
769 addr = g_new0(uam_db_address_info_t, 1);
770 addr->addr_type = UAM_ADDR_TYPE_IPv4;
771 addr->address = g_strdup(dev_info->ipv4_addr);
773 tech->addresses = g_slist_append(tech->addresses, addr);
779 int _uam_core_add_user(int *user_id, const char *account, const char *name)
783 uam_db_user_info_t *user;
784 int ret = UAM_ERROR_NONE;
786 l = g_slist_find_custom(users, account, __compare_user_account);
787 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
789 user = g_new0(uam_db_user_info_t, 1);
791 /* Add user to database */
792 ret = _uam_db_insert_user_info(&(user->user_id), name, account);
793 if (UAM_ERROR_NONE != ret) {
794 UAM_ERR("_uam_db_insert_user_info failed [%d]", ret);
799 user->name = g_strdup(name);
800 user->account = g_strdup(account);
801 user->devices = NULL;
803 *user_id = user->user_id;
805 users = g_slist_append(users, user);
807 /* Send user added event to application */
808 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
809 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
810 UAM_ERROR_NONE, user->account, user->name)))
811 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
814 return UAM_ERROR_NONE;
817 int _uam_core_remove_user(const char *account)
821 uam_db_user_info_t *user;
822 int ret = UAM_ERROR_NONE;
824 l = g_slist_find_custom(users, account, __compare_user_account);
825 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
828 /* Remove user from database */
829 ret = _uam_db_delete_by_user_id(user->user_id);
830 if (UAM_ERROR_NONE != ret) {
831 UAM_ERR("_uam_db_delete_by_user_id failed");
835 users = g_slist_remove(users, user);
837 /* Send user removed event to application */
838 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
839 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
840 UAM_ERROR_NONE, user->account, user->name)))
841 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
843 ret = __free_uam_db_user_info((gpointer)user);
844 if (UAM_ERROR_NONE != ret) {
845 UAM_WARN("_free_uam_db_user_info failed");
849 return UAM_ERROR_NONE;
852 int _uam_core_update_user(uam_user_info_s *user)
856 uam_db_user_info_t *user_info;
858 retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
860 /* Retrieve user from list */
861 l = g_slist_find_custom(users, user->account, __compare_user_account);
862 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
865 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
867 /* Update user to database */
868 if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
869 UAM_ERR("_uam_db_update_user_info failed");
870 return UAM_ERROR_DB_FAILED;
874 return UAM_ERROR_NONE;
877 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
882 uam_db_device_info_t *device;
883 uam_db_user_info_t *user;
885 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
886 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
888 l = g_slist_find_custom(users, account, __compare_user_account);
889 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
892 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
895 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
896 retv_if((dev_info->type & device->supported_techs),
897 UAM_ERROR_ALREADY_REGISTERED);
900 UAM_INFO("[%d]", user->user_id);
902 ret = _uam_pm_register_device(user->user_id, dev_info);
903 if (UAM_ERROR_NONE != ret) {
904 UAM_ERR("_uam_pm_register_device failed with %s",
905 _uam_manager_error_to_str(ret));
910 return UAM_ERROR_NONE;
913 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
916 uam_db_device_info_t *device;
919 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
920 retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
923 l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
928 if (!(device->supported_techs & dev->type))
931 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
932 uam_db_tech_info_t *tech = l->data;
938 if (dev->type != tech->tech_type)
941 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
942 uam_db_address_info_t *addr = l1->data;
947 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
948 UAM_ADDR_TYPE_BT == addr->addr_type ||
949 UAM_ADDR_TYPE_P2P == addr->addr_type ||
950 UAM_ADDR_TYPE_WIFI == addr->addr_type)
951 if (!strcasecmp(addr->address, dev->mac)) {
960 UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
962 return UAM_ERROR_NONE;
965 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
966 const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
972 ret = _uam_db_get_device_services_count(dev_info->device_id,
973 dev_info->type, dev_info->mac, &count);
974 if (UAM_ERROR_NONE != ret) {
975 UAM_ERR("_uam_db_get_device_services_count failed with %s",
976 _uam_manager_error_to_str(ret));
981 ret = UAM_ERROR_RESOURCE_BUSY;
982 UAM_WARN("other service uses this device ref:[%d]", count);
986 ret = _uam_pm_unregister_device(user_id, dev_info);
987 if (UAM_ERROR_NONE != ret) {
988 UAM_ERR("_uam_pm_unregister_device failed with %s",
989 _uam_manager_error_to_str(ret));
993 /* Send device removed event to application */
994 __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
996 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
997 /* Remove device from database */
998 ret = _uam_device_db_delete_device_info(
999 dev_info->device_id, dev_info->type, dev_info->mac);
1000 if (UAM_ERROR_NONE != ret) {
1001 UAM_ERR("_uam_device_db_delete_device_info failed");
1002 __uam_db_end_transaction(0);
1006 /* Remove device from service */
1007 for (l = tech->svc_list; l; l = g_slist_next(l)) {
1008 uam_db_service_info_t *svc = l->data;
1010 if (!svc || !svc->name)
1012 ret = _uam_core_service_remove_device(svc->name,
1013 dev_info->device_id, dev_info->type);
1014 if (UAM_ERROR_NONE != ret) {
1015 UAM_ERR("_uam_device_db_delete_device_info failed");
1018 __uam_db_end_transaction(1);
1020 /* Remove tech info from device's tech list */
1021 device->tech_list = g_slist_remove(device->tech_list, tech);
1022 device->supported_techs &= ~(tech->tech_type);
1023 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1024 __free_dev_tech_info(tech);
1026 if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1027 /* Remove device from global device list */
1028 devices = g_slist_remove(devices, device);
1030 /* Remove device from user's device list */
1031 device->user->devices = g_slist_remove(device->user->devices, device);
1033 __free_user_device(device);
1036 /* Set/update registered device list to plugins */
1037 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1038 UAM_ERR("_uam_pm_set_registered_devices failed");
1040 /* Set/update registered device list to cloud plugin */
1041 _uam_cloud_update_registered_devices();
1044 return UAM_ERROR_NONE;
1047 int _uam_core_remove_device(const char *account,
1048 const uam_device_info_s *dev_info)
1053 uam_db_tech_info_t *tech;
1054 uam_db_device_info_t *device;
1055 uam_db_user_info_t *user;
1057 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1058 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1060 /* Retrieve user from list */
1061 l = g_slist_find_custom(users, account, __compare_user_account);
1062 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1065 /* Retrieve device from list */
1066 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1067 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1069 retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1070 retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1072 /* Retrieve tech info from list */
1073 l = g_slist_find_custom(device->tech_list,
1074 &(dev_info->type), __compare_tech_type);
1075 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1078 ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1084 int _uam_core_remove_device_by_device_id(const char *device_id,
1090 uam_device_info_s dev_info;
1091 uam_db_tech_info_t *tech;
1092 uam_db_device_info_t *device;
1094 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1095 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1096 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1098 /* Retrieve device from list */
1099 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1100 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1102 retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1104 /* Retrieve tech info from list */
1105 l = g_slist_find_custom(device->tech_list,
1106 &tech_type, __compare_tech_type);
1107 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1111 ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1112 retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1114 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1120 int _uam_core_remove_device_by_mac(const char *mac)
1123 uam_db_tech_info_t *tech;
1124 uam_db_device_info_t *device;
1125 uam_device_info_s dev_info;
1128 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1130 tech = __get_tech_info_by_mac(mac);
1131 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1132 device = tech->device;
1134 ret = __copy_tech_info_to_device_info(tech, &dev_info);
1135 if (UAM_ERROR_NONE != ret) {
1136 UAM_ERR("__copy_tech_info_to_device_info failed");
1140 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1146 int _uam_core_update_device(const uam_device_info_s *a_device)
1150 int ret = UAM_ERROR_NONE;
1151 GSList *l, *l1, *l2;
1153 uam_device_info_s temp;
1154 uam_db_user_info_t *user = NULL;
1155 uam_db_device_info_t *device = NULL;
1156 uam_db_tech_info_t *tech = NULL;
1158 /* Find all tech-devices in users' devices */
1159 for (l = users; NULL != l; l = g_slist_next(l)) {
1162 l1 = g_slist_find_custom(user->devices,
1163 a_device->device_id, __compare_device_id);
1165 UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1166 user->user_id, a_device->device_id);
1171 if (!(device->supported_techs & a_device->type)) {
1172 UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1173 device->device_id, a_device->type);
1177 /* Update discriminant for devices */
1178 device->discriminant = a_device->discriminant;
1179 device->os = a_device->operating_system;
1181 l2 = g_slist_find_custom(device->tech_list,
1182 &(a_device->type), __compare_tech_type);
1184 UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1190 UAM_DBG("Device tech is NULL");
1194 /* Update discriminant for device-tech */
1195 tech->discriminant = a_device->discriminant;
1197 /* Update Payload for device-tech */
1198 tech->payload->service_id = a_device->payload.service_id;
1199 tech->payload->purpose = a_device->payload.purpose;
1200 tech->payload->device_icon = a_device->payload.device_icon;
1201 tech->payload->duid = g_memdup(&(a_device->payload.duid), UAM_BLE_PAYLOAD_DUID_LEN);
1202 tech->payload->bt_mac = g_memdup(&(a_device->payload.bt_mac), UAM_BT_MAC_ADDRESS_STRING_LEN);
1204 /* Update device's updated information to database */
1205 ret = __copy_tech_info_to_device_info(tech, &temp);
1206 if (UAM_ERROR_NONE != ret) {
1207 UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1211 ret = _uam_device_db_update_device_device(temp.device_id, temp.type,
1212 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant,
1214 if (UAM_ERROR_NONE != ret) {
1215 UAM_ERR("_uam_device_db_update_device_device failed [%d]", ret);
1220 /* Set/update registered device list to plugins */
1221 ret = _uam_pm_set_registered_devices(devices);
1222 if (UAM_ERROR_NONE != ret) {
1223 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1227 /* Set/update registered device list to cloud plugin */
1228 _uam_cloud_update_registered_devices();
1234 int _uam_core_get_default_user(uam_user_info_s *user_info)
1240 uam_db_user_info_t *user;
1242 retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1244 ret = _uam_core_add_user(&user_id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1245 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1246 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1250 l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1251 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1254 memset(user_info, 0x00, sizeof(uam_user_info_s));
1255 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1256 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1259 return UAM_ERROR_NONE;
1262 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1268 size = g_slist_length(users);
1269 *user_list = g_new0(uam_user_info_s, size);
1272 /* fetch users list from DB */
1273 for (l = users; l; l = g_slist_next(l)) {
1274 uam_db_user_info_t *db_info = l->data;
1276 if (!db_info || !db_info->account)
1279 g_strlcpy((*user_list)[*count].account,
1280 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1282 g_strlcpy((*user_list)[*count].name,
1283 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1288 UAM_INFO("Count: %d", *count);
1290 return UAM_ERROR_NONE;
1293 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1296 uam_db_user_info_t *db_info;
1299 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1301 l = g_slist_find_custom(users, account, __compare_user_account);
1302 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1305 g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1307 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1311 return UAM_ERROR_NONE;
1314 int _uam_core_get_devcie_by_device_id(
1315 const char *device_id, int tech_type, uam_device_info_s *device)
1318 uam_db_device_info_t *db_info;
1322 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1323 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1324 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1326 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1327 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1329 retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1331 memset(device, 0x00, sizeof(uam_device_info_s));
1333 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1334 uam_db_tech_info_t *tech = l1->data;
1337 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1340 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1341 uam_db_address_info_t *addr = l2->data;
1346 __uam_core_copy_addr(device, addr);
1349 device->operating_system = db_info->os;
1350 g_strlcpy(device->device_id, db_info->device_id,
1351 UAM_DEVICE_ID_MAX_STRING_LEN);
1352 device->type = tech->tech_type;
1353 device->discriminant = tech->discriminant;
1356 retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1359 return UAM_ERROR_NONE;
1362 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1366 uam_db_tech_info_t *tech;
1368 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1370 tech = __get_tech_info_by_mac(mac);
1371 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1373 ret = __copy_tech_info_to_device_info(tech, device);
1374 if (UAM_ERROR_NONE != ret) {
1375 UAM_ERR("__copy_tech_info_to_device_info failed");
1383 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1386 uam_db_device_info_t *dev;
1389 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1391 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1392 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1395 g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1396 if (dev->user->name)
1397 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1400 return UAM_ERROR_NONE;
1403 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1406 uam_db_tech_info_t *tech;
1408 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1410 tech = __get_tech_info_by_mac(mac);
1411 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1413 g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1414 if (tech->device->user->name)
1415 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1418 return UAM_ERROR_NONE;
1421 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1424 int ret = UAM_ERROR_NONE;
1426 ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1432 int _uam_core_get_user_devices(const char *account,
1433 int *count, uam_device_info_s **device_list)
1436 uam_db_user_info_t *user;
1438 int ret = UAM_ERROR_NONE;
1440 l = g_slist_find_custom(users, account, __compare_user_account);
1441 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1444 ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1450 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1454 *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1457 return UAM_ERROR_NONE;
1460 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1465 is_ready = _uam_pm_is_sensor_ready(sensor);
1466 UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1472 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
1473 uam_tech_type_e tech_type, const char *svc_name)
1476 uam_svc_dev_info_t *svc_dev = NULL;
1479 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1482 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1485 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1486 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1487 (svc_dev->tech_type == tech_type)) {
1488 UAM_DBG("Service device found in list");
1497 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1498 const char *svc_name, gboolean discriminant, unsigned long long last_seen)
1501 uam_svc_dev_info_t *svc = NULL;
1503 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1504 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1505 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1506 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1508 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1510 svc = g_new0(uam_svc_dev_info_t, 1);
1511 svc->device_id = g_strdup(device_id);
1512 svc->tech_type = tech_type;
1513 svc->service = g_strdup(svc_name);
1514 svc_devs = g_slist_append(svc_devs, svc);
1517 svc->discriminant = discriminant;
1518 svc->last_seen = last_seen;
1520 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] last_seen[%llu]",
1521 svc->service, svc->device_id, svc->tech_type, svc->discriminant, svc->last_seen);
1524 return UAM_ERROR_NONE;
1527 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
1528 uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant)
1531 uam_svc_dev_info_t *svc = NULL;
1533 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1534 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1535 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1536 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1538 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1540 svc = g_new0(uam_svc_dev_info_t, 1);
1541 svc->device_id = g_strdup(device_id);
1542 svc->tech_type = tech_type;
1543 svc->service = g_strdup(svc_name);
1544 svc_devs = g_slist_append(svc_devs, svc);
1547 svc->discriminant = discriminant;
1549 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]]",
1550 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1553 return UAM_ERROR_NONE;
1556 int _uam_core_service_add_user(const char *svc_name, const char *account)
1560 int ret = UAM_ERROR_NONE;
1561 uam_db_user_info_t *user;
1562 uam_db_service_info_t *service;
1564 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1565 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1567 /* Retrieve user from list */
1568 l = g_slist_find_custom(users, account, __compare_user_account);
1569 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1572 /* Retrieve service from list */
1573 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1574 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1577 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1578 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1579 uam_db_device_info_t *device = l->data;
1585 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1586 uam_db_tech_info_t *tech = l1->data;
1593 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1594 __compare_svc_name);
1598 __add_service_to_dev_tech_mapping(tech, service);
1600 mac = __get_mac_addr(tech);
1601 /* Insert device service info to db */
1602 ret = _uam_db_insert_device_service_info(device->device_id,
1603 tech->tech_type, mac, service->name, service->cycle,
1604 device->discriminant, 0);
1605 if (UAM_ERROR_NONE != ret) {
1606 UAM_WARN("Device service addition to persistent DB failed");
1607 __uam_db_end_transaction(0);
1610 ret = _uam_core_update_svc_dev_info(device->device_id,
1611 tech->tech_type, service->name, device->discriminant, 0);
1612 if (UAM_ERROR_NONE != ret) {
1613 UAM_WARN("Device service addition to service device mapping failed");
1614 __uam_db_end_transaction(0);
1620 __uam_db_end_transaction(1);
1626 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1630 uam_db_user_info_t *user;
1633 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1634 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1636 /* Retrieve user from list */
1637 l = g_slist_find_custom(users, account, __compare_user_account);
1638 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1641 /* Retrieve service from list */
1642 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1643 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1645 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1646 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1647 uam_db_device_info_t *device = l->data;
1653 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1654 uam_db_tech_info_t *tech = l1->data;
1661 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1662 __compare_svc_name);
1666 UAM_DBG("Service %s found, remove it from list", svc_name);
1667 __remove_service_to_dev_tech_mapping(
1668 tech, (uam_db_service_info_t *)l2->data);
1670 mac = __get_mac_addr(tech);
1671 /* Remove service-device from DB */
1672 ret = _uam_db_delete_device_service_info(device->device_id,
1673 tech->tech_type, mac, svc_name);
1674 if (UAM_ERROR_NONE != ret) {
1675 UAM_WARN("Device service removal from persistent DB failed");
1676 __uam_db_end_transaction(0);
1681 __uam_db_end_transaction(1);
1684 return UAM_ERROR_NONE;
1687 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1690 uam_db_device_info_t *device;
1693 retv_if(NULL == device_id, NULL);
1694 retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1695 retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1697 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1699 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1704 if (!device || !(device->supported_techs & tech_type)) {
1705 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1706 tech_type, device_id);
1710 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1711 uam_db_tech_info_t *tech = l->data;
1716 if (tech_type == tech->tech_type) {
1717 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1718 device_id, tech_type);
1723 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1728 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
1734 int ret = UAM_ERROR_NONE;
1735 uam_db_tech_info_t *tech_info;
1736 uam_db_service_info_t *service;
1738 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1739 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1740 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1741 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1743 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1744 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1746 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1747 retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1749 /* Retrieve service from list */
1750 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1751 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1754 __add_service_to_dev_tech_mapping(tech_info, service);
1756 mac = __get_mac_addr(tech_info);
1757 /* Insert device service info to db */
1758 ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
1759 service->name, service->cycle, tech_info->discriminant, 0);
1760 if (UAM_ERROR_NONE != ret) {
1761 UAM_WARN("Device service addition to persistent DB failed");
1764 ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
1765 tech_info->discriminant, 0);
1766 if (UAM_ERROR_NONE != ret) {
1767 UAM_WARN("Device service addition to svc dev mapping failed");
1772 return UAM_ERROR_NONE;
1775 int _uam_core_service_remove_device(const char *svc_name,
1776 const char *device_id, int tech_type)
1781 uam_db_tech_info_t *tech_info;
1782 int ret = UAM_ERROR_NONE;
1784 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1785 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1786 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1787 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1789 /* Retrieve service from list */
1790 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1791 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1793 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1794 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1796 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1797 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1799 __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1801 mac = __get_mac_addr(tech_info);
1802 /* Remove service-device from DB */
1803 ret = _uam_db_delete_device_service_info(
1804 device_id, tech_type, mac, svc_name);
1805 if (UAM_ERROR_NONE != ret) {
1806 UAM_ERR("Device service removal from persistent DB failed");
1811 return UAM_ERROR_NONE;
1814 int _uam_core_service_set_device_discriminant(const char *svc_name,
1815 const char *device_id, int tech_type, gboolean discriminant)
1819 int ret = UAM_ERROR_NONE;
1821 uam_db_tech_info_t *tech_info;
1822 uam_db_service_info_t *service;
1824 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1825 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1826 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1827 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1829 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1830 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1832 /* Retrieve service from list */
1833 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1834 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1837 mac = __get_mac_addr(tech_info);
1838 /* Insert device service info to db */
1839 ret = _uam_db_update_device_service_discriminant(device_id,
1840 tech_type, mac, service->name, discriminant);
1841 if (UAM_ERROR_NONE != ret) {
1842 UAM_WARN("Device service discriminant update to persistent DB failed");
1845 ret = _uam_core_update_svc_dev_info_discriminant(device_id,
1846 tech_type, service->name, discriminant);
1847 if (UAM_ERROR_NONE != ret) {
1848 UAM_WARN("Device service discriminant mapping update failed");
1853 return UAM_ERROR_NONE;
1856 int _uam_core_service_get_device_discriminant(const char *svc_name,
1857 const char *device_id, int tech_type, gboolean *discriminant)
1860 uam_svc_dev_info_t *svc_dev;
1862 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1863 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1864 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1865 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1867 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1868 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1869 *discriminant = (gboolean)svc_dev->discriminant;
1872 return UAM_ERROR_NONE;
1875 int _uam_core_service_get_device_last_seen(const char *svc_name,
1876 const char *device_id, int tech_type, unsigned long long *last_seen)
1879 uam_svc_dev_info_t *svc_dev;
1881 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1882 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1883 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1884 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1886 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1887 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1888 *last_seen = svc_dev->last_seen;
1891 return UAM_ERROR_NONE;
1894 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1898 uam_db_service_info_t *service;
1899 unsigned int elapsed_time;
1901 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1902 retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1903 retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1905 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1906 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1909 elapsed_time = service->cycle - service->remaining_time;
1910 service->cycle = new_cycle;
1911 if (new_cycle < elapsed_time)
1912 service->remaining_time = 0;
1914 service->remaining_time = new_cycle - elapsed_time;
1916 /* Update service detection cycle in DB */
1917 if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1918 UAM_WARN("Service cycle updation to persistent DB failed");
1921 return UAM_ERROR_NONE;
1924 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1928 uam_db_service_info_t *service;
1930 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1931 retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1933 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1934 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1936 *cycle = service->cycle;
1939 return UAM_ERROR_NONE;
1942 int _uam_core_set_detection_threshold(unsigned int sensor,
1943 int presence_threshold, int absence_threshold)
1948 ret = _uam_pm_set_detection_threshold(sensor,
1949 presence_threshold, absence_threshold);
1950 if (UAM_ERROR_NONE != ret) {
1951 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
1952 _uam_manager_error_to_str(ret));
1957 return UAM_ERROR_NONE;
1960 static gboolean __start_detection(gpointer data)
1964 uam_db_service_info_t *service = NULL;
1965 unsigned int sensors;
1966 gboolean start_detection = FALSE;
1968 unsigned int presence_env_sensors;
1969 unsigned int absence_env_sensors;
1971 presence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE);
1972 UAM_DBG("Presence Envionmental sensors: 0x%8.8X", presence_env_sensors);
1974 absence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
1975 UAM_DBG("Absence Envionmental sensors: 0x%8.8X", absence_env_sensors);
1977 if (0 != presence_env_sensors) {
1978 /* Stop PRESENCE detection on active envionmental sensors*/
1979 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
1980 if (UAM_ERROR_NONE != ret)
1981 UAM_ERR("Failed with error: %s (0x%4.4X)",
1982 _uam_manager_error_to_str(ret), ret);
1984 if (0 != absence_env_sensors) {
1985 /* Stop ABSENCE detection on envionmental sensors*/
1986 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
1987 if (UAM_ERROR_NONE != ret)
1988 UAM_ERR("Failed with error: %s (0x%4.4X)",
1989 _uam_manager_error_to_str(ret), ret);
1992 for (l = services; NULL != l; l = g_slist_next(l)) {
1994 if (!service || !service->monitors)
1997 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
1998 UAM_DBG("service->remaining_time: %d", service->remaining_time);
1999 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
2000 if (0 >= service->remaining_time) {
2001 start_detection = TRUE;
2002 service->remaining_time = service->cycle;
2006 if (!start_detection)
2009 /* Get sensors on which PRESENCE detection to be started */
2010 sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
2011 UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
2013 /* Remove env sensors from active sensors */
2014 sensors &= ~presence_env_sensors;
2015 UAM_DBG("Presence Connectivity sensors: 0x%8.8X", sensors);
2018 /* Start PRESENCE detection */
2019 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
2020 if (UAM_ERROR_NONE != ret)
2021 UAM_ERR("Failed with error: %s (0x%4.4X)",
2022 _uam_manager_error_to_str(ret), ret);
2025 /* Get sensors on which ABSENCE detection to be started */
2026 sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2027 UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
2029 /* Remove env sensors from active sensors */
2030 sensors &= ~absence_env_sensors;
2031 UAM_DBG("ABSENCE Connectivity sensors: 0x%8.8X", sensors);
2034 /* Start ABSENCE detection */
2035 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
2036 if (UAM_ERROR_NONE != ret)
2037 UAM_ERR("Failed with error: %s (0x%4.4X)",
2038 _uam_manager_error_to_str(ret), ret);
2042 if (0 != presence_env_sensors) {
2043 /* Always Start PRESENCE detection on active envionmental sensors*/
2044 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2045 if (UAM_ERROR_NONE != ret)
2046 UAM_ERR("Failed with error: %s (0x%4.4X)",
2047 _uam_manager_error_to_str(ret), ret);
2049 if (0 != absence_env_sensors) {
2050 /* Always Start ABSENCE detection on active envionmental sensors*/
2051 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2052 if (UAM_ERROR_NONE != ret)
2053 UAM_ERR("Failed with error: %s (0x%4.4X)",
2054 _uam_manager_error_to_str(ret), ret);
2061 static int __uam_core_start_detection(int detection_type,
2062 const char *svc_name, char *sender, unsigned int sensors)
2065 uam_monitor_info_t *monitor;
2066 uam_db_service_info_t *service;
2067 gboolean is_monitor_added = TRUE;
2070 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2071 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2073 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2075 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
2076 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
2077 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2078 services = g_slist_append(services, default_svc);
2082 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2083 retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2086 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2088 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2090 monitor->name = g_strdup(sender);
2091 monitor->mode = detection_type;
2092 monitor->service = service;
2093 is_monitor_added = FALSE;
2095 UAM_ERR("Memory allocation error");
2096 return UAM_ERROR_OUT_OF_MEMORY;
2100 UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2102 monitor->sensors |= sensors;
2103 if (!is_monitor_added) {
2104 monitors = g_slist_append(monitors, monitor);
2105 service->monitors = g_slist_append(service->monitors, monitor);
2108 /* Start detection */
2109 if (0 == detection_timer) {
2110 __start_detection(NULL);
2111 UAM_INFO("Monitor started detection, start timer");
2112 detection_timer = g_timeout_add_seconds(
2113 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2117 return UAM_ERROR_NONE;
2120 static int __uam_core_stop_detection(int detection_type,
2121 const char *svc_name, char *sender, unsigned int sensors)
2124 int ret = UAM_ERROR_NONE;
2125 unsigned int remaining_sensors;
2126 unsigned int active_sensors;
2127 uam_monitor_info_t *monitor;
2128 uam_db_service_info_t *service;
2130 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2131 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2133 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2134 retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2135 service = monitor->service;
2136 retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2138 /* Find sensors which are already monitoring */
2139 active_sensors = _uam_core_get_active_sensors(detection_type);
2140 UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2141 sensors, active_sensors);
2143 /* Update monitor info for application */
2144 monitor->sensors &= ~sensors;
2145 if (0 == monitor->sensors) {
2147 * App requested to stop monitoring for all of its active sensors,
2148 * remove its monitor info from list.
2150 monitors = g_slist_remove(monitors, monitor);
2151 if ((NULL == monitors) && (0 != detection_timer)) {
2152 UAM_INFO("All monitors stopped detection, stop timer");
2153 g_source_remove(detection_timer);
2154 detection_timer = 0;
2157 service->monitors = g_slist_remove(service->monitors, monitor);
2158 if (NULL == service->monitors)
2159 service->remaining_time = 0;
2161 g_free(monitor->name);
2165 /* Find sensors which are already monitoring */
2166 remaining_sensors = _uam_core_get_active_sensors(detection_type);
2167 UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2169 if (active_sensors == remaining_sensors) {
2170 UAM_INFO("NO need to stop monitoring");
2171 return UAM_ERROR_NONE;
2174 /* Stop monitoring only for sensors which aren't required anymore */
2175 sensors = (active_sensors & ~remaining_sensors);
2176 ret = _uam_pm_stop_detection(detection_type, sensors);
2177 if (UAM_ERROR_NONE != ret)
2178 UAM_ERR("Failed with error: %s (0x%4.4X)",
2179 _uam_manager_error_to_str(ret), ret);
2185 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2190 ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2196 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2201 ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2207 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2212 ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2218 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2223 ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2229 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2234 UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2235 ret = _uam_pm_set_low_power_mode(bitmask, mode);
2236 if (UAM_ERROR_NONE != ret) {
2237 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2238 bitmask, _uam_manager_error_to_str(ret));
2243 return UAM_ERROR_NONE;
2246 int _uam_core_get_detection_window(unsigned int *window)
2250 retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2252 *window = detection_window;
2255 return UAM_ERROR_NONE;
2258 int _uam_core_set_detection_window(unsigned int window)
2262 retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2263 retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2264 retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2266 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2267 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2268 return UAM_ERROR_INTERNAL;
2271 detection_window = window;
2274 return UAM_ERROR_NONE;
2277 int _uam_core_init(void)
2282 GSList *db_svc_list;
2283 GSList *db_adv_list;
2284 GSList *db_svc_dev_list;
2288 _uam_db_initialize();
2290 /* Reset detecton window to default */
2291 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2292 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2293 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2295 /* Fetch user list */
2296 db_users = _uam_db_get_all_users();
2298 UAM_INFO_C("No users in database");
2299 return UAM_ERROR_NONE;
2302 for (l = db_users; NULL != l; l = g_slist_next(l)) {
2303 db_user_info_t *info = l->data;
2304 uam_db_user_info_t *user;
2309 user = g_new0(uam_db_user_info_t, 1);
2310 user->user_id = info->user_id;
2311 user->name = g_strdup(info->name);
2312 user->account = g_strdup(info->account);
2313 user->devices = NULL;
2315 users = g_slist_prepend(users, user);
2318 /* Fetch service list */
2319 db_svc_list = _uam_service_db_get_all_services();
2321 UAM_INFO_C("No services in database");
2322 return UAM_ERROR_NONE;
2325 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2326 db_service_info_t *db_svc = l->data;
2327 uam_db_service_info_t *service;
2333 l1 = g_slist_find_custom(services,
2334 db_svc->service_name, __compare_svc_name);
2336 service = g_new0(uam_db_service_info_t, 1);
2337 service->name = g_strdup(db_svc->service_name);
2338 service->cycle = db_svc->cycle;
2339 service->presence_threshold = db_svc->presence_threshold;
2340 service->absence_threshold = db_svc->absence_threshold;
2341 services = g_slist_append(services, service);
2345 /* Fetch device list */
2346 db_devices = _uam_device_db_get_all_devices();
2348 UAM_INFO_C("No Devices registered in database");
2349 return UAM_ERROR_NONE;
2352 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2353 db_device_info_t *db_info = l->data;
2354 uam_db_user_info_t *user;
2355 GSList *svc_list = NULL;
2361 l1 = g_slist_find_custom(users,
2362 &(db_info->user_id), __compare_user_id);
2364 UAM_ERR("Invalid user Id: %d", db_info->user_id);
2369 /* Fetch device services from DB */
2370 l1 = _uam_db_get_device_services(
2371 db_info->dev_info.device_id,
2372 db_info->dev_info.type,
2373 db_info->dev_info.mac);
2375 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2376 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2377 db_info->presence_state, db_info->last_seen, svc_list);
2380 /* Fetch iBeacon adv list */
2381 db_adv_list = _uam_db_get_all_advs();
2383 UAM_INFO_C("No iBeacon adv in database");
2385 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2386 db_adv_info_t *db_adv = l->data;
2387 _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2391 /* Fetch svc dev list */
2392 db_svc_dev_list = _uam_db_get_service_devices_info();
2393 if (!db_svc_dev_list) {
2394 UAM_INFO_C("No service devices in database");
2396 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2397 db_svc_dev_info_t *db_svc = l->data;
2399 _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
2400 db_svc->svc, db_svc->discriminant, db_svc->last_seen);
2404 g_slist_free_full(db_devices, g_free);
2405 g_slist_free_full(db_users, g_free);
2406 g_slist_free_full(db_svc_list, g_free);
2407 g_slist_free_full(db_adv_list, g_free);
2408 g_slist_free_full(db_svc_dev_list, g_free);
2410 /* Set/update registered device list to plugins */
2411 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2412 UAM_ERR("_uam_pm_set_registered_devices failed");
2414 /* Set/update registered device list to cloud plugin */
2415 _uam_cloud_update_registered_devices();
2418 return UAM_ERROR_NONE;
2421 void _uam_core_deinit(void)
2426 /* de-init database */
2427 _uam_db_deinitialize();
2429 /* Reset detecton window to default */
2430 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2432 /* Release allocated memory for devices */
2433 g_slist_free_full(devices, __free_user_device);
2436 /* Release allocated memory for users */
2437 for (l = users; NULL != l; l = g_slist_next(l)) {
2438 uam_db_user_info_t *user = l->data;
2444 g_free(user->account);
2448 g_slist_free(users);
2451 /* Release allocated memory for services */
2452 for (l = services; NULL != l; l = g_slist_next(l)) {
2453 uam_db_service_info_t *service = l->data;
2458 g_free(service->name);
2461 g_slist_free(services);
2464 /* Release allocated memory for service devices */
2465 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2466 uam_svc_dev_info_t *svc_dev = l->data;
2471 g_free(svc_dev->device_id);
2472 g_free(svc_dev->service);
2475 g_slist_free(svc_devs);
2481 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2485 /* Send sensor state changed event over dbus */
2487 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2488 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2490 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2491 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2496 int _uam_core_handle_device_added(int status,
2497 int user_id, const uam_device_info_s *dev_info)
2502 int ret = UAM_ERROR_NONE;
2503 GSList *svc_list = NULL;
2504 uam_db_user_info_t *user = NULL;
2506 UAM_INFO("[%d]", user_id);
2508 /* Send reply over dbus for add device API */
2509 l = _uam_manager_get_request_list();
2510 for (; NULL != l; l = g_slist_next(l)) {
2511 uam_request_context_t *info = l->data;
2512 uam_device_info_s *dev;
2515 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2520 UAM_WARN("info->data is NULL");
2524 if (dev->type != dev_info->type ||
2525 strcasecmp(dev->device_id, dev_info->device_id)) {
2526 UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2527 dev->device_id, dev_info->device_id);
2531 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2532 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2533 _uam_manager_method_return(info->context, out_param, status);
2535 _uam_remove_timer(info->tid);
2537 _uam_manager_remove_req_ctxt_from_list(info);
2542 if (UAM_ERROR_NONE != status) {
2543 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2549 l = g_slist_find_custom(users,
2550 USER_ACCOUNT_DEFAULT, __compare_user_account);
2552 ret = _uam_core_add_user(&id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2553 if (UAM_ERROR_NONE != ret) {
2554 UAM_ERR("_uam_core_add_user failed with %s",
2555 _uam_manager_error_to_str(ret));
2556 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2562 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2564 UAM_ERR("Invalid user Id: %d", user_id);
2565 ret = UAM_ERROR_NOT_FOUND;
2566 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2571 /* Get default service and add it to device's service list by default */
2572 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2574 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2575 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2576 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2577 services = g_slist_append(services, service);
2578 svc_list = g_slist_append(svc_list, service);
2580 uam_db_service_info_t *service = l->data;
2581 svc_list = g_slist_append(svc_list, service);
2584 __uam_core_add_dev_to_list(user, dev_info,
2585 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen, svc_list);
2587 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2589 /* Add device to database */
2590 ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
2591 UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen);
2592 if (UAM_ERROR_NONE != ret) {
2593 UAM_WARN("Device addition to persistent DB failed");
2594 __uam_db_end_transaction(0);
2598 /* Insert device service info to db */
2599 ret = _uam_db_insert_device_service_info(
2600 dev_info->device_id, dev_info->type, dev_info->mac,
2601 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2602 dev_info->discriminant, 0);
2603 if (UAM_ERROR_NONE != ret) {
2604 UAM_WARN("Device service addition to persistent DB failed");
2605 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2606 __uam_db_end_transaction(0);
2609 __uam_db_end_transaction(1);
2611 ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
2612 UAM_SERVICE_DEFAULT, dev_info->discriminant, 0);
2613 if (UAM_ERROR_NONE != ret) {
2614 UAM_WARN("Device service mappiing update failed");
2615 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2619 /* Send device added event to application */
2620 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2622 /* Set/update registered device list to plugins */
2623 ret = _uam_pm_set_registered_devices(devices);
2624 if (UAM_ERROR_NONE != ret) {
2625 UAM_ERR("_uam_pm_set_registered_devices failed");
2629 _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2631 /* Set/update registered device list to cloud plugin */
2632 if (UAM_ERROR_NONE == status)
2633 _uam_cloud_update_registered_devices();
2639 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2643 unsigned long long timestamp;
2645 UAM_INFO("sensor 0x[%8.8X]", sensor);
2647 if (NULL == sensor_info) {
2648 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2649 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2650 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2655 timestamp = _uam_get_timestamp();
2657 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2658 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2659 g_variant_new("(utiidddd)", sensor, timestamp,
2660 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2661 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2662 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2667 // service specific light detection threshold
2668 for (l = services; NULL != l; l = g_slist_next(l)) {
2669 uam_db_service_info_t *svc = l->data;
2672 if (!svc || !svc->monitors)
2675 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2676 svc->name, sensor_info->values[0], svc->presence_threshold);
2678 if (sensor_info->values[0] < svc->presence_threshold)
2681 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2682 uam_monitor_info_t *mon = l1->data;
2687 UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2688 mon->name, mon->sensors);
2690 if (!(mon->sensors & sensor))
2693 if (UAM_DETECT_PRESENCE != mon->mode)
2696 _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2697 g_variant_new("(utiidddd)", sensor, timestamp,
2698 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2699 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2700 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2708 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
2709 unsigned int sensor)
2714 UAM_INFO("sensor 0x[%8.8X]", sensor);
2716 if (NULL == sensor_info) {
2717 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2718 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2719 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2724 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2725 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2726 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2727 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2728 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2729 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2734 // service specific light detection threshold
2735 for (l = services; NULL != l; l = g_slist_next(l)) {
2736 uam_db_service_info_t *svc = l->data;
2739 if (!svc || !svc->monitors)
2742 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2743 svc->name, sensor_info->values[0], svc->absence_threshold);
2745 if (sensor_info->values[0] > svc->absence_threshold)
2748 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2749 uam_monitor_info_t *mon = l1->data;
2754 if (!(mon->sensors & sensor))
2757 if (UAM_DETECT_PRESENCE != mon->mode)
2760 _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2761 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2762 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2763 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2764 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2771 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2772 uam_device_info_s *dev_info)
2777 uam_db_user_info_t *user;
2778 uam_svc_dev_info_t *svc_dev = NULL;
2779 gboolean live_monitoring = FALSE;
2780 unsigned long long timestamp;
2783 ret_if(NULL == tech);
2784 ret_if(NULL == tech->svc_list);
2785 ret_if(NULL == dev_info);
2787 user = tech->device->user;
2788 user->last_seen = tech->last_seen;
2790 for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2791 uam_db_service_info_t *svc = l->data;
2793 live_monitoring = FALSE;
2795 if (!svc || !svc->monitors)
2798 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2799 svc->name, svc->remaining_time, svc->cycle);
2801 if (!(svc->remaining_time == svc->cycle))
2804 UAM_DBG("Check service device discriminant");
2805 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2806 dev_info->type, svc->name);
2807 if (!svc_dev || !svc_dev->discriminant)
2810 UAM_DBG("Send event");
2811 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2812 uam_monitor_info_t *mon = l1->data;
2817 if (!(mon->sensors & sensor))
2820 if (UAM_DETECT_PRESENCE != mon->mode)
2824 * For current service, if any of its running monitor has same sensor
2825 * and detection_mode
2827 live_monitoring = TRUE;
2829 timestamp = _uam_get_timestamp();
2830 UAM_INFO("sensor [%d]", sensor);
2831 _uam_manager_send_event(mon->name,
2832 UAM_EVENT_USER_PRESENCE_DETECTED,
2833 g_variant_new("(utsss)", sensor, timestamp,
2834 user->account, svc->name, dev_info->device_id));
2835 UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2837 " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
2838 mon->name, dev_info->device_id,
2839 sensor, user->account,
2844 /* Update service specific device last_seen in svc_dev list and DB */
2845 if (live_monitoring) {
2846 svc_dev->last_seen = tech->last_seen;
2847 ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
2848 dev_info->type, dev_info->mac, svc->name, tech->last_seen);
2849 if (UAM_ERROR_NONE != ret)
2850 UAM_WARN("_uam_db_update_device_service_last_seen failed");
2857 int _uam_core_handle_presence_detected(unsigned int sensor,
2858 int user_id, void *info)
2861 int ret = UAM_ERROR_NONE;
2864 uam_db_user_info_t *user;
2865 uam_db_device_info_t *device;
2866 uam_db_tech_info_t *tech;
2868 uam_device_info_s *dev_info = NULL;
2869 uam_sensor_info_s *sensor_info = NULL;
2871 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2873 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2875 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2878 _uam_vpm_send_presence_detection_event(sensor);
2880 if (NULL == dev_info) {
2881 __send_sensor_presence_event(sensor_info, sensor);
2885 retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
2887 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2889 UAM_ERR("Invalid user_id [%d]", user_id);
2890 return UAM_ERROR_INVALID_PARAMETER;
2894 l = g_slist_find_custom(user->devices,
2895 dev_info->device_id, __compare_device_id);
2897 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2898 user_id, dev_info->device_id);
2899 return UAM_ERROR_INVALID_PARAMETER;
2902 if (!(device->supported_techs & dev_info->type)) {
2903 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2904 dev_info->device_id, dev_info->type);
2905 return UAM_ERROR_INVALID_PARAMETER;
2908 l = g_slist_find_custom(device->tech_list,
2909 &(dev_info->type), __compare_tech_type);
2911 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2912 return UAM_ERROR_INVALID_PARAMETER;
2916 tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2917 tech->last_seen = dev_info->last_seen;
2919 retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
2921 /* Check if IP/MAC address was updated then update in DB */
2922 if (UAM_TECH_TYPE_WIFI == dev_info->type) {
2924 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2925 uam_db_address_info_t *addr = l->data;
2930 if (UAM_ADDR_TYPE_IPv4 == addr->addr_type) {
2932 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
2933 UAM_DBG("Old IPv4: %s, New IPv4: %s",
2934 addr->address, dev_info->ipv4_addr);
2936 g_free(addr->address);
2937 addr->addr_type = UAM_ADDR_TYPE_IPv4;
2938 addr->address = g_strdup(dev_info->ipv4_addr);
2940 /* Update IP address in DB */
2941 ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
2942 dev_info->type, dev_info->ipv4_addr);
2943 if (UAM_ERROR_NONE != ret) {
2944 UAM_WARN("_uam_device_db_update_device_ip_address failed");
2945 __uam_db_end_transaction(0);
2951 if (UAM_ADDR_TYPE_WIFI == addr->addr_type) {
2953 if (strcasecmp(addr->address, dev_info->mac)) {
2954 UAM_DBG("Old MAC: %s, New MAC: %s",
2955 addr->address, dev_info->mac);
2957 g_free(addr->address);
2958 addr->addr_type = UAM_ADDR_TYPE_WIFI;
2959 addr->address = g_strdup(dev_info->mac);
2961 /* Update address in DB */
2962 ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
2963 dev_info->type, dev_info->mac);
2964 if (UAM_ERROR_NONE != ret) {
2965 UAM_WARN("_uam_device_db_update_device_mac_address failed");
2966 __uam_db_end_transaction(0);
2974 /* Update database (presence state & timestamp) */
2975 ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
2976 dev_info->type, dev_info->mac, dev_info->last_seen);
2977 if (UAM_ERROR_NONE != ret) {
2978 UAM_WARN("_uam_device_db_update_device_last_seen failed");
2979 __uam_db_end_transaction(0);
2983 ret = _uam_device_db_update_device_presence(dev_info->device_id,
2984 dev_info->type, dev_info->mac, tech->presence_state);
2985 if (UAM_ERROR_NONE != ret) {
2986 UAM_WARN("_uam_device_db_update_device_presence failed");
2987 __uam_db_end_transaction(0);
2991 /* Send user presence event and update service_device timestamp */
2992 __send_user_presence_event(tech, sensor, dev_info);
2993 __uam_db_end_transaction(1);
2999 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
3005 * For each service, find users absent on given sensor. Then for each
3006 * monitor in serivce's monitor list, if it is monitoring ABSENCE on
3007 * given sensor, send user ABSENCE event.
3009 for (l = services; NULL != l; l = g_slist_next(l)) {
3010 uam_db_service_info_t *svc = l->data;
3011 GSList *absent_users = NULL;
3012 GSList *present_users = NULL;
3016 if (!svc || !svc->monitors || !svc->dev_techs)
3019 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3020 uam_db_tech_info_t *tech = l1->data;
3022 if (!tech || (tech->tech_type != type)) {
3023 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
3027 if (!tech->device || !tech->device->user) {
3028 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
3032 l2 = g_slist_find_custom(present_users,
3033 &(tech->device->user->user_id), __compare_user_id);
3035 if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
3036 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
3038 tech->device->device_id,
3039 tech->device->user->account);
3040 /* Remove user from absent list */
3041 absent_users = g_slist_remove(absent_users, tech->device->user);
3043 /* If user not in present list, add user to the list */
3045 UAM_DBG("added present user [%s]", tech->device->user->account);
3046 present_users = g_slist_prepend(present_users, tech->device->user);
3049 /* If user not in the present list then only add it to absent list */
3050 if ((NULL == l2) && (NULL == g_slist_find_custom(
3051 absent_users, &(tech->device->user->user_id),
3052 __compare_user_id))) {
3053 UAM_DBG("added absent user [%s]", tech->device->user->account);
3054 absent_users = g_slist_prepend(absent_users, tech->device->user);
3059 g_slist_free(present_users);
3063 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
3064 uam_monitor_info_t *mon = l2->data;
3069 if (!(mon->sensors & sensor))
3072 if (UAM_DETECT_ABSENCE != mon->mode)
3075 for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
3076 uam_db_user_info_t *user = l1->data;
3081 user->last_seen = 0;
3083 _uam_manager_send_event(mon->name,
3084 UAM_EVENT_USER_ABSENCE_DETECTED,
3085 g_variant_new("(utss)", sensor, user->last_seen,
3086 user->account, svc->name));
3087 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
3088 " for 0x%8.8X, User: %s Service: %s",
3089 mon->name, sensor, user->account, svc->name);
3093 g_slist_free(absent_users);
3099 void _uam_core_handle_absence_detected(unsigned int sensor,
3100 int user_id, void *info)
3103 uam_db_user_info_t *user;
3104 uam_db_device_info_t *device;
3105 uam_db_tech_info_t *tech;
3107 uam_device_info_s *dev_info = NULL;
3108 uam_sensor_info_s *sensor_info = NULL;
3110 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3112 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3114 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3117 if (NULL == dev_info) {
3118 __send_sensor_absence_event(sensor_info, sensor);
3123 ret_if(0 > user_id);
3125 l = g_slist_find_custom(users, &user_id, __compare_user_id);
3127 UAM_ERR("Invalid user_id [%d]", user_id);
3132 l = g_slist_find_custom(user->devices,
3133 dev_info->device_id, __compare_device_id);
3135 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3136 user_id, dev_info->device_id);
3140 if (!(device->supported_techs & dev_info->type)) {
3141 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3142 dev_info->device_id, dev_info->type);
3146 l = g_slist_find_custom(device->tech_list,
3147 &(dev_info->type), __compare_tech_type);
3149 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3154 tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
3156 /* Update database (presence state) */
3157 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
3158 dev_info->type, dev_info->mac, tech->presence_state))
3159 UAM_WARN("_uam_device_db_update_device_presence failed");
3164 void _uam_core_cleanup_monitor(char *name)
3168 for (l = monitors; NULL != l; l = g_slist_next(l)) {
3169 uam_monitor_info_t *monitor = l->data;
3171 if (!monitor || !monitor->name || !monitor->service)
3174 if (0 != g_strcmp0(name, monitor->name))
3177 /* If there is a monitor that is not freed, stop detection
3178 * and free the monitor structure in the memory. */
3179 UAM_INFO("clear %s's monitor info.", monitor->name);
3180 __uam_core_stop_detection(monitor->mode,
3181 monitor->service->name, name, monitor->sensors);
3185 static void __free_user_info(gpointer data)
3188 uam_db_user_info_t *user = data;
3190 ret_if(NULL == user);
3193 g_free(user->account);
3198 static void __free_service_info(gpointer data)
3201 uam_db_service_info_t *svc = data;
3203 ret_if(NULL == svc);
3210 static void __free_monitor_info(gpointer data)
3213 uam_monitor_info_t *monitor = data;
3215 ret_if(NULL == monitor);
3217 g_free(monitor->name);
3222 static void __free_scanner_info(gpointer data)
3225 uam_scanner_info_t *scanner = data;
3227 ret_if(NULL == scanner);
3229 g_free(scanner->name);
3234 void _uam_core_reset_database(void)
3239 ret = _uam_db_clear();
3240 if (UAM_ERROR_NONE != ret) {
3241 UAM_ERR("_uam_db_clear failed with %s",
3242 _uam_manager_error_to_str(ret));
3243 unlink(DATABASE_FULL_PATH);
3247 g_slist_free_full(devices, __free_user_device);
3250 g_slist_free_full(users, __free_user_info);
3253 g_slist_free_full(services, __free_service_info);
3256 g_slist_free_full(monitors, __free_monitor_info);
3259 g_slist_free_full(scanners, __free_scanner_info);
3262 /* Set/update registered device list to plugins */
3263 ret = _uam_pm_set_registered_devices(devices);
3264 if (UAM_ERROR_NONE != ret)
3265 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3266 _uam_manager_error_to_str(ret));
3268 /* Set/update registered device list to cloud plugin */
3269 _uam_cloud_update_registered_devices();
3274 void _uam_core_handle_detection_started(unsigned int sensor)
3277 unsigned int active_sensors = 0;
3279 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3280 sensor, detecting_sensors);
3282 detecting_sensors |= sensor;
3283 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3284 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3285 if (active_sensors == detecting_sensors) {
3286 /* Send detection started event */
3287 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3293 void _uam_core_handle_detection_stopped(unsigned int sensor)
3297 uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3298 uam_cycle_state_e cycle_state;
3301 ret_if((detecting_sensors & sensor) == 0);
3302 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3303 sensor, detecting_sensors);
3304 detecting_sensors &= ~sensor;
3306 if (UAM_SENSOR_BITMASK_BLE == sensor)
3307 type = UAM_TECH_TYPE_BLE;
3308 else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3309 type = UAM_TECH_TYPE_WIFI;
3311 if (UAM_TECH_TYPE_NONE != type)
3312 __send_user_absence_event(type, sensor);
3314 if (0 == detecting_sensors) {
3315 /* Send detection stopped event */
3316 for (l = monitors; l; l = g_slist_next(l)) {
3317 uam_monitor_info_t *mon = l->data;
3319 if (!mon || !mon->name || !mon->service)
3321 uam_db_service_info_t *service = mon->service;
3322 cycle_state = UAM_DETECTION_CYCLE_END;
3324 UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d", mon->sensors, service->name, service->remaining_time);
3325 if (!(mon->sensors & _uam_core_get_env_sensors())) {
3326 if (service->remaining_time < service->cycle) {
3327 UAM_DBG("service->remaining_time < service->cycle, return");
3330 } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
3331 cycle_state = UAM_DETECTION_CYCLE_MID;
3334 _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
3335 g_variant_new("(si)", service->name, cycle_state));
3336 UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
3337 " cycle state:[%s]",
3338 mon->name, service->name, cycle_state ? "end" : "mid");
3344 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3348 retv_if(NULL == name, NULL);
3350 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3351 uam_scanner_info_t *scanner = l->data;
3353 if (!scanner || !scanner->name)
3356 if (0 == g_strcmp0(scanner->name, name)) {
3357 UAM_DBG("Scanning application found in list");
3365 static gboolean __scan_completed_cb(gpointer data)
3368 uam_scanner_info_t *scanner = data;
3370 retv_if(NULL == scanner, FALSE);
3372 if (UAM_ERROR_NONE != _uam_manager_send_event(
3373 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3374 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3376 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3379 scanners = g_slist_remove(scanners, scanner);
3380 g_free(scanner->name);
3387 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3391 uam_scanner_info_t *scanner;
3393 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3394 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3396 scanner = __uam_find_scanner(sender);
3397 retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3399 ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3400 if (UAM_ERROR_NONE != ret) {
3401 UAM_ERR("Failed with error: %s (0x%4.4X)",
3402 _uam_manager_error_to_str(ret), ret);
3406 scanner = g_malloc0(sizeof(uam_scanner_info_t));
3408 UAM_ERR("Failed to allocate memory");
3409 return UAM_ERROR_OUT_OF_MEMORY;
3411 scanner->name = g_strdup(sender);
3412 scanner->sensors |= sensors;
3413 scanner->timer = g_timeout_add_seconds(detection_period,
3414 __scan_completed_cb, scanner);
3415 scanners = g_slist_append(scanners, scanner);
3416 UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3419 return UAM_ERROR_NONE;
3422 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3426 uam_scanner_info_t *scanner;
3429 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3430 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3432 scanner = __uam_find_scanner(sender);
3433 retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3435 /* Trim sensors to a subset of active sensors for the scanner */
3436 sensors &= scanner->sensors;
3439 * modify scanner's active sensors and if active sensors are NULL
3440 * remove scanner from scanners list
3442 scanner->sensors &= ~sensors;
3443 if (0 == scanner->sensors) {
3444 scanners = g_slist_remove(scanners, scanner);
3445 g_source_remove(scanner->timer);
3446 g_free(scanner->name);
3450 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3451 uam_scanner_info_t *scanner_data = l->data;
3453 if (!scanner_data || !scanner_data->name)
3456 sensors &= ~(scanner_data->sensors);
3460 ret = _uam_pm_stop_active_device_scan(sensors);
3461 if (UAM_ERROR_NONE != ret) {
3462 UAM_ERR("Failed with error: %s (0x%4.4X)",
3463 _uam_manager_error_to_str(ret), ret);
3469 return UAM_ERROR_NONE;
3472 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3473 unsigned int sensor, const uam_device_info_s *dev_info)
3478 ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3480 for (l = scanners; NULL != l;) {
3481 uam_scanner_info_t *scanner = l->data;
3483 if (!scanner || !scanner->name) {
3484 l = g_slist_next(l);
3488 if (0 == (scanner->sensors & sensor)) {
3489 l = g_slist_next(l);
3493 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3494 scanner->sensors &= ~(sensor);
3495 UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3496 if (0 != scanner->sensors) {
3497 l = g_slist_next(l);
3501 if (UAM_ERROR_NONE != _uam_manager_send_event(
3502 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3503 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3505 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3508 l = g_slist_next(l);
3509 scanners = g_slist_remove(scanners, scanner);
3510 g_source_remove(scanner->timer);
3511 g_free(scanner->name);
3514 GVariant *param = g_variant_new("(iiisss)",
3516 dev_info->operating_system,
3519 dev_info->ipv4_addr,
3520 dev_info->device_id);
3521 if (UAM_ERROR_NONE != _uam_manager_send_event(
3522 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3523 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3525 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3527 l = g_slist_next(l);
3534 int _uam_core_register_service(uam_service_info_s *svc)
3538 uam_db_service_info_t *service;
3539 int service_number = 0;
3541 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3543 /* Retrieve service from list */
3544 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3545 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3547 service = g_new0(uam_db_service_info_t, 1);
3548 service->name = g_strdup(svc->name);
3549 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3550 service->presence_threshold = svc->presence_threshold;
3551 service->absence_threshold = svc->absence_threshold;
3553 /* Add service to database */
3554 if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3555 UAM_ERR("_uam_db_insert_service_info failed");
3557 return UAM_ERROR_DB_FAILED;
3560 services = g_slist_append(services, service);
3562 /* Send service registered event to application */
3563 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3564 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3565 UAM_ERROR_NONE, service->name)))
3566 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3569 return UAM_ERROR_NONE;
3572 int _uam_core_update_service(uam_service_info_s *svc)
3576 uam_db_service_info_t *service;
3578 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3580 /* Retrieve service from list */
3581 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3582 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3585 service->presence_threshold = svc->presence_threshold;
3586 service->absence_threshold = svc->absence_threshold;
3588 /* Update service to database */
3589 if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3590 UAM_ERR("_uam_db_update_service_info failed");
3591 return UAM_ERROR_DB_FAILED;
3595 return UAM_ERROR_NONE;
3598 int _uam_core_get_default_service(uam_service_info_s *service_info)
3603 uam_db_service_info_t *service;
3605 retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3607 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3610 // insert default service
3611 memset(service_info, 0x00, sizeof(uam_service_info_s));
3612 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3613 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3614 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3616 ret = _uam_core_register_service(service_info);
3617 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3618 UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3621 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3624 retv_if(NULL == l, UAM_ERROR_INTERNAL);
3627 memset(service_info, 0x00, sizeof(uam_service_info_s));
3628 g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3631 return UAM_ERROR_NONE;
3634 int _uam_core_unregister_service(const char *svc_name)
3638 uam_db_service_info_t *service;
3640 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3642 /* Retrieve service from list */
3643 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3644 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3647 /* Check if service is being used*/
3648 if (service->monitors) {
3649 UAM_ERR("service monitoring in progress");
3650 return UAM_ERROR_PERMISSION_DENIED;
3653 /* Remove service from database */
3654 if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3655 UAM_ERR("_uam_db_delete_service_info failed");
3656 return UAM_ERROR_DB_FAILED;
3659 /* Remove service mapping from devices*/
3660 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3661 uam_db_tech_info_t *tech = l->data;
3662 if (!tech || !tech->addresses)
3664 tech->svc_list = g_slist_remove(tech->svc_list, service);
3666 services = g_slist_remove(services, service);
3668 /* Send service unregistered event to application */
3669 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3670 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3671 UAM_ERROR_NONE, service->name)))
3672 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3675 return UAM_ERROR_NONE;
3678 static int __get_service_dev_list(
3679 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3685 int ret = UAM_ERROR_NONE;
3686 uam_svc_dev_info_t *svc_dev = NULL;
3687 uam_device_info_s *dev = NULL;
3690 /* Calculate number of devices */
3691 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3692 uam_db_tech_info_t *tech = l1->data;
3693 if (!tech || !tech->addresses)
3699 *device_list = g_new0(uam_device_info_s, *count);
3702 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3703 uam_db_tech_info_t *tech = l1->data;
3705 if (!tech || !tech->addresses)
3708 /* Copy tech info to device info */
3709 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
3710 if (UAM_ERROR_NONE != ret) {
3711 UAM_ERR("__copy_tech_info_to_device_info failed");
3715 (*device_list)[indx].last_seen = 0;
3719 UAM_INFO("Count = %d, indx = %d", *count, indx);
3721 /* Update service specific device last time */
3722 for (s = svc_devs; s; s = g_slist_next(s)) {
3725 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
3727 if (g_strcmp0(svc_dev->service, service->name))
3730 for (indx = 0; indx < *count; indx++) {
3731 dev = &((*device_list)[indx]);
3733 if (svc_dev->tech_type != dev->type ||
3734 g_strcmp0(svc_dev->device_id, dev->device_id))
3737 dev->last_seen = svc_dev->last_seen;
3745 int _uam_core_get_service_devices(const char *svc_name,
3746 int *count, uam_device_info_s **device_list)
3749 uam_db_service_info_t *service;
3751 int ret = UAM_ERROR_NONE;
3753 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3754 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3757 ret = __get_service_dev_list(service, device_list, count);
3763 static void __get_service_user_list(
3764 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3769 GSList *svc_user_list = NULL;
3772 /* Calculate number of users */
3773 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3774 uam_db_tech_info_t *tech = l->data;
3775 if (!tech || !tech->addresses)
3779 uam_db_user_info_t *db_info = tech->device->user;
3780 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3782 svc_user_list = g_slist_append(svc_user_list, db_info);
3785 *count = g_slist_length(svc_user_list);
3786 *user_list = g_new0(uam_user_info_s, *count);
3789 for (l = svc_user_list; l; l = g_slist_next(l)) {
3790 uam_db_user_info_t *db_info = l->data;
3792 if (!db_info || !db_info->account)
3795 g_strlcpy((*user_list)[indx].account,
3796 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3798 g_strlcpy((*user_list)[indx].name,
3799 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3804 UAM_INFO("Count = %d, indx = %d", *count, indx);
3808 int _uam_core_get_service_users(const char *svc_name,
3809 int *count, uam_user_info_s **user_list)
3812 uam_db_service_info_t *service;
3815 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3816 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3819 __get_service_user_list(service, user_list, count);
3822 return UAM_ERROR_NONE;
3825 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3831 size = g_slist_length(services);
3832 *service_list = g_new0(uam_service_info_s, size);
3835 /* fetch services list from DB */
3836 for (l = services; l; l = g_slist_next(l)) {
3837 uam_db_service_info_t *db_info = l->data;
3839 if (!db_info || !db_info->name)
3842 g_strlcpy((*service_list)[*count].name,
3843 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3844 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3845 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3849 UAM_INFO("Count: %d", *count);
3851 return UAM_ERROR_NONE;
3854 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3859 UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3860 iadv[0], iadv[1], iadv[2]);
3862 ret = _uam_db_insert_adv_info(adv_len, iadv);
3863 if (UAM_ERROR_NONE != ret) {
3864 UAM_ERR("_uam_db_insert_adv_info failed");
3868 ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3869 if (UAM_ERROR_NONE != ret) {
3870 UAM_ERR("Failed with error: %s (0x%4.4X)",
3871 _uam_manager_error_to_str(ret), ret);
3876 return UAM_ERROR_NONE;
3879 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
3883 uam_sensor_info_s *sensor_info = info;
3885 ret_if(NULL == info);
3887 UAM_DBG("%d %d %llu %d %d", sensor, sensor_info->status, sensor_info->timestamp,
3888 sensor_info->accuracy, sensor_info->count);
3890 UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
3891 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
3893 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3894 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
3895 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3896 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));