Add ua-manager core APIs to insert payload information
[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-vendor-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
35 typedef struct {
36         char *name;
37         unsigned int sensors;
38         uam_pm_detection_mode_e mode;
39         uam_db_service_info_t *service;
40 } uam_monitor_info_t;
41
42 typedef struct {
43         char *name;
44         unsigned int sensors;
45         guint timer;
46 } uam_scanner_info_t;
47
48 static GSList *users; /* List of users - uam_db_user_info_t */
49 static GSList *devices; /* List of devices - uam_db_device_info_t */
50 static GSList *services; /* List of services -  uam_db_service_info_t */
51 static GSList *svc_devs; /* List of service device mapping -  uam_svc_dev_info_t */
52
53 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
54 static GSList *scanners; /* List of scanning apps -  uam_scanner_info_t */
55
56 static guint detection_timer = 0;
57 static unsigned int detection_window;
58
59 static unsigned int detecting_sensors = 0;
60
61 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
62 {
63         const uam_db_user_info_t *user = data;
64         const char *account = user_data;
65
66         retv_if(NULL == user, -1);
67         retv_if(NULL == user->account, -1);
68         retv_if(NULL == account, -1);
69
70         return g_strcmp0(user->account, account);
71 }
72
73 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
74 {
75         const uam_db_user_info_t *user = data;
76         const int *id = user_data;
77
78         UAM_INFO("[%d][%d]", *id, user->user_id);
79
80         retv_if(NULL == user, -1);
81         retv_if(NULL == user->account, -1);
82         retv_if(NULL == id, -1);
83
84         if (*id != user->user_id)
85                 return 1;
86
87         return 0;
88 }
89
90 static gint __compare_svc_name(gconstpointer data, gconstpointer user_data)
91 {
92         const uam_db_service_info_t *service = data;
93         const char *svc_name = user_data;
94
95         retv_if(NULL == service, -1);
96         retv_if(NULL == service->name, -1);
97         retv_if(NULL == svc_name, -1);
98
99         return g_strcmp0(service->name, svc_name);
100 }
101
102 static void __free_address_info(gpointer data)
103 {
104         FUNC_ENTRY;
105         uam_db_address_info_t *addr = data;
106
107         ret_if(NULL == addr);
108
109         g_free(addr->address);
110         g_free(addr);
111
112         FUNC_EXIT;
113 }
114
115 static void __free_dev_tech_info(gpointer data)
116 {
117         FUNC_ENTRY;
118         uam_db_tech_info_t *tech_info = data;
119         GSList *l;
120
121         ret_if(NULL == tech_info);
122
123         /* Delete the tech information from the service list that includes tech. */
124         for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
125                 uam_db_service_info_t *svc_info = l->data;
126
127                 if (!svc_info || !svc_info->dev_techs)
128                         continue;
129
130                 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
131         }
132
133         g_slist_free_full(tech_info->addresses, __free_address_info);
134         tech_info->addresses = NULL;
135
136         g_free(tech_info);
137
138         FUNC_EXIT;
139 }
140
141 static void __free_user_device(gpointer data)
142 {
143         FUNC_ENTRY;
144         uam_db_device_info_t *device = data;
145
146         ret_if(NULL == device);
147
148         /* Remove device data from global device list */
149         devices = g_slist_remove(devices, device);
150
151         /* Free allocated memory */
152         g_free(device->device_id);
153         g_slist_free_full(device->tech_list, __free_dev_tech_info);
154         g_free(device);
155
156         FUNC_EXIT;
157 }
158
159 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
160 {
161         FUNC_ENTRY;
162         GVariant *param;
163
164         UAM_INFO_C("Send %s to applications", _uam_manager_event_to_str(event));
165         /* Send device event to application */
166         param = g_variant_new("(iiisss)",
167                         err,
168                         dev_info->operating_system,
169                         dev_info->type,
170                         dev_info->mac,
171                         dev_info->ipv4_addr,
172                         dev_info->device_id);
173         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL, event, param))
174                 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
175
176         FUNC_EXIT;
177 }
178
179 static void __print_service(gpointer data, gpointer user_data)
180 {
181         FUNC_ENTRY;
182         uam_db_service_info_t *service = data;
183         uam_db_tech_info_t *tech = user_data;
184
185         ret_if(NULL == tech);
186         ret_if(NULL == service);
187
188         UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
189                         tech->device->device_id, tech->tech_type,
190                         service->name, service->cycle);
191
192         FUNC_EXIT;
193 }
194
195 static void __add_service_to_dev_tech_mapping(
196                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
197 {
198         FUNC_ENTRY;
199
200         ret_if(NULL == tech);
201         ret_if(NULL == service);
202
203         tech->svc_list = g_slist_append(tech->svc_list, service);
204         service->dev_techs = g_slist_append(service->dev_techs, tech);
205         g_slist_foreach(tech->svc_list, __print_service, tech);
206
207         FUNC_EXIT;
208 }
209
210 static void __remove_service_to_dev_tech_mapping(
211                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
212 {
213         FUNC_ENTRY;
214
215         ret_if(NULL == tech);
216         ret_if(NULL == service);
217
218         tech->svc_list = g_slist_remove(tech->svc_list, service);
219         service->dev_techs = g_slist_remove(service->dev_techs, tech);
220         g_slist_foreach(tech->svc_list, __print_service, tech);
221
222         FUNC_EXIT;
223 }
224
225 static char *__get_mac_addr(uam_db_tech_info_t *tech)
226 {
227         FUNC_ENTRY;
228         GSList *l;
229
230         retv_if(NULL == tech, NULL);
231
232         for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
233                 uam_db_address_info_t *addr = l->data;
234
235                 if (!addr)
236                         continue;
237
238                 if (addr->addr_type == UAM_ADDR_TYPE_BT ||
239                                 addr->addr_type == UAM_ADDR_TYPE_BLE ||
240                                 addr->addr_type == UAM_ADDR_TYPE_WIFI ||
241                                 addr->addr_type == UAM_ADDR_TYPE_P2P)
242                         return addr->address;
243         }
244
245         FUNC_EXIT;
246         return NULL;
247 }
248
249 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
250 {
251         switch (addr->addr_type) {
252         case UAM_ADDR_TYPE_BLE:
253         case UAM_ADDR_TYPE_BT:
254         case UAM_ADDR_TYPE_P2P:
255         case UAM_ADDR_TYPE_WIFI:
256                 g_strlcpy(device->mac, addr->address,
257                                 UAM_MAC_ADDRESS_STRING_LEN);
258                 break;
259         case UAM_ADDR_TYPE_IPv4:
260                 g_strlcpy(device->ipv4_addr,
261                                 addr->address,
262                                 UAM_IP_ADDRESS_MAX_STRING_LEN);
263                 break;
264         default:
265                 UAM_WARN("Unknown address type %d", addr->addr_type);
266         }
267 }
268
269 /*
270 static void __uam_copy_payload_info(uam_ble_payload_s *dev_payload, uam_db_ble_payload_t *payload)
271 {
272         if (payload) {
273                 dev_payload->primary_key = payload->primary_key;
274                 dev_payload->device_icon = payload->device_icon;
275                 dev_payload->secondary_key = payload->secondary_key;
276                 if (payload->device_uid)
277                         memcpy(dev_payload->device_uid,
278                         payload->device_uid, UAM_BLE_PAYLOAD_DEVICE_UID_LEN);
279                 if (payload->bt_mac)
280                         memcpy(dev_payload->bt_mac,
281                         payload->bt_mac, UAM_BT_MAC_ADDRESS_STRING_LEN);
282         }
283 }
284 */
285
286 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
287 {
288         FUNC_ENTRY;
289         GSList *l;
290
291         retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
292
293         memset(device, 0x00, sizeof(uam_device_info_s));
294         for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
295                 uam_db_address_info_t *addr = l->data;
296
297                 if (!addr)
298                         continue;
299
300                 __uam_core_copy_addr(device, addr);
301         }
302
303         device->operating_system = tech->device->os;
304         g_strlcpy(device->device_id, tech->device->device_id,
305                         UAM_DEVICE_ID_MAX_STRING_LEN);
306         device->type = tech->tech_type;
307         device->discriminant = tech->discriminant;
308         device->last_seen = tech->last_seen;
309
310         FUNC_EXIT;
311         return UAM_ERROR_NONE;
312 }
313
314 static int _uam_remove_user_device(uam_db_device_info_t *device)
315 {
316         FUNC_ENTRY;
317         uam_device_info_s dev_info;
318         int user_id;
319         GSList *l;
320         int ret = UAM_ERROR_NONE;
321
322         retv_if(NULL == device, UAM_ERROR_INVALID_PARAMETER);
323         user_id = device->user->user_id;
324
325         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
326         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
327                 uam_db_tech_info_t *tech = l->data;
328
329                 if (!tech)
330                         continue;
331
332                 /* Copy tech info to device info */
333                 ret = __copy_tech_info_to_device_info(tech, &dev_info);
334                 if (UAM_ERROR_NONE != ret) {
335                         UAM_ERR("__copy_tech_info_to_device_info failed");
336                         __uam_db_end_transaction(0);
337                         return ret;
338                 }
339
340                 /* Unregister device from plugin */
341                 ret = _uam_pm_unregister_device(user_id, &dev_info);
342                 if (UAM_ERROR_NONE != ret)
343                         UAM_ERR("_uam_pm_unregister_device failed with %s",
344                                         _uam_manager_error_to_str(ret));
345
346                 /* Send device removed event to application */
347                 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
348
349                 /* Remove device from database */
350                 ret = _uam_device_db_delete_device_info(
351                                         dev_info.device_id, dev_info.type, dev_info.mac);
352                 if (UAM_ERROR_NONE != ret) {
353                         UAM_ERR("_uam_device_db_delete_device_info failed");
354                         __uam_db_end_transaction(0);
355                         return ret;
356                 }
357         }
358         __uam_db_end_transaction(1);
359
360         FUNC_EXIT;
361         return ret;
362 }
363
364 static int __free_uam_db_user_info(gpointer data)
365 {
366         FUNC_ENTRY;
367         uam_db_user_info_t *user = data;
368         GSList *l;
369         int ret = UAM_ERROR_NONE;
370
371         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
372                 uam_db_device_info_t *device = l->data;
373                 ret = _uam_remove_user_device(device);
374                 if (UAM_ERROR_NONE != ret) {
375                         UAM_ERR("_uam_remove_user_device failed");
376                         return ret;
377                 }
378         }
379
380         g_slist_free_full(user->devices, __free_user_device);
381
382         /* Set/update registered device list to plugins */
383         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
384                 UAM_ERR("_uam_pm_set_registered_devices failed");
385
386         /* Set/update registered device list to cloud plugin */
387         _uam_cloud_update_registered_devices();
388
389         g_free(user->name);
390         g_free(user->account);
391         g_free(user);
392
393         FUNC_EXIT;
394         return ret;
395 }
396
397 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
398 {
399         FUNC_ENTRY;
400         const uam_db_device_info_t *device = data;
401         const char *dev_id = user_data;
402
403         retv_if(NULL == device, -1);
404         retv_if(NULL == device->device_id, -1);
405         retv_if(NULL == dev_id, -1);
406
407         FUNC_EXIT;
408         return g_strcmp0(device->device_id, dev_id);
409 }
410
411 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
412 {
413         FUNC_ENTRY;
414         const uam_db_tech_info_t *tech = data;
415         const int *type = user_data;
416
417         retv_if(NULL == tech, -1);
418         retv_if(NULL == type, -1);
419
420         FUNC_EXIT;
421         return ((*type == tech->tech_type) ? 0 : 1);
422 }
423
424 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac)
425 {
426         FUNC_ENTRY;
427         GSList *l;
428
429         for (l = devices; NULL != l; l = g_slist_next(l)) {
430                 uam_db_device_info_t *dev = l->data;
431                 GSList *l1;
432
433                 if (!dev)
434                         continue;
435
436                 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
437                         uam_db_tech_info_t *tech = l1->data;
438                         GSList *l2;
439
440                         if (!tech)
441                                 continue;
442
443                         for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
444                                 uam_db_address_info_t *addr = l2->data;
445
446                                 if (!addr)
447                                         continue;
448
449                                 if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
450                                                 UAM_ADDR_TYPE_BT == addr->addr_type ||
451                                                 UAM_ADDR_TYPE_P2P == addr->addr_type ||
452                                                 UAM_ADDR_TYPE_WIFI == addr->addr_type)
453                                         if (!strcasecmp(addr->address, mac)) {
454                                                 UAM_DBG("Device found Mac: %s, type: %d",
455                                                                 addr->address, addr->addr_type);
456                                                 return tech;
457                                         }
458                         }
459                 }
460         }
461
462         FUNC_EXIT;
463         return NULL;
464 }
465
466 static int __get_uam_db_dev_list_to_uam_dev_list(
467                 GSList *db_dev_list, uam_device_info_s **device_list, int *count)
468 {
469         FUNC_ENTRY;
470         GSList *l;
471         int indx = 0;
472         int ret = UAM_ERROR_NONE;
473
474         *count = 0;
475         /* Calculate num devices first */
476         for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
477                 uam_db_device_info_t *db_info = l->data;
478                 GSList *l1;
479
480                 if (!db_info || !db_info->device_id)
481                         continue;
482
483                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
484                         uam_db_tech_info_t *tech = l1->data;
485
486                         if (!tech || !tech->addresses)
487                                 continue;
488
489                         (*count)++;
490                 }
491         }
492         UAM_INFO("Count = %d", *count);
493
494         *device_list = g_new0(uam_device_info_s, *count);
495
496         /* Copy devices */
497         for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
498                 uam_db_device_info_t *db_info = l->data;
499                 GSList *l1;
500
501                 if (!db_info || !db_info->device_id)
502                         continue;
503
504                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
505                         uam_db_tech_info_t *tech = l1->data;
506
507                         if (!tech || !tech->addresses)
508                                 continue;
509
510                         /* Copy tech info to device info */
511                         ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
512                         if (UAM_ERROR_NONE != ret) {
513                                 UAM_ERR("__copy_tech_info_to_device_info failed");
514                                 return ret;
515                         }
516                         indx++;
517                 }
518         }
519
520         UAM_INFO("Count = %d, indx = %d", *count, indx);
521         FUNC_EXIT;
522         return ret;
523 }
524
525 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
526                 const char *name, const char *svc_name, uam_pm_detection_mode_e mode)
527 {
528 //      FUNC_ENTRY;
529         GSList *l;
530
531         retv_if(NULL == name, NULL);
532         retv_if(NULL == monitor_list, NULL);
533
534         for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
535                 uam_monitor_info_t *monitor = l->data;
536
537                 if (!monitor || !monitor->name ||
538                                 !monitor->service || !monitor->service->name)
539                         continue;
540
541                 if ((mode == monitor->mode) &&
542                                 (0 == g_strcmp0(monitor->name, name)) &&
543                                 (0 == g_strcmp0(monitor->service->name, svc_name))) {
544                         UAM_DBG("Monitoring application found in list");
545                         return monitor;
546                 }
547         }
548
549 //      FUNC_EXIT;
550         return NULL;
551 }
552
553 unsigned int _uam_core_get_active_sensors(int detection_mode)
554 {
555         FUNC_ENTRY;
556         unsigned int sensors = 0;
557         GSList *l;
558
559         retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
560                         (UAM_DETECT_ABSENCE != detection_mode), 0);
561
562         for (l = monitors; NULL != l; l = g_slist_next(l)) {
563                 uam_monitor_info_t *monitor = l->data;
564
565                 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
566                         continue;
567
568                 sensors |= monitor->sensors;
569         }
570
571         FUNC_EXIT;
572         return sensors;
573 }
574
575 unsigned int _uam_core_get_env_sensors()
576 {
577         FUNC_ENTRY;
578         unsigned int sensors = 0;
579
580         sensors |= UAM_SENSOR_BITMASK_MOTION;
581         sensors |= UAM_SENSOR_BITMASK_LIGHT;
582
583         FUNC_EXIT;
584         return sensors;
585 }
586
587 unsigned int _uam_core_get_active_env_sensors(int detection_mode)
588 {
589         FUNC_ENTRY;
590         unsigned int sensors = 0;
591         GSList *l;
592
593         retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
594                         (UAM_DETECT_ABSENCE != detection_mode), 0);
595
596         for (l = monitors; NULL != l; l = g_slist_next(l)) {
597                 uam_monitor_info_t *monitor = l->data;
598
599                 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
600                         continue;
601
602                 sensors |= monitor->sensors & _uam_core_get_env_sensors();
603         }
604
605         FUNC_EXIT;
606         return sensors;
607 }
608
609 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
610 {
611         FUNC_ENTRY;
612         GSList *l;
613         GSList *svc_list = NULL;
614
615         retv_if(NULL == db_svc_list, NULL);
616
617         /*
618          * Iterate over the db_svc_list and add each service to the global
619          * service list "services" if its not already inserted. Also append this
620          * uam_db_service_info_t to svc_list.
621          */
622         for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
623                 db_service_info_t *db_svc = l->data;
624                 uam_db_service_info_t *service;
625                 GSList *l1;
626
627                 if (!db_svc)
628                         continue;
629
630                 l1 = g_slist_find_custom(services,
631                                 db_svc->service_name, __compare_svc_name);
632                 if (!l1) {
633                         service = g_new0(uam_db_service_info_t, 1);
634                         service->name = g_strdup(db_svc->service_name);
635                         service->cycle = db_svc->cycle;
636                         services = g_slist_append(services, service);
637                 } else
638                         service = l1->data;
639
640                 svc_list = g_slist_append(svc_list, service);
641         }
642
643         FUNC_EXIT;
644         return svc_list;
645 }
646
647 static void __uam_core_add_dev_to_list(
648                 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
649                 int presence_state, unsigned long long last_seen, GSList *svc_list)
650 {
651         FUNC_ENTRY;
652         uam_db_tech_info_t *tech;
653         uam_db_device_info_t *device;
654         GSList *l;
655
656         ret_if(NULL == dev_info);
657         ret_if(NULL == user);
658
659         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
660         if (NULL != l) {
661                 device = l->data;
662                 ret_if(user != device->user);
663                 ret_if(device->supported_techs & dev_info->type);
664
665                 if (device->os != dev_info->operating_system) {
666                         UAM_INFO("device->os: %d, dev_info->operating_system: %d",
667                                         device->os, dev_info->operating_system);
668                         /* Update device OS type */
669                         if (UAM_OS_TYPE_INVALID == device->os || UAM_OS_TYPE_UNDEFINED == device->os)
670                                 device->os = dev_info->operating_system;
671                         else
672                                 UAM_WARN("Strange - OS types did not match, need to check");
673                 }
674         } else {
675                 device = g_new0(uam_db_device_info_t, 1);
676                 device->device_id = g_strdup(dev_info->device_id);
677                 device->os = dev_info->operating_system;
678                 device->discriminant = dev_info->discriminant;
679                 device->user = user;
680
681                 /* Add device to global device list */
682                 devices = g_slist_append(devices, device);
683
684                 /* Add same device to user's device list */
685                 user->devices = g_slist_append(user->devices, device);
686         }
687
688         tech = g_new0(uam_db_tech_info_t, 1);
689         tech->tech_type = dev_info->type;
690         tech->presence_state = presence_state;
691         tech->last_seen = last_seen;
692         tech->device = device;
693         tech->discriminant = dev_info->discriminant;
694
695         tech->svc_list = svc_list;
696         g_slist_foreach(tech->svc_list, __print_service, tech);
697         for (l = svc_list; NULL != l; l = g_slist_next(l)) {
698                 uam_db_service_info_t *service = l->data;
699
700                 if (!service)
701                         continue;
702
703                 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
704         }
705
706         /* Add tech info to tech list */
707         device->tech_list = g_slist_append(device->tech_list, tech);
708         device->supported_techs |= tech->tech_type;
709         UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
710
711         if (0 < strlen(dev_info->mac)) {
712                 uam_db_address_info_t *addr;
713
714                 addr = g_new0(uam_db_address_info_t, 1);
715                 addr->address = g_strdup(dev_info->mac);
716
717                 switch (dev_info->type) {
718                 case UAM_TECH_TYPE_BLE:
719                         addr->addr_type = UAM_ADDR_TYPE_BLE;
720                         break;
721                 case UAM_TECH_TYPE_BT:
722                         addr->addr_type = UAM_ADDR_TYPE_BT;
723                         break;
724                 case UAM_TECH_TYPE_P2P:
725                         addr->addr_type = UAM_ADDR_TYPE_P2P;
726                         break;
727                 case UAM_TECH_TYPE_WIFI:
728                         addr->addr_type = UAM_ADDR_TYPE_WIFI;
729                         break;
730                 default:
731                         UAM_ERR("Unknown tech type: %d", dev_info->type);
732                         g_free(addr->address);
733                         g_free(addr);
734                         addr = NULL;
735                 }
736
737                 if (addr) {
738                         UAM_DBG("MAC address %s added for tech type: %d",
739                                         dev_info->mac, dev_info->type);
740                         tech->addresses = g_slist_append(tech->addresses, addr);
741                 }
742         }
743
744         if (0 < strlen(dev_info->ipv4_addr)) {
745                 uam_db_address_info_t *addr;
746
747                 if (UAM_TECH_TYPE_BLE == dev_info->type ||
748                                 UAM_TECH_TYPE_BT == dev_info->type)
749                         UAM_WARN("IPv4 address %s added for tech type: %d",
750                                         dev_info->ipv4_addr, dev_info->type);
751                 else
752                         UAM_DBG("IPv4 address %s added for tech type: %d",
753                                         dev_info->ipv4_addr, dev_info->type);
754
755                 addr = g_new0(uam_db_address_info_t, 1);
756                 addr->addr_type = UAM_ADDR_TYPE_IPv4;
757                 addr->address = g_strdup(dev_info->ipv4_addr);
758
759                 tech->addresses = g_slist_append(tech->addresses, addr);
760         }
761
762         FUNC_EXIT;
763 }
764
765 int _uam_core_add_user(int *user_id, const char *account, const char *name)
766 {
767         FUNC_ENTRY;
768         GSList *l;
769         uam_db_user_info_t *user;
770         int ret = UAM_ERROR_NONE;
771
772         l = g_slist_find_custom(users, account, __compare_user_account);
773         retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
774
775         user = g_new0(uam_db_user_info_t, 1);
776
777         /* Add user to database */
778         ret = _uam_db_insert_user_info(&(user->user_id), name, account);
779         if (UAM_ERROR_NONE != ret) {
780                 UAM_ERR("_uam_db_insert_user_info failed [%d]", ret);
781                 g_free(user);
782                 return ret;
783         }
784
785         user->name = g_strdup(name);
786         user->account = g_strdup(account);
787         user->devices = NULL;
788
789         *user_id = user->user_id;
790
791         users = g_slist_append(users, user);
792
793         /* Send user added event to application */
794         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
795                                 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
796                                         UAM_ERROR_NONE, user->account, user->name)))
797                 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
798
799         FUNC_EXIT;
800         return UAM_ERROR_NONE;
801 }
802
803 int _uam_core_remove_user(const char *account)
804 {
805         FUNC_ENTRY;
806         GSList *l;
807         uam_db_user_info_t *user;
808         int ret = UAM_ERROR_NONE;
809
810         l = g_slist_find_custom(users, account, __compare_user_account);
811         retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
812         user = l->data;
813
814         /* Remove user from database */
815         ret = _uam_db_delete_by_user_id(user->user_id);
816         if (UAM_ERROR_NONE != ret) {
817                 UAM_ERR("_uam_db_delete_by_user_id failed");
818                 return ret;
819         }
820
821         users = g_slist_remove(users, user);
822
823         /* Send user removed event to application */
824         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
825                                 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
826                                         UAM_ERROR_NONE, user->account, user->name)))
827                 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
828
829         ret = __free_uam_db_user_info((gpointer)user);
830         if (UAM_ERROR_NONE != ret) {
831                 UAM_WARN("_free_uam_db_user_info failed");
832         }
833
834         FUNC_EXIT;
835         return UAM_ERROR_NONE;
836 }
837
838 int _uam_core_update_user(uam_user_info_s *user)
839 {
840         FUNC_ENTRY;
841         GSList *l;
842         uam_db_user_info_t *user_info;
843
844         retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
845
846         /* Retrieve user from list */
847         l = g_slist_find_custom(users, user->account, __compare_user_account);
848         retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
849
850         user_info = l->data;
851         g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
852
853         /* Update user to database */
854         if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
855                 UAM_ERR("_uam_db_update_user_info failed");
856                 return UAM_ERROR_DB_FAILED;
857         }
858
859         FUNC_EXIT;
860         return UAM_ERROR_NONE;
861 }
862
863 int _uam_core_add_device(const char *account, const uam_device_info_s *dev_info)
864 {
865         FUNC_ENTRY;
866         int ret;
867         GSList *l;
868         uam_db_device_info_t *device;
869         uam_db_user_info_t *user;
870
871         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
872         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
873
874         l = g_slist_find_custom(users, account, __compare_user_account);
875         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
876         user = l->data;
877
878         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
879         if (NULL != l) {
880                 device = l->data;
881                 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
882                 retv_if((dev_info->type & device->supported_techs),
883                                 UAM_ERROR_ALREADY_REGISTERED);
884         }
885
886         UAM_INFO("[%d]", user->user_id);
887
888         ret = _uam_pm_register_device(user->user_id, dev_info);
889         if (UAM_ERROR_NONE != ret) {
890                 UAM_ERR("_uam_pm_register_device failed with %s",
891                                 _uam_manager_error_to_str(ret));
892                 return ret;
893         }
894
895         FUNC_EXIT;
896         return UAM_ERROR_NONE;
897 }
898
899 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
900 {
901         FUNC_ENTRY;
902         uam_db_device_info_t *device;
903         GSList *l;
904
905         retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
906         retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
907
908         *is_added = FALSE;
909         l = g_slist_find_custom(devices, dev->device_id, __compare_device_id);
910         if (NULL == l)
911                 goto done;
912
913         device = l->data;
914         if (!(device->supported_techs & dev->type))
915                 goto done;
916
917         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
918                 uam_db_tech_info_t *tech = l->data;
919                 GSList *l1;
920
921                 if (!tech)
922                         continue;
923
924                 if (dev->type != tech->tech_type)
925                         continue;
926
927                 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
928                         uam_db_address_info_t *addr = l1->data;
929
930                         if (!addr)
931                                 continue;
932
933                         if (UAM_ADDR_TYPE_BLE == addr->addr_type ||
934                                         UAM_ADDR_TYPE_BT == addr->addr_type ||
935                                         UAM_ADDR_TYPE_P2P == addr->addr_type ||
936                                         UAM_ADDR_TYPE_WIFI == addr->addr_type)
937                                 if (!strcasecmp(addr->address, dev->mac)) {
938                                         *is_added = TRUE;
939                                         break;
940                                 }
941                 }
942                 break;
943         }
944
945 done:
946         UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
947         FUNC_EXIT;
948         return UAM_ERROR_NONE;
949 }
950
951 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
952         const uam_device_info_s *dev_info, uam_db_tech_info_t *tech)
953 {
954         int ret;
955         GSList *l;
956         int count = 0;
957
958         ret = _uam_db_get_device_services_count(dev_info->device_id,
959                                 dev_info->type, dev_info->mac, &count);
960         if (UAM_ERROR_NONE != ret) {
961                 UAM_ERR("_uam_db_get_device_services_count failed with %s",
962                                 _uam_manager_error_to_str(ret));
963                 return ret;
964         }
965
966         if (1 < count) {
967                 ret = UAM_ERROR_RESOURCE_BUSY;
968                 UAM_WARN("other service uses this device ref:[%d]", count);
969                 return ret;
970         }
971
972         ret = _uam_pm_unregister_device(user_id, dev_info);
973         if (UAM_ERROR_NONE != ret) {
974                 UAM_ERR("_uam_pm_unregister_device failed with %s",
975                                 _uam_manager_error_to_str(ret));
976                 return ret;
977         }
978
979         /* Send device removed event to application */
980         __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
981
982         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
983         /* Remove device from database */
984         ret = _uam_device_db_delete_device_info(
985                                 dev_info->device_id, dev_info->type, dev_info->mac);
986         if (UAM_ERROR_NONE != ret) {
987                 UAM_ERR("_uam_device_db_delete_device_info failed");
988                 __uam_db_end_transaction(0);
989                 return ret;
990         }
991
992         /* Remove device from service */
993         for (l = tech->svc_list; l; l = g_slist_next(l)) {
994                 uam_db_service_info_t *svc = l->data;
995
996                 if (!svc || !svc->name)
997                         continue;
998                 ret = _uam_core_service_remove_device(svc->name,
999                                 dev_info->device_id, dev_info->type);
1000                 if (UAM_ERROR_NONE != ret) {
1001                         UAM_ERR("_uam_device_db_delete_device_info failed");
1002                 }
1003         }
1004         __uam_db_end_transaction(1);
1005
1006         /* Remove tech info from device's tech list */
1007         device->tech_list = g_slist_remove(device->tech_list, tech);
1008         device->supported_techs &= ~(tech->tech_type);
1009         UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1010         __free_dev_tech_info(tech);
1011
1012         if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1013                 /* Remove device from global device list */
1014                 devices = g_slist_remove(devices, device);
1015
1016                 /* Remove device  from user's device list */
1017                 device->user->devices = g_slist_remove(device->user->devices, device);
1018
1019                 __free_user_device(device);
1020         }
1021
1022         /* Set/update registered device list to plugins */
1023         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
1024                 UAM_ERR("_uam_pm_set_registered_devices failed");
1025
1026         /* Set/update registered device list to cloud plugin */
1027         _uam_cloud_update_registered_devices();
1028
1029         FUNC_EXIT;
1030         return UAM_ERROR_NONE;
1031 }
1032
1033 int _uam_core_remove_device(const char *account,
1034         const uam_device_info_s *dev_info)
1035 {
1036         FUNC_ENTRY;
1037         int ret;
1038         GSList *l;
1039         uam_db_tech_info_t *tech;
1040         uam_db_device_info_t *device;
1041         uam_db_user_info_t *user;
1042
1043         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1044         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1045
1046         /* Retrieve user from list */
1047         l = g_slist_find_custom(users, account, __compare_user_account);
1048         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1049         user = l->data;
1050
1051         /* Retrieve device from list */
1052         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1053         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1054         device = l->data;
1055         retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1056         retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1057
1058         /* Retrieve tech info from list */
1059         l = g_slist_find_custom(device->tech_list,
1060                         &(dev_info->type), __compare_tech_type);
1061         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1062         tech = l->data;
1063
1064         ret = __uam_remove_device(user->user_id, device, dev_info, tech);
1065
1066         FUNC_EXIT;
1067         return ret ;
1068 }
1069
1070 int _uam_core_remove_device_by_device_id(const char *device_id,
1071         int tech_type)
1072 {
1073         FUNC_ENTRY;
1074         int ret;
1075         GSList *l;
1076         uam_device_info_s dev_info;
1077         uam_db_tech_info_t *tech;
1078         uam_db_device_info_t *device;
1079
1080         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1081         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1082         retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1083
1084         /* Retrieve device from list */
1085         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1086         retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1087         device = l->data;
1088         retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1089
1090         /* Retrieve tech info from list */
1091         l = g_slist_find_custom(device->tech_list,
1092                         &tech_type, __compare_tech_type);
1093         retv_if(NULL == l, UAM_ERROR_INTERNAL);
1094         tech = l->data;
1095
1096         /* Get dev_info */
1097         ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info);
1098         retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1099
1100         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1101
1102         FUNC_EXIT;
1103         return ret;
1104 }
1105
1106 int _uam_core_remove_device_by_mac(const char *mac)
1107 {
1108         FUNC_ENTRY;
1109         uam_db_tech_info_t *tech;
1110         uam_db_device_info_t *device;
1111         uam_device_info_s dev_info;
1112         int ret;
1113
1114         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1115
1116         tech = __get_tech_info_by_mac(mac);
1117         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1118         device = tech->device;
1119
1120         ret = __copy_tech_info_to_device_info(tech, &dev_info);
1121         if (UAM_ERROR_NONE != ret) {
1122                 UAM_ERR("__copy_tech_info_to_device_info failed");
1123                 return ret;
1124         }
1125
1126         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech);
1127
1128         FUNC_EXIT;
1129         return ret;
1130 }
1131
1132 int _uam_core_update_device(const uam_device_info_s *a_device)
1133 {
1134         FUNC_ENTRY;
1135
1136         int ret = UAM_ERROR_NONE;
1137         GSList *l, *l1, *l2;
1138
1139         uam_device_info_s temp;
1140         uam_db_user_info_t *user = NULL;
1141         uam_db_device_info_t *device = NULL;
1142         uam_db_tech_info_t *tech = NULL;
1143
1144         /* Find all tech-devices in users' devices */
1145         for (l = users; NULL != l; l = g_slist_next(l)) {
1146                 user = l->data;
1147
1148                 l1 = g_slist_find_custom(user->devices,
1149                                 a_device->device_id, __compare_device_id);
1150                 if (NULL == l1) {
1151                         UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1152                                         user->user_id, a_device->device_id);
1153                         continue;
1154                 }
1155
1156                 device = l1->data;
1157                 if (!(device->supported_techs & a_device->type)) {
1158                         UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1159                                         device->device_id, a_device->type);
1160                         continue;
1161                 }
1162
1163                 /* Update discriminant for devices */
1164                 device->discriminant = a_device->discriminant;
1165                 device->os = a_device->operating_system;
1166
1167                 l2 = g_slist_find_custom(device->tech_list,
1168                                 &(a_device->type), __compare_tech_type);
1169                 if (NULL == l2) {
1170                         UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1171                         continue;
1172                 }
1173
1174                 tech = l2->data;
1175                 if (!tech) {
1176                         UAM_DBG("Device tech is NULL");
1177                         continue;
1178                 }
1179
1180                 /* Update discriminant for device-tech */
1181                 tech->discriminant = a_device->discriminant;
1182
1183                 /* Update device's updated information to database */
1184                 ret = __copy_tech_info_to_device_info(tech, &temp);
1185                 if (UAM_ERROR_NONE != ret) {
1186                         UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1187                         return ret;
1188                 }
1189
1190                 ret = _uam_device_db_update_device(temp.device_id, temp.type,
1191                                 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant);
1192                 if (UAM_ERROR_NONE != ret) {
1193                         UAM_ERR("_uam_device_db_update_device failed [%d]", ret);
1194                         return ret;
1195                 }
1196         }
1197
1198         /* Set/update registered device list to plugins */
1199         ret = _uam_pm_set_registered_devices(devices);
1200         if (UAM_ERROR_NONE != ret) {
1201                 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1202                 return ret;
1203         }
1204
1205         /* Set/update registered device list to cloud plugin */
1206         _uam_cloud_update_registered_devices();
1207
1208         FUNC_EXIT;
1209         return ret;
1210 }
1211
1212 int _uam_core_get_default_user(uam_user_info_s *user_info)
1213 {
1214         FUNC_ENTRY;
1215         int ret;
1216         int user_id;
1217         GSList *l;
1218         uam_db_user_info_t *user;
1219
1220         retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1221
1222         ret = _uam_core_add_user(&user_id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
1223         if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1224                 UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1225                 return ret;
1226         }
1227
1228         l = g_slist_find_custom(users, USER_ACCOUNT_DEFAULT, __compare_user_account);
1229         retv_if(NULL == l, UAM_ERROR_INTERNAL);
1230         user = l->data;
1231
1232         memset(user_info, 0x00, sizeof(uam_user_info_s));
1233         g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1234         g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1235
1236         FUNC_EXIT;
1237         return UAM_ERROR_NONE;
1238 }
1239
1240 int _uam_core_get_users(int *count, uam_user_info_s **user_list)
1241 {
1242         FUNC_ENTRY;
1243         guint size;
1244         GSList *l;
1245
1246         size = g_slist_length(users);
1247         *user_list = g_new0(uam_user_info_s, size);
1248         *count = 0;
1249
1250         /* fetch users list from DB */
1251         for (l = users; l; l = g_slist_next(l)) {
1252                 uam_db_user_info_t *db_info = l->data;
1253
1254                 if (!db_info || !db_info->account)
1255                         continue;
1256
1257                 g_strlcpy((*user_list)[*count].account,
1258                                 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1259                 if (db_info->name)
1260                         g_strlcpy((*user_list)[*count].name,
1261                                         db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1262
1263                 *count += 1;
1264         }
1265
1266         UAM_INFO("Count: %d", *count);
1267         FUNC_EXIT;
1268         return UAM_ERROR_NONE;
1269 }
1270
1271 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user)
1272 {
1273         FUNC_ENTRY;
1274         uam_db_user_info_t *db_info;
1275         GSList *l;
1276
1277         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1278
1279         l = g_slist_find_custom(users, account, __compare_user_account);
1280         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1281         db_info = l->data;
1282
1283         g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1284         if (db_info->name)
1285                 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
1286
1287
1288         FUNC_EXIT;
1289         return UAM_ERROR_NONE;
1290 }
1291
1292 int _uam_core_get_devcie_by_device_id(
1293                 const char *device_id, int tech_type, uam_device_info_s *device)
1294 {
1295         FUNC_ENTRY;
1296         uam_db_device_info_t *db_info;
1297         GSList *l;
1298         GSList *l1;
1299
1300         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1301         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1302         retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1303
1304         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1305         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1306         db_info = l->data;
1307         retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
1308
1309         memset(device, 0x00, sizeof(uam_device_info_s));
1310
1311         for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1312                 uam_db_tech_info_t *tech = l1->data;
1313                 GSList *l2;
1314
1315                 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
1316                         continue;
1317
1318                 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
1319                         uam_db_address_info_t *addr = l2->data;
1320
1321                         if (!addr)
1322                                 continue;
1323
1324                         __uam_core_copy_addr(device, addr);
1325                 }
1326
1327                 device->operating_system = db_info->os;
1328                 g_strlcpy(device->device_id, db_info->device_id,
1329                                 UAM_DEVICE_ID_MAX_STRING_LEN);
1330                 device->type = tech->tech_type;
1331                 device->discriminant = tech->discriminant;
1332         }
1333
1334         retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
1335
1336         FUNC_EXIT;
1337         return UAM_ERROR_NONE;
1338 }
1339
1340 int _uam_core_get_devcie_by_mac(const char *mac, uam_device_info_s *device)
1341 {
1342         FUNC_ENTRY;
1343         int ret;
1344         uam_db_tech_info_t *tech;
1345
1346         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1347
1348         tech = __get_tech_info_by_mac(mac);
1349         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1350
1351         ret = __copy_tech_info_to_device_info(tech, device);
1352         if (UAM_ERROR_NONE != ret) {
1353                 UAM_ERR("__copy_tech_info_to_device_info failed");
1354                 return ret;
1355         }
1356
1357         FUNC_EXIT;
1358         return ret;
1359 }
1360
1361 int _uam_core_get_user_by_device_id(const char *device_id, uam_user_info_s *user)
1362 {
1363         FUNC_ENTRY;
1364         uam_db_device_info_t *dev;
1365         GSList *l;
1366
1367         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1368
1369         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1370         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
1371         dev = l->data;
1372
1373         g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1374         if (dev->user->name)
1375                 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1376
1377         FUNC_EXIT;
1378         return UAM_ERROR_NONE;
1379 }
1380
1381 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user)
1382 {
1383         FUNC_ENTRY;
1384         uam_db_tech_info_t *tech;
1385
1386         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1387
1388         tech = __get_tech_info_by_mac(mac);
1389         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1390
1391         g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1392         if (tech->device->user->name)
1393                 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
1394
1395         FUNC_EXIT;
1396         return UAM_ERROR_NONE;
1397 }
1398
1399 int _uam_core_get_devices(int *count, uam_device_info_s **device_list)
1400 {
1401         FUNC_ENTRY;
1402         int ret = UAM_ERROR_NONE;
1403
1404         ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count);
1405
1406         FUNC_EXIT;
1407         return ret;
1408 }
1409
1410 int _uam_core_get_user_devices(const char *account,
1411                 int *count, uam_device_info_s **device_list)
1412 {
1413         FUNC_ENTRY;
1414         uam_db_user_info_t *user;
1415         GSList *l;
1416         int ret = UAM_ERROR_NONE;
1417
1418         l = g_slist_find_custom(users, account, __compare_user_account);
1419         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1420         user = l->data;
1421
1422         ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count);
1423
1424         FUNC_EXIT;
1425         return ret;
1426 }
1427
1428 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
1429 {
1430         FUNC_ENTRY;
1431
1432         *sensor_bitmask = _uam_pm_get_avaliable_sensors();
1433
1434         FUNC_EXIT;
1435         return UAM_ERROR_NONE;
1436 }
1437
1438 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
1439 {
1440         FUNC_ENTRY;
1441         gboolean is_ready;
1442
1443         is_ready = _uam_pm_is_sensor_ready(sensor);
1444         UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
1445
1446         FUNC_EXIT;
1447         return is_ready;
1448 }
1449
1450 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
1451         uam_tech_type_e tech_type, const char *svc_name)
1452 {
1453         FUNC_ENTRY;
1454         uam_svc_dev_info_t *svc_dev = NULL;
1455         GSList *l;
1456
1457         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1458                 svc_dev = l->data;
1459
1460                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1461                         continue;
1462
1463                 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
1464                                 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
1465                                 (svc_dev->tech_type == tech_type)) {
1466                         UAM_DBG("Service device found in list");
1467                         return svc_dev;
1468                 }
1469         }
1470
1471         FUNC_EXIT;
1472         return NULL;
1473 }
1474
1475 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
1476         const char *svc_name, gboolean discriminant, unsigned long long last_seen)
1477 {
1478         FUNC_ENTRY;
1479         uam_svc_dev_info_t *svc = NULL;
1480
1481         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1482         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1483         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1484         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1485
1486         svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1487         if (!svc) {
1488                 svc = g_new0(uam_svc_dev_info_t, 1);
1489                 svc->device_id = g_strdup(device_id);
1490                 svc->tech_type = tech_type;
1491                 svc->service = g_strdup(svc_name);
1492                 svc_devs = g_slist_append(svc_devs, svc);
1493         }
1494
1495         svc->discriminant = discriminant;
1496         svc->last_seen = last_seen;
1497
1498         UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] last_seen[%llu]",
1499                 svc->service, svc->device_id, svc->tech_type, svc->discriminant, svc->last_seen);
1500
1501         FUNC_EXIT;
1502         return UAM_ERROR_NONE;
1503 }
1504
1505 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
1506         uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant)
1507 {
1508         FUNC_ENTRY;
1509         uam_svc_dev_info_t *svc = NULL;
1510
1511         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1512         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1513         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1514         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1515
1516         svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1517         if (!svc) {
1518                 svc = g_new0(uam_svc_dev_info_t, 1);
1519                 svc->device_id = g_strdup(device_id);
1520                 svc->tech_type = tech_type;
1521                 svc->service = g_strdup(svc_name);
1522                 svc_devs = g_slist_append(svc_devs, svc);
1523         }
1524
1525         svc->discriminant = discriminant;
1526
1527         UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d]]",
1528                 svc->service, svc->device_id, svc->tech_type, svc->discriminant);
1529
1530         FUNC_EXIT;
1531         return UAM_ERROR_NONE;
1532 }
1533
1534 int _uam_core_service_add_user(const char *svc_name, const char *account)
1535 {
1536         FUNC_ENTRY;
1537         GSList *l;
1538         int ret = UAM_ERROR_NONE;
1539         uam_db_user_info_t *user;
1540         uam_db_service_info_t *service;
1541
1542         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1543         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1544
1545         /* Retrieve user from list */
1546         l = g_slist_find_custom(users, account, __compare_user_account);
1547         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1548         user = l->data;
1549
1550         /* Retrieve service from list */
1551         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1552         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1553         service = l->data;
1554
1555         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1556         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1557                 uam_db_device_info_t *device = l->data;
1558                 GSList *l1;
1559
1560                 if (!device)
1561                         continue;
1562
1563                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1564                         uam_db_tech_info_t *tech = l1->data;
1565                         char *mac;
1566                         GSList *l2;
1567
1568                         if (!tech)
1569                                 continue;
1570
1571                         l2 = g_slist_find_custom(tech->svc_list, svc_name,
1572                                         __compare_svc_name);
1573                         if (NULL != l2)
1574                                 continue;
1575
1576                         __add_service_to_dev_tech_mapping(tech, service);
1577
1578                         mac = __get_mac_addr(tech);
1579                         /* Insert device service info to db */
1580                         ret = _uam_db_insert_device_service_info(device->device_id,
1581                                                 tech->tech_type, mac, service->name, service->cycle,
1582                                                 device->discriminant, 0);
1583                         if (UAM_ERROR_NONE != ret) {
1584                                 UAM_WARN("Device service addition to persistent DB failed");
1585                                 __uam_db_end_transaction(0);
1586                                 return ret;
1587                         }
1588                         ret = _uam_core_update_svc_dev_info(device->device_id,
1589                                         tech->tech_type, service->name, device->discriminant, 0);
1590                         if (UAM_ERROR_NONE != ret) {
1591                                 UAM_WARN("Device service addition to service device mapping failed");
1592                                 __uam_db_end_transaction(0);
1593                                 return ret;
1594                         }
1595                 }
1596         }
1597
1598         __uam_db_end_transaction(1);
1599
1600         FUNC_EXIT;
1601         return ret;
1602 }
1603
1604 int _uam_core_service_remove_user(const char *svc_name, const char *account)
1605 {
1606         FUNC_ENTRY;
1607         GSList *l;
1608         uam_db_user_info_t *user;
1609         int ret;
1610
1611         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1612         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1613
1614         /* Retrieve user from list */
1615         l = g_slist_find_custom(users, account, __compare_user_account);
1616         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1617         user = l->data;
1618
1619         /* Retrieve service from list */
1620         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1621         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1622
1623         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1624         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
1625                 uam_db_device_info_t *device = l->data;
1626                 GSList *l1;
1627
1628                 if (!device)
1629                         continue;
1630
1631                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1632                         uam_db_tech_info_t *tech = l1->data;
1633                         char *mac;
1634                         GSList *l2;
1635
1636                         if (!tech)
1637                                 continue;
1638
1639                         l2 = g_slist_find_custom(tech->svc_list, svc_name,
1640                                         __compare_svc_name);
1641                         if (NULL == l2)
1642                                 continue;
1643
1644                         UAM_DBG("Service %s found, remove it from list", svc_name);
1645                         __remove_service_to_dev_tech_mapping(
1646                                         tech, (uam_db_service_info_t *)l2->data);
1647
1648                         mac = __get_mac_addr(tech);
1649                         /* Remove service-device from DB */
1650                         ret = _uam_db_delete_device_service_info(device->device_id,
1651                                         tech->tech_type, mac, svc_name);
1652                         if (UAM_ERROR_NONE != ret) {
1653                                 UAM_WARN("Device service removal from persistent DB failed");
1654                                 __uam_db_end_transaction(0);
1655                                 return ret;
1656                         }
1657                 }
1658         }
1659         __uam_db_end_transaction(1);
1660
1661         FUNC_EXIT;
1662         return UAM_ERROR_NONE;
1663 }
1664
1665 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
1666 {
1667         FUNC_ENTRY;
1668         uam_db_device_info_t *device;
1669         GSList *l;
1670
1671         retv_if(NULL == device_id, NULL);
1672         retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
1673         retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
1674
1675         l = g_slist_find_custom(devices, device_id, __compare_device_id);
1676         if (NULL == l) {
1677                 UAM_DBG("DeviceId [%s] is not in the list", device_id);
1678                 return NULL;
1679         }
1680
1681         device = l->data;
1682         if (!device || !(device->supported_techs & tech_type)) {
1683                 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
1684                                 tech_type, device_id);
1685                 return NULL;
1686         }
1687
1688         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1689                 uam_db_tech_info_t *tech = l->data;
1690
1691                 if (!tech)
1692                         continue;
1693
1694                 if (tech_type == tech->tech_type) {
1695                         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
1696                                         device_id, tech_type);
1697                         return tech;
1698                 }
1699         }
1700
1701         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
1702         FUNC_EXIT;
1703         return NULL;
1704 }
1705
1706 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
1707         int tech_type)
1708 {
1709         FUNC_ENTRY;
1710         GSList *l;
1711         char *mac;
1712         int ret = UAM_ERROR_NONE;
1713         uam_db_tech_info_t *tech_info;
1714         uam_db_service_info_t *service;
1715
1716         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1717         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1718         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1719         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1720
1721         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1722         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1723
1724         l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1725         retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
1726
1727         /* Retrieve service from list */
1728         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1729         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1730         service = l->data;
1731
1732         __add_service_to_dev_tech_mapping(tech_info, service);
1733
1734         mac = __get_mac_addr(tech_info);
1735         /* Insert device service info to db */
1736         ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
1737                                 service->name, service->cycle, tech_info->discriminant, 0);
1738         if (UAM_ERROR_NONE != ret) {
1739                 UAM_WARN("Device service addition to persistent DB failed");
1740                 return ret;
1741         }
1742         ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
1743                         tech_info->discriminant, 0);
1744         if (UAM_ERROR_NONE != ret) {
1745                 UAM_WARN("Device service addition to svc dev mapping failed");
1746                 return ret;
1747         }
1748
1749         FUNC_EXIT;
1750         return UAM_ERROR_NONE;
1751 }
1752
1753 int _uam_core_service_remove_device(const char *svc_name,
1754         const char *device_id, int tech_type)
1755 {
1756         FUNC_ENTRY;
1757         GSList *l;
1758         char *mac;
1759         uam_db_tech_info_t *tech_info;
1760         int ret = UAM_ERROR_NONE;
1761
1762         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1763         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1764         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1765         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1766
1767         /* Retrieve service from list */
1768         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1769         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1770
1771         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1772         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1773
1774         l = g_slist_find_custom(tech_info->svc_list, svc_name, __compare_svc_name);
1775         retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1776
1777         __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
1778
1779         mac = __get_mac_addr(tech_info);
1780         /* Remove service-device from DB */
1781         ret = _uam_db_delete_device_service_info(
1782                         device_id, tech_type, mac, svc_name);
1783         if (UAM_ERROR_NONE != ret) {
1784                 UAM_ERR("Device service removal from persistent DB failed");
1785                 return ret;
1786         }
1787
1788         FUNC_EXIT;
1789         return UAM_ERROR_NONE;
1790 }
1791
1792 int _uam_core_service_set_device_discriminant(const char *svc_name,
1793                 const char *device_id, int tech_type, gboolean discriminant)
1794 {
1795         FUNC_ENTRY;
1796         GSList *l;
1797         int ret = UAM_ERROR_NONE;
1798         char *mac;
1799         uam_db_tech_info_t *tech_info;
1800         uam_db_service_info_t *service;
1801
1802         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1803         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1804         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1805         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1806
1807         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
1808         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
1809
1810         /* Retrieve service from list */
1811         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1812         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1813         service = l->data;
1814
1815         mac = __get_mac_addr(tech_info);
1816         /* Insert device service info to db */
1817         ret = _uam_db_update_device_service_discriminant(device_id,
1818                                 tech_type, mac, service->name, discriminant);
1819         if (UAM_ERROR_NONE != ret) {
1820                 UAM_WARN("Device service discriminant update to persistent DB failed");
1821                 return ret;
1822         }
1823         ret = _uam_core_update_svc_dev_info_discriminant(device_id,
1824                                 tech_type, service->name, discriminant);
1825         if (UAM_ERROR_NONE != ret) {
1826                 UAM_WARN("Device service discriminant mapping update failed");
1827                 return ret;
1828         }
1829
1830         FUNC_EXIT;
1831         return UAM_ERROR_NONE;
1832 }
1833
1834 int _uam_core_service_get_device_discriminant(const char *svc_name,
1835                 const char *device_id, int tech_type, gboolean *discriminant)
1836 {
1837         FUNC_ENTRY;
1838         uam_svc_dev_info_t *svc_dev;
1839
1840         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1841         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1842         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1843         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1844
1845         svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1846         retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1847         *discriminant = (gboolean)svc_dev->discriminant;
1848
1849         FUNC_EXIT;
1850         return UAM_ERROR_NONE;
1851 }
1852
1853 int _uam_core_service_get_device_last_seen(const char *svc_name,
1854                 const char *device_id, int tech_type, unsigned long long *last_seen)
1855 {
1856         FUNC_ENTRY;
1857         uam_svc_dev_info_t *svc_dev;
1858
1859         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1860         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1861         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1862         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
1863
1864         svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name);
1865         retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
1866         *last_seen = svc_dev->last_seen;
1867
1868         FUNC_EXIT;
1869         return UAM_ERROR_NONE;
1870 }
1871
1872 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle)
1873 {
1874         FUNC_ENTRY;
1875         GSList *l;
1876         uam_db_service_info_t *service;
1877         unsigned int elapsed_time;
1878
1879         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1880         retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
1881         retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
1882
1883         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1884         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1885         service = l->data;
1886
1887         elapsed_time = service->cycle - service->remaining_time;
1888         service->cycle = new_cycle;
1889         if (new_cycle < elapsed_time)
1890                 service->remaining_time = 0;
1891         else
1892                 service->remaining_time = new_cycle - elapsed_time;
1893
1894         /* Update service detection cycle in DB */
1895         if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle))
1896                 UAM_WARN("Service cycle updation to persistent DB failed");
1897
1898         FUNC_EXIT;
1899         return UAM_ERROR_NONE;
1900 }
1901
1902 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle)
1903 {
1904         FUNC_ENTRY;
1905         GSList *l;
1906         uam_db_service_info_t *service;
1907
1908         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
1909         retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
1910
1911         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
1912         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1913         service = l->data;
1914         *cycle = service->cycle;
1915
1916         FUNC_EXIT;
1917         return UAM_ERROR_NONE;
1918 }
1919
1920 int _uam_core_set_detection_threshold(unsigned int sensor,
1921                 int presence_threshold, int absence_threshold)
1922 {
1923         FUNC_ENTRY;
1924         int ret;
1925
1926         ret = _uam_pm_set_detection_threshold(sensor,
1927                         presence_threshold, absence_threshold);
1928         if (UAM_ERROR_NONE != ret) {
1929                 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
1930                                 _uam_manager_error_to_str(ret));
1931                 return ret;
1932         }
1933
1934         FUNC_EXIT;
1935         return UAM_ERROR_NONE;
1936 }
1937
1938 static gboolean __start_detection(gpointer data)
1939 {
1940         FUNC_ENTRY;
1941         int ret;
1942         uam_db_service_info_t *service = NULL;
1943         unsigned int sensors;
1944         gboolean start_detection = FALSE;
1945         GSList *l;
1946         unsigned int presence_env_sensors;
1947         unsigned int absence_env_sensors;
1948
1949         presence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE);
1950         UAM_DBG("Presence Envionmental sensors: 0x%8.8X", presence_env_sensors);
1951
1952         absence_env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
1953         UAM_DBG("Absence Envionmental sensors: 0x%8.8X", absence_env_sensors);
1954
1955         if (0 != presence_env_sensors) {
1956                 /* Stop PRESENCE detection on active envionmental sensors*/
1957                 ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
1958                 if (UAM_ERROR_NONE != ret)
1959                         UAM_ERR("Failed with error: %s (0x%4.4X)",
1960                                         _uam_manager_error_to_str(ret), ret);
1961         }
1962         if (0 != absence_env_sensors) {
1963                 /* Stop ABSENCE detection on envionmental sensors*/
1964                 ret = _uam_pm_stop_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
1965                 if (UAM_ERROR_NONE != ret)
1966                         UAM_ERR("Failed with error: %s (0x%4.4X)",
1967                                         _uam_manager_error_to_str(ret), ret);
1968         }
1969
1970         for (l = services; NULL != l; l = g_slist_next(l)) {
1971                 service = l->data;
1972                 if (!service || !service->monitors)
1973                         continue;
1974
1975                 UAM_DBG("service: %p, monitors: %p", service, service->monitors);
1976                 UAM_DBG("service->remaining_time: %d", service->remaining_time);
1977                 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
1978                 if (0 >= service->remaining_time) {
1979                         start_detection = TRUE;
1980                         service->remaining_time = service->cycle;
1981                 }
1982         }
1983
1984         if (!start_detection)
1985                 goto done;
1986
1987         /* Get sensors on which PRESENCE detection to be started */
1988         sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
1989         UAM_DBG("PRESENCE sensors: 0x%8.8X", sensors);
1990
1991         /* Remove env sensors from active sensors */
1992         sensors &= ~presence_env_sensors;
1993         UAM_DBG("Presence Connectivity sensors: 0x%8.8X", sensors);
1994
1995         if (0 != sensors) {
1996                 /* Start PRESENCE detection */
1997                 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, sensors);
1998                 if (UAM_ERROR_NONE != ret)
1999                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2000                                         _uam_manager_error_to_str(ret), ret);
2001         }
2002
2003         /* Get sensors on which ABSENCE detection to be started */
2004         sensors = _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2005         UAM_DBG("ABSENCE sensors: 0x%8.8X", sensors);
2006
2007         /* Remove env sensors from active sensors */
2008         sensors &= ~absence_env_sensors;
2009         UAM_DBG("ABSENCE Connectivity sensors: 0x%8.8X", sensors);
2010
2011         if (0 != sensors) {
2012                 /* Start ABSENCE detection */
2013                 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, sensors);
2014                 if (UAM_ERROR_NONE != ret)
2015                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2016                                         _uam_manager_error_to_str(ret), ret);
2017         }
2018
2019 done:
2020         if (0 != presence_env_sensors) {
2021                 /* Always Start PRESENCE detection on active envionmental sensors*/
2022                 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE, presence_env_sensors);
2023                 if (UAM_ERROR_NONE != ret)
2024                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2025                                         _uam_manager_error_to_str(ret), ret);
2026         }
2027         if (0 != absence_env_sensors) {
2028                 /* Always Start ABSENCE detection on active envionmental sensors*/
2029                 ret = _uam_pm_start_detection(UAM_DETECT_ABSENCE, absence_env_sensors);
2030                 if (UAM_ERROR_NONE != ret)
2031                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2032                                         _uam_manager_error_to_str(ret), ret);
2033         }
2034
2035         FUNC_EXIT;
2036         return TRUE;
2037 }
2038
2039 static int __uam_core_start_detection(int detection_type,
2040                 const char *svc_name, char *sender, unsigned int sensors)
2041 {
2042         FUNC_ENTRY;
2043         uam_monitor_info_t *monitor;
2044         uam_db_service_info_t *service;
2045         gboolean is_monitor_added = TRUE;
2046         GSList *l;
2047
2048         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2049         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2050
2051         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
2052         if (!l) {
2053                 uam_db_service_info_t *default_svc = g_new0(uam_db_service_info_t, 1);
2054                 default_svc->name = g_strdup(UAM_SERVICE_DEFAULT);
2055                 default_svc->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2056                 services = g_slist_append(services, default_svc);
2057                 l = services;
2058         }
2059
2060         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2061         retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2062
2063         service = l->data;
2064         monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2065         if (!monitor) {
2066                 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2067                 if (monitor) {
2068                         monitor->name = g_strdup(sender);
2069                         monitor->mode = detection_type;
2070                         monitor->service = service;
2071                         is_monitor_added = FALSE;
2072                 } else {
2073                         UAM_ERR("Memory allocation error");
2074                         return UAM_ERROR_OUT_OF_MEMORY;
2075                 }
2076         }
2077
2078         UAM_DBG("Name: %s, Service: %s, Mode: %d", monitor->name, svc_name, monitor->mode);
2079
2080         monitor->sensors |= sensors;
2081         if (!is_monitor_added) {
2082                 monitors = g_slist_append(monitors, monitor);
2083                 service->monitors = g_slist_append(service->monitors, monitor);
2084         }
2085
2086         /* Start detection */
2087         if (0 == detection_timer) {
2088                 __start_detection(NULL);
2089                 UAM_INFO("Monitor started detection, start timer");
2090                 detection_timer = g_timeout_add_seconds(
2091                                 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2092         }
2093
2094         FUNC_EXIT;
2095         return UAM_ERROR_NONE;
2096 }
2097
2098 static int __uam_core_stop_detection(int detection_type,
2099                 const char *svc_name, char *sender, unsigned int sensors)
2100 {
2101         FUNC_ENTRY;
2102         int ret = UAM_ERROR_NONE;
2103         unsigned int remaining_sensors;
2104         unsigned int active_sensors;
2105         uam_monitor_info_t *monitor;
2106         uam_db_service_info_t *service;
2107
2108         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2109         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2110
2111         monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type);
2112         retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2113         service = monitor->service;
2114         retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2115
2116         /* Find sensors which are already monitoring */
2117         active_sensors = _uam_core_get_active_sensors(detection_type);
2118         UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X",
2119                         sensors, active_sensors);
2120
2121         /* Update monitor info for application */
2122         monitor->sensors &= ~sensors;
2123         if (0 == monitor->sensors) {
2124                 /*
2125                  * App requested to stop monitoring for all of its active sensors,
2126                  * remove its monitor info from list.
2127                  */
2128                 monitors = g_slist_remove(monitors, monitor);
2129                 if ((NULL == monitors) && (0 != detection_timer)) {
2130                         UAM_INFO("All monitors stopped detection, stop timer");
2131                         g_source_remove(detection_timer);
2132                         detection_timer = 0;
2133                 }
2134
2135                 service->monitors = g_slist_remove(service->monitors, monitor);
2136                 if (NULL == service->monitors)
2137                         service->remaining_time = 0;
2138
2139                 g_free(monitor->name);
2140                 g_free(monitor);
2141         }
2142
2143         /* Find sensors which are already monitoring */
2144         remaining_sensors = _uam_core_get_active_sensors(detection_type);
2145         UAM_DBG("Remaining sensors: 0x%8.8X", remaining_sensors);
2146
2147         if (active_sensors == remaining_sensors) {
2148                 UAM_INFO("NO need to stop monitoring");
2149                 return UAM_ERROR_NONE;
2150         }
2151
2152         /* Stop monitoring only for sensors which aren't required anymore */
2153         sensors = (active_sensors & ~remaining_sensors);
2154         ret = _uam_pm_stop_detection(detection_type, sensors);
2155         if (UAM_ERROR_NONE != ret)
2156                 UAM_ERR("Failed with error: %s (0x%4.4X)",
2157                                 _uam_manager_error_to_str(ret), ret);
2158
2159         FUNC_EXIT;
2160         return ret;
2161 }
2162
2163 int _uam_core_start_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2164 {
2165         FUNC_ENTRY;
2166         int ret;
2167
2168         ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2169
2170         FUNC_EXIT;
2171         return ret;
2172 }
2173
2174 int _uam_core_stop_presence_detection(const char *svc_name, char *sender, unsigned int sensors)
2175 {
2176         FUNC_ENTRY;
2177         int ret;
2178
2179         ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name, sender, sensors);
2180
2181         FUNC_EXIT;
2182         return ret;
2183 }
2184
2185 int _uam_core_start_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2186 {
2187         FUNC_ENTRY;
2188         int ret;
2189
2190         ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2191
2192         FUNC_EXIT;
2193         return ret;
2194 }
2195
2196 int _uam_core_stop_absence_detection(const char *svc_name, char *sender, unsigned int sensors)
2197 {
2198         FUNC_ENTRY;
2199         int ret;
2200
2201         ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender, sensors);
2202
2203         FUNC_EXIT;
2204         return ret;
2205 }
2206
2207 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
2208 {
2209         FUNC_ENTRY;
2210         int ret;
2211
2212         UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
2213         ret = _uam_pm_set_low_power_mode(bitmask, mode);
2214         if (UAM_ERROR_NONE != ret) {
2215                 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
2216                                 bitmask, _uam_manager_error_to_str(ret));
2217                 return ret;
2218         }
2219
2220         FUNC_EXIT;
2221         return UAM_ERROR_NONE;
2222 }
2223
2224 int _uam_core_get_detection_window(unsigned int *window)
2225 {
2226         FUNC_ENTRY;
2227
2228         retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
2229
2230         *window = detection_window;
2231
2232         FUNC_EXIT;
2233         return UAM_ERROR_NONE;
2234 }
2235
2236 int _uam_core_set_detection_window(unsigned int window)
2237 {
2238         FUNC_ENTRY;
2239
2240         retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
2241         retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
2242         retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
2243
2244         if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
2245                 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
2246                 return UAM_ERROR_INTERNAL;
2247         }
2248
2249         detection_window = window;
2250
2251         FUNC_EXIT;
2252         return UAM_ERROR_NONE;
2253 }
2254
2255 int _uam_core_init(void)
2256 {
2257         FUNC_ENTRY;
2258         GSList *db_users;
2259         GSList *db_devices;
2260         GSList *db_svc_list;
2261         GSList *db_adv_list;
2262         GSList *db_svc_dev_list;
2263         GSList *l;
2264
2265         /* Init database */
2266         _uam_db_initialize();
2267
2268         /* Reset detecton window to default */
2269         detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2270         if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
2271                 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
2272
2273         /* Fetch user list */
2274         db_users = _uam_db_get_all_users();
2275         if (!db_users) {
2276                 UAM_INFO_C("No users in database");
2277                 return UAM_ERROR_NONE;
2278         }
2279
2280         for (l = db_users; NULL != l; l = g_slist_next(l)) {
2281                 db_user_info_t *info = l->data;
2282                 uam_db_user_info_t *user;
2283
2284                 if (!info)
2285                         continue;
2286
2287                 user = g_new0(uam_db_user_info_t, 1);
2288                 user->user_id = info->user_id;
2289                 user->name = g_strdup(info->name);
2290                 user->account = g_strdup(info->account);
2291                 user->devices = NULL;
2292
2293                 users = g_slist_prepend(users, user);
2294         }
2295
2296         /* Fetch service list */
2297         db_svc_list = _uam_service_db_get_all_services();
2298         if (!db_svc_list) {
2299                 UAM_INFO_C("No services in database");
2300                 return UAM_ERROR_NONE;
2301         }
2302
2303         for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
2304                 db_service_info_t *db_svc = l->data;
2305                 uam_db_service_info_t *service;
2306                 GSList *l1;
2307
2308                 if (!db_svc)
2309                         continue;
2310
2311                 l1 = g_slist_find_custom(services,
2312                                 db_svc->service_name, __compare_svc_name);
2313                 if (!l1) {
2314                         service = g_new0(uam_db_service_info_t, 1);
2315                         service->name = g_strdup(db_svc->service_name);
2316                         service->cycle = db_svc->cycle;
2317                         service->presence_threshold = db_svc->presence_threshold;
2318                         service->absence_threshold = db_svc->absence_threshold;
2319                         services = g_slist_append(services, service);
2320                 }
2321         }
2322
2323         /* Fetch device list */
2324         db_devices = _uam_device_db_get_all_devices();
2325         if (!db_devices) {
2326                 UAM_INFO_C("No Devices registered in database");
2327                 return UAM_ERROR_NONE;
2328         }
2329
2330         for (l = db_devices; NULL != l; l = g_slist_next(l)) {
2331                 db_device_info_t *db_info = l->data;
2332                 uam_db_user_info_t *user;
2333                 GSList *svc_list = NULL;
2334                 GSList *l1;
2335
2336                 if (!db_info)
2337                         continue;
2338
2339                 l1 = g_slist_find_custom(users,
2340                                 &(db_info->user_id), __compare_user_id);
2341                 if (!l1) {
2342                         UAM_ERR("Invalid user Id: %d", db_info->user_id);
2343                         continue;
2344                 }
2345                 user = l1->data;
2346
2347                 /* Fetch device services from DB */
2348                 l1 = _uam_db_get_device_services(
2349                                 db_info->dev_info.device_id,
2350                                 db_info->dev_info.type,
2351                                 db_info->dev_info.mac);
2352
2353                 svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
2354                 __uam_core_add_dev_to_list(user, &(db_info->dev_info),
2355                                 db_info->presence_state, db_info->last_seen, svc_list);
2356         }
2357
2358         /* Fetch iBeacon adv list */
2359         db_adv_list = _uam_db_get_all_advs();
2360         if (!db_adv_list) {
2361                 UAM_INFO_C("No iBeacon adv in database");
2362         } else {
2363                 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
2364                         db_adv_info_t *db_adv = l->data;
2365                         _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
2366                 }
2367         }
2368
2369         /* Fetch svc dev list */
2370         db_svc_dev_list = _uam_db_get_service_devices_info();
2371         if (!db_svc_dev_list) {
2372                 UAM_INFO_C("No service devices in database");
2373         } else {
2374                 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
2375                         db_svc_dev_info_t *db_svc = l->data;
2376
2377                         _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
2378                                         db_svc->svc, db_svc->discriminant, db_svc->last_seen);
2379                 }
2380         }
2381
2382         g_slist_free_full(db_devices, g_free);
2383         g_slist_free_full(db_users, g_free);
2384         g_slist_free_full(db_svc_list, g_free);
2385         g_slist_free_full(db_adv_list, g_free);
2386         g_slist_free_full(db_svc_dev_list, g_free);
2387
2388         /* Set/update registered device list to plugins */
2389         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices))
2390                 UAM_ERR("_uam_pm_set_registered_devices failed");
2391
2392         /* Set/update registered device list to cloud plugin */
2393         _uam_cloud_update_registered_devices();
2394
2395         FUNC_EXIT;
2396         return UAM_ERROR_NONE;
2397 }
2398
2399 void _uam_core_deinit(void)
2400 {
2401         FUNC_ENTRY;
2402         GSList *l;
2403
2404         /* de-init database */
2405         _uam_db_deinitialize();
2406
2407         /* Reset detecton window to default */
2408         detection_window = UAM_DETECTION_WINDOW_DEFAULT;
2409
2410         /* Release allocated memory for devices */
2411         g_slist_free_full(devices, __free_user_device);
2412         devices = NULL;
2413
2414         /* Release allocated memory for users */
2415         for (l = users; NULL != l; l = g_slist_next(l)) {
2416                 uam_db_user_info_t *user = l->data;
2417
2418                 if (!user)
2419                         continue;
2420
2421                 g_free(user->name);
2422                 g_free(user->account);
2423                 g_free(user);
2424         }
2425
2426         g_slist_free(users);
2427         users = NULL;
2428
2429         /* Release allocated memory for services */
2430         for (l = services; NULL != l; l = g_slist_next(l)) {
2431                 uam_db_service_info_t *service = l->data;
2432
2433                 if (!service)
2434                         continue;
2435
2436                 g_free(service->name);
2437                 g_free(service);
2438         }
2439         g_slist_free(services);
2440         services = NULL;
2441
2442         /* Release allocated memory for service devices */
2443         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2444                 uam_svc_dev_info_t *svc_dev = l->data;
2445
2446                 if (!svc_dev)
2447                         continue;
2448
2449                 g_free(svc_dev->device_id);
2450                 g_free(svc_dev->service);
2451                 g_free(svc_dev);
2452         }
2453         g_slist_free(svc_devs);
2454         svc_devs = NULL;
2455
2456         FUNC_EXIT;
2457 }
2458
2459 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
2460 {
2461         FUNC_ENTRY;
2462
2463         /* Send sensor state changed event over dbus */
2464         if (is_ready)
2465                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
2466                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2467         else
2468                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
2469                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
2470
2471         FUNC_EXIT;
2472 }
2473
2474 int _uam_core_handle_device_added(int status,
2475                 int user_id, const uam_device_info_s *dev_info)
2476 {
2477         FUNC_ENTRY;
2478
2479         GSList *l;
2480         int ret = UAM_ERROR_NONE;
2481         GSList *svc_list = NULL;
2482         uam_db_user_info_t *user = NULL;
2483
2484         UAM_INFO("[%d]", user_id);
2485
2486         /* Send reply over dbus for add device API */
2487         l = _uam_manager_get_request_list();
2488         for (; NULL != l; l = g_slist_next(l)) {
2489                 uam_request_context_t *info = l->data;
2490                 uam_device_info_s *dev;
2491                 GArray *out_param;
2492
2493                 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
2494                         continue;
2495
2496                 dev = info->data;
2497                 if (!dev) {
2498                         UAM_WARN("info->data is NULL");
2499                         continue;
2500                 }
2501
2502                 if (dev->type != dev_info->type ||
2503                                 strcasecmp(dev->device_id, dev_info->device_id)) {
2504                         UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
2505                                         dev->device_id, dev_info->device_id);
2506                         continue;
2507                 }
2508
2509                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
2510                 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
2511                 _uam_manager_method_return(info->context, out_param, status);
2512
2513                 _uam_remove_timer(info->tid);
2514
2515                 _uam_manager_remove_req_ctxt_from_list(info);
2516
2517                 break;
2518         }
2519
2520         if (UAM_ERROR_NONE != status) {
2521                 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
2522                 return status;
2523         }
2524
2525         if (0 > user_id) {
2526                 int id = 0;
2527                 l = g_slist_find_custom(users,
2528                                 USER_ACCOUNT_DEFAULT, __compare_user_account);
2529                 if (NULL == l) {
2530                         ret = _uam_core_add_user(&id, USER_ACCOUNT_DEFAULT, USER_NAME_DEFAULT);
2531                         if (UAM_ERROR_NONE != ret) {
2532                                 UAM_ERR("_uam_core_add_user failed with %s",
2533                                                 _uam_manager_error_to_str(ret));
2534                                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2535                                 return ret;
2536                         }
2537                 }
2538                 user_id = id;
2539         }
2540         l = g_slist_find_custom(users, &user_id, __compare_user_id);
2541         if (NULL == l) {
2542                 UAM_ERR("Invalid user Id: %d", user_id);
2543                 ret = UAM_ERROR_NOT_FOUND;
2544                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2545                 return ret;
2546         }
2547         user = l->data;
2548
2549         /* Get default service and add it to device's service list by default */
2550         l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
2551         if (!l) {
2552                 uam_db_service_info_t *service = g_new0(uam_db_service_info_t, 1);
2553                 service->name = g_strdup(UAM_SERVICE_DEFAULT);
2554                 service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
2555                 services = g_slist_append(services, service);
2556                 svc_list = g_slist_append(svc_list, service);
2557         } else {
2558                 uam_db_service_info_t *service = l->data;
2559                 svc_list = g_slist_append(svc_list, service);
2560         }
2561
2562         __uam_core_add_dev_to_list(user, dev_info,
2563                         UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen, svc_list);
2564
2565         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2566
2567         /* Add device to database */
2568         ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
2569                         UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen);
2570         if (UAM_ERROR_NONE != ret) {
2571                 UAM_WARN("Device addition to persistent DB failed");
2572                 __uam_db_end_transaction(0);
2573                 return ret;
2574         }
2575
2576         /* Insert device service info to db */
2577         ret =  _uam_db_insert_device_service_info(
2578                                 dev_info->device_id, dev_info->type, dev_info->mac,
2579                                 UAM_SERVICE_DEFAULT, UAM_DETECTION_CYCLE_DEFAULT,
2580                                 dev_info->discriminant, 0);
2581         if (UAM_ERROR_NONE != ret) {
2582                 UAM_WARN("Device service addition to persistent DB failed");
2583                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2584                 __uam_db_end_transaction(0);
2585                 return ret;
2586         }
2587         __uam_db_end_transaction(1);
2588
2589         ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
2590                                 UAM_SERVICE_DEFAULT, dev_info->discriminant, 0);
2591         if (UAM_ERROR_NONE != ret) {
2592                 UAM_WARN("Device service mappiing update failed");
2593                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2594                 return ret;
2595         }
2596
2597         /* Send device added event to application */
2598         __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
2599
2600         /* Set/update registered device list to plugins */
2601         ret = _uam_pm_set_registered_devices(devices);
2602         if (UAM_ERROR_NONE != ret) {
2603                 UAM_ERR("_uam_pm_set_registered_devices failed");
2604                 return ret;
2605         }
2606
2607         _uam_cloud_send_device_added(status, (user ? user->account : NULL), dev_info);
2608
2609         /* Set/update registered device list to cloud plugin */
2610         if (UAM_ERROR_NONE == status)
2611                 _uam_cloud_update_registered_devices();
2612
2613         FUNC_EXIT;
2614         return ret;
2615 }
2616
2617 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
2618 {
2619         FUNC_ENTRY;
2620         GSList *l;
2621         unsigned long long timestamp;
2622
2623         UAM_INFO("sensor 0x[%8.8X]", sensor);
2624
2625         if (NULL == sensor_info) {
2626                 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2627                         g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2628                 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2629                 FUNC_EXIT;
2630                 return;
2631         }
2632
2633         timestamp = _uam_get_timestamp();
2634
2635         if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2636                 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
2637                         g_variant_new("(utiidddd)", sensor, timestamp,
2638                         sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2639                         sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2640                 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
2641                 FUNC_EXIT;
2642                 return;
2643         }
2644
2645         // service specific light detection threshold
2646         for (l = services; NULL != l; l = g_slist_next(l)) {
2647                 uam_db_service_info_t *svc = l->data;
2648                 GSList *l1;
2649
2650                 if (!svc || !svc->monitors)
2651                         continue;
2652
2653                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2654                                 svc->name, sensor_info->values[0], svc->presence_threshold);
2655
2656                 if (sensor_info->values[0] < svc->presence_threshold)
2657                         continue;
2658
2659                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2660                         uam_monitor_info_t *mon = l1->data;
2661
2662                         if (!mon)
2663                                 continue;
2664
2665                         UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
2666                                         mon->name, mon->sensors);
2667
2668                         if (!(mon->sensors & sensor))
2669                                 continue;
2670
2671                         if (UAM_DETECT_PRESENCE != mon->mode)
2672                                 continue;
2673
2674                         _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
2675                                 g_variant_new("(utiidddd)", sensor, timestamp,
2676                                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2677                                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2678                         UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
2679                                         mon->name, sensor);
2680                 }
2681         }
2682
2683         FUNC_EXIT;
2684 }
2685
2686 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
2687         unsigned int sensor)
2688 {
2689         FUNC_ENTRY;
2690         GSList *l;
2691
2692         UAM_INFO("sensor 0x[%8.8X]", sensor);
2693
2694         if (NULL == sensor_info) {
2695                 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2696                         g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
2697                 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2698                 FUNC_EXIT;
2699                 return;
2700         }
2701
2702         if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
2703                 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
2704                         g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2705                         sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2706                         sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2707                 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2708                 FUNC_EXIT;
2709                 return;
2710         }
2711
2712         // service specific light detection threshold
2713         for (l = services; NULL != l; l = g_slist_next(l)) {
2714                 uam_db_service_info_t *svc = l->data;
2715                 GSList *l1;
2716
2717                 if (!svc || !svc->monitors)
2718                         continue;
2719
2720                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
2721                                 svc->name, sensor_info->values[0], svc->absence_threshold);
2722
2723                 if (sensor_info->values[0] > svc->absence_threshold)
2724                         continue;
2725
2726                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2727                         uam_monitor_info_t *mon = l1->data;
2728
2729                         if (!mon)
2730                                 continue;
2731
2732                         if (!(mon->sensors & sensor))
2733                                 continue;
2734
2735                         if (UAM_DETECT_PRESENCE != mon->mode)
2736                                 continue;
2737
2738                         _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
2739                                 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
2740                                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
2741                                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
2742                         UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
2743                 }
2744         }
2745
2746         FUNC_EXIT;
2747 }
2748
2749 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
2750                 uam_device_info_s *dev_info)
2751 {
2752         FUNC_ENTRY;
2753
2754         GSList *l;
2755         uam_db_user_info_t *user;
2756         uam_svc_dev_info_t *svc_dev = NULL;
2757         gboolean live_monitoring = FALSE;
2758         unsigned long long timestamp;
2759         int ret;
2760
2761         ret_if(NULL == tech);
2762         ret_if(NULL == tech->svc_list);
2763         ret_if(NULL == dev_info);
2764
2765         user = tech->device->user;
2766         user->last_seen = tech->last_seen;
2767
2768         for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
2769                 uam_db_service_info_t *svc = l->data;
2770                 GSList *l1;
2771                 live_monitoring = FALSE;
2772
2773                 if (!svc || !svc->monitors)
2774                         continue;
2775
2776                 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
2777                         svc->name, svc->remaining_time, svc->cycle);
2778
2779                 if (!(svc->remaining_time == svc->cycle))
2780                         continue;
2781
2782                 UAM_DBG("Check service device discriminant");
2783                 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
2784                                 dev_info->type, svc->name);
2785                 if (!svc_dev || !svc_dev->discriminant)
2786                         continue;
2787
2788                 UAM_DBG("Send event");
2789                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
2790                         uam_monitor_info_t *mon = l1->data;
2791
2792                         if (!mon)
2793                                 continue;
2794
2795                         if (!(mon->sensors & sensor))
2796                                 continue;
2797
2798                         if (UAM_DETECT_PRESENCE != mon->mode)
2799                                 continue;
2800
2801                         /*
2802                          * For current service, if any of its running monitor has same sensor
2803                          * and detection_mode
2804                          */
2805                         live_monitoring = TRUE;
2806
2807                         timestamp = _uam_get_timestamp();
2808                         UAM_INFO("sensor [%d]", sensor);
2809                         _uam_manager_send_event(mon->name,
2810                                         UAM_EVENT_USER_PRESENCE_DETECTED,
2811                                         g_variant_new("(utsss)", sensor, timestamp,
2812                                                 user->account, svc->name, dev_info->device_id));
2813                         UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
2814                                         " on device %s"
2815                                         " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
2816                                         mon->name, dev_info->device_id,
2817                                         sensor, user->account,
2818                                         svc->name,
2819                                         timestamp);
2820                 }
2821
2822                 /* Update service specific device last_seen in svc_dev list and DB */
2823                 if (live_monitoring) {
2824                         svc_dev->last_seen = tech->last_seen;
2825                         ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
2826                                         dev_info->type, dev_info->mac, svc->name, tech->last_seen);
2827                         if (UAM_ERROR_NONE != ret)
2828                                 UAM_WARN("_uam_db_update_device_service_last_seen failed");
2829                 }
2830         }
2831
2832         FUNC_EXIT;
2833 }
2834
2835 int _uam_core_handle_presence_detected(unsigned int sensor,
2836                 int user_id, void *info)
2837 {
2838         FUNC_ENTRY;
2839         int ret = UAM_ERROR_NONE;
2840
2841         GSList *l;
2842         uam_db_user_info_t *user;
2843         uam_db_device_info_t *device;
2844         uam_db_tech_info_t *tech;
2845
2846         uam_device_info_s *dev_info = NULL;
2847         uam_sensor_info_s *sensor_info = NULL;
2848
2849         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
2850
2851         if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
2852                 sensor_info = info;
2853         if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
2854                 dev_info = info;
2855
2856         _uam_vpm_send_presence_detection_event(sensor);
2857
2858         if (NULL == dev_info) {
2859                 __send_sensor_presence_event(sensor_info, sensor);
2860                 return ret;
2861         }
2862
2863         retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
2864
2865         l = g_slist_find_custom(users, &user_id, __compare_user_id);
2866         if (NULL == l) {
2867                 UAM_ERR("Invalid user_id [%d]", user_id);
2868                 return UAM_ERROR_INVALID_PARAMETER;
2869         }
2870         user = l->data;
2871
2872         l = g_slist_find_custom(user->devices,
2873                         dev_info->device_id, __compare_device_id);
2874         if (NULL == l) {
2875                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
2876                                 user_id, dev_info->device_id);
2877                 return UAM_ERROR_INVALID_PARAMETER;
2878         }
2879         device = l->data;
2880         if (!(device->supported_techs & dev_info->type)) {
2881                 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
2882                                 dev_info->device_id, dev_info->type);
2883                 return UAM_ERROR_INVALID_PARAMETER;
2884         }
2885
2886         l = g_slist_find_custom(device->tech_list,
2887                         &(dev_info->type), __compare_tech_type);
2888         if (NULL == l) {
2889                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
2890                 return UAM_ERROR_INVALID_PARAMETER;
2891         }
2892         tech = l->data;
2893
2894         tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
2895         tech->last_seen = dev_info->last_seen;
2896
2897         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
2898
2899         /* Check if IP/MAC address was updated then update in DB */
2900         if (UAM_TECH_TYPE_WIFI == dev_info->type) {
2901
2902                 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
2903                         uam_db_address_info_t *addr = l->data;
2904
2905                         if (NULL == addr)
2906                                 continue;
2907
2908                         if (UAM_ADDR_TYPE_IPv4 == addr->addr_type) {
2909
2910                                 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
2911                                         UAM_DBG("Old IPv4: %s, New IPv4: %s",
2912                                                 addr->address, dev_info->ipv4_addr);
2913
2914                                         g_free(addr->address);
2915                                         addr->addr_type = UAM_ADDR_TYPE_IPv4;
2916                                         addr->address = g_strdup(dev_info->ipv4_addr);
2917
2918                                         /* Update IP address in DB */
2919                                         ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
2920                                                         dev_info->type, dev_info->ipv4_addr);
2921                                         if (UAM_ERROR_NONE != ret) {
2922                                                 UAM_WARN("_uam_device_db_update_device_ip_address failed");
2923                                                 __uam_db_end_transaction(0);
2924                                                 return ret;
2925                                         }
2926                                 }
2927                         }
2928
2929                         if (UAM_ADDR_TYPE_WIFI == addr->addr_type) {
2930
2931                                 if (strcasecmp(addr->address, dev_info->mac)) {
2932                                         UAM_DBG("Old MAC: %s, New MAC: %s",
2933                                                 addr->address, dev_info->mac);
2934
2935                                         g_free(addr->address);
2936                                         addr->addr_type = UAM_ADDR_TYPE_WIFI;
2937                                         addr->address = g_strdup(dev_info->mac);
2938
2939                                         /* Update address in DB */
2940                                         ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
2941                                                         dev_info->type, dev_info->mac);
2942                                         if (UAM_ERROR_NONE != ret) {
2943                                                 UAM_WARN("_uam_device_db_update_device_mac_address failed");
2944                                                 __uam_db_end_transaction(0);
2945                                                 return ret;
2946                                         }
2947                                 }
2948                         }
2949                 }
2950         }
2951
2952         /* Update database (presence state & timestamp) */
2953         ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
2954                                 dev_info->type, dev_info->mac, dev_info->last_seen);
2955         if (UAM_ERROR_NONE != ret) {
2956                 UAM_WARN("_uam_device_db_update_device_last_seen failed");
2957                 __uam_db_end_transaction(0);
2958                 return ret;
2959         }
2960
2961         ret = _uam_device_db_update_device_presence(dev_info->device_id,
2962                                 dev_info->type, dev_info->mac, tech->presence_state);
2963         if (UAM_ERROR_NONE != ret) {
2964                 UAM_WARN("_uam_device_db_update_device_presence failed");
2965                 __uam_db_end_transaction(0);
2966                 return ret;
2967         }
2968
2969         /* Send user presence event and update service_device timestamp */
2970         __send_user_presence_event(tech, sensor, dev_info);
2971         __uam_db_end_transaction(1);
2972
2973         FUNC_EXIT;
2974         return ret;
2975 }
2976
2977 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
2978 {
2979         FUNC_ENTRY;
2980         GSList *l;
2981
2982         /*
2983          * For each service, find users absent on given sensor. Then for each
2984          * monitor in serivce's monitor list, if it is monitoring ABSENCE on
2985          * given sensor, send user ABSENCE event.
2986          */
2987         for (l = services; NULL != l; l = g_slist_next(l)) {
2988                 uam_db_service_info_t *svc = l->data;
2989                 GSList *absent_users = NULL;
2990                 GSList *present_users = NULL;
2991                 GSList *l1;
2992                 GSList *l2;
2993
2994                 if (!svc || !svc->monitors || !svc->dev_techs)
2995                         continue;
2996
2997                 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
2998                         uam_db_tech_info_t *tech = l1->data;
2999
3000                         if (!tech || (tech->tech_type != type)) {
3001                                 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
3002                                 continue;
3003                         }
3004
3005                         if (!tech->device || !tech->device->user) {
3006                                 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
3007                                 continue;
3008                         }
3009
3010                         l2 = g_slist_find_custom(present_users,
3011                                         &(tech->device->user->user_id), __compare_user_id);
3012
3013                         if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
3014                                 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
3015                                         tech->discriminant,
3016                                         tech->device->device_id,
3017                                         tech->device->user->account);
3018                                 /* Remove user from absent list */
3019                                 absent_users = g_slist_remove(absent_users, tech->device->user);
3020
3021                                 /* If user not in present list, add user to the list */
3022                                 if (!l2) {
3023                                         UAM_DBG("added present user [%s]", tech->device->user->account);
3024                                         present_users = g_slist_prepend(present_users, tech->device->user);
3025                                 }
3026                         } else {
3027                                 /* If user not in the present list then only add it to absent list */
3028                                 if ((NULL == l2) && (NULL == g_slist_find_custom(
3029                                                                 absent_users, &(tech->device->user->user_id),
3030                                                                 __compare_user_id))) {
3031                                         UAM_DBG("added absent user [%s]", tech->device->user->account);
3032                                         absent_users = g_slist_prepend(absent_users, tech->device->user);
3033                                 }
3034                         }
3035                 }
3036
3037                 g_slist_free(present_users);
3038                 if (!absent_users)
3039                         continue;
3040
3041                 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
3042                         uam_monitor_info_t *mon = l2->data;
3043
3044                         if (!mon)
3045                                 continue;
3046
3047                         if (!(mon->sensors & sensor))
3048                                 continue;
3049
3050                         if (UAM_DETECT_ABSENCE != mon->mode)
3051                                 continue;
3052
3053                         for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
3054                                 uam_db_user_info_t *user = l1->data;
3055
3056                                 if (!user)
3057                                         continue;
3058
3059                                 user->last_seen = 0;
3060
3061                                 _uam_manager_send_event(mon->name,
3062                                                 UAM_EVENT_USER_ABSENCE_DETECTED,
3063                                                 g_variant_new("(utss)", sensor, user->last_seen,
3064                                                         user->account, svc->name));
3065                                 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
3066                                                 " for 0x%8.8X, User: %s Service: %s",
3067                                                 mon->name, sensor, user->account, svc->name);
3068                         }
3069                 }
3070
3071                 g_slist_free(absent_users);
3072         }
3073
3074         FUNC_EXIT;
3075 }
3076
3077 void _uam_core_handle_absence_detected(unsigned int sensor,
3078                 int user_id, void *info)
3079 {
3080         FUNC_ENTRY;
3081         uam_db_user_info_t *user;
3082         uam_db_device_info_t *device;
3083         uam_db_tech_info_t *tech;
3084         GSList *l;
3085         uam_device_info_s *dev_info = NULL;
3086         uam_sensor_info_s *sensor_info = NULL;
3087
3088         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3089
3090         if (info && (UAM_SENSOR_BITMASK_LIGHT == sensor || UAM_SENSOR_BITMASK_MOTION == sensor))
3091                 sensor_info = info;
3092         if (info && (UAM_SENSOR_BITMASK_BLE == sensor || UAM_SENSOR_BITMASK_WIFI == sensor))
3093                 dev_info = info;
3094
3095         if (NULL == dev_info) {
3096                 __send_sensor_absence_event(sensor_info, sensor);
3097                 FUNC_EXIT;
3098                 return;
3099         }
3100
3101         ret_if(0 > user_id);
3102
3103         l = g_slist_find_custom(users, &user_id, __compare_user_id);
3104         if (NULL == l) {
3105                 UAM_ERR("Invalid user_id [%d]", user_id);
3106                 return;
3107         }
3108         user = l->data;
3109
3110         l = g_slist_find_custom(user->devices,
3111                         dev_info->device_id, __compare_device_id);
3112         if (NULL == l) {
3113                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3114                                 user_id, dev_info->device_id);
3115                 return;
3116         }
3117         device = l->data;
3118         if (!(device->supported_techs & dev_info->type)) {
3119                 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3120                                 dev_info->device_id, dev_info->type);
3121                 return;
3122         }
3123
3124         l = g_slist_find_custom(device->tech_list,
3125                         &(dev_info->type), __compare_tech_type);
3126         if (NULL == l) {
3127                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3128                 return;
3129         }
3130         tech = l->data;
3131
3132         tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
3133
3134         /* Update database (presence state) */
3135         if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
3136                                 dev_info->type, dev_info->mac, tech->presence_state))
3137                 UAM_WARN("_uam_device_db_update_device_presence failed");
3138
3139         FUNC_EXIT;
3140 }
3141
3142 void _uam_core_cleanup_monitor(char *name)
3143 {
3144         GSList *l;
3145
3146         for (l = monitors; NULL != l; l = g_slist_next(l)) {
3147                 uam_monitor_info_t *monitor = l->data;
3148
3149                 if (!monitor || !monitor->name || !monitor->service)
3150                         continue;
3151
3152                 if (0 != g_strcmp0(name, monitor->name))
3153                         continue;
3154
3155                 /* If there is a monitor that is not freed, stop detection
3156                  * and free the monitor structure in the memory. */
3157                 UAM_INFO("clear %s's monitor info.", monitor->name);
3158                 __uam_core_stop_detection(monitor->mode,
3159                         monitor->service->name, name, monitor->sensors);
3160         }
3161 }
3162
3163 static void __free_user_info(gpointer data)
3164 {
3165         FUNC_ENTRY;
3166         uam_db_user_info_t *user = data;
3167
3168         ret_if(NULL == user);
3169
3170         g_free(user->name);
3171         g_free(user->account);
3172         g_free(user);
3173         FUNC_EXIT;
3174 }
3175
3176 static void __free_service_info(gpointer data)
3177 {
3178         FUNC_ENTRY;
3179         uam_db_service_info_t *svc = data;
3180
3181         ret_if(NULL == svc);
3182
3183         g_free(svc->name);
3184         g_free(svc);
3185         FUNC_EXIT;
3186 }
3187
3188 static void __free_monitor_info(gpointer data)
3189 {
3190         FUNC_ENTRY;
3191         uam_monitor_info_t *monitor = data;
3192
3193         ret_if(NULL == monitor);
3194
3195         g_free(monitor->name);
3196         g_free(monitor);
3197         FUNC_EXIT;
3198 }
3199
3200 static void __free_scanner_info(gpointer data)
3201 {
3202         FUNC_ENTRY;
3203         uam_scanner_info_t *scanner = data;
3204
3205         ret_if(NULL == scanner);
3206
3207         g_free(scanner->name);
3208         g_free(scanner);
3209         FUNC_EXIT;
3210 }
3211
3212 void _uam_core_reset_database(void)
3213 {
3214         FUNC_ENTRY;
3215         int ret;
3216
3217         ret = _uam_db_clear();
3218         if (UAM_ERROR_NONE != ret) {
3219                 UAM_ERR("_uam_db_clear failed with %s",
3220                                 _uam_manager_error_to_str(ret));
3221                 unlink(DATABASE_FULL_PATH);
3222                 return;
3223         }
3224
3225         g_slist_free_full(devices, __free_user_device);
3226         devices = NULL;
3227
3228         g_slist_free_full(users, __free_user_info);
3229         users = NULL;
3230
3231         g_slist_free_full(services, __free_service_info);
3232         services = NULL;
3233
3234         g_slist_free_full(monitors, __free_monitor_info);
3235         monitors = NULL;
3236
3237         g_slist_free_full(scanners, __free_scanner_info);
3238         scanners = NULL;
3239
3240         /* Set/update registered device list to plugins */
3241         ret = _uam_pm_set_registered_devices(devices);
3242         if (UAM_ERROR_NONE != ret)
3243                 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
3244                                 _uam_manager_error_to_str(ret));
3245
3246         /* Set/update registered device list to cloud plugin */
3247         _uam_cloud_update_registered_devices();
3248
3249         FUNC_EXIT;
3250 }
3251
3252 void _uam_core_handle_detection_started(unsigned int sensor)
3253 {
3254         FUNC_ENTRY;
3255         unsigned int active_sensors = 0;
3256
3257         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3258                         sensor, detecting_sensors);
3259
3260         detecting_sensors |= sensor;
3261         active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
3262         active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
3263         if (active_sensors == detecting_sensors) {
3264                 /* Send detection started event */
3265                 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
3266         }
3267
3268         FUNC_EXIT;
3269 }
3270
3271 void _uam_core_handle_detection_stopped(unsigned int sensor)
3272 {
3273         FUNC_ENTRY;
3274
3275         uam_tech_type_e type = UAM_TECH_TYPE_NONE;
3276         uam_cycle_state_e cycle_state;
3277         GSList *l = NULL;
3278
3279         ret_if((detecting_sensors & sensor) == 0);
3280         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
3281                         sensor, detecting_sensors);
3282         detecting_sensors &= ~sensor;
3283
3284         if (UAM_SENSOR_BITMASK_BLE == sensor)
3285                 type = UAM_TECH_TYPE_BLE;
3286         else if (UAM_SENSOR_BITMASK_WIFI == sensor)
3287                 type = UAM_TECH_TYPE_WIFI;
3288
3289         if (UAM_TECH_TYPE_NONE != type)
3290                 __send_user_absence_event(type, sensor);
3291
3292         if (0 == detecting_sensors) {
3293                 /* Send detection stopped event */
3294                 for (l = monitors; l; l = g_slist_next(l)) {
3295                         uam_monitor_info_t *mon = l->data;
3296
3297                         if (!mon || !mon->name || !mon->service)
3298                                 continue;
3299                         uam_db_service_info_t *service = mon->service;
3300                         cycle_state = UAM_DETECTION_CYCLE_END;
3301
3302                         UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d", mon->sensors, service->name, service->remaining_time);
3303                         if (!(mon->sensors & _uam_core_get_env_sensors())) {
3304                                 if (service->remaining_time < service->cycle) {
3305                                         UAM_DBG("service->remaining_time < service->cycle, return");
3306                                         return;
3307                                 }
3308                         } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
3309                                 cycle_state = UAM_DETECTION_CYCLE_MID;
3310                         }
3311
3312                         _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
3313                                         g_variant_new("(si)", service->name, cycle_state));
3314                         UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
3315                                         " cycle state:[%s]",
3316                                         mon->name, service->name, cycle_state ? "end" : "mid");
3317                 }
3318         }
3319         FUNC_EXIT;
3320 }
3321
3322 static uam_scanner_info_t *__uam_find_scanner(const char *name)
3323 {
3324         GSList *l;
3325
3326         retv_if(NULL == name, NULL);
3327
3328         for (l = scanners; NULL != l; l = g_slist_next(l)) {
3329                 uam_scanner_info_t *scanner = l->data;
3330
3331                 if (!scanner || !scanner->name)
3332                         continue;
3333
3334                 if (0 == g_strcmp0(scanner->name, name)) {
3335                         UAM_DBG("Scanning application found in list");
3336                         return scanner;
3337                 }
3338         }
3339
3340         return NULL;
3341 }
3342
3343 static gboolean __scan_completed_cb(gpointer data)
3344 {
3345         FUNC_ENTRY;
3346         uam_scanner_info_t *scanner = data;
3347
3348         retv_if(NULL == scanner, FALSE);
3349
3350         if (UAM_ERROR_NONE != _uam_manager_send_event(
3351                                 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3352                 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3353         else
3354                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3355
3356         /* Free scanner */
3357         scanners = g_slist_remove(scanners, scanner);
3358         g_free(scanner->name);
3359         g_free(scanner);
3360
3361         FUNC_EXIT;
3362         return FALSE;
3363 }
3364
3365 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
3366 {
3367         FUNC_ENTRY;
3368         int ret;
3369         uam_scanner_info_t *scanner;
3370
3371         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3372         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3373
3374         scanner = __uam_find_scanner(sender);
3375         retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
3376
3377         ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
3378         if (UAM_ERROR_NONE != ret) {
3379                 UAM_ERR("Failed with error: %s (0x%4.4X)",
3380                                 _uam_manager_error_to_str(ret), ret);
3381                 return ret;
3382         }
3383
3384         scanner = g_malloc0(sizeof(uam_scanner_info_t));
3385         if (!scanner) {
3386                 UAM_ERR("Failed to allocate memory");
3387                 return UAM_ERROR_OUT_OF_MEMORY;
3388         }
3389         scanner->name = g_strdup(sender);
3390         scanner->sensors |= sensors;
3391         scanner->timer = g_timeout_add_seconds(detection_period,
3392                         __scan_completed_cb, scanner);
3393         scanners = g_slist_append(scanners, scanner);
3394         UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
3395
3396         FUNC_EXIT;
3397         return UAM_ERROR_NONE;
3398 }
3399
3400 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
3401 {
3402         FUNC_ENTRY;
3403         int ret;
3404         uam_scanner_info_t *scanner;
3405         GSList *l;
3406
3407         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
3408         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
3409
3410         scanner = __uam_find_scanner(sender);
3411         retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
3412
3413         /* Trim sensors to a subset of active sensors for the scanner */
3414         sensors &= scanner->sensors;
3415
3416         /*
3417          * modify scanner's active sensors and if active sensors are NULL
3418          * remove scanner from scanners list
3419          */
3420         scanner->sensors &= ~sensors;
3421         if (0 == scanner->sensors) {
3422                 scanners = g_slist_remove(scanners, scanner);
3423                 g_source_remove(scanner->timer);
3424                 g_free(scanner->name);
3425                 g_free(scanner);
3426         }
3427
3428         for (l = scanners; NULL != l; l = g_slist_next(l)) {
3429                 uam_scanner_info_t *scanner_data = l->data;
3430
3431                 if (!scanner_data || !scanner_data->name)
3432                         continue;
3433
3434                 sensors &= ~(scanner_data->sensors);
3435         }
3436
3437         if (0 != sensors) {
3438                 ret = _uam_pm_stop_active_device_scan(sensors);
3439                 if (UAM_ERROR_NONE != ret) {
3440                         UAM_ERR("Failed with error: %s (0x%4.4X)",
3441                                         _uam_manager_error_to_str(ret), ret);
3442                         return ret;
3443                 }
3444         }
3445
3446         FUNC_EXIT;
3447         return UAM_ERROR_NONE;
3448 }
3449
3450 void _uam_core_handle_active_device(uam_active_scan_event_e event,
3451                 unsigned int sensor, const uam_device_info_s *dev_info)
3452 {
3453         FUNC_ENTRY;
3454         GSList *l;
3455
3456         ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
3457
3458         for (l = scanners; NULL != l;) {
3459                 uam_scanner_info_t *scanner = l->data;
3460
3461                 if (!scanner || !scanner->name) {
3462                         l = g_slist_next(l);
3463                         continue;
3464                 }
3465
3466                 if (0 == (scanner->sensors & sensor)) {
3467                         l = g_slist_next(l);
3468                         continue;
3469                 }
3470
3471                 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
3472                         scanner->sensors &= ~(sensor);
3473                         UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
3474                         if (0 != scanner->sensors) {
3475                                 l = g_slist_next(l);
3476                                 continue;
3477                         }
3478
3479                         if (UAM_ERROR_NONE != _uam_manager_send_event(
3480                                                 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
3481                                 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
3482                         else
3483                                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
3484
3485                         /* Free scanner */
3486                         l = g_slist_next(l);
3487                         scanners = g_slist_remove(scanners, scanner);
3488                         g_source_remove(scanner->timer);
3489                         g_free(scanner->name);
3490                         g_free(scanner);
3491                 } else {
3492                         GVariant *param = g_variant_new("(iiisss)",
3493                                         UAM_ERROR_NONE,
3494                                         dev_info->operating_system,
3495                                         dev_info->type,
3496                                         dev_info->mac,
3497                                         dev_info->ipv4_addr,
3498                                         dev_info->device_id);
3499                         if (UAM_ERROR_NONE != _uam_manager_send_event(
3500                                                 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
3501                                 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
3502                         else
3503                                 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
3504
3505                         l = g_slist_next(l);
3506                 }
3507         }
3508
3509         FUNC_EXIT;
3510 }
3511
3512 int _uam_core_register_service(uam_service_info_s *svc)
3513 {
3514         FUNC_ENTRY;
3515         GSList *l;
3516         uam_db_service_info_t *service;
3517         int service_number = 0;
3518
3519         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3520
3521         /* Retrieve service from list */
3522         l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3523         retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
3524
3525         service = g_new0(uam_db_service_info_t, 1);
3526         service->name = g_strdup(svc->name);
3527         service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
3528         service->presence_threshold = svc->presence_threshold;
3529         service->absence_threshold = svc->absence_threshold;
3530
3531         /* Add service to database */
3532         if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number, svc, service->cycle)) {
3533                 UAM_ERR("_uam_db_insert_service_info failed");
3534                 g_free(service);
3535                 return UAM_ERROR_DB_FAILED;
3536         }
3537
3538         services = g_slist_append(services, service);
3539
3540         /* Send service registered event to application */
3541         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3542                                 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
3543                                         UAM_ERROR_NONE, service->name)))
3544                 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
3545
3546         FUNC_EXIT;
3547         return UAM_ERROR_NONE;
3548 }
3549
3550 int _uam_core_update_service(uam_service_info_s *svc)
3551 {
3552         FUNC_ENTRY;
3553         GSList *l;
3554         uam_db_service_info_t *service;
3555
3556         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
3557
3558         /* Retrieve service from list */
3559         l = g_slist_find_custom(services, svc->name, __compare_svc_name);
3560         retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
3561
3562         service = l->data;
3563         service->presence_threshold = svc->presence_threshold;
3564         service->absence_threshold = svc->absence_threshold;
3565
3566         /* Update service to database */
3567         if (UAM_ERROR_NONE != _uam_db_update_service_info(service)) {
3568                 UAM_ERR("_uam_db_update_service_info failed");
3569                 return UAM_ERROR_DB_FAILED;
3570         }
3571
3572         FUNC_EXIT;
3573         return UAM_ERROR_NONE;
3574 }
3575
3576 int _uam_core_get_default_service(uam_service_info_s *service_info)
3577 {
3578         FUNC_ENTRY;
3579         int ret;
3580         GSList *l;
3581         uam_db_service_info_t *service;
3582
3583         retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
3584
3585         l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3586
3587         if (NULL == l) {
3588                 // insert default service
3589                 memset(service_info, 0x00, sizeof(uam_service_info_s));
3590                 g_strlcpy(service_info->name, UAM_SERVICE_DEFAULT, UAM_SERVICE_MAX_STRING_LEN);
3591                 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
3592                 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
3593
3594                 ret = _uam_core_register_service(service_info);
3595                 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
3596                         UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
3597                         return ret;
3598                 }
3599                 l = g_slist_find_custom(services, UAM_SERVICE_DEFAULT, __compare_svc_name);
3600         }
3601
3602         retv_if(NULL == l, UAM_ERROR_INTERNAL);
3603         service = l->data;
3604
3605         memset(service_info, 0x00, sizeof(uam_service_info_s));
3606         g_strlcpy(service_info->name, service->name, UAM_SERVICE_MAX_STRING_LEN);
3607
3608         FUNC_EXIT;
3609         return UAM_ERROR_NONE;
3610 }
3611
3612 int _uam_core_unregister_service(const char *svc_name)
3613 {
3614         FUNC_ENTRY;
3615         GSList *l;
3616         uam_db_service_info_t *service;
3617
3618         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
3619
3620         /* Retrieve service from list */
3621         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3622         retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
3623         service = l->data;
3624
3625         /* Check if service is being used*/
3626         if (service->monitors) {
3627                 UAM_ERR("service monitoring in progress");
3628                 return UAM_ERROR_PERMISSION_DENIED;
3629         }
3630
3631         /* Remove service from database */
3632         if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name)) {
3633                 UAM_ERR("_uam_db_delete_service_info failed");
3634                 return UAM_ERROR_DB_FAILED;
3635         }
3636
3637         /* Remove service mapping from devices*/
3638         for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3639                 uam_db_tech_info_t *tech = l->data;
3640                 if (!tech || !tech->addresses)
3641                         continue;
3642                 tech->svc_list = g_slist_remove(tech->svc_list, service);
3643         }
3644         services = g_slist_remove(services, service);
3645
3646         /* Send service unregistered event to application */
3647         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
3648                                 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
3649                                         UAM_ERROR_NONE, service->name)))
3650                 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
3651
3652         FUNC_EXIT;
3653         return UAM_ERROR_NONE;
3654 }
3655
3656 static int __get_service_dev_list(
3657                 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
3658 {
3659         FUNC_ENTRY;
3660         GSList *l1;
3661         GSList *s;
3662         int indx = 0;
3663         int ret = UAM_ERROR_NONE;
3664         uam_svc_dev_info_t *svc_dev = NULL;
3665         uam_device_info_s *dev = NULL;
3666
3667         *count = 0;
3668         /* Calculate number of devices */
3669         for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3670                 uam_db_tech_info_t *tech = l1->data;
3671                 if (!tech || !tech->addresses)
3672                         continue;
3673
3674                 (*count)++;
3675         }
3676
3677         *device_list = g_new0(uam_device_info_s, *count);
3678
3679         /* Copy devices */
3680         for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
3681                 uam_db_tech_info_t *tech = l1->data;
3682
3683                 if (!tech || !tech->addresses)
3684                         continue;
3685
3686                 /* Copy tech info to device info */
3687                 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
3688                 if (UAM_ERROR_NONE != ret) {
3689                         UAM_ERR("__copy_tech_info_to_device_info failed");
3690                         return ret;
3691                 }
3692
3693                 (*device_list)[indx].last_seen = 0;
3694                 indx++;
3695         }
3696
3697         UAM_INFO("Count = %d, indx = %d", *count, indx);
3698
3699         /* Update service specific device last time */
3700         for (s = svc_devs; s; s = g_slist_next(s)) {
3701                 svc_dev = s->data;
3702
3703                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
3704                         continue;
3705                 if (g_strcmp0(svc_dev->service, service->name))
3706                         continue;
3707
3708                 for (indx = 0; indx < *count; indx++) {
3709                         dev = &((*device_list)[indx]);
3710
3711                         if (svc_dev->tech_type != dev->type ||
3712                                         g_strcmp0(svc_dev->device_id, dev->device_id))
3713                                 continue;
3714
3715                         dev->last_seen = svc_dev->last_seen;
3716                 }
3717         }
3718
3719         FUNC_EXIT;
3720         return ret;
3721 }
3722
3723 int _uam_core_get_service_devices(const char *svc_name,
3724                 int *count, uam_device_info_s **device_list)
3725 {
3726         FUNC_ENTRY;
3727         uam_db_service_info_t *service;
3728         GSList *l;
3729         int ret = UAM_ERROR_NONE;
3730
3731         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3732         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3733         service = l->data;
3734
3735         ret = __get_service_dev_list(service, device_list, count);
3736
3737         FUNC_EXIT;
3738         return ret;
3739 }
3740
3741 static void __get_service_user_list(
3742                 uam_db_service_info_t* service, uam_user_info_s **user_list, int *count)
3743 {
3744         FUNC_ENTRY;
3745         GSList *l;
3746         int indx = 0;
3747         GSList *svc_user_list = NULL;
3748
3749         *count = 0;
3750         /* Calculate number of users */
3751         for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
3752                 uam_db_tech_info_t *tech = l->data;
3753                 if (!tech || !tech->addresses)
3754                         continue;
3755
3756                 GSList *l1;
3757                 uam_db_user_info_t *db_info = tech->device->user;
3758                 l1 = g_slist_find_custom(svc_user_list , db_info->account, __compare_user_account);
3759                 if (NULL == l1)
3760                         svc_user_list = g_slist_append(svc_user_list, db_info);
3761         }
3762
3763         *count = g_slist_length(svc_user_list);
3764         *user_list = g_new0(uam_user_info_s, *count);
3765
3766         /* Copy users */
3767         for (l = svc_user_list; l; l = g_slist_next(l)) {
3768                 uam_db_user_info_t *db_info = l->data;
3769
3770                 if (!db_info || !db_info->account)
3771                         continue;
3772
3773                 g_strlcpy((*user_list)[indx].account,
3774                                 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
3775                 if (db_info->name)
3776                         g_strlcpy((*user_list)[indx].name,
3777                                         db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
3778
3779                 indx += 1;
3780         }
3781
3782         UAM_INFO("Count = %d, indx = %d", *count, indx);
3783         FUNC_EXIT;
3784 }
3785
3786 int _uam_core_get_service_users(const char *svc_name,
3787                 int *count, uam_user_info_s **user_list)
3788 {
3789         FUNC_ENTRY;
3790         uam_db_service_info_t *service;
3791         GSList *l;
3792
3793         l = g_slist_find_custom(services, svc_name, __compare_svc_name);
3794         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
3795         service = l->data;
3796
3797         __get_service_user_list(service, user_list, count);
3798
3799         FUNC_EXIT;
3800         return UAM_ERROR_NONE;
3801 }
3802
3803 int _uam_core_get_services(int *count, uam_service_info_s **service_list)
3804 {
3805         FUNC_ENTRY;
3806         guint size;
3807         GSList *l;
3808
3809         size = g_slist_length(services);
3810         *service_list = g_new0(uam_service_info_s, size);
3811         *count = 0;
3812
3813         /* fetch services list from DB */
3814         for (l = services; l; l = g_slist_next(l)) {
3815                 uam_db_service_info_t *db_info = l->data;
3816
3817                 if (!db_info || !db_info->name)
3818                         continue;
3819
3820                 g_strlcpy((*service_list)[*count].name,
3821                                 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
3822                 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
3823                 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
3824                 *count += 1;
3825         }
3826
3827         UAM_INFO("Count: %d", *count);
3828         FUNC_EXIT;
3829         return UAM_ERROR_NONE;
3830 }
3831
3832 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv)
3833 {
3834         FUNC_ENTRY;
3835         int ret;
3836
3837         UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
3838                 iadv[0], iadv[1], iadv[2]);
3839
3840         ret = _uam_db_insert_adv_info(adv_len, iadv);
3841         if (UAM_ERROR_NONE != ret) {
3842                 UAM_ERR("_uam_db_insert_adv_info failed");
3843                 return ret;
3844         }
3845
3846         ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
3847         if (UAM_ERROR_NONE != ret) {
3848                 UAM_ERR("Failed with error: %s (0x%4.4X)",
3849                                 _uam_manager_error_to_str(ret), ret);
3850                 return ret;
3851         }
3852
3853         FUNC_EXIT;
3854         return UAM_ERROR_NONE;
3855 }
3856
3857 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
3858 {
3859         FUNC_ENTRY;
3860
3861         uam_sensor_info_s *sensor_info = info;
3862
3863         ret_if(NULL == info);
3864
3865         UAM_DBG("%d %d %llu %d %d", sensor, sensor_info->status, sensor_info->timestamp,
3866                 sensor_info->accuracy, sensor_info->count);
3867
3868         UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
3869                 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
3870
3871         _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
3872                 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
3873                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3874                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3875
3876         FUNC_EXIT;
3877 }
3878
3879 int _uam_core_add_payload(uam_ble_payload_s *payload,
3880                 const char *device_id, int tech_type)
3881 {
3882         FUNC_ENTRY;
3883         int ret = UAM_ERROR_NONE;
3884         uam_db_tech_info_t *tech_info;
3885 //      char *mac;
3886
3887         retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
3888         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
3889         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
3890         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
3891
3892         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
3893         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
3894 //      mac = __get_mac_addr(tech_info);
3895
3896         /*** Add payload to database ***/
3897 //      ret = _uam_db_insert_payload(payload, device_id, tech_type, mac);
3898         if (UAM_ERROR_NONE != ret) {
3899                 UAM_ERR("_uam_db_insert_adv_info failed");
3900                 return ret;
3901         }
3902
3903         FUNC_EXIT;
3904         return UAM_ERROR_NONE;
3905 }