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-power-plugin-manager.h"
31 #define UAM_MAX_USERS 255
32 #define USER_ACCOUNT_DEFAULT "default@default.com"
33 #define USER_NAME_DEFAULT "default"
34 #define USER_ACCOUNT_DEFAULT_ID 1
39 uam_pm_detection_mode_e mode;
40 uam_db_service_info_t *service;
49 static GSList *users; /* List of users - uam_db_user_info_t */
50 static GSList *devices; /* List of devices - uam_db_device_info_t */
51 static GSList *services; /* List of services - uam_db_service_info_t */
52 static GSList *svc_devs; /* List of service device mapping - uam_svc_dev_info_t */
54 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
55 static GSList *scanners; /* List of scanning apps - uam_scanner_info_t */
57 static guint detection_timer = 0;
58 static unsigned int detection_window;
60 static unsigned int detecting_sensors = 0;
62 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
64 const uam_db_user_info_t *user = data;
65 const char *account = user_data;
67 retv_if(NULL == user, -1);
68 retv_if(NULL == user->account, -1);
69 retv_if(NULL == account, -1);
71 return g_strcmp0(user->account, account);
74 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
76 const uam_db_user_info_t *user = data;
77 const unsigned short *id = user_data;
79 retv_if(NULL == user, -1);
80 retv_if(NULL == user->account, -1);
81 retv_if(NULL == id, -1);
83 if (*id != user->user_id)
89 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
91 const uam_db_service_info_t *service = data;
92 const char *svc_name = user_data;
94 retv_if(NULL == service, -1);
95 retv_if(NULL == service->name, -1);
96 retv_if(NULL == svc_name, -1);
98 return g_strcmp0(service->name, svc_name);
101 static void __free_address_info(gpointer data)
104 uam_db_address_info_t *addr = data;
106 ret_if(NULL == addr);
108 g_free(addr->address);
114 static void __free_dev_tech_info(gpointer data)
117 uam_db_tech_info_t *tech_info = data;
120 ret_if(NULL == tech_info);
122 /* Delete the tech information from the service list that includes tech. */
123 for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
124 uam_db_service_info_t *svc_info = l->data;
126 if (!svc_info || !svc_info->dev_techs)
129 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
132 g_slist_free_full(tech_info->addresses, __free_address_info);
133 tech_info->addresses = NULL;
135 if (tech_info->payload) {
136 if (tech_info->payload->duid) {
137 g_free(tech_info->payload->duid);
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 __remove_user_device(gpointer data)
258 uam_db_device_info_t *device = data;
259 uam_device_info_s dev_info;
260 unsigned short user_id;
263 ret_if(NULL == device);
265 user_id = device->user->user_id;
266 dev_info.operating_system = device->os;
267 g_strlcpy(dev_info.device_id, device->device_id, UAM_DEVICE_ID_MAX_STRING_LEN);
269 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
270 uam_db_tech_info_t *tech = l->data;
277 /* Delete the tech information from the service list that includes tech. */
278 for (l2 = tech->svc_list; NULL != l2; l2 = g_slist_next(l2)) {
279 uam_db_service_info_t *svc_info = l2->data;
281 if (!svc_info || !svc_info->dev_techs)
284 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech);
287 dev_info.type = tech->tech_type;
288 memset(dev_info.mac, 0x00, UAM_MAC_ADDRESS_STRING_LEN);
289 memset(dev_info.ipv4_addr, 0x00, UAM_IP_ADDRESS_MAX_STRING_LEN);
291 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
292 uam_db_address_info_t *addr = l1->data;
297 switch (addr->addr_type) {
298 case UAM_ADDR_TYPE_BT:
299 case UAM_ADDR_TYPE_BLE:
300 case UAM_ADDR_TYPE_P2P:
301 case UAM_ADDR_TYPE_WIFI:
302 g_strlcpy(dev_info.mac, addr->address,
303 UAM_MAC_ADDRESS_STRING_LEN);
305 case UAM_ADDR_TYPE_IPv4:
306 g_strlcpy(dev_info.ipv4_addr, addr->address,
307 UAM_IP_ADDRESS_MAX_STRING_LEN);
310 UAM_WARN("Address type %d ignored", addr->addr_type);
314 ret = _uam_pm_unregister_device(user_id, &dev_info);
315 if (UAM_ERROR_NONE != ret)
316 UAM_ERR("_uam_pm_unregister_device failed with %s",
317 _uam_manager_error_to_str(ret));
319 /* Send device removed event to application */
320 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
322 /* Remove device from database */
323 if (UAM_ERROR_NONE != _uam_device_db_delete_device_info(
324 dev_info.device_id, dev_info.type, dev_info.mac))
325 UAM_ERR("_uam_device_db_delete_device_info failed");
328 __free_user_device(device);
333 static void __free_uam_db_user_info(gpointer data)
336 uam_db_user_info_t *user = data;
338 g_slist_free_full(user->devices, __remove_user_device);
340 /* Set/update registered device list to plugins */
341 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
342 UAM_ERR("_uam_pm_set_registered_devices failed");
344 /* Set/update registered device list to cloud plugin */
345 _uam_cloud_update_registered_devices();
348 g_free(user->account);
353 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
356 const uam_db_device_info_t *device = data;
357 const char *dev_id = user_data;
359 retv_if(NULL == device, -1);
360 retv_if(NULL == device->device_id, -1);
361 retv_if(NULL == dev_id, -1);
364 return g_strcmp0(device->device_id, dev_id);
367 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
370 const uam_db_tech_info_t *tech = data;
371 const int *type = user_data;
373 retv_if(NULL == tech, -1);
374 retv_if(NULL == type, -1);
377 return ((*type == tech->tech_type) ? 0 : 1);
380 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
385 for (l = devices; NULL != l; l = g_slist_next(l)) {
386 uam_db_device_info_t *dev = l->data;
392 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
393 uam_db_tech_info_t *tech = l1->data;
399 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
400 uam_db_address_info_t *addr = l2->data;
405 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
406 UAM_ADDR_TYPE_BT == addr->addr_type ||
407 UAM_ADDR_TYPE_P2P == addr->addr_type ||
408 UAM_ADDR_TYPE_WIFI == addr->addr_type)
409 if (!strcasecmp(addr->address, mac)) {
410 UAM_DBG("Device found Mac: %s, type: %d",
411 addr->address, addr->addr_type);
422 static void __get_uam_db_dev_list_to_uam_dev_list(
423 GSList *db_dev_list, uam_device_info_s **device_list, int *count)
430 /* Calculate num devices first */
431 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
432 uam_db_device_info_t *db_info = l->data;
435 if (!db_info || !db_info->device_id)
438 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
439 uam_db_tech_info_t *tech = l1->data;
441 if (!tech || !tech->addresses)
447 UAM_INFO("Count = %d", *count);
449 *device_list = g_new0(uam_device_info_s, *count);
452 for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
453 uam_db_device_info_t *db_info = l->data;
456 if (!db_info || !db_info->device_id)
459 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
460 uam_db_tech_info_t *tech = l1->data;
463 if (!tech || !tech->addresses)
466 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
467 uam_db_address_info_t *addr = l2->data;
472 switch (addr->addr_type) {
473 case UAM_ADDR_TYPE_BLE:
474 case UAM_ADDR_TYPE_BT:
475 case UAM_ADDR_TYPE_P2P:
476 case UAM_ADDR_TYPE_WIFI:
477 g_strlcpy((*device_list)[indx].mac,
479 UAM_MAC_ADDRESS_STRING_LEN);
481 case UAM_ADDR_TYPE_IPv4:
482 g_strlcpy((*device_list)[indx].ipv4_addr,
484 UAM_IP_ADDRESS_MAX_STRING_LEN);
487 UAM_WARN("Unknown address type %d", addr->addr_type);
491 (*device_list)[indx].operating_system = db_info->os;
492 g_strlcpy((*device_list)[indx].device_id, db_info->device_id,
493 UAM_DEVICE_ID_MAX_STRING_LEN);
495 memset((*device_list)[indx].payload.duid, 0, UAM_BLE_PAYLOAD_DUID_LEN + 1);
496 memset((*device_list)[indx].payload.bt_mac, 0, UAM_BT_MAC_ADDRESS_STRING_LEN);
498 (*device_list)[indx].payload.service_id = tech->payload->service_id;
499 (*device_list)[indx].payload.device_icon = tech->payload->device_icon;
500 (*device_list)[indx].payload.purpose = tech->payload->purpose;
501 if (tech->payload->duid)
502 memcpy((*device_list)[indx].payload.duid,
503 tech->payload->duid, UAM_BLE_PAYLOAD_DUID_LEN);
504 if (tech->payload->bt_mac)
505 g_strlcpy((*device_list)[indx].payload.bt_mac,
506 tech->payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
509 (*device_list)[indx].discriminant = tech->discriminant;
510 (*device_list)[indx].last_seen = tech->timestamp;
511 (*device_list)[indx++].type = tech->tech_type;
512 UAM_INFO("%s-%d-%s-%s-%llu-%d-%d-0x%2.2X", (*device_list)[indx-1].device_id,
513 (*device_list)[indx-1].type, (*device_list)[indx-1].mac, (*device_list)[indx-1].ipv4_addr,
514 (*device_list)[indx-1].last_seen, (*device_list)[indx-1].operating_system,
515 (*device_list)[indx-1].discriminant, (*device_list)[indx-1].payload.service_id);
519 UAM_INFO("Count = %d, indx = %d", *count, indx);
523 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
525 switch (addr->addr_type) {
526 case UAM_ADDR_TYPE_BLE:
527 case UAM_ADDR_TYPE_BT:
528 case UAM_ADDR_TYPE_P2P:
529 case UAM_ADDR_TYPE_WIFI:
530 g_strlcpy(device->mac, addr->address,
531 UAM_MAC_ADDRESS_STRING_LEN);
533 case UAM_ADDR_TYPE_IPv4:
534 g_strlcpy(device->ipv4_addr,
536 UAM_IP_ADDRESS_MAX_STRING_LEN);
539 UAM_WARN("Unknown address type %d", addr->addr_type);
543 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
548 retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
550 memset(device, 0x00, sizeof(uam_device_info_s));
551 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
552 uam_db_address_info_t *addr = l->data;
557 __uam_core_copy_addr(device, addr);
560 device->operating_system = tech->device->os;
561 g_strlcpy(device->device_id, tech->device->device_id,
562 UAM_DEVICE_ID_MAX_STRING_LEN);
563 device->type = tech->tech_type;
564 device->discriminant = tech->discriminant;
565 memset(device->payload.duid, 0, UAM_BLE_PAYLOAD_DUID_LEN + 1);
566 memset(device->payload.bt_mac, 0, UAM_BT_MAC_ADDRESS_STRING_LEN);
568 device->payload.service_id = tech->payload->service_id;
569 device->payload.device_icon = tech->payload->device_icon;
570 device->payload.purpose = tech->payload->purpose;
571 if (tech->payload->duid)
572 memcpy(device->payload.duid,
573 tech->payload->duid, UAM_BLE_PAYLOAD_DUID_LEN);
574 if (tech->payload->bt_mac)
575 memcpy(device->payload.bt_mac,
576 tech->payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
580 return UAM_ERROR_NONE;
583 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
584 const char *name, const char *svc_name, uam_pm_detection_mode_e mode)
589 retv_if(NULL == name, NULL);
590 retv_if(NULL == monitor_list, NULL);
592 for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
593 uam_monitor_info_t *monitor = l->data;
595 if (!monitor || !monitor->name ||
596 !monitor->service || !monitor->service->name)
599 if ((mode == monitor->mode) &&
600 (0 == g_strcmp0(monitor->name, name)) &&
601 (0 == g_strcmp0(monitor->service->name, svc_name))) {
602 UAM_DBG("Monitoring application found in list");
611 unsigned int _uam_core_get_active_sensors(int detection_mode)
614 unsigned int sensors = 0;
617 retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
618 (UAM_DETECT_ABSENCE != detection_mode), 0);
620 for (l = monitors; NULL != l; l = g_slist_next(l)) {
621 uam_monitor_info_t *monitor = l->data;
623 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
626 sensors |= monitor->sensors;
633 unsigned int _uam_core_get_env_sensors()
636 unsigned int sensors = 0;
638 sensors |= UAM_SENSOR_BITMASK_MOTION;
639 sensors |= UAM_SENSOR_BITMASK_LIGHT;
645 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
649 GSList *svc_list = NULL;
651 retv_if(NULL == db_svc_list, NULL);
654 * Iterate over the db_svc_list and add each service to the global
655 * service list "services" if its not already inserted. Also append this
656 * uam_db_service_info_t to svc_list.
658 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
659 db_service_info_t *db_svc = l->data;
660 uam_db_service_info_t *service;
666 l1 = g_slist_find_custom(services,
667 db_svc->service_name, __compare_svc_name);
669 service = g_new0(uam_db_service_info_t, 1);
670 service->name = g_strdup(db_svc->service_name);
671 service->cycle = db_svc->cycle;
672 services = g_slist_append(services, service);
676 svc_list = g_slist_append(svc_list, service);
683 static void __uam_core_add_dev_to_list(
684 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
685 int presence_state, unsigned long long timestamp, GSList *svc_list)
688 uam_db_tech_info_t *tech;
689 uam_db_device_info_t *device;
692 ret_if(NULL == dev_info);
693 ret_if(NULL == user);
695 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
698 ret_if(user != device->user);
699 ret_if(device->supported_techs & dev_info->type);
701 if (device->os != dev_info->operating_system) {
702 UAM_INFO("device->os: %d, dev_info->operating_system: %d",
703 device->os, dev_info->operating_system);
704 /* Update device OS type */
705 if (UAM_OS_TYPE_INVALID == device->os || UAM_OS_TYPE_UNDEFINED == device->os)
706 device->os = dev_info->operating_system;
708 UAM_WARN("Strange - OS types did not match, need to check");
711 device = g_new0(uam_db_device_info_t, 1);
712 device->device_id = g_strdup(dev_info->device_id);
713 device->os = dev_info->operating_system;
714 device->discriminant = dev_info->discriminant;
717 /* Add device to global device list */
718 devices = g_slist_append(devices, device);
720 /* Add same device to user's device list */
721 user->devices = g_slist_append(user->devices, device);
724 tech = g_new0(uam_db_tech_info_t, 1);
725 tech->tech_type = dev_info->type;
726 tech->presence_state = presence_state;
727 tech->timestamp = timestamp;
728 tech->device = device;
729 tech->discriminant = dev_info->discriminant;
731 tech->payload = g_new0(uam_db_ble_payload_t, 1);
732 tech->payload->service_id = dev_info->payload.service_id;
733 tech->payload->purpose = dev_info->payload.purpose;
734 tech->payload->device_icon = dev_info->payload.device_icon;
735 tech->payload->duid = g_memdup(&(dev_info->payload.duid), UAM_BLE_PAYLOAD_DUID_LEN);
736 tech->payload->bt_mac = g_memdup(&(dev_info->payload.bt_mac), UAM_BT_MAC_ADDRESS_STRING_LEN);
738 tech->svc_list = svc_list;
739 g_slist_foreach(tech->svc_list, __print_service, tech);
740 for (l = svc_list; NULL != l; l = g_slist_next(l)) {
741 uam_db_service_info_t *service = l->data;
746 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
749 /* Add tech info to tech list */
750 device->tech_list = g_slist_append(device->tech_list, tech);
751 device->supported_techs |= tech->tech_type;
752 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
754 if (0 < strlen(dev_info->mac)) {
755 uam_db_address_info_t *addr;
757 addr = g_new0(uam_db_address_info_t, 1);
758 addr->address = g_strdup(dev_info->mac);
760 switch (dev_info->type) {
761 case UAM_TECH_TYPE_BLE:
762 addr->addr_type = UAM_ADDR_TYPE_BLE;
764 case UAM_TECH_TYPE_BT:
765 addr->addr_type = UAM_ADDR_TYPE_BT;
767 case UAM_TECH_TYPE_P2P:
768 addr->addr_type = UAM_ADDR_TYPE_P2P;
770 case UAM_TECH_TYPE_WIFI:
771 addr->addr_type = UAM_ADDR_TYPE_WIFI;
774 UAM_ERR("Unknown tech type: %d", dev_info->type);
775 g_free(addr->address);
781 UAM_DBG("MAC address %s added for tech type: %d",
782 dev_info->mac, dev_info->type);
783 tech->addresses = g_slist_append(tech->addresses, addr);
787 if (0 < strlen(dev_info->ipv4_addr)) {
788 uam_db_address_info_t *addr;
790 if (UAM_TECH_TYPE_BLE == dev_info->type ||
791 UAM_TECH_TYPE_BT == dev_info->type)
792 UAM_WARN("IPv4 address %s added for tech type: %d",
793 dev_info->ipv4_addr, dev_info->type);
795 UAM_DBG("IPv4 address %s added for tech type: %d",
796 dev_info->ipv4_addr, dev_info->type);
798 addr = g_new0(uam_db_address_info_t, 1);
799 addr->addr_type = UAM_ADDR_TYPE_IPv4;
800 addr->address = g_strdup(dev_info->ipv4_addr);
802 tech->addresses = g_slist_append(tech->addresses, addr);
808 int _uam_core_add_user(const char *account, const char *name)
812 uam_db_user_info_t *user;
814 l = g_slist_find_custom(users, account, __compare_user_account);
815 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
817 user = g_new0(uam_db_user_info_t, 1);
819 /* Add user to database */
820 if (UAM_ERROR_NONE != _uam_db_insert_user_info(&(user->user_id), name, account)) {
821 UAM_ERR("_uam_db_insert_user_info failed");
823 return UAM_ERROR_DB_FAILED;
826 user->name = g_strdup(name);
827 user->account = g_strdup(account);
828 user->devices = NULL;
830 users = g_slist_append(users, user);
832 /* Send user added event to application */
833 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
834 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
835 UAM_ERROR_NONE, user->account, user->name)))
836 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
839 return UAM_ERROR_NONE;
842 int _uam_core_remove_user(const char *account)
846 uam_db_user_info_t *user;
848 l = g_slist_find_custom(users, account, __compare_user_account);
849 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
852 /* Remove user from database */
853 if (UAM_ERROR_NONE != _uam_db_delete_by_user_id(user->user_id)) {
854 UAM_ERR("_uam_db_delete_by_user_id failed");
855 return UAM_ERROR_DB_FAILED;
858 users = g_slist_remove(users, user);
860 /* Send user removed event to application */
861 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
862 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
863 UAM_ERROR_NONE, user->account, user->name)))
864 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
866 __free_uam_db_user_info((gpointer)user);
869 return UAM_ERROR_NONE;
872 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
877 uam_db_device_info_t *device;
878 uam_db_user_info_t *user;
880 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
881 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
883 l = g_slist_find_custom(users, account, __compare_user_account);
884 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
887 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
890 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
891 retv_if((dev_info->type & device->supported_techs),
892 UAM_ERROR_ALREADY_REGISTERED);
895 ret = _uam_pm_register_device(user->user_id, dev_info);
896 if (UAM_ERROR_NONE != ret) {
897 UAM_ERR("_uam_pm_register_device failed with %s",
898 _uam_manager_error_to_str(ret));
903 return UAM_ERROR_NONE;
906 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
909 uam_db_device_info_t *device;
912 retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
913 retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
916 l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
921 if (!(device->supported_techs & dev->type))
924 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
925 uam_db_tech_info_t *tech = l->data;
931 if (dev->type != tech->tech_type)
934 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
935 uam_db_address_info_t *addr = l1->data;
940 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
941 UAM_ADDR_TYPE_BT == addr->addr_type ||
942 UAM_ADDR_TYPE_P2P == addr->addr_type ||
943 UAM_ADDR_TYPE_WIFI == addr->addr_type)
944 if (!strcasecmp(addr->address, dev->mac)) {
953 UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
955 return UAM_ERROR_NONE;
958 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
959 const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
965 ret = _uam_db_get_device_services_count(dev_info->device_id,
966 dev_info->type, dev_info->mac, &count);
967 if (UAM_ERROR_NONE != ret) {
968 UAM_ERR("_uam_db_get_device_services_count failed with %s",
969 _uam_manager_error_to_str(ret));
974 ret = UAM_ERROR_RESOURCE_BUSY;
975 UAM_WARN("other service uses this device ref:[%d]", count);
979 ret = _uam_pm_unregister_device(user_id, dev_info);
980 if (UAM_ERROR_NONE != ret) {
981 UAM_ERR("_uam_pm_unregister_device failed with %s",
982 _uam_manager_error_to_str(ret));
986 /* Send device removed event to application */
987 __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
989 /* Remove device from database */
990 if (UAM_ERROR_NONE != _uam_device_db_delete_device_info(
991 dev_info->device_id, dev_info->type, dev_info->mac))
992 UAM_ERR("_uam_device_db_delete_device_info failed");
994 /* Remove device from service */
995 for (l = tech->svc_list; l; l = g_slist_next(l)) {
996 uam_db_service_info_t *svc = l->data;
998 if (!svc || !svc->name)
1000 _uam_core_service_remove_device(svc->name, dev_info->device_id, dev_info->type);
1003 /* Remove tech info from device's tech list */
1004 device->tech_list = g_slist_remove(device->tech_list, tech);
1005 device->supported_techs &= ~(tech->tech_type);
1006 UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1007 __free_dev_tech_info(tech);
1009 if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1010 /* Remove device from global device list */
1011 devices = g_slist_remove(devices, device);
1013 /* Remove device from user's device list */
1014 device->user->devices = g_slist_remove(device->user->devices, device);
1016 __free_user_device(device);
1019 /* Set/update registered device list to plugins */
1020 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1021 UAM_ERR("_uam_pm_set_registered_devices failed");
1023 /* Set/update registered device list to cloud plugin */
1024 _uam_cloud_update_registered_devices();
1027 return UAM_ERROR_NONE;
1030 int _uam_core_remove_device(const char *account,
1031 const uam_device_info_s *dev_info)
1036 uam_db_tech_info_t *tech;
1037 uam_db_device_info_t *device;
1038 uam_db_user_info_t *user;
1040 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1041 retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1043 /* Retrieve user from list */
1044 l = g_slist_find_custom(users, account, __compare_user_account);
1045 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1048 /* Retrieve device from list */
1049 l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1050 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1052 retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1053 retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1055 /* Retrieve tech info from list */
1056 l = g_slist_find_custom(device->tech_list,
1057 &(dev_info->type), __compare_tech_type);
1058 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1061 ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1067 int _uam_core_remove_device_by_device_id(const char *device_id,
1073 uam_device_info_s dev_info;
1074 uam_db_tech_info_t *tech;
1075 uam_db_device_info_t *device;
1077 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1078 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1079 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1081 /* Retrieve device from list */
1082 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1083 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1085 retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1087 /* Retrieve tech info from list */
1088 l = g_slist_find_custom(device->tech_list,
1089 &tech_type, __compare_tech_type);
1090 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1094 ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1095 retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1097 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1103 int _uam_core_remove_device_by_mac(const char *mac)
1106 uam_db_tech_info_t *tech;
1107 uam_db_device_info_t *device;
1108 uam_device_info_s dev_info;
1111 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1113 tech = __get_tech_info_by_mac(mac);
1114 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1115 device = tech->device;
1117 ret = __copy_tech_info_to_device_info(tech, &dev_info);
1118 if (UAM_ERROR_NONE != ret) {
1119 UAM_ERR("__copy_tech_info_to_device_info failed");
1120 return UAM_ERROR_INTERNAL;
1123 ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1129 int _uam_core_update_device(const uam_device_info_s *a_device)
1134 GSList *l, *l1, *l2;
1136 uam_device_info_s temp;
1137 uam_db_user_info_t *user = NULL;
1138 uam_db_device_info_t *device = NULL;
1139 uam_db_tech_info_t *tech = NULL;
1141 /* Find all tech-devices in users' devices */
1142 for (l = users; NULL != l; l = g_slist_next(l)) {
1145 l1 = g_slist_find_custom(user->devices,
1146 a_device->device_id, __compare_device_id);
1148 UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1149 user->user_id, a_device->device_id);
1154 if (!(device->supported_techs & a_device->type)) {
1155 UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1156 device->device_id, a_device->type);
1160 /* Update discriminant for devices */
1161 device->discriminant = a_device->discriminant;
1162 device->os = a_device->operating_system;
1164 l2 = g_slist_find_custom(device->tech_list,
1165 &(a_device->type), __compare_tech_type);
1167 UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1173 UAM_DBG("Device tech is NULL");
1177 /* Update discriminant for device-tech */
1178 tech->discriminant = a_device->discriminant;
1180 /* Update Payload for device-tech */
1181 tech->payload->service_id = a_device->payload.service_id;
1182 tech->payload->purpose = a_device->payload.purpose;
1183 tech->payload->device_icon = a_device->payload.device_icon;
1184 tech->payload->duid = g_memdup(&(a_device->payload.duid), UAM_BLE_PAYLOAD_DUID_LEN);
1185 tech->payload->bt_mac = g_memdup(&(a_device->payload.bt_mac), UAM_BT_MAC_ADDRESS_STRING_LEN);
1187 /* Update device's updated information to database */
1188 __copy_tech_info_to_device_info(tech, &temp);
1190 ret = _uam_device_db_update_device_device(temp.device_id, temp.type,
1191 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant,
1193 if (UAM_ERROR_NONE != ret)
1194 UAM_WARN("_uam_device_db_update_device_device failed [%d]", ret);
1197 /* Set/update registered device list to plugins */
1198 ret = _uam_pm_set_registered_devices(devices);
1199 if (UAM_ERROR_NONE != ret)
1200 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1202 /* Set/update registered device list to cloud plugin */
1203 _uam_cloud_update_registered_devices();
1206 return UAM_ERROR_NONE;
1209 int _uam_core_get_default_user(uam_user_info_s *user_info)
1214 uam_db_user_info_t *user;
1216 retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1218 ret = _uam_core_add_user(USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1219 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1220 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1224 l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1225 retv_if(NULL == l, UAM_ERROR_INTERNAL);
1228 memset(user_info, 0x00, sizeof(uam_user_info_s));
1229 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1230 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1233 return UAM_ERROR_NONE;
1236 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1242 size = g_slist_length(users);
1243 *user_list = g_new0(uam_user_info_s, size);
1246 /* fetch users list from DB */
1247 for (l = users; l; l = g_slist_next(l)) {
1248 uam_db_user_info_t *db_info = l->data;
1250 if (!db_info || !db_info->account)
1253 g_strlcpy((*user_list)[*count].account,
1254 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1256 g_strlcpy((*user_list)[*count].name,
1257 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1262 UAM_INFO("Count: %d", *count);
1264 return UAM_ERROR_NONE;
1267 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1270 uam_db_user_info_t *db_info;
1273 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1275 l = g_slist_find_custom(users, account, __compare_user_account);
1276 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1279 g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1281 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1285 return UAM_ERROR_NONE;
1288 int _uam_core_get_devcie_by_device_id(
1289 const char *device_id, int tech_type, uam_device_info_s *device)
1292 uam_db_device_info_t *db_info;
1296 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1297 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1298 retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1300 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1301 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1303 retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1305 memset(device, 0x00, sizeof(uam_device_info_s));
1307 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1308 uam_db_tech_info_t *tech = l1->data;
1311 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1314 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1315 uam_db_address_info_t *addr = l2->data;
1320 __uam_core_copy_addr(device, addr);
1323 device->operating_system = db_info->os;
1324 g_strlcpy(device->device_id, db_info->device_id,
1325 UAM_DEVICE_ID_MAX_STRING_LEN);
1326 device->type = tech->tech_type;
1327 device->discriminant = tech->discriminant;
1330 retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1333 return UAM_ERROR_NONE;
1336 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1340 uam_db_tech_info_t *tech;
1342 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1344 tech = __get_tech_info_by_mac(mac);
1345 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1347 ret = __copy_tech_info_to_device_info(tech, device);
1348 if (UAM_ERROR_NONE != ret) {
1349 UAM_ERR("__copy_tech_info_to_device_info failed");
1350 return UAM_ERROR_INTERNAL;
1354 return UAM_ERROR_NONE;
1357 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1360 uam_db_device_info_t *dev;
1363 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1365 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1366 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1369 g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1370 if (dev->user->name)
1371 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1374 return UAM_ERROR_NONE;
1377 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1380 uam_db_tech_info_t *tech;
1382 retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1384 tech = __get_tech_info_by_mac(mac);
1385 retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1387 g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1388 if (tech->device->user->name)
1389 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1392 return UAM_ERROR_NONE;
1395 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1399 __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1402 return UAM_ERROR_NONE;
1405 int _uam_core_get_user_devices(const char *account,
1406 int *count, uam_device_info_s **device_list)
1409 uam_db_user_info_t *user;
1412 l = g_slist_find_custom(users, account, __compare_user_account);
1413 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1416 __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1419 return UAM_ERROR_NONE;
1422 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1426 *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1429 return UAM_ERROR_NONE;
1432 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1437 is_ready = _uam_pm_is_sensor_ready(sensor);
1438 UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1444 uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1445 const char *svc_name)
1448 uam_svc_dev_info_t *svc_dev = NULL;
1451 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1454 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1457 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1458 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1459 (svc_dev->tech_type == tech_type)) {
1460 UAM_DBG("Service device found in list");
1469 int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1470 const char *svc_name, gboolean discriminant)
1473 uam_svc_dev_info_t *svc = NULL;
1475 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1476 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1477 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1478 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1480 svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1482 svc = g_new0(uam_svc_dev_info_t, 1);
1483 svc->device_id = g_strdup(device_id);
1484 svc->tech_type = tech_type;
1485 svc->service = g_strdup(svc_name);
1486 svc_devs = g_slist_append(svc_devs, svc);
1489 svc->discriminant = discriminant;
1491 UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]",
1492 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1495 return UAM_ERROR_NONE;
1498 int _uam_core_service_add_user(const char *svc_name, const char *account)
1502 int ret = UAM_ERROR_NONE;
1503 uam_db_user_info_t *user;
1504 uam_db_service_info_t *service;
1506 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1507 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1508 retv_if(0 == g_strcmp0(svc_name, UAM_SERVICE_DEFAULT), UAM_ERROR_PERMISSION_DENIED);
1510 /* Retrieve user from list */
1511 l = g_slist_find_custom(users, account, __compare_user_account);
1512 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1515 /* Retrieve service from list */
1516 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1517 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1520 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1521 uam_db_device_info_t *device = l->data;
1527 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1528 uam_db_tech_info_t *tech = l1->data;
1535 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1536 __compare_svc_name);
1540 __add_service_to_dev_tech_mapping(tech, service);
1542 mac = __get_mac_addr(tech);
1543 /* Insert device service info to db */
1544 ret = _uam_db_insert_device_service_info(device->device_id,
1545 tech->tech_type, mac, service->name, service->cycle,
1546 device->discriminant);
1547 if (UAM_ERROR_NONE != ret) {
1548 UAM_WARN("Device service addition to persistent DB failed");
1551 ret = _uam_core_update_svc_dev_info(device->device_id,
1552 tech->tech_type, service->name, device->discriminant);
1553 if (UAM_ERROR_NONE != ret) {
1554 UAM_WARN("Device service addition to service device mapping failed");
1564 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1568 uam_db_user_info_t *user;
1570 retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1571 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1572 retv_if(0 == g_strcmp0(svc_name, UAM_SERVICE_DEFAULT), UAM_ERROR_PERMISSION_DENIED);
1574 /* Retrieve user from list */
1575 l = g_slist_find_custom(users, account, __compare_user_account);
1576 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1579 /* Retrieve service from list */
1580 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1581 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1583 for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1584 uam_db_device_info_t *device = l->data;
1590 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1591 uam_db_tech_info_t *tech = l1->data;
1598 l2 = g_slist_find_custom(tech->svc_list, svc_name,
1599 __compare_svc_name);
1603 UAM_DBG("Service %s found, remove it from list", svc_name);
1604 __remove_service_to_dev_tech_mapping(
1605 tech, (uam_db_service_info_t *)l2->data);
1607 mac = __get_mac_addr(tech);
1608 /* Remove service-device from DB */
1609 if (UAM_ERROR_NONE != _uam_db_delete_device_service_info(
1610 device->device_id, tech->tech_type, mac, svc_name))
1611 UAM_WARN("Device service removal from persistent DB failed");
1616 return UAM_ERROR_NONE;
1619 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1622 uam_db_device_info_t *device;
1625 retv_if(NULL == device_id, NULL);
1626 retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1627 retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1629 l = g_slist_find_custom(devices, device_id, __compare_device_id);
1631 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1636 if (!device || !(device->supported_techs & tech_type)) {
1637 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1638 tech_type, device_id);
1642 for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1643 uam_db_tech_info_t *tech = l->data;
1648 if (tech_type == tech->tech_type) {
1649 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1650 device_id, tech_type);
1655 UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1660 int _uam_core_service_add_device(const char *svc_name, const char *device_id, int tech_type)
1665 int ret = UAM_ERROR_NONE;
1666 uam_db_tech_info_t *tech_info;
1667 uam_db_service_info_t *service;
1669 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1670 retv_if(0 == g_strcmp0(svc_name, UAM_SERVICE_DEFAULT), UAM_ERROR_PERMISSION_DENIED);
1671 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1672 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1673 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1675 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1676 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1678 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1679 retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1681 /* Retrieve service from list */
1682 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1683 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1686 __add_service_to_dev_tech_mapping(tech_info, service);
1688 mac = __get_mac_addr(tech_info);
1689 /* Insert device service info to db */
1690 ret = _uam_db_insert_device_service_info(device_id,
1691 tech_type, mac, service->name, service->cycle, tech_info->discriminant);
1692 if (UAM_ERROR_NONE != ret) {
1693 UAM_WARN("Device service addition to persistent DB failed");
1696 ret = _uam_core_update_svc_dev_info(device_id,
1697 tech_type, service->name, tech_info->discriminant);
1698 if (UAM_ERROR_NONE != ret) {
1699 UAM_WARN("Device service addition to svc dev mapping failed");
1704 return UAM_ERROR_NONE;
1707 int _uam_core_service_remove_device(const char *svc_name, const char *device_id, int tech_type)
1712 uam_db_tech_info_t *tech_info;
1714 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1715 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1716 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1717 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1718 retv_if(0 == g_strcmp0(svc_name, UAM_SERVICE_DEFAULT), UAM_ERROR_PERMISSION_DENIED);
1720 /* Retrieve service from list */
1721 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1722 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1724 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1725 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1727 l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1728 retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1730 __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1732 mac = __get_mac_addr(tech_info);
1733 /* Remove service-device from DB */
1734 if (UAM_ERROR_NONE != _uam_db_delete_device_service_info(
1735 device_id, tech_type, mac, svc_name))
1736 UAM_WARN("Device service removal from persistent DB failed");
1739 return UAM_ERROR_NONE;
1742 int _uam_core_service_set_device_discriminant(const char *svc_name,
1743 const char *device_id, int tech_type, gboolean discriminant)
1747 int ret = UAM_ERROR_NONE;
1749 uam_db_tech_info_t *tech_info;
1750 uam_db_service_info_t *service;
1752 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1753 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1754 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1755 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1757 tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1758 retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1760 /* Retrieve service from list */
1761 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1762 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1765 mac = __get_mac_addr(tech_info);
1766 /* Insert device service info to db */
1767 ret = _uam_db_update_device_service_info(device_id,
1768 tech_type, mac, service->name, discriminant);
1769 if (UAM_ERROR_NONE != ret) {
1770 UAM_WARN("Device service discriminant update to persistent DB failed");
1773 ret = _uam_core_update_svc_dev_info(device_id,
1774 tech_type, service->name, discriminant);
1775 if (UAM_ERROR_NONE != ret) {
1776 UAM_WARN("Device service discriminant mapping update failed");
1781 return UAM_ERROR_NONE;
1784 int _uam_core_service_get_device_discriminant(const char *svc_name,
1785 const char *device_id, int tech_type, gboolean *discriminant)
1788 uam_svc_dev_info_t *svc_dev;
1790 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1791 retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1792 retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1793 retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1795 svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1796 retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1797 *discriminant = (gboolean)svc_dev->discriminant;
1800 return UAM_ERROR_NONE;
1803 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1807 uam_db_service_info_t *service;
1808 unsigned int elapsed_time;
1810 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1811 retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1812 retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1814 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1815 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1818 elapsed_time = service->cycle - service->remaining_time;
1819 service->cycle = new_cycle;
1820 if (new_cycle < elapsed_time)
1821 service->remaining_time = 0;
1823 service->remaining_time = new_cycle - elapsed_time;
1825 /* Update service detection cycle in DB */
1826 if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1827 UAM_WARN("Service cycle updation to persistent DB failed");
1830 return UAM_ERROR_NONE;
1833 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1837 uam_db_service_info_t *service;
1839 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1840 retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1842 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1843 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1845 *cycle = service->cycle;
1848 return UAM_ERROR_NONE;
1851 int _uam_core_set_detection_threshold(unsigned int sensor,
1852 int presence_threshold, int absence_threshold)
1857 ret = _uam_pm_set_detection_threshold(sensor,
1858 presence_threshold, absence_threshold);
1859 if (UAM_ERROR_NONE != ret) {
1860 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
1861 _uam_manager_error_to_str(ret));
1866 return UAM_ERROR_NONE;
1869 static gboolean __start_detection(gpointer data)
1873 uam_db_service_info_t *service = NULL;
1874 unsigned int sensors;
1875 gboolean start_detection = FALSE;
1877 unsigned int env_sensors;
1879 env_sensors = _uam_core_get_env_sensors();
1880 UAM_DBG("Envionmental sensors: 0x%8.8X", env_sensors);
1881 if (0 != env_sensors) {
1882 /* Stop PRESENCE detection on envionmental sensors*/
1883 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, env_sensors);
1884 if (UAM_ERROR_NONE != ret)
1885 UAM_ERR("Failed with error: %s (0x%4.4X)",
1886 _uam_manager_error_to_str(ret), ret);
1888 /* Stop ABSENCE detection on envionmental sensors*/
1889 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, env_sensors);
1890 if (UAM_ERROR_NONE != ret)
1891 UAM_ERR("Failed with error: %s (0x%4.4X)",
1892 _uam_manager_error_to_str(ret), ret);
1894 /* Always Start PRESENCE detection on envionmental sensors*/
1895 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, env_sensors);
1896 if (UAM_ERROR_NONE != ret)
1897 UAM_ERR("Failed with error: %s (0x%4.4X)",
1898 _uam_manager_error_to_str(ret), ret);
1900 /* Always Start ABSENCE detection on envionmental sensors*/
1901 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, env_sensors);
1902 if (UAM_ERROR_NONE != ret)
1903 UAM_ERR("Failed with error: %s (0x%4.4X)",
1904 _uam_manager_error_to_str(ret), ret);
1907 for (l = services; NULL != l; l = g_slist_next(l)) {
1909 if (!service || !service->monitors)
1912 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
1913 UAM_DBG("service->remaining_time: %d", service->remaining_time);
1914 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
1915 if (0 >= service->remaining_time) {
1916 start_detection = TRUE;
1917 service->remaining_time = service->cycle;
1921 if (!start_detection)
1924 /* Get sensors on which PRESENCE detection to be started */
1925 sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
1926 UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
1928 /* Remove env sensors from active sensors */
1929 sensors &= ~env_sensors;
1930 UAM_DBG("Connectivity sensors: 0x%8.8X", sensors);
1933 /* Start PRESENCE detection */
1934 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
1935 if (UAM_ERROR_NONE != ret)
1936 UAM_ERR("Failed with error: %s (0x%4.4X)",
1937 _uam_manager_error_to_str(ret), ret);
1940 /* Get sensors on which ABSENCE detection to be started */
1941 sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
1942 UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
1944 /* Remove env sensors from active sensors */
1945 sensors &= ~env_sensors;
1946 UAM_DBG("Connectivity sensors: 0x%8.8X", sensors);
1949 /* Start ABSENCE detection */
1950 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
1951 if (UAM_ERROR_NONE != ret)
1952 UAM_ERR("Failed with error: %s (0x%4.4X)",
1953 _uam_manager_error_to_str(ret), ret);
1961 static int __uam_core_start_detection(int detection_type,
1962 const char *svc_name, char *sender, unsigned int sensors)
1965 uam_monitor_info_t *monitor;
1966 uam_db_service_info_t *service;
1967 gboolean is_monitor_added = TRUE;
1970 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
1971 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1973 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1975 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
1976 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
1977 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
1978 services = g_slist_append(services, default_svc);
1982 retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1983 retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
1986 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
1988 monitor = g_malloc0(sizeof(uam_monitor_info_t));
1990 monitor->name = g_strdup(sender);
1991 monitor->mode = detection_type;
1992 monitor->service = service;
1993 is_monitor_added = FALSE;
1995 UAM_ERR("Memory allocation error");
1996 return UAM_ERROR_OUT_OF_MEMORY;
2000 UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2002 monitor->sensors |= sensors;
2003 if (!is_monitor_added) {
2004 monitors = g_slist_append(monitors, monitor);
2005 service->monitors = g_slist_append(service->monitors, monitor);
2008 /* Start detection */
2009 if (0 == detection_timer) {
2010 __start_detection(NULL);
2011 UAM_INFO("Monitor started detection, start timer");
2012 detection_timer = g_timeout_add_seconds(
2013 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2017 return UAM_ERROR_NONE;
2020 static int __uam_core_stop_detection(int detection_type,
2021 const char *svc_name, char *sender, unsigned int sensors)
2024 int ret = UAM_ERROR_NONE;
2025 unsigned int remaining_sensors;
2026 unsigned int active_sensors;
2027 uam_monitor_info_t *monitor;
2028 uam_db_service_info_t *service;
2030 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2031 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2033 monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2034 retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2035 service = monitor->service;
2036 retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2038 /* Find sensors which are already monitoring */
2039 active_sensors = _uam_core_get_active_sensors(detection_type);
2040 UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2041 sensors, active_sensors);
2043 /* Update monitor info for application */
2044 monitor->sensors &= ~sensors;
2045 if (0 == monitor->sensors) {
2047 * App requested to stop monitoring for all of its active sensors,
2048 * remove its monitor info from list.
2050 monitors = g_slist_remove(monitors, monitor);
2051 if ((NULL == monitors) && (0 != detection_timer)) {
2052 UAM_INFO("All monitors stopped detection, stop timer");
2053 g_source_remove(detection_timer);
2054 detection_timer = 0;
2057 service->monitors = g_slist_remove(service->monitors, monitor);
2058 if (NULL == service->monitors)
2059 service->remaining_time = 0;
2061 g_free(monitor->name);
2065 /* Find sensors which are already monitoring */
2066 remaining_sensors = _uam_core_get_active_sensors(detection_type);
2067 UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2069 if (active_sensors == remaining_sensors) {
2070 UAM_INFO("NO need to stop monitoring");
2071 return UAM_ERROR_NONE;
2074 /* Stop monitoring only for sensors which aren't required anymore */
2075 sensors = (active_sensors & ~remaining_sensors);
2076 ret = _uam_pm_stop_detection(detection_type, sensors);
2077 if (UAM_ERROR_NONE != ret)
2078 UAM_ERR("Failed with error: %s (0x%4.4X)",
2079 _uam_manager_error_to_str(ret), ret);
2085 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2090 ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2096 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2101 ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2107 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2112 ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2118 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2123 ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2129 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2134 UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2135 ret = _uam_pm_set_low_power_mode(bitmask, mode);
2136 if (UAM_ERROR_NONE != ret) {
2137 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2138 bitmask, _uam_manager_error_to_str(ret));
2143 return UAM_ERROR_NONE;
2146 int _uam_core_get_detection_window(unsigned int *window)
2150 retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2152 *window = detection_window;
2155 return UAM_ERROR_NONE;
2158 int _uam_core_set_detection_window(unsigned int window)
2162 retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2163 retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2164 retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2166 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2167 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2168 return UAM_ERROR_INTERNAL;
2171 detection_window = window;
2174 return UAM_ERROR_NONE;
2177 int _uam_core_init(void)
2182 GSList *db_svc_list;
2183 GSList *db_adv_list;
2184 GSList *db_svc_dev_list;
2188 _uam_db_initialize();
2190 /* Reset detecton window to default */
2191 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2192 if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2193 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2195 /* Fetch user list */
2196 db_users = _uam_db_get_all_users();
2198 UAM_INFO_C("No users in database");
2199 return UAM_ERROR_NONE;
2202 for (l = db_users; NULL != l; l = g_slist_next(l)) {
2203 db_user_info_t *info = l->data;
2204 uam_db_user_info_t *user;
2209 user = g_new0(uam_db_user_info_t, 1);
2210 user->user_id = info->user_id;
2211 user->name = g_strdup(info->name);
2212 user->account = g_strdup(info->account);
2213 user->devices = NULL;
2215 users = g_slist_prepend(users, user);
2218 /* Fetch service list */
2219 db_svc_list = _uam_service_db_get_all_services();
2221 UAM_INFO_C("No services in database");
2222 return UAM_ERROR_NONE;
2225 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2226 db_service_info_t *db_svc = l->data;
2227 uam_db_service_info_t *service;
2233 l1 = g_slist_find_custom(services,
2234 db_svc->service_name, __compare_svc_name);
2236 service = g_new0(uam_db_service_info_t, 1);
2237 service->name = g_strdup(db_svc->service_name);
2238 service->cycle = db_svc->cycle;
2239 service->presence_threshold = db_svc->presence_threshold;
2240 service->absence_threshold = db_svc->absence_threshold;
2241 services = g_slist_append(services, service);
2245 /* Fetch device list */
2246 db_devices = _uam_device_db_get_all_devices();
2248 UAM_INFO_C("No Devices registered in database");
2249 return UAM_ERROR_NONE;
2252 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2253 db_device_info_t *db_info = l->data;
2254 uam_db_user_info_t *user;
2255 GSList *svc_list = NULL;
2261 l1 = g_slist_find_custom(users,
2262 &(db_info->user_id), __compare_user_id);
2264 UAM_ERR("Invalid user Id: %d", db_info->user_id);
2269 /* Fetch device services from DB */
2270 l1 = _uam_db_get_device_services(
2271 db_info->dev_info.device_id,
2272 db_info->dev_info.type,
2273 db_info->dev_info.mac);
2275 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2276 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2277 db_info->presence_state, db_info->timestamp, svc_list);
2280 /* Fetch iBeacon adv list */
2281 db_adv_list = _uam_db_get_all_advs();
2283 UAM_INFO_C("No iBeacon adv in database");
2285 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2286 db_adv_info_t *db_adv = l->data;
2287 _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2291 /* Fetch svc dev list */
2292 db_svc_dev_list = _uam_db_get_service_devices_info();
2293 if (!db_svc_dev_list) {
2294 UAM_INFO_C("No service devices in database");
2296 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2297 db_svc_dev_info_t *db_svc = l->data;
2298 _uam_core_update_svc_dev_info((char *)&(db_svc->device_id), db_svc->type,
2299 (char *)&(db_svc->svc), db_svc->discriminant);
2303 g_slist_free_full(db_devices, g_free);
2304 g_slist_free_full(db_users, g_free);
2305 g_slist_free_full(db_svc_list, g_free);
2306 g_slist_free_full(db_adv_list, g_free);
2307 g_slist_free_full(db_svc_dev_list, g_free);
2309 /* Set/update registered device list to plugins */
2310 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2311 UAM_ERR("_uam_pm_set_registered_devices failed");
2313 /* Set/update registered device list to cloud plugin */
2314 _uam_cloud_update_registered_devices();
2317 return UAM_ERROR_NONE;
2320 void _uam_core_deinit(void)
2325 /* de-init database */
2326 _uam_db_deinitialize();
2328 /* Reset detecton window to default */
2329 detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2331 /* Release allocated memory for devices */
2332 g_slist_free_full(devices, __free_user_device);
2335 /* Release allocated memory for users */
2336 for (l = users; NULL != l; l = g_slist_next(l)) {
2337 uam_db_user_info_t *user = l->data;
2343 g_free(user->account);
2347 g_slist_free(users);
2350 /* Release allocated memory for services */
2351 for (l = services; NULL != l; l = g_slist_next(l)) {
2352 uam_db_service_info_t *service = l->data;
2357 g_free(service->name);
2360 g_slist_free(services);
2363 /* Release allocated memory for service devices */
2364 for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2365 uam_svc_dev_info_t *svc_dev = l->data;
2370 g_free(svc_dev->device_id);
2371 g_free(svc_dev->service);
2374 g_slist_free(svc_devs);
2380 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2384 /* Send sensor state changed event over dbus */
2386 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2387 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2389 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2390 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2395 int _uam_core_handle_device_added(int status,
2396 int user_id, const uam_device_info_s *dev_info)
2400 int ret = UAM_ERROR_NONE;
2401 uam_db_user_info_t *user = NULL;
2402 GSList *svc_list = NULL;
2403 unsigned long long timestamp;
2405 /* Send reply over dbus for add device API */
2406 l = _uam_manager_get_request_list();
2407 for (; NULL != l; l = g_slist_next(l)) {
2408 uam_request_context_t *info = l->data;
2409 uam_device_info_s *dev;
2412 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2417 UAM_WARN("info->data is NULL");
2418 _uam_manager_remove_req_ctxt_from_list(info);
2422 if (dev->type != dev_info->type ||
2423 strcasecmp(dev->device_id, dev_info->device_id)) {
2424 UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2425 dev->device_id, dev_info->device_id);
2426 _uam_manager_remove_req_ctxt_from_list(info);
2430 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2431 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2432 _uam_manager_method_return(info->context, out_param, status);
2434 _uam_manager_remove_req_ctxt_from_list(info);
2438 if (UAM_ERROR_NONE != status) {
2439 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2444 l = g_slist_find_custom(users,
2445 USER_ACCOUNT_DEFAULT, __compare_user_account);
2447 ret = _uam_core_add_user(
2448 USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2449 if (UAM_ERROR_NONE != ret) {
2450 UAM_ERR("_uam_core_add_user failed with %s",
2451 _uam_manager_error_to_str(ret));
2452 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2456 user_id = USER_ACCOUNT_DEFAULT_ID;
2458 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2460 UAM_ERR("Invalid user Id: %d", user_id);
2461 ret = UAM_ERROR_NOT_FOUND;
2462 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2467 /* Get default service and add it to device's service list by default */
2468 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2470 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2471 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2472 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2473 services = g_slist_append(services, service);
2474 svc_list = g_slist_append(svc_list, service);
2476 uam_db_service_info_t *service = l->data;
2477 svc_list = g_slist_append(svc_list, service);
2480 timestamp = (unsigned long long)time(NULL);
2481 __uam_core_add_dev_to_list(user, dev_info,
2482 UAM_PRESENCE_STATE_PRESENT, timestamp, svc_list);
2484 /* Add device to database */
2485 ret = _uam_device_db_insert_device_info(user->user_id,
2486 dev_info, UAM_PRESENCE_STATE_PRESENT, timestamp);
2487 if (UAM_ERROR_NONE != ret) {
2488 UAM_WARN("Device addition to persistent DB failed");
2492 /* Insert device service info to db */
2493 ret = _uam_db_insert_device_service_info(
2494 dev_info->device_id, dev_info->type, dev_info->mac,
2495 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2496 dev_info->discriminant);
2497 if (UAM_ERROR_NONE != ret) {
2498 UAM_WARN("Device service addition to persistent DB failed");
2499 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2503 ret = _uam_core_update_svc_dev_info(
2504 dev_info->device_id, dev_info->type,
2505 UAM_SERVICE_DEFAULT, dev_info->discriminant);
2506 if (UAM_ERROR_NONE != ret) {
2507 UAM_WARN("Device service mappiing update failed");
2508 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2512 /* Send device added event to application */
2513 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2515 /* Set/update registered device list to plugins */
2516 ret = _uam_pm_set_registered_devices(devices);
2517 if (UAM_ERROR_NONE != ret) {
2518 UAM_ERR("_uam_pm_set_registered_devices failed");
2522 _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2524 /* Set/update registered device list to cloud plugin */
2525 if (UAM_ERROR_NONE == status)
2526 _uam_cloud_update_registered_devices();
2532 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2537 UAM_INFO("sensor 0x[%8.8X]", sensor);
2539 if (NULL == sensor_info) {
2540 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2541 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2542 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2547 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2548 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2549 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2550 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2551 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2552 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2557 // service specific light detection threshold
2558 for (l = services; NULL != l; l = g_slist_next(l)) {
2559 uam_db_service_info_t *svc = l->data;
2562 if (!svc || !svc->monitors)
2565 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2566 svc->name, sensor_info->values[0], svc->presence_threshold);
2568 if (sensor_info->values[0] < svc->presence_threshold)
2571 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2572 uam_monitor_info_t *mon = l1->data;
2577 UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2578 mon->name, mon->sensors);
2580 if (!(mon->sensors & sensor))
2583 if (UAM_DETECT_PRESENCE != mon->mode)
2586 _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2587 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2588 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2589 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2590 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2598 void __send_sensor_absence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2603 UAM_INFO("sensor 0x[%8.8X]", sensor);
2605 if (NULL == sensor_info) {
2606 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2607 g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2608 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2613 if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2614 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2615 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2616 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2617 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2618 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2623 // service specific light detection threshold
2624 for (l = services; NULL != l; l = g_slist_next(l)) {
2625 uam_db_service_info_t *svc = l->data;
2628 if (!svc || !svc->monitors)
2631 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2632 svc->name, sensor_info->values[0], svc->absence_threshold);
2634 if (sensor_info->values[0] > svc->absence_threshold)
2637 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2638 uam_monitor_info_t *mon = l1->data;
2643 if (!(mon->sensors & sensor))
2646 if (UAM_DETECT_PRESENCE != mon->mode)
2649 _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2650 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2651 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2652 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2653 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2660 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2664 uam_db_user_info_t *user;
2666 uam_svc_dev_info_t *svc_dev = NULL;
2668 ret_if(NULL == tech);
2669 ret_if(NULL == tech->svc_list);
2671 user = tech->device->user;
2672 for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2673 uam_db_service_info_t *svc = l->data;
2676 if (!svc || !svc->monitors)
2679 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2680 svc->name, svc->remaining_time, svc->cycle);
2682 if (!(svc->remaining_time == svc->cycle))
2685 UAM_DBG("Check service device discriminant");
2686 svc_dev = _uam_core_find_svc_dev_info(device_id, tech->tech_type, svc->name);
2687 if (!svc_dev || !svc_dev->discriminant)
2690 UAM_DBG("Send event");
2691 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2692 uam_monitor_info_t *mon = l1->data;
2697 if (!(mon->sensors & sensor))
2700 if (UAM_DETECT_PRESENCE != mon->mode)
2703 user->timestamp = (unsigned long long) time(NULL);
2704 UAM_INFO("sensor [%d]", sensor);
2705 _uam_manager_send_event(mon->name,
2706 UAM_EVENT_USER_PRESENCE_DETECTED,
2707 g_variant_new("(ussst)", sensor,
2708 user->account, svc->name,
2709 device_id, user->timestamp));
2710 UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2712 " for 0x%8.8X, User: %s Service: %s",
2713 mon->name, device_id,
2714 sensor, user->account,
2722 void _uam_core_handle_presence_detected(unsigned int sensor,
2723 int user_id, void *info)
2726 uam_db_user_info_t *user;
2727 uam_db_device_info_t *device;
2728 uam_db_tech_info_t *tech;
2730 uam_device_info_s *dev_info = NULL;
2731 uam_sensor_info_s *sensor_info = NULL;
2733 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2735 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2737 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2740 _uam_ppm_send_presence_detection_event(sensor);
2742 if (NULL == dev_info) {
2743 __send_sensor_presence_event(sensor_info, sensor);
2747 ret_if(0 > user_id);
2749 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2751 UAM_ERR("Invalid user_id [%d]", user_id);
2756 l = g_slist_find_custom(user->devices,
2757 dev_info->device_id, __compare_device_id);
2759 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2760 user_id, dev_info->device_id);
2764 if (!(device->supported_techs & dev_info->type)) {
2765 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2766 dev_info->device_id, dev_info->type);
2770 l = g_slist_find_custom(device->tech_list,
2771 &(dev_info->type), __compare_tech_type);
2773 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2778 tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2779 tech->timestamp = (unsigned long long)time(NULL);
2781 /* Check if IP address was updated then update in DB */
2782 if (UAM_TECH_TYPE_WIFI == dev_info->type) {
2783 uam_db_address_info_t *addr_info = NULL;
2784 gboolean is_updated = TRUE;
2786 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2787 uam_db_address_info_t *addr = l->data;
2789 if (!addr || (UAM_ADDR_TYPE_IPv4 != addr->addr_type))
2792 if (!strcasecmp(addr->address, dev_info->ipv4_addr))
2795 UAM_DBG("Old IPv4: %s, New IPv4: %s",
2796 addr->address, dev_info->ipv4_addr);
2803 addr_info = g_new0(uam_db_address_info_t, 1);
2804 tech->addresses = g_slist_append(tech->addresses, addr_info);
2806 g_free(addr_info->address);
2809 addr_info->addr_type = UAM_ADDR_TYPE_IPv4;
2810 addr_info->address = g_strdup(dev_info->ipv4_addr);
2812 /* Update address in DB */
2813 if (UAM_ERROR_NONE != _uam_device_db_update_device_ip_address(dev_info->device_id,
2814 dev_info->type, dev_info->mac, dev_info->ipv4_addr))
2815 UAM_WARN("_uam_device_db_update_device_ip_address failed");
2819 /* Update database (presence state & timestamp) */
2820 if (UAM_ERROR_NONE != _uam_device_db_update_device_timestamp(dev_info->device_id,
2821 dev_info->type, dev_info->mac, tech->timestamp))
2822 UAM_WARN("_uam_device_db_update_device_timestamp failed");
2824 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
2825 dev_info->type, dev_info->mac, tech->presence_state))
2826 UAM_WARN("_uam_device_db_update_device_presence failed");
2828 __send_user_presence_event(tech, sensor, dev_info->device_id);
2833 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
2839 * For each service, find users absent on given sensor. Then for each
2840 * monitor in serivce's monitor list, if it is monitoring ABSENCE on
2841 * given sensor, send user ABSENCE event.
2843 for (l = services; NULL != l; l = g_slist_next(l)) {
2844 uam_db_service_info_t *svc = l->data;
2845 GSList *absent_users = NULL;
2846 GSList *present_users = NULL;
2850 if (!svc || !svc->monitors || !svc->dev_techs)
2853 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
2854 uam_db_tech_info_t *tech = l1->data;
2856 if (!tech || (tech->tech_type != type)) {
2857 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
2861 if (!tech->device || !tech->device->user) {
2862 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
2866 l2 = g_slist_find_custom(present_users,
2867 &(tech->device->user->user_id), __compare_user_id);
2869 if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
2870 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
2872 tech->device->device_id,
2873 tech->device->user->account);
2874 /* Remove user from absent list */
2875 absent_users = g_slist_remove(absent_users, tech->device->user);
2877 /* If user not in present list, add user to the list */
2879 UAM_DBG("added present user [%s]", tech->device->user->account);
2880 present_users = g_slist_prepend(present_users, tech->device->user);
2883 /* If user not in the present list then only add it to absent list */
2884 if ((NULL == l2) && (NULL == g_slist_find_custom(
2885 absent_users, &(tech->device->user->user_id),
2886 __compare_user_id))) {
2887 UAM_DBG("added absent user [%s]", tech->device->user->account);
2888 absent_users = g_slist_prepend(absent_users, tech->device->user);
2893 g_slist_free(present_users);
2897 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
2898 uam_monitor_info_t *mon = l2->data;
2903 if (!(mon->sensors & sensor))
2906 if (UAM_DETECT_ABSENCE != mon->mode)
2909 for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
2910 uam_db_user_info_t *user = l1->data;
2915 user->timestamp = (unsigned long long) time(NULL);
2916 _uam_manager_send_event(mon->name,
2917 UAM_EVENT_USER_ABSENCE_DETECTED,
2918 g_variant_new("(usst)", sensor,
2919 user->account, svc->name,
2921 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
2922 " for 0x%8.8X, User: %s Service: %s"
2923 " timestamp [%llu]",
2924 mon->name, sensor, user->account,
2925 svc->name, user->timestamp);
2929 g_slist_free(absent_users);
2935 void _uam_core_handle_absence_detected(unsigned int sensor,
2936 int user_id, void *info)
2939 uam_db_user_info_t *user;
2940 uam_db_device_info_t *device;
2941 uam_db_tech_info_t *tech;
2943 uam_device_info_s *dev_info = NULL;
2944 uam_sensor_info_s *sensor_info = NULL;
2946 UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2948 if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2950 if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2953 if (NULL == dev_info) {
2954 __send_sensor_absence_event(sensor_info, sensor);
2959 ret_if(0 > user_id);
2961 l = g_slist_find_custom(users, &user_id, __compare_user_id);
2963 UAM_ERR("Invalid user_id [%d]", user_id);
2968 l = g_slist_find_custom(user->devices,
2969 dev_info->device_id, __compare_device_id);
2971 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2972 user_id, dev_info->device_id);
2976 if (!(device->supported_techs & dev_info->type)) {
2977 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2978 dev_info->device_id, dev_info->type);
2982 l = g_slist_find_custom(device->tech_list,
2983 &(dev_info->type), __compare_tech_type);
2985 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2990 tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
2992 /* Update database (presence state) */
2993 if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
2994 dev_info->type, dev_info->mac, tech->presence_state))
2995 UAM_WARN("_uam_device_db_update_device_presence failed");
3000 void _uam_core_cleanup_monitor(char *name)
3004 for (l = monitors; NULL != l; l = g_slist_next(l)) {
3005 uam_monitor_info_t *monitor = l->data;
3007 if (!monitor || !monitor->name || !monitor->service)
3010 if (0 != g_strcmp0(name, monitor->name))
3013 __uam_core_stop_detection(monitor->mode,
3014 monitor->service->name, name, monitor->sensors);
3018 static void __free_user_info(gpointer data)
3021 uam_db_user_info_t *user = data;
3023 ret_if(NULL == user);
3026 g_free(user->account);
3031 static void __free_service_info(gpointer data)
3034 uam_db_service_info_t *svc = data;
3036 ret_if(NULL == svc);
3043 static void __free_monitor_info(gpointer data)
3046 uam_monitor_info_t *monitor = data;
3048 ret_if(NULL == monitor);
3050 g_free(monitor->name);
3055 static void __free_scanner_info(gpointer data)
3058 uam_scanner_info_t *scanner = data;
3060 ret_if(NULL == scanner);
3062 g_free(scanner->name);
3067 void _uam_core_reset_database(void)
3072 ret = _uam_db_clear();
3073 if (UAM_ERROR_NONE != ret) {
3074 UAM_ERR("_uam_db_clear failed with %s",
3075 _uam_manager_error_to_str(ret));
3079 g_slist_free_full(devices, __free_user_device);
3082 g_slist_free_full(users, __free_user_info);
3085 g_slist_free_full(services, __free_service_info);
3088 g_slist_free_full(monitors, __free_monitor_info);
3091 g_slist_free_full(scanners, __free_scanner_info);
3094 /* Set/update registered device list to plugins */
3095 ret = _uam_pm_set_registered_devices(devices);
3096 if (UAM_ERROR_NONE != ret)
3097 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3098 _uam_manager_error_to_str(ret));
3100 /* Set/update registered device list to cloud plugin */
3101 _uam_cloud_update_registered_devices();
3106 void _uam_core_handle_detection_started(unsigned int sensor)
3109 unsigned int active_sensors = 0;
3111 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3112 sensor, detecting_sensors);
3114 detecting_sensors |= sensor;
3115 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3116 active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3117 if (active_sensors == detecting_sensors) {
3118 /* Send detection started event */
3119 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3125 void _uam_core_handle_detection_stopped(unsigned int sensor)
3128 uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3130 UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3131 sensor, detecting_sensors);
3132 detecting_sensors &= ~sensor;
3134 if (UAM_SENSOR_BITMASK_BLE == sensor)
3135 type = UAM_TECH_TYPE_BLE;
3136 else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3137 type = UAM_TECH_TYPE_WIFI;
3139 if (UAM_TECH_TYPE_NONE != type)
3140 __send_user_absence_event(type, sensor);
3142 if (0 == detecting_sensors)
3143 /* Send detection stopped event */
3144 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STOPPED, NULL);
3149 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3153 retv_if(NULL == name, NULL);
3155 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3156 uam_scanner_info_t *scanner = l->data;
3158 if (!scanner || !scanner->name)
3161 if (0 == g_strcmp0(scanner->name, name)) {
3162 UAM_DBG("Scanning application found in list");
3170 static gboolean __scan_completed_cb(gpointer data)
3173 uam_scanner_info_t *scanner = data;
3175 retv_if(NULL == scanner, FALSE);
3177 if (UAM_ERROR_NONE != _uam_manager_send_event(
3178 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3179 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3181 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3184 scanners = g_slist_remove(scanners, scanner);
3185 g_free(scanner->name);
3192 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3196 uam_scanner_info_t *scanner;
3198 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3199 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3201 scanner = __uam_find_scanner(sender);
3202 retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3204 ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3205 if (UAM_ERROR_NONE != ret) {
3206 UAM_ERR("Failed with error: %s (0x%4.4X)",
3207 _uam_manager_error_to_str(ret), ret);
3211 scanner = g_malloc0(sizeof(uam_scanner_info_t));
3213 UAM_ERR("Failed to allocate memory");
3214 return UAM_ERROR_OUT_OF_MEMORY;
3216 scanner->name = g_strdup(sender);
3217 scanner->sensors |= sensors;
3218 scanner->timer = g_timeout_add_seconds(detection_period,
3219 __scan_completed_cb, scanner);
3220 scanners = g_slist_append(scanners, scanner);
3221 UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3224 return UAM_ERROR_NONE;
3227 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3231 uam_scanner_info_t *scanner;
3234 retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3235 retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3237 scanner = __uam_find_scanner(sender);
3238 retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3240 /* Trim sensors to a subset of active sensors for the scanner */
3241 sensors &= scanner->sensors;
3244 * modify scanner's active sensors and if active sensors are NULL
3245 * remove scanner from scanners list
3247 scanner->sensors &= ~sensors;
3248 if (0 == scanner->sensors) {
3249 scanners = g_slist_remove(scanners, scanner);
3250 g_source_remove(scanner->timer);
3251 g_free(scanner->name);
3255 for (l = scanners; NULL != l; l = g_slist_next(l)) {
3256 uam_scanner_info_t *scanner_data = l->data;
3258 if (!scanner_data || !scanner_data->name)
3261 sensors &= ~(scanner_data->sensors);
3265 ret = _uam_pm_stop_active_device_scan(sensors);
3266 if (UAM_ERROR_NONE != ret) {
3267 UAM_ERR("Failed with error: %s (0x%4.4X)",
3268 _uam_manager_error_to_str(ret), ret);
3274 return UAM_ERROR_NONE;
3277 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3278 unsigned int sensor, const uam_device_info_s *dev_info)
3283 ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3285 for (l = scanners; NULL != l;) {
3286 uam_scanner_info_t *scanner = l->data;
3288 if (!scanner || !scanner->name) {
3289 l = g_slist_next(l);
3293 if (0 == (scanner->sensors & sensor)) {
3294 l = g_slist_next(l);
3298 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3299 scanner->sensors &= ~(sensor);
3300 UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3301 if (0 != scanner->sensors) {
3302 l = g_slist_next(l);
3306 if (UAM_ERROR_NONE != _uam_manager_send_event(
3307 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3308 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3310 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3313 l = g_slist_next(l);
3314 scanners = g_slist_remove(scanners, scanner);
3315 g_source_remove(scanner->timer);
3316 g_free(scanner->name);
3319 GVariant *param = g_variant_new("(iiisss)",
3321 dev_info->operating_system,
3324 dev_info->ipv4_addr,
3325 dev_info->device_id);
3326 if (UAM_ERROR_NONE != _uam_manager_send_event(
3327 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3328 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3330 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3332 l = g_slist_next(l);
3339 int _uam_core_register_service(uam_service_info_s *svc)
3343 uam_db_service_info_t *service;
3344 int service_number = 0;
3346 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3348 /* Retrieve service from list */
3349 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3350 retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3352 service = g_new0(uam_db_service_info_t, 1);
3353 service->name = g_strdup(svc->name);
3354 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3355 service->presence_threshold = svc->presence_threshold;
3356 service->absence_threshold = svc->absence_threshold;
3358 /* Add service to database */
3359 if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3360 UAM_ERR("_uam_db_insert_service_info failed");
3362 return UAM_ERROR_DB_FAILED;
3365 services = g_slist_append(services, service);
3367 /* Send service registered event to application */
3368 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3369 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3370 UAM_ERROR_NONE, service->name)))
3371 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3374 return UAM_ERROR_NONE;
3377 int _uam_core_update_service(uam_service_info_s *svc)
3381 uam_db_service_info_t *service;
3383 retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3385 /* Retrieve service from list */
3386 l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3387 retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3390 service->presence_threshold = svc->presence_threshold;
3391 service->absence_threshold = svc->absence_threshold;
3393 /* Update service to database */
3394 if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3395 UAM_ERR("_uam_db_update_service_info failed");
3396 return UAM_ERROR_DB_FAILED;
3400 return UAM_ERROR_NONE;
3403 int _uam_core_get_default_service(uam_service_info_s *service_info)
3408 uam_db_service_info_t *service;
3410 retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3412 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3415 // insert default service
3416 memset(service_info, 0x00, sizeof(uam_service_info_s));
3417 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3418 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3419 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3421 ret = _uam_core_register_service(service_info);
3422 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3423 UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3426 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3429 retv_if(NULL == l, UAM_ERROR_INTERNAL);
3432 memset(service_info, 0x00, sizeof(uam_service_info_s));
3433 g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3436 return UAM_ERROR_NONE;
3439 int _uam_core_unregister_service(const char *svc_name)
3443 uam_db_service_info_t *service;
3445 retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3447 /* Retrieve service from list */
3448 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3449 retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3452 /* Check if service is being used*/
3453 if (service->monitors) {
3454 UAM_ERR("service monitoring in progress");
3455 return UAM_ERROR_PERMISSION_DENIED;
3458 /* Remove service from database */
3459 if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3460 UAM_ERR("_uam_db_delete_service_info failed");
3461 return UAM_ERROR_DB_FAILED;
3464 /* Remove service mapping from devices*/
3465 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3466 uam_db_tech_info_t *tech = l->data;
3467 if (!tech || !tech->addresses)
3469 tech->svc_list = g_slist_remove(tech->svc_list, service);
3471 services = g_slist_remove(services, service);
3473 /* Send service unregistered event to application */
3474 if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3475 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3476 UAM_ERROR_NONE, service->name)))
3477 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3480 return UAM_ERROR_NONE;
3483 static void __get_service_dev_list(
3484 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3491 /* Calculate number of devices */
3492 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3493 uam_db_tech_info_t *tech = l1->data;
3494 if (!tech || !tech->addresses)
3500 *device_list = g_new0(uam_device_info_s, *count);
3503 for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3504 uam_db_tech_info_t *tech = l1->data;
3507 if (!tech || !tech->addresses)
3510 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
3511 uam_db_address_info_t *addr = l2->data;
3516 switch (addr->addr_type) {
3517 case UAM_ADDR_TYPE_BLE:
3518 case UAM_ADDR_TYPE_BT:
3519 case UAM_ADDR_TYPE_P2P:
3520 case UAM_ADDR_TYPE_WIFI:
3521 g_strlcpy((*device_list)[indx].mac,
3523 UAM_MAC_ADDRESS_STRING_LEN);
3525 case UAM_ADDR_TYPE_IPv4:
3526 g_strlcpy((*device_list)[indx].ipv4_addr,
3528 UAM_IP_ADDRESS_MAX_STRING_LEN);
3531 UAM_WARN("Unknown address type %d", addr->addr_type);
3535 uam_db_device_info_t *db_info = tech->device;
3536 (*device_list)[indx].operating_system = db_info->os;
3537 g_strlcpy((*device_list)[indx].device_id, db_info->device_id,
3538 UAM_DEVICE_ID_MAX_STRING_LEN);
3539 (*device_list)[indx].last_seen = tech->timestamp;
3540 (*device_list)[indx].discriminant = tech->discriminant;
3541 memset((*device_list)[indx].payload.duid, 0, UAM_BLE_PAYLOAD_DUID_LEN + 1);
3542 memset((*device_list)[indx].payload.bt_mac, 0, UAM_BT_MAC_ADDRESS_STRING_LEN);
3543 if (tech->payload) {
3544 if (tech->payload->service_id)
3545 (*device_list)[indx].payload.service_id = tech->payload->service_id;
3546 if (tech->payload->device_icon)
3547 (*device_list)[indx].payload.device_icon = tech->payload->device_icon;
3548 if (tech->payload->purpose)
3549 (*device_list)[indx].payload.purpose = tech->payload->purpose;
3550 if (tech->payload->duid)
3551 memcpy((*device_list)[indx].payload.duid,
3552 tech->payload->duid, UAM_BLE_PAYLOAD_DUID_LEN);
3553 if (tech->payload->bt_mac)
3554 g_strlcpy((*device_list)[indx].payload.bt_mac,
3555 tech->payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
3558 (*device_list)[indx++].type = tech->tech_type;
3561 UAM_INFO("Count = %d, indx = %d", *count, indx);
3565 int _uam_core_get_service_devices(const char *svc_name,
3566 int *count, uam_device_info_s **device_list)
3569 uam_db_service_info_t *service;
3572 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3573 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3576 __get_service_dev_list(service, device_list, count);
3579 return UAM_ERROR_NONE;
3582 static void __get_service_user_list(
3583 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3588 GSList *svc_user_list = NULL;
3591 /* Calculate number of users */
3592 for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3593 uam_db_tech_info_t *tech = l->data;
3594 if (!tech || !tech->addresses)
3598 uam_db_user_info_t *db_info = tech->device->user;
3599 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3601 svc_user_list = g_slist_append(svc_user_list, db_info);
3604 *count = g_slist_length(svc_user_list);
3605 *user_list = g_new0(uam_user_info_s, *count);
3608 for (l = svc_user_list; l; l = g_slist_next(l)) {
3609 uam_db_user_info_t *db_info = l->data;
3611 if (!db_info || !db_info->account)
3614 g_strlcpy((*user_list)[indx].account,
3615 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3617 g_strlcpy((*user_list)[indx].name,
3618 db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3623 UAM_INFO("Count = %d, indx = %d", *count, indx);
3627 int _uam_core_get_service_users(const char *svc_name,
3628 int *count, uam_user_info_s **user_list)
3631 uam_db_service_info_t *service;
3634 l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3635 retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3638 __get_service_user_list(service, user_list, count);
3641 return UAM_ERROR_NONE;
3644 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3650 size = g_slist_length(services);
3651 *service_list = g_new0(uam_service_info_s, size);
3654 /* fetch services list from DB */
3655 for (l = services; l; l = g_slist_next(l)) {
3656 uam_db_service_info_t *db_info = l->data;
3658 if (!db_info || !db_info->name)
3661 g_strlcpy((*service_list)[*count].name,
3662 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3663 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3664 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3668 UAM_INFO("Count: %d", *count);
3670 return UAM_ERROR_NONE;
3673 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3678 UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3679 iadv[0], iadv[1], iadv[2]);
3681 ret = _uam_db_insert_adv_info(adv_len, iadv);
3682 if (UAM_ERROR_NONE != ret) {
3683 UAM_ERR("_uam_db_insert_adv_info failed");
3687 ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3688 if (UAM_ERROR_NONE != ret) {
3689 UAM_ERR("Failed with error: %s (0x%4.4X)",
3690 _uam_manager_error_to_str(ret), ret);
3695 return UAM_ERROR_NONE;
3698 void _uam_core_handle_status_changed(unsigned int sensor, unsigned int type,
3703 uam_sensor_info_s *sensor_info = info;
3705 ret_if(NULL == info);
3707 sensor_info->status = type;
3709 UAM_INFO("sensor: 0x%8.8X, detection_type: %d", sensor, type);
3711 if (UAS_ABSENCE == type) {
3712 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3713 g_variant_new("(uutiidddd)", type, sensor, 0, 0, 0, 0, 0, 0, 0));
3714 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
3716 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3717 g_variant_new("(uutiidddd)", type, sensor, sensor_info->timestamp,
3718 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3719 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));