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