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