fc29fff1380d686628e2650f1542de2df3482991
[platform/core/connectivity/ua-manager.git] / ua-daemon / src / ua-manager-core.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <time.h>
19
20 #include "ua-api.h"
21 #include "ua-plugin.h"
22 #include "ua-internal.h"
23 #include "ua-manager-common.h"
24 #include "ua-plugin-manager.h"
25
26 #include "ua-manager-database.h"
27 #include "ua-cloud-plugin-handler.h"
28
29 #include "ua-power-plugin-manager.h"
30
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
35
36 typedef struct {
37         char *name;
38         unsigned int sensors;
39         uam_pm_detection_mode_e mode;
40         uam_db_service_info_t *service;
41 } uam_monitor_info_t;
42
43 typedef struct {
44         char *name;
45         unsigned int sensors;
46         guint timer;
47 } uam_scanner_info_t;
48
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 */
53
54 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
55 static GSList *scanners; /* List of scanning apps -  uam_scanner_info_t */
56
57 static guint detection_timer = 0;
58 static unsigned int detection_window;
59
60 static unsigned int detecting_sensors = 0;
61
62 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
63 {
64         const uam_db_user_info_t *user = data;
65         const char *account = user_data;
66
67         retv_if(NULL == user, -1);
68         retv_if(NULL == user->account, -1);
69         retv_if(NULL == account, -1);
70
71         return g_strcmp0(user->account, account);
72 }
73
74 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
75 {
76         const uam_db_user_info_t *user = data;
77         const unsigned short *id = user_data;
78
79         retv_if(NULL == user, -1);
80         retv_if(NULL == user->account, -1);
81         retv_if(NULL == id, -1);
82
83         if (*id != user->user_id)
84                 return 1;
85
86         return 0;
87 }
88
89 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
90 {
91         const uam_db_service_info_t *service = data;
92         const char *svc_name = user_data;
93
94         retv_if(NULL == service, -1);
95         retv_if(NULL == service->name, -1);
96         retv_if(NULL == svc_name, -1);
97
98         return g_strcmp0(service->name, svc_name);
99 }
100
101 static void __free_address_info(gpointer data)
102 {
103         FUNC_ENTRY;
104         uam_db_address_info_t *addr = data;
105
106         ret_if(NULL == addr);
107
108         g_free(addr->address);
109         g_free(addr);
110
111         FUNC_EXIT;
112 }
113
114 static void __free_dev_tech_info(gpointer data)
115 {
116         FUNC_ENTRY;
117         uam_db_tech_info_t *tech_info = data;
118         GSList *l;
119
120         ret_if(NULL == tech_info);
121
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;
125
126                 if (!svc_info || !svc_info->dev_techs)
127                         continue;
128
129                 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
130         }
131
132         g_slist_free_full(tech_info->addresses, __free_address_info);
133         tech_info->addresses = NULL;
134
135         if (tech_info->payload) {
136                 if (tech_info->payload->duid) {
137                         g_free(tech_info->payload->duid);
138                 }
139                 g_free(tech_info->payload);
140         }
141
142         g_free(tech_info);
143
144         FUNC_EXIT;
145 }
146
147 static void __free_user_device(gpointer data)
148 {
149         FUNC_ENTRY;
150         uam_db_device_info_t *device = data;
151
152         ret_if(NULL == device);
153
154         /* Remove device data from global device list */
155         devices = g_slist_remove(devices, device);
156
157         /* Free allocated memory */
158         g_free(device->device_id);
159         g_slist_free_full(device->tech_list, __free_dev_tech_info);
160         g_free(device);
161
162         FUNC_EXIT;
163 }
164
165 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
166 {
167         FUNC_ENTRY;
168         GVariant *param;
169
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)",
173                         err,
174                         dev_info->operating_system,
175                         dev_info->type,
176                         dev_info->mac,
177                         dev_info->ipv4_addr,
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));
181
182         FUNC_EXIT;
183 }
184
185 static void __print_service(gpointer data, gpointer user_data)
186 {
187         FUNC_ENTRY;
188         uam_db_service_info_t *service = data;
189         uam_db_tech_info_t *tech = user_data;
190
191         ret_if(NULL == tech);
192         ret_if(NULL == service);
193
194         UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
195                         tech->device->device_id, tech->tech_type,
196                         service->name, service->cycle);
197
198         FUNC_EXIT;
199 }
200
201 static void __add_service_to_dev_tech_mapping(
202                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
203 {
204         FUNC_ENTRY;
205
206         ret_if(NULL == tech);
207         ret_if(NULL == service);
208
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);
212
213         FUNC_EXIT;
214 }
215
216 static void __remove_service_to_dev_tech_mapping(
217                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
218 {
219         FUNC_ENTRY;
220
221         ret_if(NULL == tech);
222         ret_if(NULL == service);
223
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);
227
228         FUNC_EXIT;
229 }
230
231 static char *__get_mac_addr(uam_db_tech_info_t *tech)
232 {
233         FUNC_ENTRY;
234         GSList *l;
235
236         retv_if(NULL == tech, NULL);
237
238         for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
239                 uam_db_address_info_t *addr = l->data;
240
241                 if (!addr)
242                         continue;
243
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;
249         }
250
251         FUNC_EXIT;
252         return NULL;
253 }
254
255 static void __remove_user_device(gpointer data)
256 {
257         FUNC_ENTRY;
258         uam_db_device_info_t *device = data;
259         uam_device_info_s dev_info;
260         unsigned short user_id;
261         GSList *l;
262
263         ret_if(NULL == device);
264
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);
268
269         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
270                 uam_db_tech_info_t *tech = l->data;
271                 GSList *l1, *l2;
272                 int ret;
273
274                 if (!tech)
275                         continue;
276
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;
280
281                         if (!svc_info || !svc_info->dev_techs)
282                                 continue;
283
284                         svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech);
285                 }
286
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);
290
291                 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
292                         uam_db_address_info_t *addr = l1->data;
293
294                         if (!addr)
295                                 continue;
296
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);
304                                 break;
305                         case UAM_ADDR_TYPE_IPv4:
306                                 g_strlcpy(dev_info.ipv4_addr, addr->address,
307                                                 UAM_IP_ADDRESS_MAX_STRING_LEN);
308                                 break;
309                         default:
310                                 UAM_WARN("Address type %d ignored", addr->addr_type);
311                         }
312                 }
313
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));
318
319                 /* Send device removed event to application */
320                 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
321
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");
326         }
327
328         __free_user_device(device);
329
330         FUNC_EXIT;
331 }
332
333 static void __free_uam_db_user_info(gpointer data)
334 {
335         FUNC_ENTRY;
336         uam_db_user_info_t *user = data;
337
338         g_slist_free_full(user->devices, __remove_user_device);
339
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");
343
344         /* Set/update registered device list to cloud plugin */
345         _uam_cloud_update_registered_devices();
346
347         g_free(user->name);
348         g_free(user->account);
349         g_free(user);
350         FUNC_EXIT;
351 }
352
353 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
354 {
355         FUNC_ENTRY;
356         const uam_db_device_info_t *device = data;
357         const char *dev_id = user_data;
358
359         retv_if(NULL == device, -1);
360         retv_if(NULL == device->device_id, -1);
361         retv_if(NULL == dev_id, -1);
362
363         FUNC_EXIT;
364         return g_strcmp0(device->device_id, dev_id);
365 }
366
367 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
368 {
369         FUNC_ENTRY;
370         const uam_db_tech_info_t *tech = data;
371         const int *type = user_data;
372
373         retv_if(NULL == tech, -1);
374         retv_if(NULL == type, -1);
375
376         FUNC_EXIT;
377         return ((*type == tech->tech_type) ? 0 : 1);
378 }
379
380 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
381 {
382         FUNC_ENTRY;
383         GSList *l;
384
385         for (l = devices; NULL != l; l = g_slist_next(l)) {
386                 uam_db_device_info_t *dev = l->data;
387                 GSList *l1;
388
389                 if (!dev)
390                         continue;
391
392                 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
393                         uam_db_tech_info_t *tech = l1->data;
394                         GSList *l2;
395
396                         if (!tech)
397                                 continue;
398
399                         for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
400                                 uam_db_address_info_t *addr = l2->data;
401
402                                 if (!addr)
403                                         continue;
404
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);
412                                                 return tech;
413                                         }
414                         }
415                 }
416         }
417
418         FUNC_EXIT;
419         return NULL;
420 }
421
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)
424 {
425         FUNC_ENTRY;
426         GSList *l;
427         int indx = 0;
428
429         *count = 0;
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;
433                 GSList *l1;
434
435                 if (!db_info || !db_info->device_id)
436                         continue;
437
438                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
439                         uam_db_tech_info_t *tech = l1->data;
440
441                         if (!tech || !tech->addresses)
442                                 continue;
443
444                         (*count)++;
445                 }
446         }
447         UAM_INFO("Count = %d", *count);
448
449         *device_list = g_new0(uam_device_info_s, *count);
450
451         /* Copy devices */
452         for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
453                 uam_db_device_info_t *db_info = l->data;
454                 GSList *l1;
455
456                 if (!db_info || !db_info->device_id)
457                         continue;
458
459                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
460                         uam_db_tech_info_t *tech = l1->data;
461                         GSList *l2;
462
463                         if (!tech || !tech->addresses)
464                                 continue;
465
466                         for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
467                                 uam_db_address_info_t *addr = l2->data;
468
469                                 if (!addr)
470                                         continue;
471
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,
478                                                         addr->address,
479                                                         UAM_MAC_ADDRESS_STRING_LEN);
480                                         break;
481                                 case UAM_ADDR_TYPE_IPv4:
482                                         g_strlcpy((*device_list)[indx].ipv4_addr,
483                                                         addr->address,
484                                                         UAM_IP_ADDRESS_MAX_STRING_LEN);
485                                         break;
486                                 default:
487                                         UAM_WARN("Unknown address type %d", addr->addr_type);
488                                 }
489                         }
490
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);
494
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);
497                         if (tech->payload) {
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);
507                         }
508
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);
516                 }
517         }
518
519         UAM_INFO("Count = %d, indx = %d", *count, indx);
520         FUNC_EXIT;
521 }
522
523 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
524 {
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);
532                 break;
533         case UAM_ADDR_TYPE_IPv4:
534                 g_strlcpy(device->ipv4_addr,
535                                 addr->address,
536                                 UAM_IP_ADDRESS_MAX_STRING_LEN);
537                 break;
538         default:
539                 UAM_WARN("Unknown address type %d", addr->addr_type);
540         }
541 }
542
543 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
544 {
545         FUNC_ENTRY;
546         GSList *l;
547
548         retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
549
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;
553
554                 if (!addr)
555                         continue;
556
557                 __uam_core_copy_addr(device, addr);
558         }
559
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);
567         if (tech->payload) {
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);
577         }
578
579         FUNC_EXIT;
580         return UAM_ERROR_NONE;
581 }
582
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)
585 {
586 //      FUNC_ENTRY;
587         GSList *l;
588
589         retv_if(NULL == name, NULL);
590         retv_if(NULL == monitor_list, NULL);
591
592         for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
593                 uam_monitor_info_t *monitor = l->data;
594
595                 if (!monitor || !monitor->name ||
596                                 !monitor->service || !monitor->service->name)
597                         continue;
598
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");
603                         return monitor;
604                 }
605         }
606
607 //      FUNC_EXIT;
608         return NULL;
609 }
610
611 unsigned int _uam_core_get_active_sensors(int detection_mode)
612 {
613         FUNC_ENTRY;
614         unsigned int sensors = 0;
615         GSList *l;
616
617         retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
618                         (UAM_DETECT_ABSENCE != detection_mode), 0);
619
620         for (l = monitors; NULL != l; l = g_slist_next(l)) {
621                 uam_monitor_info_t *monitor = l->data;
622
623                 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
624                         continue;
625
626                 sensors |= monitor->sensors;
627         }
628
629         FUNC_EXIT;
630         return sensors;
631 }
632
633 unsigned int _uam_core_get_env_sensors()
634 {
635         FUNC_ENTRY;
636         unsigned int sensors = 0;
637
638         sensors |= UAM_SENSOR_BITMASK_MOTION;
639         sensors |= UAM_SENSOR_BITMASK_LIGHT;
640
641         FUNC_EXIT;
642         return sensors;
643 }
644
645 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
646 {
647         FUNC_ENTRY;
648         GSList *l;
649         GSList *svc_list = NULL;
650
651         retv_if(NULL == db_svc_list, NULL);
652
653         /*
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.
657          */
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;
661                 GSList *l1;
662
663                 if (!db_svc)
664                         continue;
665
666                 l1 = g_slist_find_custom(services,
667                                 db_svc->service_name, __compare_svc_name);
668                 if (!l1) {
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);
673                 } else
674                         service = l1->data;
675
676                 svc_list = g_slist_append(svc_list, service);
677         }
678
679         FUNC_EXIT;
680         return svc_list;
681 }
682
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)
686 {
687         FUNC_ENTRY;
688         uam_db_tech_info_t *tech;
689         uam_db_device_info_t *device;
690         GSList *l;
691
692         ret_if(NULL == dev_info);
693         ret_if(NULL == user);
694
695         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
696         if (NULL != l) {
697                 device = l->data;
698                 ret_if(user != device->user);
699                 ret_if(device->supported_techs & dev_info->type);
700
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;
707                         else
708                                 UAM_WARN("Strange - OS types did not match, need to check");
709                 }
710         } else {
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;
715                 device->user = user;
716
717                 /* Add device to global device list */
718                 devices = g_slist_append(devices, device);
719
720                 /* Add same device to user's device list */
721                 user->devices = g_slist_append(user->devices, device);
722         }
723
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;
730
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);
737
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;
742
743                 if (!service)
744                         continue;
745
746                 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
747         }
748
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);
753
754         if (0 < strlen(dev_info->mac)) {
755                 uam_db_address_info_t *addr;
756
757                 addr = g_new0(uam_db_address_info_t, 1);
758                 addr->address = g_strdup(dev_info->mac);
759
760                 switch (dev_info->type) {
761                 case UAM_TECH_TYPE_BLE:
762                         addr->addr_type = UAM_ADDR_TYPE_BLE;
763                         break;
764                 case UAM_TECH_TYPE_BT:
765                         addr->addr_type = UAM_ADDR_TYPE_BT;
766                         break;
767                 case UAM_TECH_TYPE_P2P:
768                         addr->addr_type = UAM_ADDR_TYPE_P2P;
769                         break;
770                 case UAM_TECH_TYPE_WIFI:
771                         addr->addr_type = UAM_ADDR_TYPE_WIFI;
772                         break;
773                 default:
774                         UAM_ERR("Unknown tech type: %d", dev_info->type);
775                         g_free(addr->address);
776                         g_free(addr);
777                         addr = NULL;
778                 }
779
780                 if (addr) {
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);
784                 }
785         }
786
787         if (0 < strlen(dev_info->ipv4_addr)) {
788                 uam_db_address_info_t *addr;
789
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);
794                 else
795                         UAM_DBG("IPv4 address %s added for tech type: %d",
796                                         dev_info->ipv4_addr, dev_info->type);
797
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);
801
802                 tech->addresses = g_slist_append(tech->addresses, addr);
803         }
804
805         FUNC_EXIT;
806 }
807
808 int _uam_core_add_user(const char *account, const char *name)
809 {
810         FUNC_ENTRY;
811         GSList *l;
812         uam_db_user_info_t *user;
813
814         l = g_slist_find_custom(users, account, __compare_user_account);
815         retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
816
817         user = g_new0(uam_db_user_info_t, 1);
818
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");
822                 g_free(user);
823                 return UAM_ERROR_DB_FAILED;
824         }
825
826         user->name = g_strdup(name);
827         user->account = g_strdup(account);
828         user->devices = NULL;
829
830         users = g_slist_append(users, user);
831
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");
837
838         FUNC_EXIT;
839         return UAM_ERROR_NONE;
840 }
841
842 int _uam_core_remove_user(const char *account)
843 {
844         FUNC_ENTRY;
845         GSList *l;
846         uam_db_user_info_t *user;
847
848         l = g_slist_find_custom(users, account, __compare_user_account);
849         retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
850         user = l->data;
851
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;
856         }
857
858         users = g_slist_remove(users, user);
859
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");
865
866         __free_uam_db_user_info((gpointer)user);
867
868         FUNC_EXIT;
869         return UAM_ERROR_NONE;
870 }
871
872 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
873 {
874         FUNC_ENTRY;
875         int ret;
876         GSList *l;
877         uam_db_device_info_t *device;
878         uam_db_user_info_t *user;
879
880         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
881         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
882
883         l = g_slist_find_custom(users, account, __compare_user_account);
884         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
885         user = l->data;
886
887         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
888         if (NULL != l) {
889                 device = l->data;
890                 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
891                 retv_if((dev_info->type & device->supported_techs),
892                                 UAM_ERROR_ALREADY_REGISTERED);
893         }
894
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));
899                 return ret;
900         }
901
902         FUNC_EXIT;
903         return UAM_ERROR_NONE;
904 }
905
906 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
907 {
908         FUNC_ENTRY;
909         uam_db_device_info_t *device;
910         GSList *l;
911
912         retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
913         retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
914
915         *is_added = FALSE;
916         l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
917         if (NULL == l)
918                 goto done;
919
920         device = l->data;
921         if (!(device->supported_techs & dev->type))
922                 goto done;
923
924         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
925                 uam_db_tech_info_t *tech = l->data;
926                 GSList *l1;
927
928                 if (!tech)
929                         continue;
930
931                 if (dev->type != tech->tech_type)
932                         continue;
933
934                 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
935                         uam_db_address_info_t *addr = l1->data;
936
937                         if (!addr)
938                                 continue;
939
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)) {
945                                         *is_added = TRUE;
946                                         break;
947                                 }
948                 }
949                 break;
950         }
951
952 done:
953         UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
954         FUNC_EXIT;
955         return UAM_ERROR_NONE;
956 }
957
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)
960 {
961         int ret;
962         GSList *l;
963         int count = 0;
964
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));
970                 return ret;
971         }
972
973         if (1 < count) {
974                 ret = UAM_ERROR_RESOURCE_BUSY;
975                 UAM_WARN("other service uses this device ref:[%d]", count);
976                 return ret;
977         }
978
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));
983                 return ret;
984         }
985
986         /* Send device removed event to application */
987         __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
988
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");
993
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;
997
998                 if (!svc || !svc->name)
999                         continue;
1000                 _uam_core_service_remove_device(svc->name, dev_info->device_id, dev_info->type);
1001         }
1002
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);
1008
1009         if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1010                 /* Remove device from global device list */
1011                 devices = g_slist_remove(devices, device);
1012
1013                 /* Remove device  from user's device list */
1014                 device->user->devices = g_slist_remove(device->user->devices, device);
1015
1016                 __free_user_device(device);
1017         }
1018
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");
1022
1023         /* Set/update registered device list to cloud plugin */
1024         _uam_cloud_update_registered_devices();
1025
1026         FUNC_EXIT;
1027         return UAM_ERROR_NONE;
1028 }
1029
1030 int _uam_core_remove_device(const char *account,
1031         const uam_device_info_s *dev_info)
1032 {
1033         FUNC_ENTRY;
1034         int ret;
1035         GSList *l;
1036         uam_db_tech_info_t *tech;
1037         uam_db_device_info_t *device;
1038         uam_db_user_info_t *user;
1039
1040         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1041         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1042
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);
1046         user = l->data;
1047
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);
1051         device = l->data;
1052         retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1053         retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1054
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);
1059         tech = l->data;
1060
1061         ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1062
1063         FUNC_EXIT;
1064         return ret ;
1065 }
1066
1067 int _uam_core_remove_device_by_device_id(const char *device_id,
1068         int tech_type)
1069 {
1070         FUNC_ENTRY;
1071         int ret;
1072         GSList *l;
1073         uam_device_info_s dev_info;
1074         uam_db_tech_info_t *tech;
1075         uam_db_device_info_t *device;
1076
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);
1080
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);
1084         device = l->data;
1085         retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1086
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);
1091         tech = l->data;
1092
1093         /* Get dev_info */
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);
1096
1097         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1098
1099         FUNC_EXIT;
1100         return ret;
1101 }
1102
1103 int _uam_core_remove_device_by_mac(const char *mac)
1104 {
1105         FUNC_ENTRY;
1106         uam_db_tech_info_t *tech;
1107         uam_db_device_info_t *device;
1108         uam_device_info_s dev_info;
1109         int ret;
1110
1111         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1112
1113         tech = __get_tech_info_by_mac(mac);
1114         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1115         device = tech->device;
1116
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;
1121         }
1122
1123         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1124
1125         FUNC_EXIT;
1126         return ret;
1127 }
1128
1129 int _uam_core_update_device(const uam_device_info_s *a_device)
1130 {
1131         FUNC_ENTRY;
1132
1133         int ret;
1134         GSList *l, *l1, *l2;
1135
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;
1140
1141         /* Find all tech-devices in users' devices */
1142         for (l = users; NULL != l; l = g_slist_next(l)) {
1143                 user = l->data;
1144
1145                 l1 = g_slist_find_custom(user->devices,
1146                                 a_device->device_id, __compare_device_id);
1147                 if (NULL == l1) {
1148                         UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1149                                         user->user_id, a_device->device_id);
1150                         continue;
1151                 }
1152
1153                 device = l1->data;
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);
1157                         continue;
1158                 }
1159
1160                 /* Update discriminant for devices */
1161                 device->discriminant = a_device->discriminant;
1162                 device->os = a_device->operating_system;
1163
1164                 l2 = g_slist_find_custom(device->tech_list,
1165                                 &(a_device->type), __compare_tech_type);
1166                 if (NULL == l2) {
1167                         UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1168                         continue;
1169                 }
1170
1171                 tech = l2->data;
1172                 if (!tech) {
1173                         UAM_DBG("Device tech is NULL");
1174                         continue;
1175                 }
1176
1177                 /* Update discriminant for device-tech */
1178                 tech->discriminant = a_device->discriminant;
1179
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);
1186
1187                 /* Update device's updated information to database */
1188                 __copy_tech_info_to_device_info(tech, &temp);
1189
1190                 ret = _uam_device_db_update_device_device(temp.device_id, temp.type,
1191                                 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant,
1192                                 temp.payload);
1193                 if (UAM_ERROR_NONE != ret)
1194                         UAM_WARN("_uam_device_db_update_device_device failed [%d]", ret);
1195         }
1196
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);
1201
1202         /* Set/update registered device list to cloud plugin */
1203         _uam_cloud_update_registered_devices();
1204
1205         FUNC_EXIT;
1206         return UAM_ERROR_NONE;
1207 }
1208
1209 int _uam_core_get_default_user(uam_user_info_s *user_info)
1210 {
1211         FUNC_ENTRY;
1212         int ret;
1213         GSList *l;
1214         uam_db_user_info_t *user;
1215
1216         retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1217
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));
1221                 return ret;
1222         }
1223
1224         l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1225         retv_if(NULL == l, UAM_ERROR_INTERNAL);
1226         user = l->data;
1227
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);
1231
1232         FUNC_EXIT;
1233         return UAM_ERROR_NONE;
1234 }
1235
1236 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1237 {
1238         FUNC_ENTRY;
1239         guint size;
1240         GSList *l;
1241
1242         size = g_slist_length(users);
1243         *user_list = g_new0(uam_user_info_s, size);
1244         *count = 0;
1245
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;
1249
1250                 if (!db_info || !db_info->account)
1251                         continue;
1252
1253                 g_strlcpy((*user_list)[*count].account,
1254                                 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1255                 if (db_info->name)
1256                         g_strlcpy((*user_list)[*count].name,
1257                                         db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1258
1259                 *count += 1;
1260         }
1261
1262         UAM_INFO("Count: %d", *count);
1263         FUNC_EXIT;
1264         return UAM_ERROR_NONE;
1265 }
1266
1267 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1268 {
1269         FUNC_ENTRY;
1270         uam_db_user_info_t *db_info;
1271         GSList *l;
1272
1273         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1274
1275         l = g_slist_find_custom(users, account, __compare_user_account);
1276         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1277         db_info = l->data;
1278
1279         g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1280         if (db_info->name)
1281                 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1282
1283
1284         FUNC_EXIT;
1285         return UAM_ERROR_NONE;
1286 }
1287
1288 int _uam_core_get_devcie_by_device_id(
1289                 const char *device_id, int tech_type, uam_device_info_s *device)
1290 {
1291         FUNC_ENTRY;
1292         uam_db_device_info_t *db_info;
1293         GSList *l;
1294         GSList *l1;
1295
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);
1299
1300         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1301         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1302         db_info = l->data;
1303         retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1304
1305         memset(device, 0x00, sizeof(uam_device_info_s));
1306
1307         for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1308                 uam_db_tech_info_t *tech = l1->data;
1309                 GSList *l2;
1310
1311                 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1312                         continue;
1313
1314                 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1315                         uam_db_address_info_t *addr = l2->data;
1316
1317                         if (!addr)
1318                                 continue;
1319
1320                         __uam_core_copy_addr(device, addr);
1321                 }
1322
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;
1328         }
1329
1330         retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1331
1332         FUNC_EXIT;
1333         return UAM_ERROR_NONE;
1334 }
1335
1336 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1337 {
1338         FUNC_ENTRY;
1339         int ret;
1340         uam_db_tech_info_t *tech;
1341
1342         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1343
1344         tech = __get_tech_info_by_mac(mac);
1345         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1346
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;
1351         }
1352
1353         FUNC_EXIT;
1354         return UAM_ERROR_NONE;
1355 }
1356
1357 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1358 {
1359         FUNC_ENTRY;
1360         uam_db_device_info_t *dev;
1361         GSList *l;
1362
1363         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1364
1365         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1366         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1367         dev = l->data;
1368
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);
1372
1373         FUNC_EXIT;
1374         return UAM_ERROR_NONE;
1375 }
1376
1377 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1378 {
1379         FUNC_ENTRY;
1380         uam_db_tech_info_t *tech;
1381
1382         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1383
1384         tech = __get_tech_info_by_mac(mac);
1385         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1386
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);
1390
1391         FUNC_EXIT;
1392         return UAM_ERROR_NONE;
1393 }
1394
1395 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1396 {
1397         FUNC_ENTRY;
1398
1399         __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1400
1401         FUNC_EXIT;
1402         return UAM_ERROR_NONE;
1403 }
1404
1405 int _uam_core_get_user_devices(const char *account,
1406                 int *count, uam_device_info_s **device_list)
1407 {
1408         FUNC_ENTRY;
1409         uam_db_user_info_t *user;
1410         GSList *l;
1411
1412         l = g_slist_find_custom(users, account, __compare_user_account);
1413         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1414         user = l->data;
1415
1416         __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1417
1418         FUNC_EXIT;
1419         return UAM_ERROR_NONE;
1420 }
1421
1422 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1423 {
1424         FUNC_ENTRY;
1425
1426         *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1427
1428         FUNC_EXIT;
1429         return UAM_ERROR_NONE;
1430 }
1431
1432 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1433 {
1434         FUNC_ENTRY;
1435         gboolean is_ready;
1436
1437         is_ready = _uam_pm_is_sensor_ready(sensor);
1438         UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1439
1440         FUNC_EXIT;
1441         return is_ready;
1442 }
1443
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)
1446 {
1447         FUNC_ENTRY;
1448         uam_svc_dev_info_t *svc_dev = NULL;
1449         GSList *l;
1450
1451         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1452                 svc_dev = l->data;
1453
1454                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1455                         continue;
1456
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");
1461                         return svc_dev;
1462                 }
1463         }
1464
1465         FUNC_EXIT;
1466         return NULL;
1467 }
1468
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)
1471 {
1472         FUNC_ENTRY;
1473         uam_svc_dev_info_t *svc = NULL;
1474
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);
1479
1480         svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1481         if (!svc) {
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);
1487         }
1488
1489         svc->discriminant = discriminant;
1490
1491         UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]",
1492                 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1493
1494         FUNC_EXIT;
1495         return UAM_ERROR_NONE;
1496 }
1497
1498 int _uam_core_service_add_user(const char *svc_name, const char *account)
1499 {
1500         FUNC_ENTRY;
1501         GSList *l;
1502         int ret = UAM_ERROR_NONE;
1503         uam_db_user_info_t *user;
1504         uam_db_service_info_t *service;
1505
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);
1509
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);
1513         user = l->data;
1514
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);
1518         service = l->data;
1519
1520         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1521                 uam_db_device_info_t *device = l->data;
1522                 GSList *l1;
1523
1524                 if (!device)
1525                         continue;
1526
1527                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1528                         uam_db_tech_info_t *tech = l1->data;
1529                         char *mac;
1530                         GSList *l2;
1531
1532                         if (!tech)
1533                                 continue;
1534
1535                         l2 = g_slist_find_custom(tech->svc_list, svc_name,
1536                                         __compare_svc_name);
1537                         if (NULL != l2)
1538                                 continue;
1539
1540                         __add_service_to_dev_tech_mapping(tech, service);
1541
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");
1549                                 return ret;
1550                         }
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");
1555                                 return ret;
1556                         }
1557                 }
1558         }
1559
1560         FUNC_EXIT;
1561         return ret;
1562 }
1563
1564 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1565 {
1566         FUNC_ENTRY;
1567         GSList *l;
1568         uam_db_user_info_t *user;
1569
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);
1573
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);
1577         user = l->data;
1578
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);
1582
1583         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1584                 uam_db_device_info_t *device = l->data;
1585                 GSList *l1;
1586
1587                 if (!device)
1588                         continue;
1589
1590                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1591                         uam_db_tech_info_t *tech = l1->data;
1592                         char *mac;
1593                         GSList *l2;
1594
1595                         if (!tech)
1596                                 continue;
1597
1598                         l2 = g_slist_find_custom(tech->svc_list, svc_name,
1599                                         __compare_svc_name);
1600                         if (NULL == l2)
1601                                 continue;
1602
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);
1606
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");
1612                 }
1613         }
1614
1615         FUNC_EXIT;
1616         return UAM_ERROR_NONE;
1617 }
1618
1619 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1620 {
1621         FUNC_ENTRY;
1622         uam_db_device_info_t *device;
1623         GSList *l;
1624
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);
1628
1629         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1630         if (NULL == l) {
1631                 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1632                 return NULL;
1633         }
1634
1635         device = l->data;
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);
1639                 return NULL;
1640         }
1641
1642         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1643                 uam_db_tech_info_t *tech = l->data;
1644
1645                 if (!tech)
1646                         continue;
1647
1648                 if (tech_type == tech->tech_type) {
1649                         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1650                                         device_id, tech_type);
1651                         return tech;
1652                 }
1653         }
1654
1655         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1656         FUNC_EXIT;
1657         return NULL;
1658 }
1659
1660 int _uam_core_service_add_device(const char *svc_name, const char *device_id, int tech_type)
1661 {
1662         FUNC_ENTRY;
1663         GSList *l;
1664         char *mac;
1665         int ret = UAM_ERROR_NONE;
1666         uam_db_tech_info_t *tech_info;
1667         uam_db_service_info_t *service;
1668
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);
1674
1675         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1676         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1677
1678         l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1679         retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1680
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);
1684         service = l->data;
1685
1686         __add_service_to_dev_tech_mapping(tech_info, service);
1687
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");
1694                 return ret;
1695         }
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");
1700                 return ret;
1701         }
1702
1703         FUNC_EXIT;
1704         return UAM_ERROR_NONE;
1705 }
1706
1707 int _uam_core_service_remove_device(const char *svc_name, const char *device_id, int tech_type)
1708 {
1709         FUNC_ENTRY;
1710         GSList *l;
1711         char *mac;
1712         uam_db_tech_info_t *tech_info;
1713
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);
1719
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);
1723
1724         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1725         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1726
1727         l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1728         retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1729
1730         __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1731
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");
1737
1738         FUNC_EXIT;
1739         return UAM_ERROR_NONE;
1740 }
1741
1742 int _uam_core_service_set_device_discriminant(const char *svc_name,
1743                 const char *device_id, int tech_type, gboolean discriminant)
1744 {
1745         FUNC_ENTRY;
1746         GSList *l;
1747         int ret = UAM_ERROR_NONE;
1748         char *mac;
1749         uam_db_tech_info_t *tech_info;
1750         uam_db_service_info_t *service;
1751
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);
1756
1757         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1758         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1759
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);
1763         service = l->data;
1764
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");
1771                 return ret;
1772         }
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");
1777                 return ret;
1778         }
1779
1780         FUNC_EXIT;
1781         return UAM_ERROR_NONE;
1782 }
1783
1784 int _uam_core_service_get_device_discriminant(const char *svc_name,
1785                 const char *device_id, int tech_type, gboolean *discriminant)
1786 {
1787         FUNC_ENTRY;
1788         uam_svc_dev_info_t *svc_dev;
1789
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);
1794
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;
1798
1799         FUNC_EXIT;
1800         return UAM_ERROR_NONE;
1801 }
1802
1803 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1804 {
1805         FUNC_ENTRY;
1806         GSList *l;
1807         uam_db_service_info_t *service;
1808         unsigned int elapsed_time;
1809
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);
1813
1814         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1815         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1816         service = l->data;
1817
1818         elapsed_time = service->cycle - service->remaining_time;
1819         service->cycle = new_cycle;
1820         if (new_cycle < elapsed_time)
1821                 service->remaining_time = 0;
1822         else
1823                 service->remaining_time = new_cycle - elapsed_time;
1824
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");
1828
1829         FUNC_EXIT;
1830         return UAM_ERROR_NONE;
1831 }
1832
1833 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1834 {
1835         FUNC_ENTRY;
1836         GSList *l;
1837         uam_db_service_info_t *service;
1838
1839         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1840         retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1841
1842         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1843         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1844         service = l->data;
1845         *cycle = service->cycle;
1846
1847         FUNC_EXIT;
1848         return UAM_ERROR_NONE;
1849 }
1850
1851 int _uam_core_set_detection_threshold(unsigned int sensor,
1852                 int presence_threshold, int absence_threshold)
1853 {
1854         FUNC_ENTRY;
1855         int ret;
1856
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));
1862                 return ret;
1863         }
1864
1865         FUNC_EXIT;
1866         return UAM_ERROR_NONE;
1867 }
1868
1869 static gboolean __start_detection(gpointer data)
1870 {
1871         FUNC_ENTRY;
1872         int ret;
1873         uam_db_service_info_t *service = NULL;
1874         unsigned int sensors;
1875         gboolean start_detection = FALSE;
1876         GSList *l;
1877         unsigned int env_sensors;
1878
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);
1887
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);
1893
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);
1899
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);
1905         }
1906
1907         for (l = services; NULL != l; l = g_slist_next(l)) {
1908                 service = l->data;
1909                 if (!service || !service->monitors)
1910                         continue;
1911
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;
1918                 }
1919         }
1920
1921         if (!start_detection)
1922                 goto done;
1923
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);
1927
1928         /* Remove env sensors from active sensors */
1929         sensors &= ~env_sensors;
1930         UAM_DBG("Connectivity sensors: 0x%8.8X", sensors);
1931
1932         if (0 != 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);
1938         }
1939
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);
1943
1944         /* Remove env sensors from active sensors */
1945         sensors &= ~env_sensors;
1946         UAM_DBG("Connectivity sensors: 0x%8.8X", sensors);
1947
1948         if (0 != 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);
1954         }
1955
1956 done:
1957         FUNC_EXIT;
1958         return TRUE;
1959 }
1960
1961 static int __uam_core_start_detection(int detection_type,
1962                 const char *svc_name, char *sender, unsigned int sensors)
1963 {
1964         FUNC_ENTRY;
1965         uam_monitor_info_t *monitor;
1966         uam_db_service_info_t *service;
1967         gboolean is_monitor_added = TRUE;
1968         GSList *l;
1969
1970         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
1971         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1972
1973         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1974         if (!l) {
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);
1979                 l = services;
1980         }
1981
1982         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1983         retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
1984
1985         service = l->data;
1986         monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
1987         if (!monitor) {
1988                 monitor = g_malloc0(sizeof(uam_monitor_info_t));
1989                 if (monitor) {
1990                         monitor->name = g_strdup(sender);
1991                         monitor->mode = detection_type;
1992                         monitor->service = service;
1993                         is_monitor_added = FALSE;
1994                 } else {
1995                         UAM_ERR("Memory allocation error");
1996                         return UAM_ERROR_OUT_OF_MEMORY;
1997                 }
1998         }
1999
2000         UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2001
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);
2006         }
2007
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);
2014         }
2015
2016         FUNC_EXIT;
2017         return UAM_ERROR_NONE;
2018 }
2019
2020 static int __uam_core_stop_detection(int detection_type,
2021                 const char *svc_name, char *sender, unsigned int sensors)
2022 {
2023         FUNC_ENTRY;
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;
2029
2030         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2031         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2032
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);
2037
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);
2042
2043         /* Update monitor info for application */
2044         monitor->sensors &= ~sensors;
2045         if (0 == monitor->sensors) {
2046                 /*
2047                  * App requested to stop monitoring for all of its active sensors,
2048                  * remove its monitor info from list.
2049                  */
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;
2055                 }
2056
2057                 service->monitors = g_slist_remove(service->monitors, monitor);
2058                 if (NULL == service->monitors)
2059                         service->remaining_time = 0;
2060
2061                 g_free(monitor->name);
2062                 g_free(monitor);
2063         }
2064
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);
2068
2069         if (active_sensors == remaining_sensors) {
2070                 UAM_INFO("NO need to stop monitoring");
2071                 return UAM_ERROR_NONE;
2072         }
2073
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);
2080
2081         FUNC_EXIT;
2082         return ret;
2083 }
2084
2085 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2086 {
2087         FUNC_ENTRY;
2088         int ret;
2089
2090         ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2091
2092         FUNC_EXIT;
2093         return ret;
2094 }
2095
2096 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2097 {
2098         FUNC_ENTRY;
2099         int ret;
2100
2101         ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2102
2103         FUNC_EXIT;
2104         return ret;
2105 }
2106
2107 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2108 {
2109         FUNC_ENTRY;
2110         int ret;
2111
2112         ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2113
2114         FUNC_EXIT;
2115         return ret;
2116 }
2117
2118 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2119 {
2120         FUNC_ENTRY;
2121         int ret;
2122
2123         ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2124
2125         FUNC_EXIT;
2126         return ret;
2127 }
2128
2129 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2130 {
2131         FUNC_ENTRY;
2132         int ret;
2133
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));
2139                 return ret;
2140         }
2141
2142         FUNC_EXIT;
2143         return UAM_ERROR_NONE;
2144 }
2145
2146 int _uam_core_get_detection_window(unsigned int *window)
2147 {
2148         FUNC_ENTRY;
2149
2150         retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2151
2152         *window = detection_window;
2153
2154         FUNC_EXIT;
2155         return UAM_ERROR_NONE;
2156 }
2157
2158 int _uam_core_set_detection_window(unsigned int window)
2159 {
2160         FUNC_ENTRY;
2161
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);
2165
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;
2169         }
2170
2171         detection_window = window;
2172
2173         FUNC_EXIT;
2174         return UAM_ERROR_NONE;
2175 }
2176
2177 int _uam_core_init(void)
2178 {
2179         FUNC_ENTRY;
2180         GSList *db_users;
2181         GSList *db_devices;
2182         GSList *db_svc_list;
2183         GSList *db_adv_list;
2184         GSList *db_svc_dev_list;
2185         GSList *l;
2186
2187         /* Init database */
2188         _uam_db_initialize();
2189
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);
2194
2195         /* Fetch user list */
2196         db_users = _uam_db_get_all_users();
2197         if (!db_users) {
2198                 UAM_INFO_C("No users in database");
2199                 return UAM_ERROR_NONE;
2200         }
2201
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;
2205
2206                 if (!info)
2207                         continue;
2208
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;
2214
2215                 users = g_slist_prepend(users, user);
2216         }
2217
2218         /* Fetch service list */
2219         db_svc_list = _uam_service_db_get_all_services();
2220         if (!db_svc_list) {
2221                 UAM_INFO_C("No services in database");
2222                 return UAM_ERROR_NONE;
2223         }
2224
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;
2228                 GSList *l1;
2229
2230                 if (!db_svc)
2231                         continue;
2232
2233                 l1 = g_slist_find_custom(services,
2234                                 db_svc->service_name, __compare_svc_name);
2235                 if (!l1) {
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);
2242                 }
2243         }
2244
2245         /* Fetch device list */
2246         db_devices = _uam_device_db_get_all_devices();
2247         if (!db_devices) {
2248                 UAM_INFO_C("No Devices registered in database");
2249                 return UAM_ERROR_NONE;
2250         }
2251
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;
2256                 GSList *l1;
2257
2258                 if (!db_info)
2259                         continue;
2260
2261                 l1 = g_slist_find_custom(users,
2262                                 &(db_info->user_id), __compare_user_id);
2263                 if (!l1) {
2264                         UAM_ERR("Invalid user Id: %d", db_info->user_id);
2265                         continue;
2266                 }
2267                 user = l1->data;
2268
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);
2274
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);
2278         }
2279
2280         /* Fetch iBeacon adv list */
2281         db_adv_list = _uam_db_get_all_advs();
2282         if (!db_adv_list) {
2283                 UAM_INFO_C("No iBeacon adv in database");
2284         } else {
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);
2288                 }
2289         }
2290
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");
2295         } else {
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);
2300                 }
2301         }
2302
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);
2308
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");
2312
2313         /* Set/update registered device list to cloud plugin */
2314         _uam_cloud_update_registered_devices();
2315
2316         FUNC_EXIT;
2317         return UAM_ERROR_NONE;
2318 }
2319
2320 void _uam_core_deinit(void)
2321 {
2322         FUNC_ENTRY;
2323         GSList *l;
2324
2325         /* de-init database */
2326         _uam_db_deinitialize();
2327
2328         /* Reset detecton window to default */
2329         detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2330
2331         /* Release allocated memory for devices */
2332         g_slist_free_full(devices, __free_user_device);
2333         devices = NULL;
2334
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;
2338
2339                 if (!user)
2340                         continue;
2341
2342                 g_free(user->name);
2343                 g_free(user->account);
2344                 g_free(user);
2345         }
2346
2347         g_slist_free(users);
2348         users = NULL;
2349
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;
2353
2354                 if (!service)
2355                         continue;
2356
2357                 g_free(service->name);
2358                 g_free(service);
2359         }
2360         g_slist_free(services);
2361         services = NULL;
2362
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;
2366
2367                 if (!svc_dev)
2368                         continue;
2369
2370                 g_free(svc_dev->device_id);
2371                 g_free(svc_dev->service);
2372                 g_free(svc_dev);
2373         }
2374         g_slist_free(svc_devs);
2375         svc_devs = NULL;
2376
2377         FUNC_EXIT;
2378 }
2379
2380 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2381 {
2382         FUNC_ENTRY;
2383
2384         /* Send sensor state changed event over dbus */
2385         if (is_ready)
2386                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2387                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2388         else
2389                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2390                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2391
2392         FUNC_EXIT;
2393 }
2394
2395 int _uam_core_handle_device_added(int status,
2396                 int user_id, const uam_device_info_s *dev_info)
2397 {
2398         FUNC_ENTRY;
2399         GSList *l;
2400         int ret = UAM_ERROR_NONE;
2401         uam_db_user_info_t *user = NULL;
2402         GSList *svc_list = NULL;
2403         unsigned long long timestamp;
2404
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;
2410                 GArray *out_param;
2411
2412                 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2413                         continue;
2414
2415                 dev = info->data;
2416                 if (!dev) {
2417                         UAM_WARN("info->data is NULL");
2418                         _uam_manager_remove_req_ctxt_from_list(info);
2419                         continue;
2420                 }
2421
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);
2427                         continue;
2428                 }
2429
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);
2433                 g_free(info->data);
2434                 _uam_manager_remove_req_ctxt_from_list(info);
2435                 break;
2436         }
2437
2438         if (UAM_ERROR_NONE != status) {
2439                 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2440                 return status;
2441         }
2442
2443         if (0 > user_id) {
2444                 l = g_slist_find_custom(users,
2445                                 USER_ACCOUNT_DEFAULT, __compare_user_account);
2446                 if (NULL == l) {
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);
2453                                 return ret;
2454                         }
2455                 }
2456                 user_id = USER_ACCOUNT_DEFAULT_ID;
2457         }
2458         l = g_slist_find_custom(users, &user_id, __compare_user_id);
2459         if (NULL == l) {
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);
2463                 return ret;
2464         }
2465         user = l->data;
2466
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);
2469         if (!l) {
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);
2475         } else {
2476                 uam_db_service_info_t *service = l->data;
2477                 svc_list = g_slist_append(svc_list, service);
2478         }
2479
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);
2483
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");
2489                 return ret;
2490         }
2491
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);
2500                 return ret;
2501         }
2502
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);
2509                 return ret;
2510         }
2511
2512         /* Send device added event to application */
2513         __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2514
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");
2519                 return ret;
2520         }
2521
2522         _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2523
2524         /* Set/update registered device list to cloud plugin */
2525         if (UAM_ERROR_NONE == status)
2526                 _uam_cloud_update_registered_devices();
2527
2528         FUNC_EXIT;
2529         return ret;
2530 }
2531
2532 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2533 {
2534         FUNC_ENTRY;
2535         GSList *l;
2536
2537         UAM_INFO("sensor 0x[%8.8X]", sensor);
2538
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);
2543                 FUNC_EXIT;
2544                 return;
2545         }
2546
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);
2553                 FUNC_EXIT;
2554                 return;
2555         }
2556
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;
2560                 GSList *l1;
2561
2562                 if (!svc || !svc->monitors)
2563                         continue;
2564
2565                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2566                                 svc->name, sensor_info->values[0], svc->presence_threshold);
2567
2568                 if (sensor_info->values[0] < svc->presence_threshold)
2569                         continue;
2570
2571                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2572                         uam_monitor_info_t *mon = l1->data;
2573
2574                         if (!mon)
2575                                 continue;
2576
2577                         UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2578                                         mon->name, mon->sensors);
2579
2580                         if (!(mon->sensors & sensor))
2581                                 continue;
2582
2583                         if (UAM_DETECT_PRESENCE != mon->mode)
2584                                 continue;
2585
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",
2591                                         mon->name, sensor);
2592                 }
2593         }
2594
2595         FUNC_EXIT;
2596 }
2597
2598 void __send_sensor_absence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2599 {
2600         FUNC_ENTRY;
2601         GSList *l;
2602
2603         UAM_INFO("sensor 0x[%8.8X]", sensor);
2604
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);
2609                 FUNC_EXIT;
2610                 return;
2611         }
2612
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);
2619                 FUNC_EXIT;
2620                 return;
2621         }
2622
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;
2626                 GSList *l1;
2627
2628                 if (!svc || !svc->monitors)
2629                         continue;
2630
2631                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2632                                 svc->name, sensor_info->values[0], svc->absence_threshold);
2633
2634                 if (sensor_info->values[0] > svc->absence_threshold)
2635                         continue;
2636
2637                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2638                         uam_monitor_info_t *mon = l1->data;
2639
2640                         if (!mon)
2641                                 continue;
2642
2643                         if (!(mon->sensors & sensor))
2644                                 continue;
2645
2646                         if (UAM_DETECT_PRESENCE != mon->mode)
2647                                 continue;
2648
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);
2654                 }
2655         }
2656
2657         FUNC_EXIT;
2658 }
2659
2660 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2661                                 char *device_id)
2662 {
2663         FUNC_ENTRY;
2664         uam_db_user_info_t *user;
2665         GSList *l;
2666         uam_svc_dev_info_t *svc_dev = NULL;
2667
2668         ret_if(NULL == tech);
2669         ret_if(NULL == tech->svc_list);
2670
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;
2674                 GSList *l1;
2675
2676                 if (!svc || !svc->monitors)
2677                         continue;
2678
2679                 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2680                         svc->name, svc->remaining_time, svc->cycle);
2681
2682                 if (!(svc->remaining_time == svc->cycle))
2683                         continue;
2684
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)
2688                         continue;
2689
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;
2693
2694                         if (!mon)
2695                                 continue;
2696
2697                         if (!(mon->sensors & sensor))
2698                                 continue;
2699
2700                         if (UAM_DETECT_PRESENCE != mon->mode)
2701                                 continue;
2702
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"
2711                                         " on device %s"
2712                                         " for 0x%8.8X, User: %s Service: %s",
2713                                         mon->name, device_id,
2714                                         sensor, user->account,
2715                                         svc->name);
2716                 }
2717         }
2718
2719         FUNC_EXIT;
2720 }
2721
2722 void _uam_core_handle_presence_detected(unsigned int sensor,
2723                 int user_id, void *info)
2724 {
2725         FUNC_ENTRY;
2726         uam_db_user_info_t *user;
2727         uam_db_device_info_t *device;
2728         uam_db_tech_info_t *tech;
2729         GSList *l;
2730         uam_device_info_s *dev_info = NULL;
2731         uam_sensor_info_s *sensor_info = NULL;
2732
2733         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2734
2735         if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2736                 sensor_info = info;
2737         if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2738                 dev_info = info;
2739
2740         _uam_ppm_send_presence_detection_event(sensor);
2741
2742         if (NULL == dev_info) {
2743                 __send_sensor_presence_event(sensor_info, sensor);
2744                 return;
2745         }
2746
2747         ret_if(0 > user_id);
2748
2749         l = g_slist_find_custom(users, &user_id, __compare_user_id);
2750         if (NULL == l) {
2751                 UAM_ERR("Invalid user_id [%d]", user_id);
2752                 return;
2753         }
2754         user = l->data;
2755
2756         l = g_slist_find_custom(user->devices,
2757                         dev_info->device_id, __compare_device_id);
2758         if (NULL == l) {
2759                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2760                                 user_id, dev_info->device_id);
2761                 return;
2762         }
2763         device = l->data;
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);
2767                 return;
2768         }
2769
2770         l = g_slist_find_custom(device->tech_list,
2771                         &(dev_info->type), __compare_tech_type);
2772         if (NULL == l) {
2773                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2774                 return;
2775         }
2776         tech = l->data;
2777
2778         tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2779         tech->timestamp = (unsigned long long)time(NULL);
2780
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;
2785
2786                 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2787                         uam_db_address_info_t *addr = l->data;
2788
2789                         if (!addr || (UAM_ADDR_TYPE_IPv4 != addr->addr_type))
2790                                 continue;
2791
2792                         if (!strcasecmp(addr->address, dev_info->ipv4_addr))
2793                                 is_updated = FALSE;
2794                         else
2795                                 UAM_DBG("Old IPv4: %s, New IPv4: %s",
2796                                                 addr->address, dev_info->ipv4_addr);
2797                         addr_info = addr;
2798                         break;
2799                 }
2800
2801                 if (is_updated) {
2802                         if (!addr_info) {
2803                                 addr_info = g_new0(uam_db_address_info_t, 1);
2804                                 tech->addresses = g_slist_append(tech->addresses, addr_info);
2805                         } else {
2806                                 g_free(addr_info->address);
2807                         }
2808
2809                         addr_info->addr_type = UAM_ADDR_TYPE_IPv4;
2810                         addr_info->address = g_strdup(dev_info->ipv4_addr);
2811
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");
2816                 }
2817         }
2818
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");
2823
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");
2827
2828         __send_user_presence_event(tech, sensor, dev_info->device_id);
2829
2830         FUNC_EXIT;
2831 }
2832
2833 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
2834 {
2835         FUNC_ENTRY;
2836         GSList *l;
2837
2838         /*
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.
2842          */
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;
2847                 GSList *l1;
2848                 GSList *l2;
2849
2850                 if (!svc || !svc->monitors || !svc->dev_techs)
2851                         continue;
2852
2853                 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
2854                         uam_db_tech_info_t *tech = l1->data;
2855
2856                         if (!tech || (tech->tech_type != type)) {
2857                                 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
2858                                 continue;
2859                         }
2860
2861                         if (!tech->device || !tech->device->user) {
2862                                 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
2863                                 continue;
2864                         }
2865
2866                         l2 = g_slist_find_custom(present_users,
2867                                         &(tech->device->user->user_id), __compare_user_id);
2868
2869                         if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
2870                                 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
2871                                         tech->discriminant,
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);
2876
2877                                 /* If user not in present list, add user to the list */
2878                                 if (!l2) {
2879                                         UAM_DBG("added present user [%s]", tech->device->user->account);
2880                                         present_users = g_slist_prepend(present_users, tech->device->user);
2881                                 }
2882                         } else {
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);
2889                                 }
2890                         }
2891                 }
2892
2893                 g_slist_free(present_users);
2894                 if (!absent_users)
2895                         continue;
2896
2897                 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
2898                         uam_monitor_info_t *mon = l2->data;
2899
2900                         if (!mon)
2901                                 continue;
2902
2903                         if (!(mon->sensors & sensor))
2904                                 continue;
2905
2906                         if (UAM_DETECT_ABSENCE != mon->mode)
2907                                 continue;
2908
2909                         for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
2910                                 uam_db_user_info_t *user = l1->data;
2911
2912                                 if (!user)
2913                                         continue;
2914
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,
2920                                                         user->timestamp));
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);
2926                         }
2927                 }
2928
2929                 g_slist_free(absent_users);
2930         }
2931
2932         FUNC_EXIT;
2933 }
2934
2935 void _uam_core_handle_absence_detected(unsigned int sensor,
2936                 int user_id, void *info)
2937 {
2938         FUNC_ENTRY;
2939         uam_db_user_info_t *user;
2940         uam_db_device_info_t *device;
2941         uam_db_tech_info_t *tech;
2942         GSList *l;
2943         uam_device_info_s *dev_info = NULL;
2944         uam_sensor_info_s *sensor_info = NULL;
2945
2946         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2947
2948         if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2949                 sensor_info = info;
2950         if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2951                 dev_info = info;
2952
2953         if (NULL == dev_info) {
2954                 __send_sensor_absence_event(sensor_info, sensor);
2955                 FUNC_EXIT;
2956                 return;
2957         }
2958
2959         ret_if(0 > user_id);
2960
2961         l = g_slist_find_custom(users, &user_id, __compare_user_id);
2962         if (NULL == l) {
2963                 UAM_ERR("Invalid user_id [%d]", user_id);
2964                 return;
2965         }
2966         user = l->data;
2967
2968         l = g_slist_find_custom(user->devices,
2969                         dev_info->device_id, __compare_device_id);
2970         if (NULL == l) {
2971                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2972                                 user_id, dev_info->device_id);
2973                 return;
2974         }
2975         device = l->data;
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);
2979                 return;
2980         }
2981
2982         l = g_slist_find_custom(device->tech_list,
2983                         &(dev_info->type), __compare_tech_type);
2984         if (NULL == l) {
2985                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2986                 return;
2987         }
2988         tech = l->data;
2989
2990         tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
2991
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");
2996
2997         FUNC_EXIT;
2998 }
2999
3000 void _uam_core_cleanup_monitor(char *name)
3001 {
3002         GSList *l;
3003
3004         for (l = monitors; NULL != l; l = g_slist_next(l)) {
3005                 uam_monitor_info_t *monitor = l->data;
3006
3007                 if (!monitor || !monitor->name || !monitor->service)
3008                         continue;
3009
3010                 if (0 != g_strcmp0(name, monitor->name))
3011                         continue;
3012
3013                 __uam_core_stop_detection(monitor->mode,
3014                                 monitor->service->name, name, monitor->sensors);
3015         }
3016 }
3017
3018 static void __free_user_info(gpointer data)
3019 {
3020         FUNC_ENTRY;
3021         uam_db_user_info_t *user = data;
3022
3023         ret_if(NULL == user);
3024
3025         g_free(user->name);
3026         g_free(user->account);
3027         g_free(user);
3028         FUNC_EXIT;
3029 }
3030
3031 static void __free_service_info(gpointer data)
3032 {
3033         FUNC_ENTRY;
3034         uam_db_service_info_t *svc = data;
3035
3036         ret_if(NULL == svc);
3037
3038         g_free(svc->name);
3039         g_free(svc);
3040         FUNC_EXIT;
3041 }
3042
3043 static void __free_monitor_info(gpointer data)
3044 {
3045         FUNC_ENTRY;
3046         uam_monitor_info_t *monitor = data;
3047
3048         ret_if(NULL == monitor);
3049
3050         g_free(monitor->name);
3051         g_free(monitor);
3052         FUNC_EXIT;
3053 }
3054
3055 static void __free_scanner_info(gpointer data)
3056 {
3057         FUNC_ENTRY;
3058         uam_scanner_info_t *scanner = data;
3059
3060         ret_if(NULL == scanner);
3061
3062         g_free(scanner->name);
3063         g_free(scanner);
3064         FUNC_EXIT;
3065 }
3066
3067 void _uam_core_reset_database(void)
3068 {
3069         FUNC_ENTRY;
3070         int ret;
3071
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));
3076                 return;
3077         }
3078
3079         g_slist_free_full(devices, __free_user_device);
3080         devices = NULL;
3081
3082         g_slist_free_full(users, __free_user_info);
3083         users = NULL;
3084
3085         g_slist_free_full(services, __free_service_info);
3086         services = NULL;
3087
3088         g_slist_free_full(monitors, __free_monitor_info);
3089         monitors = NULL;
3090
3091         g_slist_free_full(scanners, __free_scanner_info);
3092         scanners = NULL;
3093
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));
3099
3100         /* Set/update registered device list to cloud plugin */
3101         _uam_cloud_update_registered_devices();
3102
3103         FUNC_EXIT;
3104 }
3105
3106 void _uam_core_handle_detection_started(unsigned int sensor)
3107 {
3108         FUNC_ENTRY;
3109         unsigned int active_sensors = 0;
3110
3111         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3112                         sensor, detecting_sensors);
3113
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);
3120         }
3121
3122         FUNC_EXIT;
3123 }
3124
3125 void _uam_core_handle_detection_stopped(unsigned int sensor)
3126 {
3127         FUNC_ENTRY;
3128         uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3129
3130         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3131                         sensor, detecting_sensors);
3132         detecting_sensors &= ~sensor;
3133
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;
3138
3139         if (UAM_TECH_TYPE_NONE != type)
3140                 __send_user_absence_event(type, sensor);
3141
3142         if (0 == detecting_sensors)
3143                 /* Send detection stopped event */
3144                 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STOPPED, NULL);
3145
3146         FUNC_EXIT;
3147 }
3148
3149 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3150 {
3151         GSList *l;
3152
3153         retv_if(NULL == name, NULL);
3154
3155         for (l = scanners; NULL != l; l = g_slist_next(l)) {
3156                 uam_scanner_info_t *scanner = l->data;
3157
3158                 if (!scanner || !scanner->name)
3159                         continue;
3160
3161                 if (0 == g_strcmp0(scanner->name, name)) {
3162                         UAM_DBG("Scanning application found in list");
3163                         return scanner;
3164                 }
3165         }
3166
3167         return NULL;
3168 }
3169
3170 static gboolean __scan_completed_cb(gpointer data)
3171 {
3172         FUNC_ENTRY;
3173         uam_scanner_info_t *scanner = data;
3174
3175         retv_if(NULL == scanner, FALSE);
3176
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");
3180         else
3181                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3182
3183         /* Free scanner */
3184         scanners = g_slist_remove(scanners, scanner);
3185         g_free(scanner->name);
3186         g_free(scanner);
3187
3188         FUNC_EXIT;
3189         return FALSE;
3190 }
3191
3192 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3193 {
3194         FUNC_ENTRY;
3195         int ret;
3196         uam_scanner_info_t *scanner;
3197
3198         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3199         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3200
3201         scanner = __uam_find_scanner(sender);
3202         retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3203
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);
3208                 return ret;
3209         }
3210
3211         scanner = g_malloc0(sizeof(uam_scanner_info_t));
3212         if (!scanner) {
3213                 UAM_ERR("Failed to allocate memory");
3214                 return UAM_ERROR_OUT_OF_MEMORY;
3215         }
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);
3222
3223         FUNC_EXIT;
3224         return UAM_ERROR_NONE;
3225 }
3226
3227 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3228 {
3229         FUNC_ENTRY;
3230         int ret;
3231         uam_scanner_info_t *scanner;
3232         GSList *l;
3233
3234         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3235         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3236
3237         scanner = __uam_find_scanner(sender);
3238         retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3239
3240         /* Trim sensors to a subset of active sensors for the scanner */
3241         sensors &= scanner->sensors;
3242
3243         /*
3244          * modify scanner's active sensors and if active sensors are NULL
3245          * remove scanner from scanners list
3246          */
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);
3252                 g_free(scanner);
3253         }
3254
3255         for (l = scanners; NULL != l; l = g_slist_next(l)) {
3256                 uam_scanner_info_t *scanner_data = l->data;
3257
3258                 if (!scanner_data || !scanner_data->name)
3259                         continue;
3260
3261                 sensors &= ~(scanner_data->sensors);
3262         }
3263
3264         if (0 != 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);
3269                         return ret;
3270                 }
3271         }
3272
3273         FUNC_EXIT;
3274         return UAM_ERROR_NONE;
3275 }
3276
3277 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3278                 unsigned int sensor, const uam_device_info_s *dev_info)
3279 {
3280         FUNC_ENTRY;
3281         GSList *l;
3282
3283         ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3284
3285         for (l = scanners; NULL != l;) {
3286                 uam_scanner_info_t *scanner = l->data;
3287
3288                 if (!scanner || !scanner->name) {
3289                         l = g_slist_next(l);
3290                         continue;
3291                 }
3292
3293                 if (0 == (scanner->sensors & sensor)) {
3294                         l = g_slist_next(l);
3295                         continue;
3296                 }
3297
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);
3303                                 continue;
3304                         }
3305
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");
3309                         else
3310                                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3311
3312                         /* Free scanner */
3313                         l = g_slist_next(l);
3314                         scanners = g_slist_remove(scanners, scanner);
3315                         g_source_remove(scanner->timer);
3316                         g_free(scanner->name);
3317                         g_free(scanner);
3318                 } else {
3319                         GVariant *param = g_variant_new("(iiisss)",
3320                                         UAM_ERROR_NONE,
3321                                         dev_info->operating_system,
3322                                         dev_info->type,
3323                                         dev_info->mac,
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));
3329                         else
3330                                 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3331
3332                         l = g_slist_next(l);
3333                 }
3334         }
3335
3336         FUNC_EXIT;
3337 }
3338
3339 int _uam_core_register_service(uam_service_info_s *svc)
3340 {
3341         FUNC_ENTRY;
3342         GSList *l;
3343         uam_db_service_info_t *service;
3344         int service_number = 0;
3345
3346         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3347
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);
3351
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;
3357
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");
3361                 g_free(service);
3362                 return UAM_ERROR_DB_FAILED;
3363         }
3364
3365         services = g_slist_append(services, service);
3366
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");
3372
3373         FUNC_EXIT;
3374         return UAM_ERROR_NONE;
3375 }
3376
3377 int _uam_core_update_service(uam_service_info_s *svc)
3378 {
3379         FUNC_ENTRY;
3380         GSList *l;
3381         uam_db_service_info_t *service;
3382
3383         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3384
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);
3388
3389         service = l->data;
3390         service->presence_threshold = svc->presence_threshold;
3391         service->absence_threshold = svc->absence_threshold;
3392
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;
3397         }
3398
3399         FUNC_EXIT;
3400         return UAM_ERROR_NONE;
3401 }
3402
3403 int _uam_core_get_default_service(uam_service_info_s *service_info)
3404 {
3405         FUNC_ENTRY;
3406         int ret;
3407         GSList *l;
3408         uam_db_service_info_t *service;
3409
3410         retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3411
3412         l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3413
3414         if (NULL == l) {
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;
3420
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));
3424                         return ret;
3425                 }
3426                 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3427         }
3428
3429         retv_if(NULL == l, UAM_ERROR_INTERNAL);
3430         service = l->data;
3431
3432         memset(service_info, 0x00, sizeof(uam_service_info_s));
3433         g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3434
3435         FUNC_EXIT;
3436         return UAM_ERROR_NONE;
3437 }
3438
3439 int _uam_core_unregister_service(const char *svc_name)
3440 {
3441         FUNC_ENTRY;
3442         GSList *l;
3443         uam_db_service_info_t *service;
3444
3445         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3446
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);
3450         service = l->data;
3451
3452         /* Check if service is being used*/
3453         if (service->monitors) {
3454                 UAM_ERR("service monitoring in progress");
3455                 return UAM_ERROR_PERMISSION_DENIED;
3456         }
3457
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;
3462         }
3463
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)
3468                         continue;
3469                 tech->svc_list = g_slist_remove(tech->svc_list, service);
3470         }
3471         services = g_slist_remove(services, service);
3472
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");
3478
3479         FUNC_EXIT;
3480         return UAM_ERROR_NONE;
3481 }
3482
3483 static void __get_service_dev_list(
3484                 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3485 {
3486         FUNC_ENTRY;
3487         GSList *l1;
3488         int indx = 0;
3489
3490         *count = 0;
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)
3495                         continue;
3496
3497                 (*count)++;
3498         }
3499
3500         *device_list = g_new0(uam_device_info_s, *count);
3501
3502         /* Copy devices */
3503         for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3504                 uam_db_tech_info_t *tech = l1->data;
3505                 GSList *l2;
3506
3507                 if (!tech || !tech->addresses)
3508                         continue;
3509
3510                 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
3511                         uam_db_address_info_t *addr = l2->data;
3512
3513                         if (!addr)
3514                                 continue;
3515
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,
3522                                                 addr->address,
3523                                                 UAM_MAC_ADDRESS_STRING_LEN);
3524                                 break;
3525                         case UAM_ADDR_TYPE_IPv4:
3526                                 g_strlcpy((*device_list)[indx].ipv4_addr,
3527                                                 addr->address,
3528                                                 UAM_IP_ADDRESS_MAX_STRING_LEN);
3529                                 break;
3530                         default:
3531                                 UAM_WARN("Unknown address type %d", addr->addr_type);
3532                         }
3533                 }
3534
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);
3556                         }
3557
3558                 (*device_list)[indx++].type = tech->tech_type;
3559         }
3560
3561         UAM_INFO("Count = %d, indx = %d", *count, indx);
3562         FUNC_EXIT;
3563 }
3564
3565 int _uam_core_get_service_devices(const char *svc_name,
3566                 int *count, uam_device_info_s **device_list)
3567 {
3568         FUNC_ENTRY;
3569         uam_db_service_info_t *service;
3570         GSList *l;
3571
3572         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3573         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3574         service = l->data;
3575
3576         __get_service_dev_list(service, device_list, count);
3577
3578         FUNC_EXIT;
3579         return UAM_ERROR_NONE;
3580 }
3581
3582 static void __get_service_user_list(
3583                 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3584 {
3585         FUNC_ENTRY;
3586         GSList *l;
3587         int indx = 0;
3588         GSList *svc_user_list = NULL;
3589
3590         *count = 0;
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)
3595                         continue;
3596
3597                 GSList *l1;
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);
3600                 if (NULL == l1)
3601                         svc_user_list = g_slist_append(svc_user_list, db_info);
3602         }
3603
3604         *count = g_slist_length(svc_user_list);
3605         *user_list = g_new0(uam_user_info_s, *count);
3606
3607         /* Copy users */
3608         for (l = svc_user_list; l; l = g_slist_next(l)) {
3609                 uam_db_user_info_t *db_info = l->data;
3610
3611                 if (!db_info || !db_info->account)
3612                         continue;
3613
3614                 g_strlcpy((*user_list)[indx].account,
3615                                 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3616                 if (db_info->name)
3617                         g_strlcpy((*user_list)[indx].name,
3618                                         db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3619
3620                 indx += 1;
3621         }
3622
3623         UAM_INFO("Count = %d, indx = %d", *count, indx);
3624         FUNC_EXIT;
3625 }
3626
3627 int _uam_core_get_service_users(const char *svc_name,
3628                 int *count, uam_user_info_s **user_list)
3629 {
3630         FUNC_ENTRY;
3631         uam_db_service_info_t *service;
3632         GSList *l;
3633
3634         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3635         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3636         service = l->data;
3637
3638         __get_service_user_list(service, user_list, count);
3639
3640         FUNC_EXIT;
3641         return UAM_ERROR_NONE;
3642 }
3643
3644 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3645 {
3646         FUNC_ENTRY;
3647         guint size;
3648         GSList *l;
3649
3650         size = g_slist_length(services);
3651         *service_list = g_new0(uam_service_info_s, size);
3652         *count = 0;
3653
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;
3657
3658                 if (!db_info || !db_info->name)
3659                         continue;
3660
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;
3665                 *count += 1;
3666         }
3667
3668         UAM_INFO("Count: %d", *count);
3669         FUNC_EXIT;
3670         return UAM_ERROR_NONE;
3671 }
3672
3673 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3674 {
3675         FUNC_ENTRY;
3676         int ret;
3677
3678         UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3679                 iadv[0], iadv[1], iadv[2]);
3680
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");
3684                 return ret;
3685         }
3686
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);
3691                 return ret;
3692         }
3693
3694         FUNC_EXIT;
3695         return UAM_ERROR_NONE;
3696 }
3697
3698 void _uam_core_handle_status_changed(unsigned int sensor, unsigned int type,
3699         void *info)
3700 {
3701         FUNC_ENTRY;
3702
3703         uam_sensor_info_s *sensor_info = info;
3704
3705         ret_if(NULL == info);
3706
3707         sensor_info->status = type;
3708
3709         UAM_INFO("sensor: 0x%8.8X, detection_type: %d", sensor, type);
3710
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);
3715         } else {
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]));
3720         }
3721
3722         FUNC_EXIT;
3723 }
3724