Replace g_memdup to g_memdup2
[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 #include "ua-manager-database.h"
26 #include "ua-cloud-plugin-handler.h"
27 #include "ua-vendor-plugin-manager.h"
28
29 #define UAM_MAX_USERS 255
30 #define USER_ACCOUNT_DEFAULT "default@default.com"
31 #define USER_ACCOUNT_DEFAULT_SUFFIX "@default.com"
32 #define USER_NAME_DEFAULT "default"
33 #define UAM_APP_NUM_MAX_LEN 50
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 static GSList *svc_users; /* List of service user mapping -  uam_svc_user_info_t */
53
54 static GSList *payloads; /* List of payloads - uam_db_payload_info_t */
55 static GSList *temp_devices; /* List of devices whichi will be temporary and \
56                                 will be cleared in the end of addition \
57                                 uam_db_device_info_t */
58
59 static GSList *monitors; /* List of monitoring apps - uam_monitor_info_t */
60 static GSList *scanners; /* List of scanning apps -  uam_scanner_info_t */
61
62 static guint detection_timer = 0;
63 static unsigned int detection_window;
64 static unsigned int detecting_sensors = 0;
65
66 /* Utility functions to print */
67 static void __print_service(gpointer data, gpointer user_data)
68 {
69         uam_db_service_info_t *service = data;
70         uam_db_tech_info_t *tech = user_data;
71
72         ret_if(NULL == tech);
73         ret_if(NULL == service);
74
75         UAM_DBG("DevId: %s, Type: %d, Svc: %s, Cycle: %d",
76                         tech->device->device_id, tech->tech_type,
77                         service->name, service->cycle);
78 }
79
80 static void __print_svc_dev(gpointer data, gpointer user_data)
81 {
82         uam_svc_dev_info_t *svc_dev = data;
83
84         ret_if(NULL == svc_dev);
85
86         UAM_DBG("DevId: %s, Svc: %s, payload primary key: %d",
87                         svc_dev->device_id, svc_dev->service,
88                         svc_dev->payload->primary_key);
89 }
90
91 void __print_payload(const uam_ble_payload_s *payload)
92 {
93         ret_if(NULL == payload);
94         int user_data_len = UAM_BLE_PAYLOAD_DEVICE_UID_MAX_LEN - 1 - payload->device_uid_len;
95
96         UAM_DBG("Payload primary key: [0x%2.2X], secondary_key: [0x%2.2X], " \
97                 "device_type: [0x%2.2X] device uid len: [%d]",
98                 payload->primary_key, payload->secondary_key, payload->device_type,
99                 payload->device_uid_len);
100
101         for (int i = 0; i < payload->device_uid_len; i++)
102                 UAM_DBG("Device uid [0x%2.2X]", payload->device_uid[i]);
103
104         for (int i = 0; i < user_data_len; i++)
105                 UAM_DBG("User data [0x%2.2X]", payload->user_data[i]);
106 }
107
108 void __print_db_payload(const uam_db_payload_info_t *payload)
109 {
110         ret_if(NULL == payload);
111
112         int user_data_len = UAM_BLE_PAYLOAD_DEVICE_UID_MAX_LEN - 1 - payload->device_uid_len;
113
114         UAM_DBG("Payload primary key: [0x%2.2X], secondary_key: [0x%2.2X], " \
115                 "device type: [0x%2.2X] device uid len: [%d]",
116                 payload->primary_key, payload->secondary_key, payload->device_type,
117                 payload->device_uid_len);
118
119         for (int i = 0; i < payload->device_uid_len; i++)
120                 UAM_DBG("Device uid [0x%2.2X]", payload->device_uid[i]);
121
122         for (int i = 0; i < user_data_len; i++)
123                 UAM_DBG("User data [0x%2.2X]", payload->user_data[i]);
124 }
125
126 /* Utility functions to compare */
127 static gint __compare_user_account(gconstpointer data, gconstpointer user_data)
128 {
129         const uam_db_user_info_t *user = data;
130         const char *account = user_data;
131
132         retv_if(NULL == user, -1);
133         retv_if(NULL == user->account, -1);
134         retv_if(NULL == account, -1);
135
136         return g_strcmp0(user->account, account);
137 }
138
139 static gint __compare_user(gconstpointer data, gconstpointer user_data)
140 {
141         const uam_db_user_info_t *user = data;
142         const uam_db_user_info_t *temp_user = user_data;
143
144         retv_if(NULL == user, -1);
145         retv_if(NULL == user->account, -1);
146         retv_if(NULL == temp_user, -1);
147         retv_if(NULL == temp_user->account, -1);
148
149         UAM_DBG("user list app_num %d account %s " \
150                         "temp user app_num %d account %s",
151                         user->app_num, user->account,
152                         temp_user->app_num, temp_user->account);
153
154         if (user->app_num != temp_user->app_num)
155                 return -1;
156
157         return g_strcmp0(user->account, temp_user->account);
158 }
159
160 static gint __compare_user_id(gconstpointer data, gconstpointer user_data)
161 {
162         const uam_db_user_info_t *user = data;
163         const int *id = user_data;
164
165         retv_if(NULL == user, -1);
166         retv_if(NULL == user->account, -1);
167         retv_if(NULL == id, -1);
168
169         UAM_INFO("[%d][%d]", *id, user->user_id);
170
171         if (*id != user->user_id)
172                 return -1;
173
174         return 0;
175 }
176
177 static gint __compare_service(gconstpointer data, gconstpointer user_data)
178 {
179         const uam_db_service_info_t *service = data;
180         const uam_db_service_info_t *tmp = user_data;
181
182         retv_if(NULL == service, -1);
183         retv_if(NULL == service->name, -1);
184         retv_if(NULL == tmp, -1);
185         retv_if(NULL == tmp->name, -1);
186
187         if (service->app_num == tmp->app_num)
188                 return g_strcmp0(service->name, tmp->name);
189         else
190                 return -1;
191 }
192
193 static gint __compare_svc_user(gconstpointer data, gconstpointer user_data)
194 {
195         const uam_svc_user_info_t *svc_user = data;
196         const uam_svc_user_info_t *tmp_svc_user = user_data;
197
198         retv_if(NULL == svc_user, -1);
199         retv_if(NULL == tmp_svc_user, -1);
200         retv_if(NULL == svc_user->svc_name, -1);
201         retv_if(NULL == tmp_svc_user->svc_name, -1);
202         retv_if(NULL == svc_user->account, -1);
203         retv_if(NULL == tmp_svc_user->account, -1);
204
205         if (g_strcmp0(svc_user->svc_name, tmp_svc_user->svc_name) == 0)
206                 if (g_strcmp0(svc_user->account, tmp_svc_user->account) == 0)
207                         return svc_user->app_num ==  tmp_svc_user->app_num ? 0 : -1;
208                 else
209                         return -1;
210         else
211                 return -1;
212 }
213
214 static gint __compare_svc_user_account(gconstpointer data, gconstpointer user_data)
215 {
216         const uam_svc_user_info_t *svc_user = data;
217         const uam_db_user_info_t *user = user_data;
218
219         retv_if(NULL == svc_user, -1);
220         retv_if(NULL == user, -1);
221
222         if (g_strcmp0(svc_user->account, user->account) == 0)
223                 return svc_user->app_num == user->app_num ? 0 : -1;
224         else
225                 return -1;
226 }
227
228 static gint __compare_payload(gconstpointer data, gconstpointer user_data)
229 {
230         const uam_db_payload_info_t *db_payload = data;
231         const uam_ble_payload_s *payload = user_data;
232
233         __print_payload(payload);
234         __print_db_payload(db_payload);
235
236         retv_if(NULL == db_payload, -1);
237         retv_if(NULL == payload, -1);
238
239         if ((db_payload->primary_key == payload->primary_key) &&
240                 (db_payload->secondary_key == payload->secondary_key) &&
241                 (db_payload->device_uid_len == payload->device_uid_len) &&
242                 (0 == memcmp(db_payload->device_uid, payload->device_uid,
243                         payload->device_uid_len)))
244                 return 0;
245
246         return -1;
247 }
248
249 static gint __compare_device(gconstpointer data, gconstpointer user_data)
250 {
251         FUNC_ENTRY;
252         const uam_db_device_info_t *device = data;
253         const uam_db_device_info_t *temp_device = user_data;
254
255         retv_if(NULL == device, -1);
256         retv_if(NULL == device->device_id, -1);
257         retv_if(NULL == temp_device, -1);
258         retv_if(device->app_num != temp_device->app_num, -1);
259
260         FUNC_EXIT;
261         return g_strcmp0(device->device_id, temp_device->device_id);
262 }
263
264 static gint __compare_device_id(gconstpointer data, gconstpointer user_data)
265 {
266         FUNC_ENTRY;
267         const uam_db_device_info_t *device = data;
268         const char *dev_id = user_data;
269
270         retv_if(NULL == device, -1);
271         retv_if(NULL == device->device_id, -1);
272         retv_if(NULL == dev_id, -1);
273
274         FUNC_EXIT;
275         return g_strcmp0(device->device_id, dev_id);
276 }
277
278 static gint __compare_device_id_and_appnum(gconstpointer data, gconstpointer user_data)
279 {
280         FUNC_ENTRY;
281         const uam_db_device_info_t *device = data;
282         const uam_device_info_s *dev_info = user_data;
283
284         retv_if(NULL == device, -1);
285         retv_if(NULL == device->device_id, -1);
286         retv_if(NULL == dev_info->device_id, -1);
287         retv_if(device->app_num != dev_info->app_num, -1);
288
289         FUNC_EXIT;
290         return g_strcmp0(device->device_id, dev_info->device_id);
291 }
292
293 static gint __compare_tech_type(gconstpointer data, gconstpointer user_data)
294 {
295         FUNC_ENTRY;
296         const uam_db_tech_info_t *tech = data;
297         const int *type = user_data;
298
299         retv_if(NULL == tech, -1);
300         retv_if(NULL == type, -1);
301
302         FUNC_EXIT;
303         return ((*type == tech->tech_type) ? 0 : 1);
304 }
305
306 static gint __compare_app_key(gconstpointer data, gconstpointer user_data)
307 {
308         const uam_sender_app_t *app_data = data;
309         const char *app_key = user_data;
310
311         retv_if(NULL == app_data, -1);
312         retv_if(NULL == app_data->app_key, -1);
313         retv_if(NULL == app_key, -1);
314
315         return g_strcmp0(app_data->app_key, app_key);
316 }
317
318 /* Utility functions to get pm info */
319 unsigned int _uam_core_get_env_sensors()
320 {
321         return _uam_pm_get_env_sensors();
322 }
323
324 unsigned int _uam_core_get_user_sensors()
325 {
326         return _uam_pm_get_user_sensors();
327 }
328
329 /* Utility functions to free memory */
330 static void __free_address_info(gpointer data)
331 {
332         FUNC_ENTRY;
333         uam_db_address_info_t *addr = data;
334
335         ret_if(NULL == addr);
336
337         g_free(addr->address);
338         g_free(addr);
339
340         FUNC_EXIT;
341 }
342
343 static void __free_dev_tech_info(gpointer data)
344 {
345         FUNC_ENTRY;
346         uam_db_tech_info_t *tech_info = data;
347         GSList *l;
348
349         ret_if(NULL == tech_info);
350
351         /* Delete the tech information from the service list that includes tech. */
352         for (l = tech_info->svc_list; NULL != l; l = g_slist_next(l)) {
353                 uam_db_service_info_t *svc_info = l->data;
354
355                 if (!svc_info || !svc_info->dev_techs)
356                         continue;
357
358                 svc_info->dev_techs = g_slist_remove(svc_info->dev_techs, tech_info);
359         }
360
361         g_slist_free_full(tech_info->addresses, __free_address_info);
362         tech_info->addresses = NULL;
363
364         g_free(tech_info);
365
366         FUNC_EXIT;
367 }
368
369 static void __free_user_device(gpointer data)
370 {
371         FUNC_ENTRY;
372         uam_db_device_info_t *device = data;
373         ret_if(NULL == device);
374         /* Remove device data from global device list */
375         devices = g_slist_remove(devices, device);
376
377         /* Free allocated memory */
378         g_free(device->device_id);
379
380         g_slist_free_full(device->tech_list, __free_dev_tech_info);
381
382         g_free(device);
383
384         FUNC_EXIT;
385 }
386
387 static void __free_user_info(gpointer data)
388 {
389         FUNC_ENTRY;
390         uam_db_user_info_t *user = data;
391
392         ret_if(NULL == user);
393
394         g_free(user->name);
395         g_free(user->account);
396         g_free(user);
397         FUNC_EXIT;
398 }
399
400 static void __free_service_info(gpointer data)
401 {
402         FUNC_ENTRY;
403         uam_db_service_info_t *svc = data;
404
405         ret_if(NULL == svc);
406
407         g_free(svc->name);
408         g_free(svc);
409         FUNC_EXIT;
410 }
411
412 static void __free_monitor_info(gpointer data)
413 {
414         FUNC_ENTRY;
415         uam_monitor_info_t *monitor = data;
416
417         ret_if(NULL == monitor);
418
419         g_free(monitor->name);
420         g_free(monitor);
421         FUNC_EXIT;
422 }
423
424 static void __free_scanner_info(gpointer data)
425 {
426         FUNC_ENTRY;
427         uam_scanner_info_t *scanner = data;
428
429         ret_if(NULL == scanner);
430
431         g_free(scanner->name);
432         g_free(scanner);
433         FUNC_EXIT;
434 }
435
436 /* Utility functions to copy */
437 static void __uam_core_copy_addr(uam_device_info_s *device, uam_db_address_info_t *addr)
438 {
439         switch (addr->addr_type) {
440         case UAM_ADDR_TYPE_BLE:
441         case UAM_ADDR_TYPE_BT:
442         case UAM_ADDR_TYPE_P2P:
443         case UAM_ADDR_TYPE_WIFI:
444         case UAM_ADDR_TYPE_UWB:
445                 g_strlcpy(device->mac, addr->address,
446                                 UAM_MAC_ADDRESS_STRING_LEN);
447                 break;
448         case UAM_ADDR_TYPE_IPv4:
449                 g_strlcpy(device->ipv4_addr,
450                                 addr->address,
451                                 UAM_IP_ADDRESS_MAX_STRING_LEN);
452                 break;
453         default:
454                 UAM_WARN("Unknown address type %d", addr->addr_type);
455         }
456 }
457
458 static int __copy_tech_info_to_device_info(uam_db_tech_info_t *tech, uam_device_info_s *device)
459 {
460         FUNC_ENTRY;
461         GSList *l;
462
463         retv_if(NULL == tech, UAM_ERROR_INVALID_PARAMETER);
464
465         memset(device, 0x00, sizeof(uam_device_info_s));
466         for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
467                 uam_db_address_info_t *addr = l->data;
468
469                 if (!addr)
470                         continue;
471
472                 __uam_core_copy_addr(device, addr);
473         }
474
475         device->operating_system = tech->os;  // make it display the tech->os as the device->os
476         g_strlcpy(device->device_id, tech->device->device_id,
477                 UAM_DEVICE_ID_MAX_STRING_LEN);
478         device->type = tech->tech_type;
479         device->discriminant = tech->discriminant;
480         device->last_seen = tech->last_seen;
481         device->app_num = tech->device->app_num;
482
483         FUNC_EXIT;
484         return UAM_ERROR_NONE;
485 }
486
487 static void __uam_copy_db_payload_info(uam_ble_payload_s *dst_payload,
488         uam_db_payload_info_t *src_payload)
489 {
490         FUNC_ENTRY;
491
492         int user_data_len = 0;
493         ret_if(NULL == src_payload);
494
495         dst_payload->primary_key = src_payload->primary_key;
496         dst_payload->device_type = src_payload->device_type;
497         dst_payload->secondary_key = src_payload->secondary_key;
498         dst_payload->ext_val1 = src_payload->ext_val1;
499         dst_payload->ext_val2 = src_payload->ext_val2;
500         dst_payload->device_uid_len = src_payload->device_uid_len;
501
502         memset(dst_payload->device_uid, 0, src_payload->device_uid_len);
503         if (src_payload->device_uid)
504                 memcpy(dst_payload->device_uid,
505                 src_payload->device_uid, src_payload->device_uid_len);
506
507         user_data_len = UAM_BLE_PAYLOAD_DEVICE_UID_MAX_LEN - 1 - src_payload->device_uid_len;
508         ret_if(0 == user_data_len);
509         memset(dst_payload->user_data, 0, user_data_len);
510         if (src_payload->user_data)
511                 memcpy(dst_payload->user_data,
512                 src_payload->user_data, user_data_len);
513
514         FUNC_EXIT;
515         return;
516 }
517
518 static void __uam_copy_uam_payload_info(
519                 uam_db_payload_info_t *dst_payload, uam_ble_payload_s *src_payload)
520 {
521         FUNC_ENTRY;
522
523         int user_data_len = 0;
524         ret_if(NULL == src_payload);
525
526         dst_payload->primary_key = src_payload->primary_key;
527         dst_payload->device_type = src_payload->device_type;
528         dst_payload->secondary_key = src_payload->secondary_key;
529         dst_payload->ext_val1 = src_payload->ext_val1;
530         dst_payload->ext_val2 = src_payload->ext_val2;
531         dst_payload->device_uid_len = src_payload->device_uid_len;
532         dst_payload->device_uid = g_memdup2(&(src_payload->device_uid),
533                                 src_payload->device_uid_len);
534
535         user_data_len = UAM_BLE_PAYLOAD_DEVICE_UID_MAX_LEN - 1 - src_payload->device_uid_len;
536         ret_if(0 == user_data_len);
537         dst_payload->user_data = g_memdup2(&(src_payload->user_data),
538                                 user_data_len);
539
540         FUNC_EXIT;
541         return;
542 }
543
544 static void __uam_copy_uam_db_service_info(
545                 uam_service_info_s *dst, uam_db_service_info_t *src)
546 {
547         FUNC_ENTRY;
548         ret_if(NULL == src);
549         ret_if(NULL == dst);
550
551         memset(dst, 0x00, sizeof(uam_service_info_s));
552         g_strlcpy(dst->name, src->name, UAM_SERVICE_MAX_STRING_LEN);
553         dst->presence_threshold = src->presence_threshold;
554         dst->absence_threshold = src->absence_threshold;
555         dst->app_num = src->app_num;
556
557         return;
558 }
559
560 static void __uam_copy_uam_service_info(
561                 uam_db_service_info_t *dst, uam_service_info_s *src)
562 {
563         FUNC_ENTRY;
564         ret_if(NULL == src);
565         ret_if(NULL == dst);
566
567         dst->name = g_strdup(src->name);
568         dst->presence_threshold = src->presence_threshold;
569         dst->absence_threshold = src->absence_threshold;
570         dst->app_num = src->app_num;
571
572         return;
573 }
574
575 static void __uam_copy_db_service_info(
576                 uam_db_service_info_t *dst, db_service_info_t *src)
577 {
578         FUNC_ENTRY;
579         ret_if(NULL == src);
580         ret_if(NULL == dst);
581
582         dst->name = g_strdup(src->service_name);
583         dst->presence_threshold = src->presence_threshold;
584         dst->absence_threshold = src->absence_threshold;
585         dst->app_num = src->app_num;
586         dst->cycle = src->cycle;
587
588         return;
589 }
590
591 /* Utility functions to search */
592 GSList* __search_service(GSList* list, const char *svc_name, int app_num)
593 {
594         /* Search user in existing user list */
595         GSList *l;
596         uam_db_service_info_t *temp_svc;
597
598         temp_svc = g_new0(uam_db_service_info_t, 1);
599         temp_svc->name = g_strdup(svc_name);
600         temp_svc->app_num = app_num;
601
602         l = g_slist_find_custom(list, temp_svc, __compare_service);
603
604         g_free(temp_svc->name);
605         g_free(temp_svc);
606
607         return l;
608 }
609
610 GSList* __search_user(const char *account, int app_num)
611 {
612         /* Search user in existing user list */
613         GSList *l;
614         uam_db_user_info_t *temp_user;
615
616         temp_user = g_new0(uam_db_user_info_t, 1);
617         temp_user->account = g_strdup(account);
618         temp_user->app_num = app_num;
619
620         l = g_slist_find_custom(users, temp_user, __compare_user);
621
622         free_n_null(&(temp_user->account));
623         free_n_null(&temp_user);
624
625         return l;
626 }
627
628 GSList* __search_svc_user(const char* svc_name, const char* account, int app_num)
629 {
630         GSList* l;
631
632         uam_svc_user_info_t *svc_user;
633
634         svc_user = g_new0(uam_svc_user_info_t, 1);
635         svc_user->svc_name = g_strdup(svc_name);
636         svc_user->account = g_strdup(account);
637         svc_user->app_num = app_num;
638
639         l = g_slist_find_custom(svc_users, svc_user, __compare_svc_user);
640
641         free_n_null(&(svc_user->svc_name));
642         free_n_null(&(svc_user->account));
643         free_n_null(&svc_user);
644
645         return l;
646 }
647
648 GSList* __search_device(const char *device_id, int app_num)
649 {
650         /* Search device in existing device list */
651         GSList *l;
652         uam_db_device_info_t *temp_dev;
653
654         temp_dev = g_new0(uam_db_device_info_t, 1);
655         temp_dev->device_id = g_strdup(device_id);
656         temp_dev->app_num = app_num;
657
658         l = g_slist_find_custom(devices, temp_dev, __compare_device);
659         free_n_null(&(temp_dev->device_id));
660         free_n_null(&temp_dev);
661
662         return l;
663 }
664
665 static gboolean __is_mac_addr(uam_addr_type_e addr_type)
666 {
667         if (addr_type == UAM_ADDR_TYPE_BT ||
668                 addr_type == UAM_ADDR_TYPE_BLE ||
669                 addr_type == UAM_ADDR_TYPE_WIFI ||
670                 addr_type == UAM_ADDR_TYPE_UWB ||
671                 addr_type == UAM_ADDR_TYPE_P2P)
672                 return 1;
673         return 0;
674 }
675
676 static char *__get_mac_addr(uam_db_tech_info_t *tech)
677 {
678         FUNC_ENTRY;
679         GSList *l;
680
681         retv_if(NULL == tech, NULL);
682
683         for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
684                 uam_db_address_info_t *addr = l->data;
685
686                 if (!addr)
687                         continue;
688
689                 if (__is_mac_addr(addr->addr_type))
690                         return addr->address;
691         }
692
693         FUNC_EXIT;
694         return NULL;
695 }
696
697 static uam_monitor_info_t *__uam_find_monitor(GSList *monitor_list,
698                 const char *name, const char *svc_name, uam_pm_detection_mode_e mode, const int app_num)
699 {
700 //      FUNC_ENTRY;
701         GSList *l;
702
703         retv_if(NULL == name, NULL);
704         retv_if(NULL == monitor_list, NULL);
705
706         for (l = monitor_list; NULL != l; l = g_slist_next(l)) {
707                 uam_monitor_info_t *monitor = l->data;
708
709                 if (!monitor || !monitor->name ||
710                                 !monitor->service || !monitor->service->name)
711                         continue;
712
713                 if ((mode == monitor->mode) &&
714                                 (0 == g_strcmp0(monitor->name, name)) &&
715                                 (0 == g_strcmp0(monitor->service->name, svc_name)) &&
716                                 (monitor->service->app_num == app_num)) {
717                         UAM_DBG("Monitoring application found in list");
718                         return monitor;
719                 }
720         }
721
722 //      FUNC_EXIT;
723         return NULL;
724 }
725
726 /* Utility functions to convert info */
727 static unsigned int __uam_core_tech_type_to_addr_type(uam_tech_type_e tech_type)
728 {
729         switch (tech_type) {
730         case UAM_TECH_TYPE_BLE:
731                 return UAM_ADDR_TYPE_BLE;
732         case UAM_TECH_TYPE_BT:
733                 return UAM_ADDR_TYPE_BT;
734         case UAM_TECH_TYPE_P2P:
735                 return UAM_ADDR_TYPE_P2P;
736         case UAM_TECH_TYPE_WIFI:
737                 return UAM_ADDR_TYPE_WIFI;
738         case UAM_TECH_TYPE_WIFI_LOCATION:
739                 return UAM_ADDR_TYPE_WIFI;
740         case UAM_TECH_TYPE_UWB:
741                 return UAM_ADDR_TYPE_UWB;
742         default:
743                 UAM_ERR("Unknown tech type: %d", tech_type);
744                 return 0;
745         }
746 }
747
748 static unsigned int __uam_core_sensor_to_tech_type(unsigned int sensor)
749 {
750         switch (sensor) {
751         case UAM_SENSOR_BITMASK_BLE:
752                 return UAM_TECH_TYPE_BLE;
753         case UAM_SENSOR_BITMASK_WIFI:
754                 return UAM_TECH_TYPE_WIFI;
755         case UAM_SENSOR_BITMASK_WIFI_LOCATION:
756                 return UAM_TECH_TYPE_WIFI_LOCATION;
757         case UAM_SENSOR_BITMASK_UWB:
758                 return UAM_TECH_TYPE_UWB;
759         default:
760                 UAM_ERR("Unknown sensor: %d", sensor);
761                 return 0;
762         }
763 }
764
765 static unsigned int __uam_core_tech_type_to_sensor(unsigned int tech_type)
766 {
767         switch (tech_type) {
768         case UAM_TECH_TYPE_BLE:
769                 return UAM_SENSOR_BITMASK_BLE;
770         case UAM_TECH_TYPE_WIFI:
771                 return UAM_SENSOR_BITMASK_WIFI;
772         case UAM_TECH_TYPE_WIFI_LOCATION:
773                 return UAM_SENSOR_BITMASK_WIFI_LOCATION;
774         case UAM_TECH_TYPE_UWB:
775                 return UAM_SENSOR_BITMASK_UWB;
776         default:
777                 UAM_ERR("Unknown tech type: %d", tech_type);
778                 return 0;
779         }
780 }
781
782 /* Other Utility functions */
783 static void __send_device_event(int err, int event, const uam_device_info_s *dev_info)
784 {
785         FUNC_ENTRY;
786         char *dest = NULL;
787         GVariant *param;
788
789         UAM_INFO_C("Send %s to applications", _uam_manager_event_to_str(event));
790         /* Send device event to application */
791         param = g_variant_new("(iiisss)",
792                         err,
793                         dev_info->operating_system,
794                         dev_info->type,
795                         dev_info->mac,
796                         dev_info->ipv4_addr,
797                         dev_info->device_id);
798
799         _uam_get_sender_from_app_num(dev_info->app_num, &dest);
800
801         if (UAM_ERROR_NONE != _uam_manager_send_event(dest, event, param))
802                 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
803
804         FUNC_EXIT;
805 }
806
807 static void __add_service_to_dev_tech_mapping(
808                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
809 {
810         FUNC_ENTRY;
811
812         ret_if(NULL == tech);
813         ret_if(NULL == service);
814
815         tech->svc_list = g_slist_append(tech->svc_list, service);
816         service->dev_techs = g_slist_append(service->dev_techs, tech);
817         g_slist_foreach(tech->svc_list, __print_service, tech);
818
819         FUNC_EXIT;
820 }
821
822 static void __add_svc_dev_to_dev_tech_mapping(
823                 uam_db_tech_info_t *tech, uam_svc_dev_info_t *svc_dev)
824 {
825         FUNC_ENTRY;
826
827         ret_if(NULL == tech);
828         ret_if(NULL == svc_dev);
829
830         tech->svc_dev_list = g_slist_append(tech->svc_dev_list, svc_dev);
831         g_slist_foreach(tech->svc_dev_list, __print_svc_dev, NULL);
832
833         FUNC_EXIT;
834 }
835
836 static void __remove_service_to_dev_tech_mapping(
837                 uam_db_tech_info_t *tech, uam_db_service_info_t *service)
838 {
839         FUNC_ENTRY;
840
841         ret_if(NULL == tech);
842         ret_if(NULL == service);
843
844         tech->svc_list = g_slist_remove(tech->svc_list, service);
845         service->dev_techs = g_slist_remove(service->dev_techs, tech);
846         g_slist_foreach(tech->svc_list, __print_service, tech);
847
848         FUNC_EXIT;
849 }
850
851 static int _uam_remove_user_device(uam_db_device_info_t *device)
852 {
853         FUNC_ENTRY;
854         uam_device_info_s dev_info;
855         int user_id;
856         GSList *l;
857         int ret = UAM_ERROR_NONE;
858
859         retv_if(NULL == device, UAM_ERROR_INVALID_PARAMETER);
860         user_id = device->user->user_id;
861
862         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
863         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
864                 uam_db_tech_info_t *tech = l->data;
865
866                 if (!tech)
867                         continue;
868
869                 /* Copy tech info to device info */
870                 ret = __copy_tech_info_to_device_info(tech, &dev_info);
871                 if (UAM_ERROR_NONE != ret) {
872                         UAM_ERR("__copy_tech_info_to_device_info failed");
873                         __uam_db_end_transaction(0);
874                         return ret;
875                 }
876
877                 /* Unregister device from plugin */
878                 ret = _uam_pm_unregister_device(user_id, &dev_info);
879                 if (UAM_ERROR_NONE != ret)
880                         UAM_ERR("_uam_pm_unregister_device failed with %s",
881                                         _uam_manager_error_to_str(ret));
882
883                 /* Send device removed event to application */
884                 __send_device_event(UAM_ERROR_NONE, UAM_EVENT_DEVICE_REMOVED, &dev_info);
885
886                 /* Remove device from database */
887                 ret = _uam_device_db_delete_device_info(
888                                         dev_info.device_id, dev_info.type, dev_info.mac, dev_info.app_num);
889                 if (UAM_ERROR_NONE != ret) {
890                         UAM_ERR("_uam_device_db_delete_device_info failed");
891                         __uam_db_end_transaction(0);
892                         return ret;
893                 }
894         }
895         __uam_db_end_transaction(1);
896
897         FUNC_EXIT;
898         return ret;
899 }
900
901 static int __remove_uam_db_user_info(gpointer data)
902 {
903         FUNC_ENTRY;
904         uam_db_user_info_t **ptr = data;
905         uam_db_user_info_t *user = *ptr;
906         GSList *l;
907         int ret = UAM_ERROR_NONE;
908         unsigned int bitmask;
909
910         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
911                 uam_db_device_info_t *device = l->data;
912                 ret = _uam_remove_user_device(device);
913                 if (UAM_ERROR_NONE != ret) {
914                         UAM_ERR("_uam_remove_user_device failed");
915                         return ret;
916                 }
917         }
918
919         g_slist_free_full(user->devices, __free_user_device);
920
921         bitmask = _uam_core_get_user_sensors();
922
923         /* Set/update registered device list to plugins */
924         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices, bitmask))
925                 UAM_ERR("_uam_pm_set_registered_devices failed");
926
927         /* Set/update registered device list to cloud plugin */
928         _uam_cloud_update_registered_devices();
929
930         __free_user_info(user);
931         *ptr = NULL;
932
933         FUNC_EXIT;
934         return ret;
935 }
936
937 static uam_db_tech_info_t *__get_tech_info_by_mac(const char *mac,
938                 const int app_num)
939 {
940         FUNC_ENTRY;
941         GSList *l;
942
943         for (l = devices; NULL != l; l = g_slist_next(l)) {
944                 uam_db_device_info_t *dev = l->data;
945                 GSList *l1;
946
947                 if (!dev || dev->app_num != app_num)
948                         continue;
949
950                 for (l1 = dev->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
951                         uam_db_tech_info_t *tech = l1->data;
952                         GSList *l2;
953
954                         if (!tech)
955                                 continue;
956
957                         for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
958                                 uam_db_address_info_t *addr = l2->data;
959
960                                 if (!addr)
961                                         continue;
962
963                                 if (__is_mac_addr(addr->addr_type) &&
964                                                 !strcasecmp(addr->address, mac)) {
965                                                 UAM_DBG("Device found Mac: %s, type: %d",
966                                                                 addr->address, addr->addr_type);
967                                                 return tech;
968                                         }
969                         }
970                 }
971         }
972
973         FUNC_EXIT;
974         return NULL;
975 }
976
977 static void __get_default_service_name(int app_num, gchar **dest)
978 {
979         gchar buf[UAM_APP_NUM_MAX_LEN];
980         memset(buf, 0x00, sizeof(buf));
981         g_snprintf(buf, UAM_APP_NUM_MAX_LEN, "%d", app_num);
982         *dest = g_strjoin(".", UAM_SERVICE_DEFAULT, buf, NULL);
983 }
984
985 static void __get_default_user(int app_num, gchar **account, gchar **user_name)
986 {
987         gchar buf[UAM_APP_NUM_MAX_LEN];
988         memset(buf, 0x00, sizeof(buf));
989         g_snprintf(buf, UAM_APP_NUM_MAX_LEN, "%d", app_num);
990
991         if (user_name != NULL) {
992                 *user_name = g_strjoin(".", USER_NAME_DEFAULT, buf, NULL);
993                 UAM_INFO("Default username: [%s]", *user_name);
994                 if (account != NULL) {
995                         *account = g_strjoin(NULL, *user_name, USER_ACCOUNT_DEFAULT_SUFFIX, NULL);
996                         UAM_INFO("Default account: [%s]", *account);
997                 }
998         }
999 }
1000
1001 /* Give count of devices matching given details. Mac would be compared if
1002  * non-null, otherwise upto tech_type would be matched.
1003  */
1004 static void _uam_device_match_count(const char *device_id, int tech_type,
1005         const char *mac, int *count)
1006 {
1007         FUNC_ENTRY;
1008         GSList *l;
1009         uam_db_device_info_t *device;
1010         uam_db_tech_info_t *tech;
1011
1012         ret_if(NULL == count);
1013         *count = 0;
1014         ret_if(NULL == device_id);
1015
1016         for (l = devices; l; l = g_slist_next(l)) {
1017                 device = l->data;
1018                 if (!device || !(device->supported_techs & tech_type) ||
1019                                 g_strcmp0(device->device_id, device_id))
1020                         continue;
1021
1022                 if (!mac) {
1023                         (*count)++;
1024                         continue;
1025                 }
1026
1027                 GSList *l1;
1028                 for (l1 = device->tech_list; l1; l1 = g_slist_next(l1)) {
1029                         tech = l1->data;
1030                         GSList *l2;
1031                         if (!tech)
1032                                 continue;
1033
1034                         for (l2 = tech->addresses; l2; l2 = g_slist_next(l2)) {
1035                                 uam_db_address_info_t *addr = l2->data;
1036                                 if (!addr)
1037                                         continue;
1038
1039                                 if (__is_mac_addr(addr->addr_type) &&
1040                                                 !strcasecmp(addr->address, mac))
1041                                                 (*count)++;
1042                         }
1043                 }
1044         }
1045         UAM_DBG("device match count [%d]", *count);
1046         FUNC_EXIT;
1047 }
1048
1049 /* Initial service_user mapping. Here, using user's device list information
1050  * and the service_device mapping, service and user are mapped.
1051  */
1052 static void __init_svc_user_mapping()
1053 {
1054         FUNC_ENTRY;
1055         GSList *l, *ll, *tmp;
1056
1057         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1058
1059                 uam_svc_dev_info_t *svc_dev = l->data;
1060                 char *device_id = svc_dev->device_id;
1061
1062                 /* Search for devices */
1063                 ll = __search_device(device_id, svc_dev->app_num);
1064                 if (NULL == ll)
1065                         continue;
1066
1067                 uam_db_device_info_t *device = ll->data;
1068                 uam_db_user_info_t *user_info = device->user;
1069
1070                 if (!user_info)
1071                         continue;
1072
1073                 tmp = __search_svc_user(svc_dev->service, user_info->account, svc_dev->app_num);
1074                 if (!tmp) {
1075
1076                         uam_svc_user_info_t *svc_user = g_new0(uam_svc_user_info_t, 1);
1077                         svc_user->svc_name = g_strdup(svc_dev->service);
1078                         svc_user->account = g_strdup(user_info->account);
1079                         svc_user->app_num = svc_dev->app_num;
1080
1081                         svc_users = g_slist_prepend(svc_users, svc_user);
1082                 }
1083         }
1084 }
1085
1086 static int __get_uam_db_dev_list_to_uam_dev_list(
1087                 GSList *db_dev_list, uam_device_info_s **device_list,
1088                 int *count, const int app_num)
1089 {
1090         FUNC_ENTRY;
1091         GSList *l;
1092         int indx = 0;
1093         int ret = UAM_ERROR_NONE;
1094
1095         *count = 0;
1096
1097         /* Calculate num devices first */
1098         for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
1099                 uam_db_device_info_t *db_info = l->data;
1100                 GSList *l1;
1101
1102                 if (!db_info || !db_info->device_id || db_info->app_num != app_num)
1103                         continue;
1104
1105                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1106                         uam_db_tech_info_t *tech = l1->data;
1107
1108                         if (!tech || !tech->addresses)
1109                                 continue;
1110
1111                         (*count)++;
1112                 }
1113         }
1114
1115         UAM_INFO("Count = %d", *count);
1116
1117         *device_list = g_new0(uam_device_info_s, *count);
1118
1119         /* Copy devices */
1120         for (l = db_dev_list; NULL != l; l = g_slist_next(l)) {
1121                 uam_db_device_info_t *db_info = l->data;
1122                 GSList *l1;
1123
1124                 if (!db_info || !db_info->device_id || db_info->app_num != app_num)
1125                         continue;
1126
1127                 for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
1128                         uam_db_tech_info_t *tech = l1->data;
1129
1130                         if (!tech || !tech->addresses)
1131                                 continue;
1132
1133                         /* Copy tech info to device info */
1134                         ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
1135                         if (UAM_ERROR_NONE != ret) {
1136                                 UAM_ERR("__copy_tech_info_to_device_info failed");
1137                                 return ret;
1138                         }
1139                         indx++;
1140                 }
1141         }
1142
1143         UAM_INFO("Count = %d, indx = %d", *count, indx);
1144         FUNC_EXIT;
1145         return ret;
1146 }
1147
1148 unsigned int _uam_core_get_active_sensors(int detection_mode)
1149 {
1150         FUNC_ENTRY;
1151         unsigned int sensors = 0;
1152         GSList *l;
1153
1154         retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
1155                         (UAM_DETECT_ABSENCE != detection_mode) &&
1156                         (UAM_DETECT_LOCATION != detection_mode), 0);
1157
1158         for (l = monitors; NULL != l; l = g_slist_next(l)) {
1159                 uam_monitor_info_t *monitor = l->data;
1160
1161                 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
1162                         continue;
1163
1164                 sensors |= monitor->sensors;
1165         }
1166
1167         FUNC_EXIT;
1168         return sensors;
1169 }
1170
1171 unsigned int _uam_core_get_active_env_sensors(int detection_mode)
1172 {
1173         FUNC_ENTRY;
1174         unsigned int sensors = 0;
1175         GSList *l;
1176
1177         retv_if((UAM_DETECT_PRESENCE != detection_mode) &&
1178                         (UAM_DETECT_ABSENCE != detection_mode), 0);
1179
1180         for (l = monitors; NULL != l; l = g_slist_next(l)) {
1181                 uam_monitor_info_t *monitor = l->data;
1182
1183                 if (!monitor || !monitor->name || (detection_mode != monitor->mode))
1184                         continue;
1185
1186                 sensors |= monitor->sensors & _uam_core_get_env_sensors();
1187         }
1188
1189         FUNC_EXIT;
1190         return sensors;
1191 }
1192
1193 static GSList *_uam_core_find_svc_dev_list(uam_device_info_s *dev_info)
1194 {
1195         FUNC_ENTRY;
1196         uam_svc_dev_info_t *svc_dev = NULL;
1197         GSList *l;
1198         GSList *svc_dev_list = NULL;
1199
1200         retv_if(NULL == dev_info, NULL);
1201
1202         /*
1203          * Iterate over the svc_devs and find each service device information
1204          */
1205         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
1206                 svc_dev = l->data;
1207
1208                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
1209                         continue;
1210
1211                 if ((0 == g_strcmp0(svc_dev->device_id, dev_info->device_id)) &&
1212                                 (svc_dev->tech_type == dev_info->type)) {
1213                         svc_dev_list = g_slist_append(svc_dev_list, svc_dev);
1214                         UAM_DBG("Service %s found for device in list",
1215                                                         svc_dev->service);
1216                 }
1217         }
1218
1219         FUNC_EXIT;
1220         return svc_dev_list;
1221 }
1222
1223 void _uam_core_get_app_num_from_app_key(const char* app_key, int *app_num)
1224 {
1225         GSList *l = NULL;
1226         uam_sender_app_t *sender_app = NULL;
1227         GSList *sender_apps = *(_uam_manager_get_sender_apps());
1228
1229         l = g_slist_find_custom(sender_apps, app_key, __compare_app_key);
1230
1231         if (l == NULL) {
1232                 UAM_DBG("App key not found in the list");
1233                 return;
1234         }
1235         sender_app = l->data;
1236         *app_num = sender_app->app_num;
1237         UAM_DBG("app_num is [%d]", *app_num);
1238 }
1239
1240 int __uam_core_get_app_num_from_sec_list_devices(const uam_device_info_s *dev_info)
1241 {
1242         FUNC_ENTRY;
1243         uam_db_device_info_t *temp_device;
1244         GSList *l = NULL;
1245
1246         retv_if(NULL == dev_info, 0);
1247
1248         l = g_slist_find_custom(temp_devices, dev_info->device_id, __compare_device_id);
1249         if (NULL != l) {
1250                 temp_device = l->data;
1251                 return temp_device->app_num;
1252         } else {
1253                 return 0;
1254         }
1255         FUNC_EXIT;
1256 }
1257
1258 static GSList *__convert_db_svc_list_to_uam_svc_list(GSList *db_svc_list)
1259 {
1260         FUNC_ENTRY;
1261         GSList *l;
1262         GSList *svc_list = NULL;
1263
1264         retv_if(NULL == db_svc_list, NULL);
1265
1266         /*
1267          * Iterate over the db_svc_list and add each service to the global
1268          * service list "services" if its not already inserted. Also append this
1269          * uam_db_service_info_t to svc_list.
1270          */
1271         for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
1272                 db_service_info_t *db_svc = l->data;
1273                 uam_db_service_info_t *service;
1274                 GSList *ll;
1275
1276                 if (!db_svc)
1277                         continue;
1278
1279                 ll = __search_service(services, db_svc->service_name, db_svc->app_num);
1280
1281                 if (!ll) {
1282                         service = g_new0(uam_db_service_info_t, 1);
1283                         __uam_copy_db_service_info(service, db_svc);
1284                         services = g_slist_append(services, service);
1285                 } else
1286                         service = ll->data;
1287
1288                 svc_list = g_slist_append(svc_list, service);
1289         }
1290
1291         FUNC_EXIT;
1292         return svc_list;
1293 }
1294
1295 static void __uam_core_add_dev_to_sec_list_devices(const uam_device_info_s *dev_info)
1296 {
1297         FUNC_ENTRY;
1298         uam_db_device_info_t *temp_device;
1299         GSList *l;
1300
1301         ret_if(NULL == dev_info);
1302
1303         /* create a new entry in list if the app_num is different */
1304         l = g_slist_find_custom(temp_devices, dev_info, __compare_device_id_and_appnum);
1305         if (NULL != l) {
1306                 temp_device = l->data;
1307         } else {
1308                 temp_device = g_new0(uam_db_device_info_t, 1);
1309                 temp_device->device_id = g_strdup(dev_info->device_id);
1310                 temp_device->os = dev_info->operating_system;
1311                 temp_device->discriminant = dev_info->discriminant;
1312                 temp_device->app_num = dev_info->app_num;
1313
1314                 /* Add device to global temp_devices list */
1315                 temp_devices = g_slist_prepend(temp_devices, temp_device);
1316         }
1317         temp_device->supported_techs |= dev_info->type;
1318
1319         FUNC_EXIT;
1320 }
1321
1322 static void __uam_core_remove_dev_from_sec_list_devices(
1323                         const uam_device_info_s *dev_info)
1324 {
1325         FUNC_ENTRY;
1326         uam_db_device_info_t *temp_device;
1327         GSList *l = NULL;
1328
1329         ret_if(NULL == dev_info);
1330
1331         l = g_slist_find_custom(temp_devices, dev_info->device_id,
1332                                                 __compare_device_id);
1333         if (NULL != l) {
1334                 temp_device = l->data;
1335
1336                 /* update device */
1337                 temp_device->supported_techs &= ~(dev_info->type);
1338
1339                 if (temp_device->supported_techs == 0) {
1340                         /* Remove device from global temp_devices list */
1341                         temp_devices = g_slist_remove(temp_devices, temp_device);
1342
1343                         /* free memory of temp_device */
1344                         g_free(temp_device->device_id);
1345                         g_free(temp_device);
1346                 }
1347         }
1348
1349         FUNC_EXIT;
1350 }
1351
1352 static void __uam_core_add_dev_to_list(
1353                 uam_db_user_info_t *user, const uam_device_info_s *dev_info,
1354                 int presence_state, unsigned long long last_seen, GSList *svc_list,
1355                 GSList *svc_dev_list)
1356 {
1357         FUNC_ENTRY;
1358         uam_db_tech_info_t *tech;
1359         uam_db_device_info_t *device;
1360         GSList *l;
1361
1362         ret_if(NULL == dev_info);
1363         ret_if(NULL == user);
1364
1365         UAM_DBG("device-id %s", dev_info->device_id);
1366
1367         l = g_slist_find_custom(devices, dev_info->device_id, __compare_device_id);
1368         if (NULL != l) {
1369                 UAM_DBG("The device already exists");
1370                 device = l->data;
1371                 ret_if(user != device->user);
1372                 ret_if(device->supported_techs & dev_info->type);
1373
1374                 if (device->os != dev_info->operating_system) {
1375                         UAM_INFO("device->os: %d, dev_info->operating_system: %d",
1376                                         device->os, dev_info->operating_system);
1377
1378                         /* Update device OS type */
1379                         if (UAM_OS_TYPE_INVALID == device->os)
1380                                 device->os = dev_info->operating_system;
1381                         else
1382                                 UAM_WARN("Strange - OS types did not match, need to check");
1383                 }
1384         } else {
1385                 device = g_new0(uam_db_device_info_t, 1);
1386                 device->device_id = g_strdup(dev_info->device_id);
1387                 device->os = dev_info->operating_system;
1388                 device->discriminant = dev_info->discriminant;
1389                 device->user = user;
1390                 device->app_num = dev_info->app_num;
1391
1392                 /* Add device to global device list */
1393                 devices = g_slist_append(devices, device);
1394
1395                 /* Add same device to user's device list */
1396                 user->devices = g_slist_append(user->devices, device);
1397         }
1398
1399         tech = g_new0(uam_db_tech_info_t, 1);
1400         tech->tech_type = dev_info->type;
1401         tech->os = dev_info->operating_system;
1402         tech->presence_state = presence_state;
1403         tech->last_seen = last_seen;
1404         tech->device = device;
1405         tech->discriminant = dev_info->discriminant;
1406
1407         tech->svc_list = svc_list;
1408         g_slist_foreach(tech->svc_list, __print_service, tech);
1409         for (l = svc_list; NULL != l; l = g_slist_next(l)) {
1410                 uam_db_service_info_t *service = l->data;
1411
1412                 if (!service)
1413                         continue;
1414
1415                 service->dev_techs = g_slist_prepend(service->dev_techs, tech);
1416         }
1417         tech->svc_dev_list = svc_dev_list;
1418         g_slist_foreach(tech->svc_dev_list, __print_svc_dev, NULL);
1419
1420         /* Add tech info to tech list */
1421         device->tech_list = g_slist_append(device->tech_list, tech);
1422         device->supported_techs |= tech->tech_type;
1423         UAM_INFO("device->supported_techs: 0x%8.8X", device->supported_techs);
1424
1425         if (0 < strlen(dev_info->mac)) {
1426                 uam_db_address_info_t *addr;
1427
1428                 addr = g_new0(uam_db_address_info_t, 1);
1429                 if (addr) {
1430                         addr->address = g_strdup(dev_info->mac);
1431                         addr->addr_type = __uam_core_tech_type_to_addr_type(dev_info->type);
1432
1433                         UAM_DBG("MAC address %s added for tech type: %d",
1434                                         dev_info->mac, dev_info->type);
1435                         tech->addresses = g_slist_append(tech->addresses, addr);
1436                 }
1437         }
1438
1439         if (0 < strlen(dev_info->ipv4_addr)) {
1440                 uam_db_address_info_t *addr;
1441
1442                 UAM_DBG("IPv4 address %s added for tech type: %d",
1443                                 dev_info->ipv4_addr, dev_info->type);
1444
1445                 addr = g_new0(uam_db_address_info_t, 1);
1446                 addr->addr_type = UAM_ADDR_TYPE_IPv4;
1447                 addr->address = g_strdup(dev_info->ipv4_addr);
1448
1449                 tech->addresses = g_slist_append(tech->addresses, addr);
1450         }
1451
1452         FUNC_EXIT;
1453 }
1454
1455 int _uam_core_add_user(int *user_id, const char *account, const char *name,
1456                 const int app_num)
1457 {
1458         FUNC_ENTRY;
1459         GSList *l;
1460         uam_db_user_info_t *user;
1461         char *dest = NULL;
1462         int ret = UAM_ERROR_NONE;
1463
1464         retv_if(!user_id, UAM_ERROR_INVALID_PARAMETER);
1465         retv_if(!account, UAM_ERROR_INVALID_PARAMETER);
1466         retv_if(!name, UAM_ERROR_INVALID_PARAMETER);
1467         retv_if(app_num <= 0, UAM_ERROR_INVALID_PARAMETER);
1468
1469         l = __search_user(account, app_num);
1470         retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
1471
1472         user = g_new0(uam_db_user_info_t, 1);
1473         /* Add user to database */
1474         ret = _uam_db_insert_user_info(&(user->user_id), name, account, app_num);
1475         if (UAM_ERROR_NONE != ret) {
1476                 __free_user_info(user);
1477                 UAM_ERR("_uam_db_insert_user_info failed [%d]", ret);
1478                 return ret;
1479         }
1480
1481         user->name = g_strdup(name);
1482         user->account = g_strdup(account);
1483         user->app_num = app_num;
1484         user->devices = NULL;
1485         users = g_slist_append(users, user);
1486
1487         *user_id = user->user_id;
1488         _uam_get_sender_from_app_num(app_num, &dest);
1489
1490         /* Send user added event to application */
1491         if (UAM_ERROR_NONE != _uam_manager_send_event(dest,
1492                                 UAM_EVENT_USER_ADDED, g_variant_new("(iss)",
1493                                 UAM_ERROR_NONE, user->account, user->name)))
1494                 UAM_ERR("Failed to send UAM_EVENT_USER_ADDED");
1495
1496         g_free(dest);
1497
1498         FUNC_EXIT;
1499         return UAM_ERROR_NONE;
1500 }
1501
1502 int _uam_core_remove_user(const char *account, const int app_num)
1503 {
1504         FUNC_ENTRY;
1505         GSList *l;
1506         uam_db_user_info_t *user;
1507         char *dest = NULL;
1508         int ret = UAM_ERROR_NONE;
1509
1510         l = __search_user(account, app_num);
1511         retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
1512         user = l->data;
1513
1514         /* Remove user from database */
1515         ret = _uam_db_delete_by_user_id(user->user_id);
1516         if (UAM_ERROR_NONE != ret) {
1517                 UAM_ERR("_uam_db_delete_by_user_id failed");
1518                 return ret;
1519         }
1520
1521         users = g_slist_remove(users, user);
1522         _uam_get_sender_from_app_num(app_num, &dest);
1523
1524         /* Send user removed event to application */
1525         if (UAM_ERROR_NONE != _uam_manager_send_event(dest,
1526                                 UAM_EVENT_USER_REMOVED, g_variant_new("(iss)",
1527                                 UAM_ERROR_NONE, user->account, user->name)))
1528                 UAM_ERR("Failed to send UAM_EVENT_USER_REMOVED");
1529
1530         ret = __remove_uam_db_user_info((gpointer)&user);
1531         if (UAM_ERROR_NONE != ret)
1532                 UAM_WARN("_free_uam_db_user_info failed");
1533
1534         FUNC_EXIT;
1535         return UAM_ERROR_NONE;
1536 }
1537
1538 int _uam_core_update_user(uam_user_info_s *user)
1539 {
1540         FUNC_ENTRY;
1541         GSList *l;
1542         uam_db_user_info_t *user_info;
1543
1544         retv_if(NULL == user, UAM_ERROR_INVALID_PARAMETER);
1545
1546         /* Retrieve user from list */
1547         l = __search_user(user->account, user->app_num);
1548         retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
1549
1550         user_info = l->data;
1551         g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1552
1553         /* Update user to database */
1554         if (UAM_ERROR_NONE != _uam_db_update_user_info(user_info)) {
1555                 UAM_ERR("_uam_db_update_user_info failed");
1556                 return UAM_ERROR_DB_FAILED;
1557         }
1558
1559         FUNC_EXIT;
1560         return UAM_ERROR_NONE;
1561 }
1562
1563 int _uam_core_add_device(const char *account, uam_device_info_s *dev_info)
1564 {
1565         FUNC_ENTRY;
1566         int ret;
1567         GSList *l;
1568         uam_db_device_info_t *device;
1569         uam_db_user_info_t *user;
1570
1571         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1572         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1573
1574         /* Search user to link with device */
1575         l = __search_user(account, dev_info->app_num);
1576         retv_if(l == NULL, UAM_ERROR_INVALID_PARAMETER);
1577         user = l->data;
1578
1579         /* Search if device already exist */
1580         l = __search_device(dev_info->device_id, dev_info->app_num);
1581         if (NULL != l) {
1582                 UAM_DBG("The device id was found in the current list");
1583                 device = l->data;
1584                 retv_if(user != device->user, UAM_ERROR_ALREADY_REGISTERED);
1585                 retv_if((dev_info->type & device->supported_techs),
1586                                 UAM_ERROR_ALREADY_REGISTERED);
1587                 retv_if(dev_info->app_num != device->app_num, UAM_ERROR_INVALID_PARAMETER);
1588         }
1589
1590         UAM_INFO("device to be added for user_id [%d]", user->user_id);
1591         __uam_core_add_dev_to_sec_list_devices(dev_info);
1592
1593         ret = _uam_pm_register_device(user->user_id, dev_info);
1594         if (UAM_ERROR_NONE != ret) {
1595                 UAM_ERR("_uam_pm_register_device failed with %s",
1596                                 _uam_manager_error_to_str(ret));
1597                 return ret;
1598         }
1599
1600         FUNC_EXIT;
1601         return UAM_ERROR_NONE;
1602 }
1603
1604 int _uam_core_is_device_added(uam_device_info_s *dev, gboolean *is_added)
1605 {
1606         FUNC_ENTRY;
1607         uam_db_device_info_t *device;
1608         GSList *l;
1609
1610         retv_if(NULL == dev, UAM_ERROR_INVALID_PARAMETER);
1611         retv_if(NULL == is_added, UAM_ERROR_INVALID_PARAMETER);
1612
1613         *is_added = FALSE;
1614         l = __search_device(dev->device_id, dev->app_num);
1615         if (NULL == l)
1616                 goto done;
1617
1618         device = l->data;
1619         if (!(device->supported_techs & dev->type))
1620                 goto done;
1621
1622         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
1623                 uam_db_tech_info_t *tech = l->data;
1624                 GSList *l1;
1625
1626                 if (!tech)
1627                         continue;
1628
1629                 if (dev->type != tech->tech_type)
1630                         continue;
1631
1632                 for (l1 = tech->addresses; NULL != l1; l1 = g_slist_next(l1)) {
1633                         uam_db_address_info_t *addr = l1->data;
1634
1635                         if (!addr)
1636                                 continue;
1637
1638                         if (__is_mac_addr(addr->addr_type) &&
1639                                         !strcasecmp(addr->address, dev->mac)) {
1640                                         *is_added = TRUE;
1641                                         break;
1642                                 }
1643                 }
1644                 break;
1645         }
1646
1647 done:
1648         UAM_INFO("Device %s", (*is_added ? "Added" : "Not Added"));
1649         FUNC_EXIT;
1650         return UAM_ERROR_NONE;
1651 }
1652
1653 static int __uam_remove_device(int user_id, uam_db_device_info_t *device,
1654         const uam_device_info_s *dev_info, uam_db_tech_info_t *tech, const int app_num)
1655 {
1656         int ret;
1657         GSList *l;
1658         int count = 0;
1659         unsigned int bitmask;
1660
1661         ret = _uam_db_get_device_services_count(dev_info->device_id,
1662                                 dev_info->type, dev_info->mac, dev_info->app_num, &count);
1663         if (UAM_ERROR_NONE != ret) {
1664                 UAM_ERR("_uam_db_get_device_services_count failed with %s",
1665                                 _uam_manager_error_to_str(ret));
1666                 return ret;
1667         }
1668
1669         if (1 < count) {
1670                 ret = UAM_ERROR_RESOURCE_BUSY;
1671                 UAM_WARN("other service uses this device ref:[%d]", count);
1672                 return ret;
1673         }
1674
1675         _uam_device_match_count(dev_info->device_id, dev_info->type,
1676                 dev_info->mac, &count);
1677         /* If no copies present then remove from plugin too.
1678          * Note: Discriminant is not considered for current logic.
1679          */
1680         if (count == 1) {
1681                 ret = _uam_pm_unregister_device(user_id, dev_info);
1682                 if (UAM_ERROR_NONE != ret) {
1683                         UAM_ERR("_uam_pm_unregister_device failed with %s",
1684                                         _uam_manager_error_to_str(ret));
1685                         return ret;
1686                 }
1687         }
1688
1689         /* Send device removed event to application */
1690         __send_device_event(ret, UAM_EVENT_DEVICE_REMOVED, dev_info);
1691
1692         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
1693         /* Remove device from database */
1694         ret = _uam_device_db_delete_device_info(dev_info->device_id, dev_info->type,
1695                                 dev_info->mac, dev_info->app_num);
1696         if (UAM_ERROR_NONE != ret) {
1697                 UAM_ERR("_uam_device_db_delete_device_info failed");
1698                 __uam_db_end_transaction(0);
1699                 return ret;
1700         }
1701
1702         /* Remove device from service */
1703         for (l = tech->svc_list; l; l = g_slist_next(l)) {
1704                 uam_db_service_info_t *svc = l->data;
1705
1706                 if (!svc || !svc->name)
1707                         continue;
1708                 //TODO: check _uam_core_service_remove_device for app_num updates
1709                 ret = _uam_core_service_remove_device(svc->name,
1710                                 dev_info->device_id, dev_info->type, app_num);
1711                 if (UAM_ERROR_NONE != ret)
1712                         UAM_ERR("_uam_device_db_delete_device_info failed");
1713         }
1714         __uam_db_end_transaction(1);
1715
1716         bitmask = __uam_core_tech_type_to_sensor(tech->tech_type);
1717         /* Remove tech info from device's tech list */
1718         device->tech_list = g_slist_remove(device->tech_list, tech);
1719         device->supported_techs &= ~(tech->tech_type);
1720         UAM_INFO("device->supported_techs: %8.8X", device->supported_techs);
1721         __free_dev_tech_info(tech);
1722
1723         if (UAM_TECH_TYPE_NONE == device->supported_techs) {
1724                 /* Remove device from global device list */
1725                 devices = g_slist_remove(devices, device);
1726
1727                 /* Remove device  from user's device list */
1728                 device->user->devices = g_slist_remove(device->user->devices, device);
1729                 __free_user_device(device);
1730         }
1731
1732
1733         /* Set/update registered device list to plugins */
1734         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices, bitmask))
1735                 UAM_ERR("_uam_pm_set_registered_devices failed");
1736
1737         /* Set/update registered device list to cloud plugin */
1738         _uam_cloud_update_registered_devices();
1739
1740         FUNC_EXIT;
1741         return UAM_ERROR_NONE;
1742 }
1743
1744 int _uam_core_remove_device(const char *account,
1745         const uam_device_info_s *dev_info, const int app_num)
1746 {
1747         FUNC_ENTRY;
1748         int ret;
1749         GSList *l;
1750         uam_db_tech_info_t *tech;
1751         uam_db_device_info_t *device;
1752         uam_db_user_info_t *user;
1753
1754         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
1755         retv_if(NULL == dev_info, UAM_ERROR_INVALID_PARAMETER);
1756
1757         /* Retrieve user from list */
1758         l = __search_user(account, dev_info->app_num);
1759         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1760         user = l->data;
1761
1762         /* Retrieve device from list */
1763         l = __search_device(dev_info->device_id, dev_info->app_num);
1764         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1765         device = l->data;
1766
1767         retv_if(user != device->user, UAM_ERROR_INVALID_PARAMETER);
1768         retv_if(!(device->supported_techs & dev_info->type), UAM_ERROR_INVALID_PARAMETER);
1769
1770         /* Retrieve tech info from list */
1771         l = g_slist_find_custom(device->tech_list,
1772                         &(dev_info->type), __compare_tech_type);
1773         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
1774         tech = l->data;
1775
1776         ret = __uam_remove_device(user->user_id, device, dev_info, tech, app_num);
1777
1778         FUNC_EXIT;
1779         return ret ;
1780 }
1781
1782 int _uam_core_remove_device_by_device_id(const char *device_id,
1783         int tech_type, const int app_num)
1784 {
1785         FUNC_ENTRY;
1786         int ret;
1787         GSList *l;
1788         uam_device_info_s dev_info;
1789         uam_db_tech_info_t *tech;
1790         uam_db_device_info_t *device;
1791
1792         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
1793         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
1794         retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
1795
1796         /* Retrieve device from list */
1797         l = __search_device(device_id, app_num);
1798         retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
1799         device = l->data;
1800         retv_if(!(device->supported_techs & tech_type), UAM_ERROR_NOT_REGISTERED);
1801
1802         /* Retrieve tech info from list */
1803         l = g_slist_find_custom(device->tech_list,
1804                         &tech_type, __compare_tech_type);
1805         retv_if(NULL == l, UAM_ERROR_INTERNAL);
1806         tech = l->data;
1807
1808         /* Get dev_info */
1809         ret = _uam_core_get_devcie_by_device_id(device_id, tech_type, &dev_info, app_num);
1810         retv_if(UAM_ERROR_NONE != ret, UAM_ERROR_NOT_REGISTERED);
1811
1812         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech, dev_info.app_num);
1813
1814         FUNC_EXIT;
1815         return ret;
1816 }
1817
1818 int _uam_core_remove_device_by_mac(const char *mac, const int app_num)
1819 {
1820         FUNC_ENTRY;
1821         uam_db_tech_info_t *tech;
1822         uam_db_device_info_t *device;
1823         uam_device_info_s dev_info;
1824         int ret;
1825
1826         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
1827
1828         tech = __get_tech_info_by_mac(mac, app_num);
1829         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
1830         device = tech->device;
1831
1832         ret = __copy_tech_info_to_device_info(tech, &dev_info);
1833         if (UAM_ERROR_NONE != ret) {
1834                 UAM_ERR("__copy_tech_info_to_device_info failed");
1835                 return ret;
1836         }
1837
1838         ret = __uam_remove_device(device->user->user_id, device, &dev_info, tech, app_num);
1839
1840         FUNC_EXIT;
1841         return ret;
1842 }
1843
1844 int _uam_core_update_device(uam_device_info_s *a_device)
1845 {
1846         FUNC_ENTRY;
1847
1848         int ret = UAM_ERROR_NONE;
1849         GSList *l, *l1, *l2;
1850
1851         uam_device_info_s temp;
1852         uam_db_user_info_t *user = NULL;
1853         uam_db_device_info_t *device = NULL;
1854         uam_db_device_info_t *temp_dev = NULL;
1855         uam_db_tech_info_t *tech = NULL;
1856
1857         temp_dev = g_new0(uam_db_device_info_t, 1);
1858         temp_dev->device_id = a_device->device_id;
1859         temp_dev->app_num = a_device->app_num;
1860         UAM_DBG("temp_device device id %s", temp_dev->device_id);
1861         UAM_DBG("temp_device  app_num is %d", temp_dev->app_num);
1862
1863         /* Find all tech-devices in users' devices */
1864         for (l = users; NULL != l; l = g_slist_next(l)) {
1865                 user = l->data;
1866
1867                 UAM_DBG("user->app_num %d a_device->app_num %d", user->app_num , a_device->app_num);
1868                 if (user->app_num != a_device->app_num)
1869                         continue;
1870
1871                 l1 = g_slist_find_custom(user->devices,
1872                                 temp_dev, __compare_device);
1873                 if (NULL == l1) {
1874                         UAM_DBG("Valid user_id [%d] but Invalid device_id [%s]",
1875                                         user->user_id, a_device->device_id);
1876                         continue;
1877                 }
1878
1879                 device = l1->data;
1880                 if (!(device->supported_techs & a_device->type)) {
1881                         UAM_DBG("Valid device_id [%s] but Invalid tech type [%d]",
1882                                         device->device_id, a_device->type);
1883                         continue;
1884                 }
1885
1886                 /* Update discriminant for devices */
1887                 device->discriminant = a_device->discriminant;
1888
1889                 l2 = g_slist_find_custom(device->tech_list,
1890                                 &(a_device->type), __compare_tech_type);
1891                 if (NULL == l2) {
1892                         UAM_DBG("device->tech_list, tech type [%d] not found", a_device->type);
1893                         continue;
1894                 }
1895
1896                 tech = l2->data;
1897                 if (!tech) {
1898                         UAM_DBG("Device tech is NULL");
1899                         continue;
1900                 }
1901
1902                 /* Update discriminant for device-tech */
1903                 tech->discriminant = a_device->discriminant;
1904                 tech->os = a_device->operating_system;
1905
1906                 /* Update device's updated information to database */
1907                 ret = __copy_tech_info_to_device_info(tech, &temp);
1908
1909                 if (UAM_ERROR_NONE != ret) {
1910                         UAM_ERR("__copy_tech_info_to_device_info failed [%d]", ret);
1911                         goto done;
1912                 }
1913
1914                 ret = _uam_device_db_update_device(temp.device_id, temp.type,
1915                                 temp.mac, temp.ipv4_addr, temp.operating_system, temp.discriminant, temp.app_num);
1916                 if (UAM_ERROR_NONE != ret) {
1917                         UAM_ERR("_uam_device_db_update_device failed [%d]", ret);
1918                         goto done;
1919                 }
1920         }
1921
1922         /* Set/update registered device list to plugins */
1923         ret = _uam_pm_set_registered_devices(devices,
1924                         __uam_core_tech_type_to_sensor(a_device->type));
1925         if (UAM_ERROR_NONE != ret) {
1926                 UAM_ERR("_uam_pm_set_registered_devices failed [%d]", ret);
1927                 goto done;
1928         }
1929
1930         /* Set/update registered device list to cloud plugin */
1931         _uam_cloud_update_registered_devices();
1932
1933 done:
1934         free_n_null(&temp_dev);
1935         FUNC_EXIT;
1936         return ret;
1937 }
1938
1939 int _uam_core_get_default_user(uam_user_info_s *user_info, const int app_num)
1940 {
1941         FUNC_ENTRY;
1942         int ret = UAM_ERROR_NONE;
1943         int user_id;
1944         GSList *l;
1945         uam_db_user_info_t *user;
1946         gchar *default_user_name = NULL;
1947         gchar *default_account_name = NULL;
1948
1949         retv_if(NULL == user_info, UAM_ERROR_INVALID_PARAMETER);
1950         retv_if(app_num <= 0, UAM_ERROR_INVALID_PARAMETER);
1951
1952         __get_default_user(app_num, &default_account_name, &default_user_name);
1953         UAM_DBG("default user account: [%s] name: [%s]",
1954                 default_account_name, default_user_name);
1955
1956         l = __search_user(default_account_name, app_num);
1957         if (NULL == l) {
1958                 ret = _uam_core_add_user(&user_id, default_account_name,
1959                         default_user_name, app_num);
1960
1961                 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
1962                         UAM_ERR("_uam_core_add_user failed with %s", _uam_manager_error_to_str(ret));
1963                         goto done;
1964                 }
1965         } else {
1966                 user = l->data;
1967                 memset(user_info, 0x00, sizeof(uam_user_info_s));
1968                 g_strlcpy(user_info->account, user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
1969                 g_strlcpy(user_info->name, user->name, UAM_USER_NAME_MAX_STRING_LEN);
1970                 user_info->app_num = user->app_num;
1971         }
1972
1973 done:
1974         free_n_null(&default_user_name);
1975         free_n_null(&default_account_name);
1976
1977         FUNC_EXIT;
1978         return ret;
1979 }
1980
1981 int _uam_core_get_users(int *count, uam_user_info_s **user_list,
1982                 const int app_num)
1983 {
1984         FUNC_ENTRY;
1985         guint size = 0;
1986         GSList *l;
1987
1988         for (l = users; l; l = g_slist_next(l)) {
1989                 uam_db_user_info_t *db_info = l->data;
1990                 if (db_info && db_info->app_num == app_num)
1991                         size++;
1992         }
1993
1994         *user_list = g_new0(uam_user_info_s, size);
1995         *count = 0;
1996
1997         /* fetch users list from DB */
1998         for (l = users; l; l = g_slist_next(l)) {
1999                 uam_db_user_info_t *db_info = l->data;
2000
2001                 if (!db_info || !db_info->account || db_info->app_num != app_num)
2002                         continue;
2003
2004                 g_strlcpy((*user_list)[*count].account,
2005                                 db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
2006                 if (db_info->name)
2007                         g_strlcpy((*user_list)[*count].name,
2008                                         db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
2009                 (*user_list)[*count].app_num = db_info->app_num;
2010
2011                 *count += 1;
2012         }
2013
2014         UAM_INFO("Count: %d", *count);
2015         FUNC_EXIT;
2016         return UAM_ERROR_NONE;
2017 }
2018
2019 int _uam_core_get_app_num_from_userid(int user_id, int *app_num)
2020 {
2021         GSList *l;
2022         for (l = users; l; l = g_slist_next(l)) {
2023                 uam_db_user_info_t *db_info = l->data;
2024
2025                 if (!db_info || !db_info->account)
2026                         continue;
2027                 if (db_info->user_id == user_id) {
2028                         *app_num = db_info->app_num;
2029                         break;
2030                 }
2031         }
2032         return UAM_ERROR_NONE;
2033 }
2034
2035 int _uam_core_get_user_by_account(const char *account, uam_user_info_s *user,
2036                 const int app_num)
2037 {
2038         FUNC_ENTRY;
2039         uam_db_user_info_t *db_info;
2040         GSList *l;
2041
2042         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
2043         retv_if(!user, UAM_ERROR_INVALID_PARAMETER);
2044
2045         l = __search_user(account, app_num);
2046         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2047         db_info = l->data;
2048
2049         g_strlcpy(user->account, db_info->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
2050         if (db_info->name)
2051                 g_strlcpy(user->name, db_info->name, UAM_USER_NAME_MAX_STRING_LEN);
2052         user->app_num = db_info->app_num;
2053
2054         FUNC_EXIT;
2055         return UAM_ERROR_NONE;
2056 }
2057
2058 int _uam_core_get_devcie_by_device_id(
2059                 const char *device_id, int tech_type, uam_device_info_s *device, const int app_num)
2060 {
2061         FUNC_ENTRY;
2062         uam_db_device_info_t *db_info;
2063         GSList *l;
2064         GSList *l1;
2065
2066         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2067         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2068         retv_if(UAM_TECH_TYPE_P2P < tech_type, UAM_ERROR_INVALID_PARAMETER);
2069
2070         l = __search_device(device_id, app_num);
2071         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2072         db_info = l->data;
2073         retv_if(!(tech_type & db_info->supported_techs), UAM_ERROR_NOT_FOUND);
2074
2075         memset(device, 0x00, sizeof(uam_device_info_s));
2076
2077         for (l1 = db_info->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
2078                 uam_db_tech_info_t *tech = l1->data;
2079                 GSList *l2;
2080
2081                 if (!tech || !tech->addresses || (tech->tech_type != tech_type))
2082                         continue;
2083
2084                 for (l2 = tech->addresses; NULL != l2; l2 = g_slist_next(l2)) {
2085                         uam_db_address_info_t *addr = l2->data;
2086
2087                         if (!addr)
2088                                 continue;
2089
2090                         __uam_core_copy_addr(device, addr);
2091                 }
2092
2093                 device->operating_system = db_info->os;
2094                 g_strlcpy(device->device_id, db_info->device_id,
2095                                 UAM_DEVICE_ID_MAX_STRING_LEN);
2096                 device->type = tech->tech_type;
2097                 device->discriminant = tech->discriminant;
2098                 device->app_num = db_info->app_num;
2099         }
2100
2101         retv_if(UAM_TECH_TYPE_NONE == device->type, UAM_ERROR_NOT_FOUND);
2102
2103         FUNC_EXIT;
2104         return UAM_ERROR_NONE;
2105 }
2106
2107 int _uam_core_get_device_by_mac(const char *mac, uam_device_info_s *device,
2108                 const int app_num)
2109 {
2110         FUNC_ENTRY;
2111         int ret;
2112         uam_db_tech_info_t *tech;
2113
2114         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
2115
2116         tech = __get_tech_info_by_mac(mac, app_num);
2117         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
2118
2119         ret = __copy_tech_info_to_device_info(tech, device);
2120         if (UAM_ERROR_NONE != ret) {
2121                 UAM_ERR("__copy_tech_info_to_device_info failed");
2122                 return ret;
2123         }
2124
2125         FUNC_EXIT;
2126         return ret;
2127 }
2128
2129 int _uam_core_get_user_by_device_id(const char *device_id,
2130                 uam_user_info_s *user, const int app_num)
2131 {
2132         FUNC_ENTRY;
2133         uam_db_device_info_t *dev;
2134         GSList *l;
2135
2136         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2137         retv_if(!user, UAM_ERROR_INVALID_PARAMETER);
2138
2139         l = __search_device(device_id, app_num);
2140         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2141         dev = l->data;
2142
2143         g_strlcpy(user->account, dev->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
2144         if (dev->user->name)
2145                 g_strlcpy(user->name, dev->user->name, UAM_USER_NAME_MAX_STRING_LEN);
2146         user->app_num = dev->user->app_num;
2147
2148         FUNC_EXIT;
2149         return UAM_ERROR_NONE;
2150 }
2151
2152 int _uam_core_get_user_by_mac(const char *mac, uam_user_info_s *user,
2153                 const int app_num)
2154 {
2155         FUNC_ENTRY;
2156         uam_db_tech_info_t *tech;
2157
2158         retv_if(NULL == mac, UAM_ERROR_INVALID_PARAMETER);
2159
2160         tech = __get_tech_info_by_mac(mac, app_num);
2161         retv_if(NULL == tech, UAM_ERROR_NOT_FOUND);
2162
2163         g_strlcpy(user->account, tech->device->user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
2164         if (tech->device->user->name)
2165                 g_strlcpy(user->name, tech->device->user->name, UAM_USER_NAME_MAX_STRING_LEN);
2166         user->app_num = tech->device->user->app_num;
2167
2168         FUNC_EXIT;
2169         return UAM_ERROR_NONE;
2170 }
2171
2172 int _uam_core_get_devices(int *count, uam_device_info_s **device_list, const int app_num)
2173 {
2174         FUNC_ENTRY;
2175         int ret = UAM_ERROR_NONE;
2176
2177         UAM_DBG("app_num %d", app_num);
2178         ret = __get_uam_db_dev_list_to_uam_dev_list(devices, device_list, count, app_num);
2179
2180         FUNC_EXIT;
2181         return ret;
2182 }
2183
2184 int _uam_core_get_user_devices(const char *account,
2185                 int *count, uam_device_info_s **device_list, const int app_num)
2186 {
2187         FUNC_ENTRY;
2188         uam_db_user_info_t *user;
2189         GSList *l;
2190         int ret = UAM_ERROR_NONE;
2191
2192         l = __search_user(account, app_num);
2193         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2194         user = l->data;
2195
2196         ret = __get_uam_db_dev_list_to_uam_dev_list(user->devices, device_list, count, app_num);
2197
2198         FUNC_EXIT;
2199         return ret;
2200 }
2201
2202 int _uam_core_get_available_sensors(unsigned int *sensor_bitmask)
2203 {
2204         FUNC_ENTRY;
2205
2206         *sensor_bitmask = _uam_pm_get_avaliable_sensors();
2207
2208         FUNC_EXIT;
2209         return UAM_ERROR_NONE;
2210 }
2211
2212 gboolean _uam_core_is_sensor_ready(unsigned int sensor)
2213 {
2214         FUNC_ENTRY;
2215         gboolean is_ready;
2216
2217         is_ready = _uam_pm_is_sensor_ready(sensor);
2218         UAM_DBG("%8.8X is %s", sensor, (is_ready ? "Ready" : "NOT Ready"));
2219
2220         FUNC_EXIT;
2221         return is_ready;
2222 }
2223
2224 static uam_svc_dev_info_t *_uam_core_find_svc_dev_info(const char *device_id,
2225         uam_tech_type_e tech_type, const char *svc_name, const int app_num)
2226 {
2227         FUNC_ENTRY;
2228         uam_svc_dev_info_t *svc_dev = NULL;
2229         GSList *l;
2230
2231         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
2232                 svc_dev = l->data;
2233
2234                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
2235                         continue;
2236
2237                 if ((0 == g_strcmp0(svc_dev->device_id, device_id)) &&
2238                                 (0 == g_strcmp0(svc_dev->service, svc_name)) &&
2239                                 (svc_dev->app_num == app_num) &&
2240                                 (svc_dev->tech_type == tech_type)) {
2241                         UAM_DBG("Service device found in list");
2242                         return svc_dev;
2243                 }
2244         }
2245
2246         FUNC_EXIT;
2247         return NULL;
2248 }
2249
2250 static int _uam_core_update_svc_dev_info(const char *device_id, uam_tech_type_e tech_type,
2251         const char *svc_name, gboolean discriminant, unsigned long long last_seen,
2252         uam_ble_payload_s *payload_info, const int app_num)
2253 {
2254         FUNC_ENTRY;
2255         uam_svc_dev_info_t *svc = NULL;
2256
2257         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2258         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2259         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2260         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2261
2262         svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name, app_num);
2263         if (!svc) {
2264                 svc = g_new0(uam_svc_dev_info_t, 1);
2265                 svc->device_id = g_strdup(device_id);
2266                 svc->app_num = app_num;
2267                 svc->tech_type = tech_type;
2268                 svc->service = g_strdup(svc_name);
2269
2270                 svc->payload = g_new0(uam_db_payload_info_t, 1);
2271                 if (payload_info)
2272                         __uam_copy_uam_payload_info(svc->payload, payload_info);
2273
2274                 svc_devs = g_slist_append(svc_devs, svc);
2275         }
2276
2277         if (discriminant >= 0)
2278                 svc->discriminant = discriminant;
2279         if (last_seen > 0)
2280                 svc->last_seen = last_seen;
2281
2282         /* TODO free existing payload structure */
2283         if (payload_info)
2284                 __uam_copy_uam_payload_info(svc->payload, payload_info);
2285
2286         UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] " \
2287                 "last_seen [%llu] payload primary key [%d] app number [%d]",
2288                 svc->service, svc->device_id, svc->tech_type, svc->discriminant,
2289                 svc->last_seen, svc->payload->primary_key, svc->app_num);
2290
2291         FUNC_EXIT;
2292         return UAM_ERROR_NONE;
2293 }
2294
2295 static int _uam_core_update_svc_dev_info_discriminant(const char *device_id,
2296         uam_tech_type_e tech_type, const char *svc_name, gboolean discriminant, const int app_num)
2297 {
2298         FUNC_ENTRY;
2299         uam_svc_dev_info_t *svc = NULL;
2300
2301         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2302         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2303         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2304         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2305
2306         svc = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name, app_num);
2307         if (!svc) {
2308                 svc = g_new0(uam_svc_dev_info_t, 1);
2309                 svc->device_id = g_strdup(device_id);
2310                 svc->tech_type = tech_type;
2311                 svc->app_num = app_num;
2312                 svc->service = g_strdup(svc_name);
2313                 svc_devs = g_slist_append(svc_devs, svc);
2314         }
2315
2316         svc->discriminant = discriminant;
2317
2318         UAM_DBG("Service [%s] device [%s] tech_type [%d] discriminant [%d] app_num [%d]",
2319                 svc->service, svc->device_id, svc->tech_type, svc->discriminant, svc->app_num);
2320
2321         FUNC_EXIT;
2322         return UAM_ERROR_NONE;
2323 }
2324
2325 int _uam_core_service_add_user(const char *svc_name, const char *account, const int app_num)
2326 {
2327         FUNC_ENTRY;
2328         GSList *l;
2329         int ret = UAM_ERROR_NONE;
2330         uam_db_user_info_t *user;
2331         uam_db_service_info_t *service;
2332
2333         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
2334         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2335
2336         /* Retrieve user from list */
2337         l = __search_user(account, app_num);
2338         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2339         user = l->data;
2340
2341         /* Retrieve service from list */
2342         l = __search_service(services, svc_name, app_num);
2343         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2344
2345         service = l->data;
2346
2347         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2348         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
2349                 uam_db_device_info_t *device = l->data;
2350                 GSList *l1;
2351
2352                 if (!device)
2353                         continue;
2354
2355                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
2356                         uam_db_tech_info_t *tech = l1->data;
2357                         char *mac;
2358                         GSList *l2;
2359
2360                         if (!tech)
2361                                 continue;
2362
2363                         l2 = __search_service(tech->svc_list, svc_name, app_num);
2364                         if (NULL != l2)
2365                                 continue;
2366
2367                         __add_service_to_dev_tech_mapping(tech, service);
2368
2369                         mac = __get_mac_addr(tech);
2370
2371                         /* Insert device service info to db */
2372                         ret = _uam_db_insert_device_service_info(device->device_id,
2373                                                 tech->tech_type, mac, service->name, service->cycle,
2374                                                 device->discriminant, 0, app_num);
2375                         if (UAM_ERROR_NONE != ret) {
2376                                 UAM_WARN("Device service addition to persistent DB failed");
2377                                 __uam_db_end_transaction(0);
2378                                 return ret;
2379                         }
2380
2381                         ret = _uam_core_update_svc_dev_info(device->device_id, tech->tech_type,
2382                                                 service->name, device->discriminant, 0, NULL, app_num);
2383                         if (UAM_ERROR_NONE != ret) {
2384                                 UAM_WARN("Device service addition to service device mapping failed");
2385                                 __uam_db_end_transaction(0);
2386                                 return ret;
2387                         }
2388                 }
2389         }
2390
2391         __uam_db_end_transaction(1);
2392
2393         /* Add service to user mapping */
2394         l = __search_svc_user(svc_name, account, app_num);
2395
2396         if (!l) {
2397                 uam_svc_user_info_t *svc_user = g_new0(uam_svc_user_info_t, 1);
2398                 svc_user->svc_name = g_strdup(svc_name);
2399                 svc_user->account = g_strdup(account);
2400                 svc_user->app_num = app_num;
2401
2402                 svc_users = g_slist_prepend(svc_users, svc_user);
2403         }
2404         else
2405                 UAM_INFO("USER SERVICE MAPPING ALLREADY PRESENT.");
2406
2407         FUNC_EXIT;
2408         return ret;
2409 }
2410
2411 int _uam_core_service_remove_user(const char *svc_name, const char *account, const int app_num)
2412 {
2413         FUNC_ENTRY;
2414         GSList *l;
2415         uam_db_user_info_t *user;
2416         int ret = UAM_ERROR_NONE;
2417
2418         retv_if(NULL == account, UAM_ERROR_INVALID_PARAMETER);
2419         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2420         retv_if(app_num <= 0, UAM_ERROR_INVALID_PARAMETER);
2421
2422         /* Retrieve user from list */
2423         l = __search_user(account, app_num);
2424         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2425
2426         user = l->data;
2427
2428         /* Retrieve service from list */
2429         l = __search_service(services, svc_name, app_num);
2430         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2431
2432         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
2433         for (l = user->devices; NULL != l; l = g_slist_next(l)) {
2434                 uam_db_device_info_t *device = l->data;
2435                 GSList *l1;
2436
2437                 if (!device)
2438                         continue;
2439
2440                 for (l1 = device->tech_list; NULL != l1; l1 = g_slist_next(l1)) {
2441                         uam_db_tech_info_t *tech = l1->data;
2442                         char *mac;
2443                         GSList *l2;
2444
2445                         if (!tech)
2446                                 continue;
2447
2448                         l2 = __search_service(tech->svc_list, svc_name, app_num);
2449                         if (NULL == l2)
2450                                 continue;
2451
2452                         UAM_DBG("Service %s found, remove it from list", svc_name);
2453                         __remove_service_to_dev_tech_mapping(
2454                                         tech, (uam_db_service_info_t *)l2->data);
2455
2456                         mac = __get_mac_addr(tech);
2457                         /* Remove service-device from DB */
2458                         ret = _uam_db_delete_device_service_info(device->device_id,
2459                                         tech->tech_type, mac, svc_name, app_num);
2460                         if (UAM_ERROR_NONE != ret) {
2461                                 UAM_WARN("Device service removal from persistent DB failed");
2462                                 __uam_db_end_transaction(0);
2463                                 return ret;
2464                         }
2465                 }
2466         }
2467
2468         __uam_db_end_transaction(1);
2469
2470         /* Removne service-user mapping from svc_users */
2471
2472         l = __search_svc_user(svc_name, account, app_num);
2473         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2474
2475         uam_svc_user_info_t *svc_user = l->data;
2476         svc_users = g_slist_remove_all(svc_users, svc_user);
2477
2478         g_free(svc_user->svc_name);
2479         g_free(svc_user->account);
2480         g_free(svc_user);
2481
2482         FUNC_EXIT;
2483         return UAM_ERROR_NONE;
2484 }
2485
2486 static uam_db_tech_info_t *__uam_core_get_dev_tech_info(const char *device_id, int tech_type)
2487 {
2488         FUNC_ENTRY;
2489         uam_db_device_info_t *device;
2490         GSList *l;
2491
2492         retv_if(NULL == device_id, NULL);
2493         retv_if(UAM_TECH_TYPE_NONE >= tech_type, NULL);
2494         retv_if(UAM_TECH_TYPE_MAX <= tech_type, NULL);
2495
2496         l = g_slist_find_custom(devices, device_id, __compare_device_id);
2497         if (NULL == l) {
2498                 UAM_DBG("DeviceId [%s] is not in the list", device_id);
2499                 return NULL;
2500         }
2501
2502         device = l->data;
2503         if (!device || !(device->supported_techs & tech_type)) {
2504                 UAM_DBG("Device type [0x%2.2X] for deviceId [%s] not found",
2505                                 tech_type, device_id);
2506                 return NULL;
2507         }
2508
2509         for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
2510                 uam_db_tech_info_t *tech = l->data;
2511
2512                 if (!tech)
2513                         continue;
2514
2515                 if (tech_type == tech->tech_type) {
2516                         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] found",
2517                                         device_id, tech_type);
2518                         return tech;
2519                 }
2520         }
2521
2522         UAM_DBG("DeviceId [%s], Device type [0x%2.2X] not found", device_id, tech_type);
2523         FUNC_EXIT;
2524         return NULL;
2525 }
2526
2527 int _uam_core_service_add_device(const char *svc_name, const char *device_id,
2528         int tech_type, const int app_num)
2529 {
2530         FUNC_ENTRY;
2531         GSList *l;
2532         char *mac;
2533         int ret = UAM_ERROR_NONE;
2534         uam_db_tech_info_t *tech_info;
2535         uam_db_service_info_t *service;
2536         uam_svc_dev_info_t *svc_dev = NULL;
2537
2538         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2539         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2540         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2541         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2542
2543         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
2544         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
2545
2546         l = __search_service(tech_info->svc_list, svc_name, app_num);
2547         retv_if(NULL != l, UAM_ERROR_ALREADY_REGISTERED);
2548
2549         /* Retrieve service from list */
2550         l = __search_service(services, svc_name, app_num);
2551         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2552
2553         service = l->data;
2554
2555         __add_service_to_dev_tech_mapping(tech_info, service);
2556
2557         _uam_core_update_svc_dev_info(device_id, tech_type,
2558                 service->name, -1, -1, NULL, app_num);
2559         svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, service->name, app_num);
2560         __add_svc_dev_to_dev_tech_mapping(tech_info, svc_dev);
2561
2562         mac = __get_mac_addr(tech_info);
2563         /* Insert device service info to db */
2564         ret = _uam_db_insert_device_service_info(device_id, tech_type, mac,
2565                                 service->name, service->cycle, tech_info->discriminant, 0, app_num);
2566         if (UAM_ERROR_NONE != ret) {
2567                 UAM_WARN("Device service addition to persistent DB failed");
2568                 return ret;
2569         }
2570         ret = _uam_core_update_svc_dev_info(device_id, tech_type, service->name,
2571                         tech_info->discriminant, 0, NULL, app_num);
2572         if (UAM_ERROR_NONE != ret) {
2573                 UAM_WARN("Device service addition to svc dev mapping failed");
2574                 return ret;
2575         }
2576
2577         FUNC_EXIT;
2578         return UAM_ERROR_NONE;
2579 }
2580
2581 int _uam_core_service_remove_device(const char *svc_name,
2582         const char *device_id, int tech_type, const int app_num)
2583 {
2584         FUNC_ENTRY;
2585         GSList *l;
2586         char *mac;
2587         uam_db_tech_info_t *tech_info;
2588         int ret = UAM_ERROR_NONE;
2589
2590         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2591         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2592         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2593         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2594
2595         /* Retrieve service from list */
2596         l = __search_service(services, svc_name, app_num);
2597         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2598
2599         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
2600         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
2601
2602         l = __search_service(tech_info->svc_list, svc_name, app_num);
2603         retv_if(NULL == l, UAM_ERROR_NOT_REGISTERED);
2604
2605         __remove_service_to_dev_tech_mapping(tech_info, (uam_db_service_info_t *)l->data);
2606
2607         mac = __get_mac_addr(tech_info);
2608         /* Remove service-device from DB */
2609         ret = _uam_db_delete_device_service_info(
2610                         device_id, tech_type, mac, svc_name, app_num);
2611         if (UAM_ERROR_NONE != ret) {
2612                 UAM_ERR("Device service removal from persistent DB failed");
2613                 return ret;
2614         }
2615
2616         FUNC_EXIT;
2617         return UAM_ERROR_NONE;
2618 }
2619
2620 int _uam_core_service_set_device_discriminant(const char *svc_name,
2621                 const char *device_id, int tech_type, gboolean discriminant, const int app_num)
2622 {
2623         FUNC_ENTRY;
2624         GSList *l;
2625         int ret = UAM_ERROR_NONE;
2626         char *mac;
2627         uam_db_tech_info_t *tech_info;
2628         uam_db_service_info_t *service;
2629
2630         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2631         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2632         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2633         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2634
2635         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
2636         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
2637
2638         /* Retrieve service from list */
2639         l = __search_service(services, svc_name, app_num);
2640         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2641         service = l->data;
2642
2643         mac = __get_mac_addr(tech_info);
2644         /* Insert device service info to db */
2645         ret = _uam_db_update_device_service_discriminant(device_id,
2646                                 tech_type, mac, service->name, discriminant, app_num);
2647         if (UAM_ERROR_NONE != ret) {
2648                 UAM_WARN("Device service discriminant update to persistent DB failed");
2649                 return ret;
2650         }
2651         ret = _uam_core_update_svc_dev_info_discriminant(device_id,
2652                                 tech_type, service->name, discriminant, app_num);
2653         if (UAM_ERROR_NONE != ret) {
2654                 UAM_WARN("Device service discriminant mapping update failed");
2655                 return ret;
2656         }
2657
2658         FUNC_EXIT;
2659         return UAM_ERROR_NONE;
2660 }
2661
2662 int _uam_core_service_get_device_discriminant(const char *svc_name,
2663                 const char *device_id, int tech_type, gboolean *discriminant, const int app_num)
2664 {
2665         FUNC_ENTRY;
2666         uam_svc_dev_info_t *svc_dev;
2667
2668         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2669         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2670         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2671         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2672
2673         svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name, app_num);
2674         retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
2675         *discriminant = (gboolean)svc_dev->discriminant;
2676
2677         FUNC_EXIT;
2678         return UAM_ERROR_NONE;
2679 }
2680
2681 int _uam_core_service_get_device_last_seen(const char *svc_name,
2682                 const char *device_id, int tech_type, unsigned long long *last_seen, const int app_num)
2683 {
2684         FUNC_ENTRY;
2685         uam_svc_dev_info_t *svc_dev;
2686
2687         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2688         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
2689         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
2690         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
2691
2692         svc_dev = _uam_core_find_svc_dev_info(device_id, tech_type, svc_name, app_num);
2693         retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
2694         *last_seen = svc_dev->last_seen;
2695
2696         FUNC_EXIT;
2697         return UAM_ERROR_NONE;
2698 }
2699
2700 int _uam_core_set_service_detection_cycle(const char *svc_name, unsigned int new_cycle, const int app_num)
2701 {
2702         FUNC_ENTRY;
2703         GSList *l;
2704         uam_db_service_info_t *service;
2705         unsigned int elapsed_time;
2706
2707         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2708         retv_if(UAM_DETECTION_CYCLE_MIN > new_cycle, UAM_ERROR_INVALID_PARAMETER);
2709         retv_if(0 != (new_cycle % UAM_DETECTION_CYCLE_MIN), UAM_ERROR_INVALID_PARAMETER);
2710
2711         l = __search_service(services, svc_name, app_num);
2712         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2713         service = l->data;
2714
2715         elapsed_time = service->cycle - service->remaining_time;
2716         service->cycle = new_cycle;
2717
2718         if (service->monitors) {
2719                 UAM_DBG("Detection ongoing, Update service remaining time");
2720                 if (new_cycle < elapsed_time)
2721                         service->remaining_time = 0;
2722                 else
2723                         service->remaining_time = new_cycle - elapsed_time;
2724         }
2725
2726         /* Update service detection cycle in DB */
2727         if (UAM_ERROR_NONE != _uam_db_update_service_cycle(svc_name, new_cycle, app_num))
2728                 UAM_WARN("Service cycle updation to persistent DB failed");
2729
2730         FUNC_EXIT;
2731         return UAM_ERROR_NONE;
2732 }
2733
2734 int _uam_core_get_service_detection_cycle(const char *svc_name, unsigned int *cycle, const int app_num)
2735 {
2736         FUNC_ENTRY;
2737         GSList *l;
2738         uam_db_service_info_t *service;
2739
2740         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2741         retv_if(NULL == cycle, UAM_ERROR_INVALID_PARAMETER);
2742
2743         l = __search_service(services, svc_name, app_num);
2744         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
2745
2746         service = l->data;
2747         *cycle = service->cycle;
2748
2749         FUNC_EXIT;
2750         return UAM_ERROR_NONE;
2751 }
2752
2753 int _uam_core_set_detection_threshold(unsigned int sensor,
2754                 int presence_threshold, int absence_threshold)
2755 {
2756         FUNC_ENTRY;
2757         int ret;
2758
2759         ret = _uam_pm_set_detection_threshold(sensor,
2760                         presence_threshold, absence_threshold);
2761         if (UAM_ERROR_NONE != ret) {
2762                 UAM_ERR("_uam_pm_set_detection_threshold failed with %s",
2763                                 _uam_manager_error_to_str(ret));
2764                 return ret;
2765         }
2766
2767         FUNC_EXIT;
2768         return UAM_ERROR_NONE;
2769 }
2770
2771 static gboolean __start_detection(gpointer data)
2772 {
2773         FUNC_ENTRY;
2774         int ret;
2775         uam_db_service_info_t *service = NULL;
2776         unsigned int sensors;
2777         gboolean start_detection = FALSE;
2778         GSList *l;
2779         unsigned int env_sensors;
2780         unsigned int loc_sensors;
2781
2782         env_sensors = _uam_core_get_active_env_sensors(UAM_DETECT_PRESENCE) |
2783                         _uam_core_get_active_env_sensors(UAM_DETECT_ABSENCE);
2784         UAM_DBG("Active envionmental sensors: 0x%8.8X", env_sensors);
2785
2786         for (l = services; NULL != l; l = g_slist_next(l)) {
2787                 service = l->data;
2788                 if (!service || !service->monitors)
2789                         continue;
2790
2791                 UAM_DBG("service: %s, monitors: %p", service->name, service->monitors);
2792                 UAM_DBG("service->remaining_time: %d", service->remaining_time);
2793                 service->remaining_time -= UAM_DETECTION_CYCLE_MIN;
2794                 if (0 >= service->remaining_time) {
2795                         start_detection = TRUE;
2796                         service->remaining_time = service->cycle;
2797                 }
2798         }
2799
2800         if (!start_detection)
2801                 goto done;
2802
2803         /* Get sensors on which detection to be started */
2804         sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE) |
2805                         _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2806         UAM_DBG("Active sensors: 0x%8.8X", sensors);
2807
2808         /* Remove env sensors from active sensors */
2809         sensors &= ~env_sensors;
2810         UAM_DBG("Active connectivity sensors: 0x%8.8X", sensors);
2811
2812         if (0 != sensors) {
2813                 /* Start detection */
2814                 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE | UAM_DETECT_ABSENCE,
2815                                 sensors);
2816                 if (UAM_ERROR_NONE != ret)
2817                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2818                                         _uam_manager_error_to_str(ret), ret);
2819         }
2820
2821 done:
2822         if (0 != env_sensors) {
2823                 /* continuous monitoring
2824                  * always start detection on active envionmental sensors */
2825                 ret = _uam_pm_start_detection(UAM_DETECT_PRESENCE | UAM_DETECT_ABSENCE,
2826                         env_sensors);
2827                 if (UAM_ERROR_NONE != ret)
2828                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2829                                         _uam_manager_error_to_str(ret), ret);
2830         }
2831
2832         /* location detection */
2833         loc_sensors = _uam_core_get_active_sensors(UAM_DETECT_LOCATION);
2834         UAM_DBG("Active sensors for location detection: 0x%8.8X", loc_sensors);
2835
2836         if (0 != loc_sensors) {
2837                 /* Start location detection */
2838                 ret = _uam_pm_start_detection(UAM_DETECT_LOCATION, loc_sensors);
2839                 if (UAM_ERROR_NONE != ret)
2840                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2841                                         _uam_manager_error_to_str(ret), ret);
2842         }
2843
2844         FUNC_EXIT;
2845         return TRUE;
2846 }
2847
2848 static int __uam_core_start_detection(int detection_type,
2849                 const char *svc_name, char *sender, unsigned int sensors, int app_num)
2850 {
2851         FUNC_ENTRY;
2852         uam_monitor_info_t *monitor;
2853         uam_db_service_info_t *service;
2854         gboolean is_monitor_added = TRUE;
2855         GSList *l;
2856
2857         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2858         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2859
2860         l = __search_service(services, svc_name, app_num);
2861         if (!l)
2862                 UAM_ERR("Service not found");
2863
2864         retv_if(NULL == l, UAM_ERROR_NOT_FOUND);
2865         retv_if(NULL == l->data, UAM_ERROR_INTERNAL);
2866
2867         service = l->data;
2868         monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type, app_num);
2869         if (!monitor) {
2870                 monitor = g_malloc0(sizeof(uam_monitor_info_t));
2871                 if (monitor) {
2872                         monitor->name = g_strdup(sender);
2873                         monitor->mode = detection_type;
2874                         monitor->service = service;
2875                         is_monitor_added = FALSE;
2876                 } else {
2877                         UAM_ERR("Memory allocation error");
2878                         return UAM_ERROR_OUT_OF_MEMORY;
2879                 }
2880         }
2881
2882         UAM_DBG("Name: %s, Service: %s, Mode: %d, App_num: %d", monitor->name, svc_name,
2883                         monitor->mode, app_num);
2884
2885         monitor->sensors |= sensors;
2886         if (!is_monitor_added) {
2887                 monitors = g_slist_append(monitors, monitor);
2888                 service->monitors = g_slist_append(service->monitors, monitor);
2889         }
2890
2891         /* Start detection */
2892         if (0 == detection_timer) {
2893                 __start_detection(NULL);
2894                 UAM_INFO("Monitor started detection, start timer");
2895                 detection_timer = g_timeout_add_seconds(
2896                                 UAM_DETECTION_CYCLE_MIN, __start_detection, NULL);
2897         }
2898
2899         FUNC_EXIT;
2900         return UAM_ERROR_NONE;
2901 }
2902
2903 static int __uam_core_stop_detection(int detection_type,
2904                 const char *svc_name, char *sender, unsigned int sensors, int app_num)
2905 {
2906         FUNC_ENTRY;
2907         int ret = UAM_ERROR_NONE;
2908         unsigned int remaining_sensors;
2909         unsigned int active_sensors;
2910         unsigned int remaining_sensors_loc;
2911         unsigned int active_sensors_loc;
2912         uam_monitor_info_t *monitor;
2913         uam_db_service_info_t *service;
2914
2915         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
2916         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
2917
2918         monitor = __uam_find_monitor(monitors, sender, svc_name, detection_type, app_num);
2919         retv_if(NULL == monitor, UAM_ERROR_NOT_IN_OPERATION);
2920         service = monitor->service;
2921         retv_if(0 != g_strcmp0(service->name, svc_name), UAM_ERROR_NOT_IN_OPERATION);
2922
2923         /* Find sensors which are already monitoring */
2924         active_sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE) |
2925                                 _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2926         active_sensors_loc = _uam_core_get_active_sensors(UAM_DETECT_LOCATION);
2927
2928         UAM_DBG("sensors: 0x%8.8X, Active sensors: 0x%8.8X " \
2929                         "Active sensors location 0x%8.8X",
2930                         sensors, active_sensors, active_sensors_loc);
2931
2932         /* Update monitor info for application */
2933         monitor->sensors &= ~sensors;
2934         if (0 == monitor->sensors) {
2935                 /*
2936                  * App requested to stop monitoring for all of its active sensors,
2937                  * remove its monitor info from list.
2938                  */
2939                 monitors = g_slist_remove(monitors, monitor);
2940                 if ((NULL == monitors) && (0 != detection_timer)) {
2941                         UAM_INFO("All monitors stopped detection, stop timer");
2942                         g_source_remove(detection_timer);
2943                         detection_timer = 0;
2944                 }
2945
2946                 service->monitors = g_slist_remove(service->monitors, monitor);
2947                 if (NULL == service->monitors)
2948                         service->remaining_time = 0;
2949
2950                 g_free(monitor->name);
2951                 g_free(monitor);
2952         }
2953
2954         /* Find sensors which are already monitoring */
2955         remaining_sensors = _uam_core_get_active_sensors(UAM_DETECT_PRESENCE) |
2956                                 _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
2957         remaining_sensors_loc = _uam_core_get_active_sensors(UAM_DETECT_LOCATION);
2958
2959         UAM_DBG("Remaining sensors: 0x%8.8X Remaining sensors location: 0x%8.8X",
2960                         remaining_sensors, remaining_sensors_loc);
2961
2962         /* Stop location detection */
2963         if (detection_type == UAM_DETECT_LOCATION &&
2964                 (active_sensors_loc != remaining_sensors_loc)) {
2965
2966                 ret = _uam_pm_stop_detection(UAM_DETECT_LOCATION,
2967                         active_sensors_loc & ~remaining_sensors_loc);
2968                 if (UAM_ERROR_NONE != ret)
2969                         UAM_ERR("Failed with error: %s (0x%4.4X)",
2970                                         _uam_manager_error_to_str(ret), ret);
2971                 return ret;
2972         }
2973
2974         if (active_sensors == remaining_sensors) {
2975                 UAM_INFO("No need to stop monitoring");
2976                 return UAM_ERROR_NONE;
2977         }
2978
2979         /* Stop monitoring only for sensors which aren't required anymore */
2980         sensors = (active_sensors & ~remaining_sensors);
2981         ret = _uam_pm_stop_detection(UAM_DETECT_PRESENCE | UAM_DETECT_ABSENCE, sensors);
2982         if (UAM_ERROR_NONE != ret)
2983                 UAM_ERR("Failed with error: %s (0x%4.4X)",
2984                                 _uam_manager_error_to_str(ret), ret);
2985
2986         FUNC_EXIT;
2987         return ret;
2988 }
2989
2990 int _uam_core_start_presence_detection(const char *svc_name, char *sender,
2991                 unsigned int sensors, int app_num)
2992 {
2993         FUNC_ENTRY;
2994         int ret;
2995
2996         ret = __uam_core_start_detection(UAM_DETECT_PRESENCE, svc_name,
2997                         sender, sensors, app_num);
2998
2999         FUNC_EXIT;
3000         return ret;
3001 }
3002
3003 int _uam_core_stop_presence_detection(const char *svc_name, char *sender,
3004                 unsigned int sensors, int app_num)
3005 {
3006         FUNC_ENTRY;
3007         int ret;
3008
3009         ret = __uam_core_stop_detection(UAM_DETECT_PRESENCE, svc_name,
3010                         sender, sensors, app_num);
3011
3012         FUNC_EXIT;
3013         return ret;
3014 }
3015
3016 int _uam_core_start_absence_detection(const char *svc_name, char *sender,
3017                 unsigned int sensors, int app_num)
3018 {
3019         FUNC_ENTRY;
3020         int ret;
3021
3022         ret = __uam_core_start_detection(UAM_DETECT_ABSENCE, svc_name, sender,
3023                         sensors, app_num);
3024
3025         FUNC_EXIT;
3026         return ret;
3027 }
3028
3029 int _uam_core_stop_absence_detection(const char *svc_name, char *sender,
3030                 unsigned int sensors, int app_num)
3031 {
3032         FUNC_ENTRY;
3033         int ret;
3034
3035         ret = __uam_core_stop_detection(UAM_DETECT_ABSENCE, svc_name, sender,
3036                         sensors, app_num);
3037
3038         FUNC_EXIT;
3039         return ret;
3040 }
3041
3042 int _uam_core_start_location_detection(const char *svc_name, char *sender,
3043                                                 unsigned int sensors, int app_num)
3044 {
3045         FUNC_ENTRY;
3046         int ret;
3047
3048         ret = __uam_core_start_detection(UAM_DETECT_LOCATION,
3049                                 svc_name, sender, sensors, app_num);
3050
3051         FUNC_EXIT;
3052         return ret;
3053 }
3054
3055 int _uam_core_stop_location_detection(const char *svc_name, char *sender,
3056                                         unsigned int sensors, int app_num)
3057 {
3058         FUNC_ENTRY;
3059         int ret;
3060
3061         ret = __uam_core_stop_detection(UAM_DETECT_LOCATION,
3062                                 svc_name, sender, sensors, app_num);
3063
3064         FUNC_EXIT;
3065         return ret;
3066 }
3067
3068 int _uam_core_set_low_power_mode(unsigned int bitmask, gboolean mode)
3069 {
3070         FUNC_ENTRY;
3071         int ret;
3072
3073         UAM_INFO("bitmask [%x] mode [%d]", bitmask, mode);
3074         ret = _uam_pm_set_low_power_mode(bitmask, mode);
3075         if (UAM_ERROR_NONE != ret) {
3076                 UAM_ERR("_uam_pm_set_low_power_mode failed with [%x] %s",
3077                                 bitmask, _uam_manager_error_to_str(ret));
3078                 return ret;
3079         }
3080
3081         FUNC_EXIT;
3082         return UAM_ERROR_NONE;
3083 }
3084
3085 int _uam_core_get_detection_window(unsigned int *window)
3086 {
3087         FUNC_ENTRY;
3088
3089         retv_if(NULL == window, UAM_ERROR_INVALID_PARAMETER);
3090
3091         *window = detection_window;
3092
3093         FUNC_EXIT;
3094         return UAM_ERROR_NONE;
3095 }
3096
3097 int _uam_core_set_detection_window(unsigned int window)
3098 {
3099         FUNC_ENTRY;
3100
3101         retv_if(0 >= window, UAM_ERROR_INVALID_PARAMETER);
3102         retv_if(UAM_DETECTION_WINDOW_MAX < window, UAM_ERROR_INVALID_PARAMETER);
3103         retv_if(0 != (window % UAM_DETECTION_WINDOW_STEP), UAM_ERROR_INVALID_PARAMETER);
3104
3105         if (UAM_ERROR_NONE != _uam_pm_set_detection_window(window)) {
3106                 UAM_ERR("_uam_pm_set_detection_window(%d) failed", window);
3107                 return UAM_ERROR_INTERNAL;
3108         }
3109
3110         detection_window = window;
3111
3112         FUNC_EXIT;
3113         return UAM_ERROR_NONE;
3114 }
3115
3116 int _uam_core_init(void)
3117 {
3118         FUNC_ENTRY;
3119         GSList *db_users;
3120         GSList *db_devices;
3121         GSList *db_svc_list;
3122         GSList *db_adv_list;
3123         GSList *db_svc_dev_list;
3124         GSList *db_payload_list;
3125         GSList *db_sender_apps;
3126         GSList *l;
3127
3128         /* Init database */
3129         _uam_db_initialize();
3130
3131         /* Reset detecton window to default */
3132         detection_window = UAM_DETECTION_WINDOW_DEFAULT;
3133         if (UAM_ERROR_NONE != _uam_pm_set_detection_window(detection_window))
3134                 UAM_ERR("_uam_pm_set_detection_window(%d) failed", detection_window);
3135
3136         /* Fetch user list */
3137         db_users = _uam_db_get_all_users(-1);
3138         if (!db_users) {
3139                 UAM_INFO_C("No users in database");
3140         } else {
3141                 for (l = db_users; NULL != l; l = g_slist_next(l)) {
3142                         db_user_info_t *info = l->data;
3143                         uam_db_user_info_t *user;
3144
3145                         if (!info)
3146                                 continue;
3147
3148                         user = g_new0(uam_db_user_info_t, 1);
3149                         user->user_id = info->user_id;
3150                         user->name = g_strdup(info->name);
3151                         user->account = g_strdup(info->account);
3152                         user->app_num = info->app_num;
3153                         user->devices = NULL;
3154
3155                         users = g_slist_prepend(users, user);
3156                 }
3157         }
3158
3159         /* Fetch service list */
3160         db_svc_list = _uam_service_db_get_all_services(-1);
3161         if (!db_svc_list) {
3162                 UAM_INFO_C("No services in database");
3163         } else {
3164                 for (l = db_svc_list; NULL != l; l = g_slist_next(l)) {
3165                         db_service_info_t *db_svc = l->data;
3166                         uam_db_service_info_t *service;
3167
3168                         if (!db_svc)
3169                                 continue;
3170                         service = g_new0(uam_db_service_info_t, 1);
3171                         __uam_copy_db_service_info(service, db_svc);
3172                         services = g_slist_append(services, service);
3173                 }
3174         }
3175
3176         /* Fetch payload list */
3177         db_payload_list = _uam_db_get_all_payloads(-1);
3178         if (!db_payload_list) {
3179                 UAM_INFO_C("No device payload in database");
3180         } else {
3181                 for (l = db_payload_list; NULL != l; l = g_slist_next(l)) {
3182                         db_payload_info_t *db_payload = l->data;
3183                         uam_db_payload_info_t *payload;
3184                         GSList *l1 = NULL;
3185
3186                         if (!db_payload)
3187                                 continue;
3188
3189                         l1 = g_slist_find_custom(payloads, &(db_payload->payload_info),
3190                                         __compare_payload);
3191                         if (!l1) {
3192                                 payload = g_new0(uam_db_payload_info_t, 1);
3193                                 __uam_copy_uam_payload_info(payload, &(db_payload->payload_info));
3194                                 payload->device_id = g_strdup(db_payload->device_id);
3195                                 payload->tech_type = db_payload->type;
3196                                 payloads = g_slist_append(payloads, payload);
3197                         }
3198                 }
3199         }
3200
3201         /* Fetch svc dev list */
3202         db_svc_dev_list = _uam_db_get_service_devices_info(-1);
3203         if (!db_svc_dev_list) {
3204                 UAM_INFO_C("No service devices in database");
3205         } else {
3206                 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
3207                         db_svc_dev_info_t *db_svc = l->data;
3208
3209                         _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
3210                                         db_svc->svc, db_svc->discriminant, db_svc->last_seen,
3211                                         &(db_svc->payload_info), db_svc->app_num);
3212                 }
3213         }
3214         g_slist_free_full(db_svc_dev_list, g_free);
3215
3216         db_svc_dev_list = _uam_db_get_service_devices_payloads_info(-1);
3217         if (!db_svc_dev_list) {
3218                 UAM_INFO_C("No service devices payloads in database");
3219         } else {
3220                 for (l = db_svc_dev_list; NULL != l; l = g_slist_next(l)) {
3221                         db_svc_dev_info_t *db_svc = l->data;
3222
3223                         _uam_core_update_svc_dev_info(db_svc->device_id, db_svc->type,
3224                                         db_svc->svc, db_svc->discriminant, db_svc->last_seen,
3225                                         &(db_svc->payload_info), db_svc->app_num);
3226                 }
3227         }
3228
3229         /* Fetch device list */
3230         db_devices = _uam_device_db_get_all_devices(-1);
3231         if (!db_devices) {
3232                 UAM_INFO_C("No Devices registered in database");
3233         } else {
3234                 for (l = db_devices; NULL != l; l = g_slist_next(l)) {
3235                         db_device_info_t *db_info = l->data;
3236                         uam_db_user_info_t *user;
3237                         GSList *svc_list = NULL;
3238                         GSList *svc_dev_list = NULL;
3239                         GSList *l1;
3240
3241                         if (!db_info)
3242                                 continue;
3243
3244                         l1 = g_slist_find_custom(users,
3245                                 &(db_info->user_id), __compare_user_id);
3246                         if (!l1) {
3247                                 UAM_ERR("Invalid user Id: %d", db_info->user_id);
3248                                 continue;
3249                         }
3250                         user = l1->data;
3251                         UAM_DBG("db_info->app_num %d", db_info->app_num);
3252                         UAM_DBG("dev_info.app_num %d", db_info->dev_info.app_num);
3253                         db_info->dev_info.app_num = db_info->app_num;
3254
3255                         /* Fetch device services from DB */
3256                         l1 = _uam_db_get_device_services(
3257                                 db_info->dev_info.device_id,
3258                                 db_info->dev_info.type,
3259                                 db_info->dev_info.mac,
3260                                 db_info->app_num);
3261
3262                         svc_list = __convert_db_svc_list_to_uam_svc_list(l1);
3263
3264                         svc_dev_list = _uam_core_find_svc_dev_list(&(db_info->dev_info));
3265                         __uam_core_add_dev_to_list(user, &(db_info->dev_info),
3266                                 db_info->presence_state, db_info->last_seen,
3267                                 svc_list, svc_dev_list);
3268                 }
3269         }
3270
3271         /* Update user_service_mapping */
3272         __init_svc_user_mapping();
3273
3274         /* Fetch iBeacon adv list */
3275         db_adv_list = _uam_db_get_all_advs(-1);
3276         if (!db_adv_list) {
3277                 UAM_INFO_C("No iBeacon adv in database");
3278         } else {
3279                 for (l = db_adv_list; NULL != l; l = g_slist_next(l)) {
3280                         db_adv_info_t *db_adv = l->data;
3281                         _uam_pm_add_ibeacon_adv(db_adv->adv_len, db_adv->iadv);
3282                 }
3283         }
3284
3285         /* Fetch sender_apps list */
3286         db_sender_apps = _uam_db_get_all_apps();
3287         if (!db_sender_apps) {
3288                 UAM_INFO_C("No sender_apps in database");
3289         } else {
3290                 GSList **sender_apps = _uam_manager_get_sender_apps();
3291                 uam_sender_app_t *sender_app = NULL;
3292                 for (l = db_sender_apps; l; l = g_slist_next(l)) {
3293                         db_app_info_t *db_sender_app = l->data;
3294                         if (!db_sender_app) {
3295                                 UAM_WARN("db_sender_apps list has NULL data element");
3296                                 continue;
3297                         }
3298
3299                         sender_app = g_malloc0(sizeof(uam_sender_app_t));
3300                         if (sender_app) {
3301                                 sender_app->app_num = db_sender_app->app_num;
3302                                 sender_app->app_key = g_strdup(db_sender_app->app_key);
3303                                 *sender_apps = g_slist_prepend(*sender_apps, sender_app);
3304                         } else {
3305                                 UAM_ERR("Memory Allocation error");
3306                                 return UAM_ERROR_OUT_OF_MEMORY;
3307                         }
3308                 }
3309         }
3310
3311
3312         g_slist_free_full(db_devices, g_free);
3313         g_slist_free_full(db_users, g_free);
3314         g_slist_free_full(db_svc_list, g_free);
3315         g_slist_free_full(db_adv_list, g_free);
3316         g_slist_free_full(db_svc_dev_list, g_free);
3317         g_slist_free_full(db_payload_list, g_free);
3318         g_slist_free_full(db_sender_apps, g_free);
3319
3320         if (devices) {
3321                 unsigned int bitmask;
3322                 bitmask = _uam_core_get_user_sensors();
3323
3324                 /* Set/update registered device list to plugins */
3325                 if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices, bitmask))
3326                         UAM_ERR("_uam_pm_set_registered_devices failed");
3327
3328                 /* Set/update registered device list to cloud plugin */
3329                 _uam_cloud_update_registered_devices();
3330         }
3331
3332         FUNC_EXIT;
3333         return UAM_ERROR_NONE;
3334 }
3335
3336 void _uam_core_deinit(void)
3337 {
3338         FUNC_ENTRY;
3339         GSList *l;
3340
3341         /* de-init database */
3342         _uam_db_deinitialize();
3343
3344         /* Reset detecton window to default */
3345         detection_window = UAM_DETECTION_WINDOW_DEFAULT;
3346
3347         /* Release allocated memory for devices */
3348         g_slist_free_full(devices, __free_user_device);
3349         devices = NULL;
3350
3351         /* Release allocated memory for users */
3352         for (l = users; NULL != l; l = g_slist_next(l)) {
3353                 uam_db_user_info_t *user = l->data;
3354
3355                 if (!user)
3356                         continue;
3357
3358                 g_free(user->name);
3359                 g_free(user->account);
3360                 g_free(user);
3361         }
3362
3363         g_slist_free(users);
3364         users = NULL;
3365
3366         /* Release allocated memory for services */
3367         for (l = services; NULL != l; l = g_slist_next(l)) {
3368                 uam_db_service_info_t *service = l->data;
3369
3370                 if (!service)
3371                         continue;
3372                 __free_service_info(service);
3373         }
3374         g_slist_free(services);
3375         services = NULL;
3376
3377         /* Release allocated memory for service devices */
3378         for (l = svc_devs; NULL != l; l = g_slist_next(l)) {
3379                 uam_svc_dev_info_t *svc_dev = l->data;
3380
3381                 if (!svc_dev)
3382                         continue;
3383
3384                 g_free(svc_dev->device_id);
3385                 g_free(svc_dev->service);
3386                 g_free(svc_dev->payload);
3387                 g_free(svc_dev);
3388         }
3389         g_slist_free(svc_devs);
3390         svc_devs = NULL;
3391
3392         /* Release allocated memory for service users */
3393         for (l = svc_users; NULL != l; l = g_slist_next(l)) {
3394                 uam_svc_user_info_t *svc_user = l->data;
3395
3396                 if (!svc_user)
3397                         continue;
3398
3399                 g_free(svc_user->svc_name);
3400                 g_free(svc_user->account);
3401                 g_free(svc_user);
3402         }
3403         g_slist_free(svc_users);
3404         svc_users = NULL;
3405
3406         /* Release allocated memory for payloads */
3407         for (l = payloads; NULL != l; l = g_slist_next(l)) {
3408                 uam_db_payload_info_t *payload = l->data;
3409
3410                 if (!payload)
3411                         continue;
3412                 g_free(payload->device_uid);
3413                 g_free(payload);
3414         }
3415         g_slist_free(payloads);
3416         payloads = NULL;
3417
3418         /* Release allocated memory for sender_apps*/
3419         GSList *sender_apps = *(_uam_manager_get_sender_apps());
3420         for (l = sender_apps; l; l = g_slist_next(l)) {
3421                 uam_sender_app_t *sender_app = l->data;
3422
3423                 if (!sender_app)
3424                         continue;
3425                 g_free(sender_app->sender);
3426                 g_free(sender_app->app_key);
3427                 g_free(sender_app);
3428         }
3429         g_slist_free(sender_apps);
3430
3431         FUNC_EXIT;
3432 }
3433
3434 void _uam_core_handle_sensor_ready(unsigned int sensor, gboolean is_ready)
3435 {
3436         FUNC_ENTRY;
3437
3438         /* Send sensor state changed event over dbus */
3439         if (is_ready)
3440                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_READY,
3441                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
3442         else
3443                 _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATE_NOT_READY,
3444                                 g_variant_new("(iu)", UAM_ERROR_NONE, sensor));
3445
3446         FUNC_EXIT;
3447 }
3448
3449 int _uam_core_handle_device_added(int status,
3450                 int user_id, uam_device_info_s *dev_info)
3451 {
3452         FUNC_ENTRY;
3453
3454         GSList *l;
3455         int ret = UAM_ERROR_NONE;
3456         GSList *svc_list = NULL;
3457         GSList *svc_dev_list = NULL;
3458         uam_db_user_info_t *user = NULL;
3459         uam_svc_dev_info_t *svc_dev = NULL;
3460         uam_db_service_info_t *service = NULL;
3461         gchar *default_service_name = NULL;
3462         int value = 0;
3463
3464         UAM_INFO("user_id is [%d]", user_id);
3465
3466         value = __uam_core_get_app_num_from_sec_list_devices(dev_info);
3467         UAM_DBG("The app_num is %d", value);
3468         if (value != 0)
3469                 dev_info->app_num = value;
3470         else
3471                 UAM_DBG("could not find app_num");
3472
3473         __uam_core_remove_dev_from_sec_list_devices(dev_info);
3474
3475         /* Send reply over dbus for add device API */
3476         l = _uam_manager_get_request_list();
3477         for (; NULL != l; l = g_slist_next(l)) {
3478                 uam_request_context_t *info = l->data;
3479                 uam_device_info_s *dev;
3480                 GArray *out_param;
3481
3482                 if (!info || (UAM_REQUEST_ADD_DEVICE != info->function))
3483                         continue;
3484
3485                 dev = info->data;
3486                 if (!dev) {
3487                         UAM_WARN("info->data is NULL");
3488                         continue;
3489                 }
3490
3491                 if (dev->type != dev_info->type ||
3492                                 strcasecmp(dev->device_id, dev_info->device_id)) {
3493                         UAM_WARN("[%d != %d] || [%s != %s]", dev->type, dev_info->type,
3494                                         dev->device_id, dev_info->device_id);
3495                         continue;
3496                 }
3497                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
3498                 g_array_append_vals(out_param, dev_info, sizeof(uam_device_info_s));
3499                 _uam_manager_method_return(info->context, out_param, status);
3500
3501                 _uam_remove_timer(info->tid);
3502
3503                 _uam_manager_remove_req_ctxt_from_list(info);
3504
3505                 break;
3506         }
3507
3508         if (UAM_ERROR_NONE != status) {
3509                 __send_device_event(status, UAM_EVENT_DEVICE_ADDED, dev_info);
3510                 return status;
3511         }
3512         if (0 > user_id) {
3513                 int id = 0;
3514                 gchar *default_user_account = NULL;
3515                 __get_default_user(dev_info->app_num, &default_user_account, NULL);
3516
3517                 l = g_slist_find_custom(users,
3518                                 default_user_account, __compare_user_account);
3519                 if (NULL == l) {
3520                         UAM_ERR("default user not found for account %s",
3521                                 default_user_account ? default_user_account : "");
3522                         return ret;
3523                 }
3524                 user_id = id;
3525         }
3526
3527         l = g_slist_find_custom(users, &user_id, __compare_user_id);
3528         if (NULL == l || NULL == l->data) {
3529                 UAM_ERR("Invalid user Id: %d", user_id);
3530                 ret = UAM_ERROR_NOT_FOUND;
3531                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
3532                 return ret;
3533         }
3534         user = l->data;
3535
3536         /* Get default service */
3537         __get_default_service_name(dev_info->app_num, &default_service_name);
3538
3539         l = __search_service(services, default_service_name, dev_info->app_num);
3540         if (!l)
3541                 UAM_WARN("Default service not found");
3542         else
3543                 service = l->data;
3544
3545         /** updates for svc dev*/
3546         ret = _uam_core_update_svc_dev_info(dev_info->device_id, dev_info->type,
3547                                 default_service_name, dev_info->discriminant,
3548                                 0, NULL, dev_info->app_num);
3549         if (UAM_ERROR_NONE != ret) {
3550                 UAM_WARN("Device service mapping update failed");
3551                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
3552                 goto done;
3553         }
3554
3555         svc_list = g_slist_append(svc_list, service);
3556         svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
3557                         dev_info->type, default_service_name, dev_info->app_num);
3558         svc_dev_list = g_slist_append(svc_dev_list, svc_dev);
3559         __uam_core_add_dev_to_list(user, dev_info, UAM_PRESENCE_STATE_PRESENT,
3560                         dev_info->last_seen, svc_list, svc_dev_list);
3561
3562         /** Start database transaction */
3563         ret = __uam_db_begin_transaction();
3564         if (UAM_ERROR_NONE != ret) {
3565                 UAM_WARN("__uam_db_begin_transaction failed");
3566                 goto done;
3567         }
3568
3569         /* Add device to database */
3570         ret = _uam_device_db_insert_device_info(user->user_id, dev_info,
3571                         UAM_PRESENCE_STATE_PRESENT, dev_info->last_seen, dev_info->app_num);
3572         if (UAM_ERROR_NONE != ret) {
3573                 UAM_WARN("Device addition to persistent DB failed");
3574                 __uam_db_end_transaction(0);
3575                 goto done;
3576         }
3577
3578         /* Insert device service info to db */
3579         ret =  _uam_db_insert_device_service_info(
3580                                 dev_info->device_id, dev_info->type, dev_info->mac,
3581                                 default_service_name, UAM_DETECTION_CYCLE_DEFAULT,
3582                                 dev_info->discriminant, 0, dev_info->app_num);
3583         if (UAM_ERROR_NONE != ret) {
3584                 UAM_WARN("Device service addition to persistent DB failed");
3585                 __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
3586                 __uam_db_end_transaction(0);
3587                 goto done;
3588         }
3589
3590         /* Add device to user mapped service */
3591         uam_svc_user_info_t* svc_user = NULL;
3592
3593         l = g_slist_find_custom(svc_users, user, __compare_svc_user_account);
3594         if (!l)
3595                 UAM_WARN("User service mapping not found.");
3596         else
3597                 svc_user = l->data;
3598
3599         if (svc_user != NULL && svc_user->svc_name)
3600                 _uam_core_service_add_device(svc_user->svc_name, dev_info->device_id,
3601                                 dev_info->type, dev_info->app_num);
3602
3603         __uam_db_end_transaction(1);
3604         /** End database transaction */
3605
3606         /* Send device added event to application */
3607         __send_device_event(ret, UAM_EVENT_DEVICE_ADDED, dev_info);
3608
3609         /* Set/update registered device list to plugins */
3610         ret = _uam_pm_set_registered_devices(devices,
3611                         __uam_core_tech_type_to_sensor(dev_info->type));
3612         if (UAM_ERROR_NONE != ret) {
3613                 UAM_ERR("_uam_pm_set_registered_devices failed");
3614                 goto done;
3615         }
3616
3617         _uam_cloud_send_device_added(status, user->account, dev_info);
3618
3619         /* Set/update registered device list to cloud plugin */
3620         if (UAM_ERROR_NONE == status)
3621                 _uam_cloud_update_registered_devices();
3622 done:
3623         free_n_null(&default_service_name);
3624         FUNC_EXIT;
3625         return ret;
3626 }
3627
3628 void __send_sensor_presence_event(uam_sensor_info_s *sensor_info, unsigned int sensor)
3629 {
3630         FUNC_ENTRY;
3631         GSList *l;
3632         unsigned long long timestamp;
3633
3634         UAM_INFO("sensor 0x[%8.8X]", sensor);
3635
3636         if (NULL == sensor_info) {
3637                 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
3638                         g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
3639                 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
3640                 FUNC_EXIT;
3641                 return;
3642         }
3643
3644         timestamp = _uam_get_timestamp();
3645
3646         if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
3647                 _uam_manager_send_event(NULL, UAM_EVENT_PRESENCE_DETECTED,
3648                         g_variant_new("(utiidddd)", sensor, timestamp,
3649                         sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3650                         sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3651                 UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED for 0x%8.8X", sensor);
3652                 FUNC_EXIT;
3653                 return;
3654         }
3655
3656         // service specific light detection threshold
3657         for (l = services; NULL != l; l = g_slist_next(l)) {
3658                 uam_db_service_info_t *svc = l->data;
3659                 GSList *l1;
3660
3661                 if (!svc || !svc->monitors)
3662                         continue;
3663
3664                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
3665                                 svc->name, sensor_info->values[0], svc->presence_threshold);
3666
3667                 if (sensor_info->values[0] < svc->presence_threshold)
3668                         continue;
3669
3670                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
3671                         uam_monitor_info_t *mon = l1->data;
3672
3673                         if (!mon)
3674                                 continue;
3675
3676                         UAM_INFO("monitor [%s] sensors 0x[%8.8X]",
3677                                         mon->name, mon->sensors);
3678
3679                         if (!(mon->sensors & sensor))
3680                                 continue;
3681
3682                         if (UAM_DETECT_PRESENCE != mon->mode)
3683                                 continue;
3684
3685                         _uam_manager_send_event(mon->name, UAM_EVENT_PRESENCE_DETECTED,
3686                                 g_variant_new("(utiidddd)", sensor, timestamp,
3687                                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3688                                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3689                         UAM_DBG("Sent UAM_EVENT_PRESENCE_DETECTED to %s for 0x%8.8X",
3690                                         mon->name, sensor);
3691                 }
3692         }
3693
3694         FUNC_EXIT;
3695 }
3696
3697 static void __send_sensor_absence_event(uam_sensor_info_s *sensor_info,
3698         unsigned int sensor)
3699 {
3700         FUNC_ENTRY;
3701         GSList *l;
3702
3703         UAM_INFO("sensor 0x[%8.8X]", sensor);
3704
3705         if (NULL == sensor_info) {
3706                 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
3707                         g_variant_new("(utiidddd)", sensor, 0, 0, 0, 0, 0, 0, 0));
3708                 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
3709                 FUNC_EXIT;
3710                 return;
3711         }
3712
3713         if (UAM_SENSOR_BITMASK_LIGHT != sensor) {
3714                 _uam_manager_send_event(NULL, UAM_EVENT_ABSENCE_DETECTED,
3715                         g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
3716                         sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3717                         sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3718                 UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
3719                 FUNC_EXIT;
3720                 return;
3721         }
3722
3723         // service specific light detection threshold
3724         for (l = services; NULL != l; l = g_slist_next(l)) {
3725                 uam_db_service_info_t *svc = l->data;
3726                 GSList *l1;
3727
3728                 if (!svc || !svc->monitors)
3729                         continue;
3730
3731                 UAM_INFO("service [%s] sensor value [%f] threshold [%u]",
3732                                 svc->name, sensor_info->values[0], svc->absence_threshold);
3733
3734                 if (sensor_info->values[0] > svc->absence_threshold)
3735                         continue;
3736
3737                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
3738                         uam_monitor_info_t *mon = l1->data;
3739
3740                         if (!mon)
3741                                 continue;
3742
3743                         if (!(mon->sensors & sensor))
3744                                 continue;
3745
3746                         if (UAM_DETECT_PRESENCE != mon->mode)
3747                                 continue;
3748
3749                         _uam_manager_send_event(mon->name, UAM_EVENT_ABSENCE_DETECTED,
3750                                 g_variant_new("(utiidddd)", sensor, sensor_info->timestamp,
3751                                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
3752                                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
3753                         UAM_DBG("Sent UAM_EVENT_ABSENCE_DETECTED for 0x%8.8X", sensor);
3754                 }
3755         }
3756
3757         FUNC_EXIT;
3758 }
3759
3760 void __send_user_presence_event(uam_db_tech_info_t *tech, unsigned int sensor,
3761                 uam_device_info_s *dev_info, uam_ble_payload_s *payload)
3762 {
3763         FUNC_ENTRY;
3764
3765         GSList *l;
3766         uam_db_user_info_t *user;
3767         uam_svc_dev_info_t *svc_dev = NULL;
3768         gboolean live_monitoring = FALSE;
3769         unsigned long long timestamp;
3770         int ret;
3771
3772         ret_if(NULL == tech);
3773         ret_if(NULL == tech->svc_list);
3774         ret_if(NULL == dev_info);
3775
3776         user = tech->device->user;
3777         user->last_seen = tech->last_seen;
3778
3779         for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
3780                 uam_db_service_info_t *svc = l->data;
3781                 GSList *l1;
3782                 live_monitoring = FALSE;
3783
3784                 if (!svc || !svc->monitors)
3785                         continue;
3786
3787                 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
3788                         svc->name, svc->remaining_time, svc->cycle);
3789
3790                 if (!(svc->remaining_time == svc->cycle))
3791                         continue;
3792
3793                 UAM_DBG("Check service device discriminant");
3794                 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
3795                                 dev_info->type, svc->name, dev_info->app_num);
3796                 if (!svc_dev || !svc_dev->discriminant)
3797                         continue;
3798
3799                 /** Compare device payload*/
3800                 /** If payload is NULL, send event to all services */
3801                 if (payload) {
3802                         UAM_DBG("Compare payload - primary_key detected: [%d], svc_dev: [%d] ",
3803                                 payload->primary_key, svc_dev->payload->primary_key);
3804
3805                         if (0 != __compare_payload(svc_dev->payload, payload))
3806                                 continue;
3807                 } else {
3808                         UAM_DBG("Detected payload is NULL");
3809                 }
3810
3811                 UAM_DBG("Send event");
3812                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
3813                         uam_monitor_info_t *mon = l1->data;
3814
3815                         if (!mon)
3816                                 continue;
3817
3818                         if (!(mon->sensors & sensor))
3819                                 continue;
3820
3821                         if (UAM_DETECT_PRESENCE != mon->mode)
3822                                 continue;
3823
3824                         /*
3825                          * For current service, if any of its running monitor has same sensor
3826                          * and detection_mode
3827                          */
3828                         live_monitoring = TRUE;
3829
3830                         timestamp = _uam_get_timestamp();
3831                         UAM_INFO("sensor [%d]", sensor);
3832                         _uam_manager_send_event(mon->name,
3833                                         UAM_EVENT_USER_PRESENCE_DETECTED,
3834                                         g_variant_new("(utsss)", sensor, timestamp,
3835                                                 user->account, svc->name, dev_info->device_id));
3836                         UAM_DBG("Sent UAM_EVENT_USER_PRESENCE_DETECTED to %s"
3837                                         " on device %s"
3838                                         " for 0x%8.8X, User: %s Service: %s Timestamp: %llu",
3839                                         mon->name, dev_info->device_id,
3840                                         sensor, user->account,
3841                                         svc->name,
3842                                         timestamp);
3843                 }
3844
3845                 /* Update service specific device last_seen in svc_dev list and DB */
3846                 if (live_monitoring) {
3847                         svc_dev->last_seen = tech->last_seen;
3848                         ret = _uam_db_update_device_service_last_seen(dev_info->device_id,
3849                                         dev_info->type, dev_info->mac, svc->name, tech->last_seen, dev_info->app_num);
3850                         if (UAM_ERROR_NONE != ret)
3851                                 UAM_WARN("_uam_db_update_device_service_last_seen failed");
3852                 }
3853         }
3854
3855         FUNC_EXIT;
3856 }
3857
3858 static int __uam_core_update_device_addr(uam_db_address_info_t *addr,
3859                                         uam_device_info_s *dev_info)
3860 {
3861         FUNC_ENTRY;
3862         int ret = UAM_ERROR_NONE;
3863
3864         retv_if(!addr, UAM_ERROR_INVALID_PARAMETER);
3865         retv_if(!dev_info, UAM_ERROR_INVALID_PARAMETER);
3866
3867         switch (addr->addr_type) {
3868         case UAM_ADDR_TYPE_IPv4:
3869                 if (strcasecmp(addr->address, dev_info->ipv4_addr)) {
3870                         UAM_DBG("Old IPv4: %s, New IPv4: %s",
3871                                 addr->address, dev_info->ipv4_addr);
3872
3873                         g_free(addr->address);
3874                         addr->address = g_strdup(dev_info->ipv4_addr);
3875
3876                         /* Update IP address in DB */
3877                         ret = _uam_device_db_update_device_ip_address(dev_info->device_id,
3878                                         dev_info->type, dev_info->ipv4_addr, dev_info->app_num);
3879                         if (UAM_ERROR_NONE != ret) {
3880                                 UAM_WARN("_uam_device_db_update_device_ip_address failed");
3881                                 return ret;
3882                         }
3883                 }
3884                 break;
3885         case UAM_ADDR_TYPE_WIFI:
3886                 if (strcasecmp(addr->address, dev_info->mac)) {
3887                         UAM_DBG("Old MAC: %s, New MAC: %s",
3888                                 addr->address, dev_info->mac);
3889
3890                         g_free(addr->address);
3891                         addr->address = g_strdup(dev_info->mac);
3892
3893                         /* Update address in DB */
3894                         ret = _uam_device_db_update_device_mac_address(dev_info->device_id,
3895                                         dev_info->type, dev_info->mac, dev_info->app_num);
3896                         if (UAM_ERROR_NONE != ret) {
3897                                 UAM_WARN("_uam_device_db_update_device_mac_address failed");
3898                                 __uam_db_end_transaction(0);
3899                                 return ret;
3900                         }
3901                 }
3902                 break;
3903         default:
3904                 UAM_DBG("Unknown addr type: %d", addr->addr_type);
3905         }
3906
3907         FUNC_EXIT;
3908         return ret;
3909 }
3910
3911 int _uam_core_handle_presence_detected(unsigned int sensor,
3912                 int user_id, void *info, uam_ble_payload_s *payload)
3913 {
3914         FUNC_ENTRY;
3915         int ret = UAM_ERROR_NONE;
3916
3917         GSList *l;
3918         uam_db_user_info_t *user;
3919         uam_db_device_info_t *device;
3920         uam_db_tech_info_t *tech;
3921
3922         uam_device_info_s *dev_info = NULL;
3923         uam_sensor_info_s *sensor_info = NULL;
3924
3925         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
3926
3927         if (info && (sensor & _uam_core_get_env_sensors())) {
3928                 /* Received info is sensor information */
3929                 sensor_info = info;
3930         }
3931
3932         if (info && (sensor & _uam_core_get_user_sensors())) {
3933                 /* Received info is device information */
3934                 dev_info = info;
3935         }
3936
3937         _uam_vpm_send_presence_detection_event(sensor);
3938
3939         if (NULL == dev_info) {
3940                 __send_sensor_presence_event(sensor_info, sensor);
3941                 return ret;
3942         }
3943
3944         retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
3945
3946         /* fetch the app_num info for the corresponding user_id */
3947         _uam_core_get_app_num_from_userid(user_id, &dev_info->app_num);
3948
3949         l = g_slist_find_custom(users, &user_id, __compare_user_id);
3950         if (NULL == l) {
3951                 UAM_ERR("Invalid user_id [%d]", user_id);
3952                 return UAM_ERROR_INVALID_PARAMETER;
3953         }
3954         user = l->data;
3955
3956         l = g_slist_find_custom(user->devices,
3957                         dev_info->device_id, __compare_device_id);
3958         if (NULL == l) {
3959                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
3960                                 user_id, dev_info->device_id);
3961                 return UAM_ERROR_INVALID_PARAMETER;
3962         }
3963         device = l->data;
3964
3965         if (!(device->supported_techs & dev_info->type)) {
3966                 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
3967                                 dev_info->device_id, dev_info->type);
3968                 return UAM_ERROR_INVALID_PARAMETER;
3969         }
3970
3971         l = g_slist_find_custom(device->tech_list,
3972                         &(dev_info->type), __compare_tech_type);
3973         if (NULL == l) {
3974                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
3975                 return UAM_ERROR_INVALID_PARAMETER;
3976         }
3977         tech = l->data;
3978
3979         tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
3980         tech->last_seen = dev_info->last_seen;
3981
3982         /** Update payload info in list with user data */
3983         if (payload) {
3984                 l = g_slist_find_custom(payloads, payload, __compare_payload);
3985                 if (l)
3986                         __uam_copy_uam_payload_info(l->data, payload);
3987         }
3988
3989         retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_INVALID_PARAMETER);
3990
3991         /* Check if IP/MAC address was updated then update in DB */
3992         if (UAM_TECH_TYPE_WIFI == dev_info->type) {
3993                 for (l = tech->addresses; NULL != l; l = g_slist_next(l)) {
3994                         uam_db_address_info_t *addr = l->data;
3995
3996                         if (NULL == addr)
3997                                 continue;
3998
3999                         ret = __uam_core_update_device_addr(addr, dev_info);
4000                         if (UAM_ERROR_NONE != ret) {
4001                                 UAM_WARN("_uam_device_db_update_device_ip_address failed");
4002                                 __uam_db_end_transaction(0);
4003                                 return ret;
4004                         }
4005                 }
4006         }
4007
4008         /* Update database (presence state & timestamp) */
4009         ret = _uam_device_db_update_device_last_seen(dev_info->device_id,
4010                                 dev_info->type, dev_info->mac, dev_info->last_seen, dev_info->app_num);
4011         if (UAM_ERROR_NONE != ret) {
4012                 UAM_WARN("_uam_device_db_update_device_last_seen failed");
4013                 __uam_db_end_transaction(0);
4014                 return ret;
4015         }
4016
4017         ret = _uam_device_db_update_device_presence(dev_info->device_id,
4018                                 dev_info->type, dev_info->mac, tech->presence_state, dev_info->app_num);
4019         if (UAM_ERROR_NONE != ret) {
4020                 UAM_WARN("_uam_device_db_update_device_presence failed");
4021                 __uam_db_end_transaction(0);
4022                 return ret;
4023         }
4024
4025         /* Update database (payload user data) */
4026         if (payload) {
4027                 ret = _uam_db_update_payload_info(dev_info->device_id,
4028                                         dev_info->type, dev_info->mac, payload, dev_info->app_num);
4029                 if (UAM_ERROR_NONE != ret) {
4030                         UAM_WARN("_uam_db_update_payload_user_data failed");
4031                         __uam_db_end_transaction(0);
4032                         return ret;
4033                 }
4034         }
4035
4036         __uam_db_end_transaction(1);
4037
4038         /* Send user presence event and update service_device timestamp */
4039         __send_user_presence_event(tech, sensor, dev_info, payload);
4040
4041         FUNC_EXIT;
4042         return ret;
4043 }
4044
4045 void __send_user_location_event(uam_db_tech_info_t *tech,
4046                 unsigned int sensor, uam_device_info_s *dev_info)
4047 {
4048         FUNC_ENTRY;
4049
4050         GSList *l;
4051         uam_db_user_info_t *user;
4052         uam_svc_dev_info_t *svc_dev = NULL;
4053         unsigned long long timestamp;
4054
4055         ret_if(NULL == tech);
4056         ret_if(NULL == tech->svc_list);
4057         ret_if(NULL == dev_info);
4058
4059         user = tech->device->user;
4060
4061         for (l = tech->svc_list; NULL != l; l = g_slist_next(l)) {
4062                 uam_db_service_info_t *svc = l->data;
4063                 GSList *l1;
4064
4065                 if (!svc || !svc->monitors)
4066                         continue;
4067
4068                 UAM_DBG("Check service device discriminant");
4069                 svc_dev = _uam_core_find_svc_dev_info(dev_info->device_id,
4070                                 dev_info->type, svc->name, dev_info->app_num);
4071                 if (!svc_dev || !svc_dev->discriminant)
4072                         continue;
4073
4074                 UAM_DBG("Send event");
4075                 for (l1 = svc->monitors; NULL != l1; l1 = g_slist_next(l1)) {
4076                         uam_monitor_info_t *mon = l1->data;
4077
4078                         if (!mon)
4079                                 continue;
4080
4081                         if (!(mon->sensors & sensor))
4082                                 continue;
4083
4084                         if (UAM_DETECT_LOCATION != mon->mode)
4085                                 continue;
4086
4087                         /*
4088                          * For current service, if any of its running monitor has same sensor
4089                          * and detection_mode
4090                          */
4091
4092                         timestamp = _uam_get_timestamp();
4093                         UAM_INFO("sensor [%d]", sensor);
4094                         _uam_manager_send_event(mon->name,
4095                                         UAM_EVENT_USER_LOCATION_DETECTED,
4096                                         g_variant_new("(utsssiiii)", sensor, timestamp,
4097                                         user->account, svc->name, dev_info->device_id,
4098                                         dev_info->distance_mm, dev_info->x, dev_info->y,
4099                                         dev_info->z));
4100                         UAM_DBG("Sent UAM_EVENT_USER_LOCATION_DETECTED to %s"
4101                                         " on device %s for 0x%8.8X, User: %s"
4102                                         " Service: %s Timestamp: %llu distance: %d"
4103                                         " coordinates x:%d y:%d z:%d",
4104                                         mon->name, dev_info->device_id,
4105                                         sensor, user->account, svc->name,
4106                                         timestamp, dev_info->distance_mm,
4107                                         dev_info->x, dev_info->y, dev_info->z);
4108                 }
4109         }
4110
4111         FUNC_EXIT;
4112 }
4113
4114 int _uam_core_handle_location_detected(unsigned int sensor,
4115                                         int user_id, void *info)
4116 {
4117         FUNC_ENTRY;
4118         int ret = UAM_ERROR_NONE;
4119
4120         GSList *l;
4121         uam_db_user_info_t *user;
4122         uam_db_device_info_t *device;
4123         uam_db_tech_info_t *tech;
4124         uam_device_info_s *dev_info = NULL;
4125
4126         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
4127
4128         if (info && (sensor & _uam_core_get_user_sensors())) {
4129                 /* Received info is device information */
4130                 dev_info = info;
4131         }
4132
4133         if (NULL == dev_info) {
4134                 /* To-Do: Handle location detection if no dev info available */
4135                 return ret;
4136         }
4137
4138         retv_if(0 > user_id, UAM_ERROR_INVALID_PARAMETER);
4139
4140         /* fetch the app_num info for the corresponding user_id */
4141         _uam_core_get_app_num_from_userid(user_id, &dev_info->app_num);
4142
4143         /* Search user */
4144         l = g_slist_find_custom(users, &user_id, __compare_user_id);
4145         if (NULL == l) {
4146                 UAM_ERR("Invalid user_id [%d]", user_id);
4147                 return UAM_ERROR_INVALID_PARAMETER;
4148         }
4149         user = l->data;
4150
4151         /* Search device */
4152         l = g_slist_find_custom(user->devices,
4153                         dev_info->device_id, __compare_device_id);
4154         if (NULL == l) {
4155                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
4156                                 user_id, dev_info->device_id);
4157                 return UAM_ERROR_INVALID_PARAMETER;
4158         }
4159         device = l->data;
4160
4161         if (!(device->supported_techs & dev_info->type)) {
4162                 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
4163                                 dev_info->device_id, dev_info->type);
4164                 return UAM_ERROR_INVALID_PARAMETER;
4165         }
4166
4167         l = g_slist_find_custom(device->tech_list,
4168                         &(dev_info->type), __compare_tech_type);
4169         if (NULL == l) {
4170                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
4171                 return UAM_ERROR_INVALID_PARAMETER;
4172         }
4173         tech = l->data;
4174
4175         /* Send user location event */
4176         __send_user_location_event(tech, sensor, dev_info);
4177
4178         FUNC_EXIT;
4179         return ret;
4180 }
4181
4182 static void __send_user_absence_event(uam_tech_type_e type, unsigned int sensor)
4183 {
4184         FUNC_ENTRY;
4185         GSList *l;
4186
4187         /*
4188          * For each service, find users absent on given sensor. Then for each
4189          * monitor in serivce's monitor list, if it is monitoring ABSENCE on
4190          * given sensor, send user ABSENCE event.
4191          */
4192         for (l = services; NULL != l; l = g_slist_next(l)) {
4193                 uam_db_service_info_t *svc = l->data;
4194                 GSList *absent_users = NULL;
4195                 GSList *present_users = NULL;
4196                 GSList *l1;
4197                 GSList *l2;
4198
4199                 if (!svc || !svc->monitors || !svc->dev_techs)
4200                         continue;
4201
4202                 UAM_INFO("service [%s] remaining time [%d] cycle [%d]",
4203                                 svc->name, svc->remaining_time, svc->cycle);
4204
4205                 if (!(svc->remaining_time == svc->cycle))
4206                         continue;
4207
4208                 for (l1 = svc->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
4209                         uam_db_tech_info_t *tech = l1->data;
4210
4211                         if (!tech || (tech->tech_type != type)) {
4212                                 UAM_WARN("tech is NULL or tech->tech_type != type [%d]", type);
4213                                 continue;
4214                         }
4215
4216                         if (!tech->device || !tech->device->user) {
4217                                 UAM_WARN("tech->device is NULL or tech->device->user is NULL");
4218                                 continue;
4219                         }
4220
4221                         l2 = g_slist_find_custom(present_users,
4222                                         &(tech->device->user->user_id), __compare_user_id);
4223
4224                         if (UAM_PRESENCE_STATE_PRESENT == tech->presence_state && tech->discriminant) {
4225                                 UAM_DBG("tech->discriminant [%d] device_id [%s] account [%s]",
4226                                         tech->discriminant,
4227                                         tech->device->device_id,
4228                                         tech->device->user->account);
4229                                 /* Remove user from absent list */
4230                                 absent_users = g_slist_remove(absent_users, tech->device->user);
4231
4232                                 /* If user not in present list, add user to the list */
4233                                 if (!l2) {
4234                                         UAM_DBG("added present user [%s]", tech->device->user->account);
4235                                         present_users = g_slist_prepend(present_users, tech->device->user);
4236                                 }
4237                         } else {
4238                                 /* If user not in the present list then only add it to absent list */
4239                                 if ((NULL == l2) && (NULL == g_slist_find_custom(
4240                                                                 absent_users, &(tech->device->user->user_id),
4241                                                                 __compare_user_id))) {
4242                                         UAM_DBG("added absent user [%s]", tech->device->user->account);
4243                                         absent_users = g_slist_prepend(absent_users, tech->device->user);
4244                                 }
4245                         }
4246                 }
4247
4248                 g_slist_free(present_users);
4249                 if (!absent_users)
4250                         continue;
4251
4252                 for (l2 = svc->monitors; NULL != l2; l2 = g_slist_next(l2)) {
4253                         uam_monitor_info_t *mon = l2->data;
4254
4255                         if (!mon)
4256                                 continue;
4257
4258                         if (!(mon->sensors & sensor))
4259                                 continue;
4260
4261                         if (UAM_DETECT_ABSENCE != mon->mode)
4262                                 continue;
4263
4264                         for (l1 = absent_users; NULL != l1; l1 = g_slist_next(l1)) {
4265                                 uam_db_user_info_t *user = l1->data;
4266
4267                                 if (!user)
4268                                         continue;
4269
4270                                 user->last_seen = 0;
4271
4272                                 _uam_manager_send_event(mon->name,
4273                                                 UAM_EVENT_USER_ABSENCE_DETECTED,
4274                                                 g_variant_new("(utss)", sensor, user->last_seen,
4275                                                         user->account, svc->name));
4276                                 UAM_DBG("Sent UAM_EVENT_USER_ABSENCE_DETECTED to %s"
4277                                                 " for 0x%8.8X, User: %s Service: %s",
4278                                                 mon->name, sensor, user->account, svc->name);
4279                         }
4280                 }
4281
4282                 g_slist_free(absent_users);
4283         }
4284
4285         FUNC_EXIT;
4286 }
4287
4288 void _uam_core_handle_absence_detected(unsigned int sensor,
4289                 int user_id, void *info)
4290 {
4291         FUNC_ENTRY;
4292         uam_db_user_info_t *user;
4293         uam_db_device_info_t *device;
4294         uam_db_tech_info_t *tech;
4295         GSList *l;
4296         uam_device_info_s *dev_info = NULL;
4297         uam_sensor_info_s *sensor_info = NULL;
4298
4299         UAM_INFO("sensor: 0x%8.8X, user_id: %d", sensor, user_id);
4300
4301         if (info && (sensor & _uam_core_get_env_sensors())) {
4302                 /* received info is sensor information */
4303                 sensor_info = info;
4304         }
4305
4306         if (info && (sensor & _uam_core_get_user_sensors())) {
4307                 /* received info is device information */
4308                 dev_info = info;
4309         }
4310
4311         if (NULL == dev_info) {
4312                 __send_sensor_absence_event(sensor_info, sensor);
4313                 FUNC_EXIT;
4314                 return;
4315         }
4316
4317         ret_if(0 > user_id);
4318
4319         l = g_slist_find_custom(users, &user_id, __compare_user_id);
4320         if (NULL == l) {
4321                 UAM_ERR("Invalid user_id [%d]", user_id);
4322                 return;
4323         }
4324         user = l->data;
4325
4326         l = g_slist_find_custom(user->devices,
4327                         dev_info->device_id, __compare_device_id);
4328         if (NULL == l) {
4329                 UAM_ERR("Valid user_id [%d] but Invalid device_id [%s]",
4330                                 user_id, dev_info->device_id);
4331                 return;
4332         }
4333         device = l->data;
4334         if (!(device->supported_techs & dev_info->type)) {
4335                 UAM_ERR("Valid device_id [%s] but Invalid tech type [%d]",
4336                                 dev_info->device_id, dev_info->type);
4337                 return;
4338         }
4339
4340         l = g_slist_find_custom(device->tech_list,
4341                         &(dev_info->type), __compare_tech_type);
4342         if (NULL == l) {
4343                 UAM_ERR("Strange, tech type [%d] not found", dev_info->type);
4344                 return;
4345         }
4346         tech = l->data;
4347
4348         tech->presence_state = UAM_PRESENCE_STATE_ABSENT;
4349
4350         /* Update database (presence state) */
4351         if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
4352                                 dev_info->type, dev_info->mac, tech->presence_state, dev_info->app_num))
4353                 UAM_WARN("_uam_device_db_update_device_presence failed");
4354
4355         FUNC_EXIT;
4356 }
4357
4358 void _uam_core_cleanup_monitor(char *name)
4359 {
4360         GSList *l;
4361
4362         for (l = monitors; NULL != l; l = g_slist_next(l)) {
4363                 uam_monitor_info_t *monitor = l->data;
4364
4365                 if (!monitor || !monitor->name || !monitor->service)
4366                         continue;
4367
4368                 if (0 != g_strcmp0(name, monitor->name))
4369                         continue;
4370
4371                 /* If there is a monitor that is not freed, stop detection
4372                  * and free the monitor structure in the memory. */
4373                 UAM_INFO("clear %s's monitor info.", monitor->name);
4374                 __uam_core_stop_detection(monitor->mode,
4375                         monitor->service->name, name, monitor->sensors, monitor->service->app_num);
4376         }
4377 }
4378
4379 void _uam_core_reset_database(void)
4380 {
4381         FUNC_ENTRY;
4382         int ret;
4383         unsigned int bitmask;
4384
4385         ret = _uam_db_clear();
4386         if (UAM_ERROR_NONE != ret) {
4387                 UAM_ERR("_uam_db_clear failed with %s",
4388                                 _uam_manager_error_to_str(ret));
4389                 unlink(DATABASE_FULL_PATH);
4390                 return;
4391         }
4392
4393         g_slist_free_full(devices, __free_user_device);
4394         devices = NULL;
4395
4396         g_slist_free_full(users, __free_user_info);
4397         users = NULL;
4398
4399         g_slist_free_full(services, __free_service_info);
4400         services = NULL;
4401
4402         g_slist_free_full(monitors, __free_monitor_info);
4403         monitors = NULL;
4404
4405         g_slist_free_full(scanners, __free_scanner_info);
4406         scanners = NULL;
4407
4408         bitmask = _uam_core_get_user_sensors();
4409         /* Set/update registered device list to plugins */
4410         ret = _uam_pm_set_registered_devices(devices, bitmask);
4411         if (UAM_ERROR_NONE != ret)
4412                 UAM_ERR("_uam_pm_set_registered_devices failed with %s",
4413                                 _uam_manager_error_to_str(ret));
4414
4415         /* Set/update registered device list to cloud plugin */
4416         _uam_cloud_update_registered_devices();
4417
4418         FUNC_EXIT;
4419 }
4420
4421 void _uam_core_handle_detection_started(unsigned int sensor)
4422 {
4423         FUNC_ENTRY;
4424         unsigned int active_sensors = 0;
4425
4426         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
4427                         sensor, detecting_sensors);
4428
4429         detecting_sensors |= sensor;
4430         active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_PRESENCE);
4431         active_sensors |= _uam_core_get_active_sensors(UAM_DETECT_ABSENCE);
4432
4433         if (active_sensors == detecting_sensors) {
4434                 /* Send detection started event */
4435                 _uam_manager_send_event(NULL, UAM_EVENT_DETECTION_STARTED, NULL);
4436         }
4437
4438         FUNC_EXIT;
4439 }
4440
4441 void _uam_core_handle_detection_stopped(unsigned int sensor)
4442 {
4443         FUNC_ENTRY;
4444
4445         uam_tech_type_e type = UAM_TECH_TYPE_NONE;
4446         uam_cycle_state_e cycle_state;
4447         GSList *l = NULL;
4448
4449         ret_if((detecting_sensors & sensor) == 0);
4450         UAM_DBG("Sensor: 0x%8.8X, detecting_sensors: 0x%8.8X",
4451                         sensor, detecting_sensors);
4452         detecting_sensors &= ~sensor;
4453
4454         type = __uam_core_sensor_to_tech_type(sensor);
4455
4456         if (UAM_TECH_TYPE_NONE != type)
4457                 __send_user_absence_event(type, sensor);
4458
4459         if (0 == detecting_sensors) {
4460                 /* Send detection stopped event */
4461                 for (l = monitors; l; l = g_slist_next(l)) {
4462                         uam_monitor_info_t *mon = l->data;
4463
4464                         if (!mon || !mon->name || !mon->service)
4465                                 continue;
4466                         uam_db_service_info_t *service = mon->service;
4467                         cycle_state = UAM_DETECTION_CYCLE_END;
4468
4469                         UAM_DBG("mon->sensors[0x%X], [%s]->remaining_time: %d",
4470                                 mon->sensors, service->name, service->remaining_time);
4471                         if (!(mon->sensors & _uam_core_get_env_sensors())) {
4472                                 if (service->remaining_time < service->cycle) {
4473                                         UAM_DBG("service->remaining_time < service->cycle, return");
4474                                         continue;
4475                                 }
4476                         } else if (service->remaining_time > UAM_DETECTION_CYCLE_MIN) {
4477                                 cycle_state = UAM_DETECTION_CYCLE_MID;
4478                         }
4479
4480                         _uam_manager_send_event(mon->name, UAM_EVENT_DETECTION_STOPPED,
4481                                         g_variant_new("(si)", service->name, cycle_state));
4482                         UAM_DBG("Sent UAM_EVENT_DETECTION_STOPPED to %s, Service: %s,"
4483                                         " cycle state:[%s]",
4484                                         mon->name, service->name, cycle_state ? "end" : "mid");
4485                 }
4486         }
4487         FUNC_EXIT;
4488 }
4489
4490 static uam_scanner_info_t *__uam_find_scanner(const char *name)
4491 {
4492         GSList *l;
4493
4494         retv_if(NULL == name, NULL);
4495
4496         for (l = scanners; NULL != l; l = g_slist_next(l)) {
4497                 uam_scanner_info_t *scanner = l->data;
4498
4499                 if (!scanner || !scanner->name)
4500                         continue;
4501
4502                 if (0 == g_strcmp0(scanner->name, name)) {
4503                         UAM_DBG("Scanning application found in list");
4504                         return scanner;
4505                 }
4506         }
4507
4508         return NULL;
4509 }
4510
4511 static gboolean __scan_completed_cb(gpointer data)
4512 {
4513         FUNC_ENTRY;
4514         uam_scanner_info_t *scanner = data;
4515
4516         retv_if(NULL == scanner, FALSE);
4517
4518         if (UAM_ERROR_NONE != _uam_manager_send_event(
4519                                 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
4520                 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
4521         else
4522                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
4523
4524         /* Free scanner */
4525         scanners = g_slist_remove(scanners, scanner);
4526         g_free(scanner->name);
4527         g_free(scanner);
4528
4529         FUNC_EXIT;
4530         return FALSE;
4531 }
4532
4533 int _uam_core_start_active_device_scan(char *sender, unsigned int sensors, int detection_period)
4534 {
4535         FUNC_ENTRY;
4536         int ret;
4537         uam_scanner_info_t *scanner;
4538
4539         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
4540         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
4541
4542         scanner = __uam_find_scanner(sender);
4543         retv_if(NULL != scanner, UAM_ERROR_NOW_IN_PROGRESS);
4544
4545         ret = _uam_pm_start_active_device_scan(&sensors, detection_period);
4546         if (UAM_ERROR_NONE != ret) {
4547                 UAM_ERR("Failed with error: %s (0x%4.4X)",
4548                                 _uam_manager_error_to_str(ret), ret);
4549                 return ret;
4550         }
4551
4552         scanner = g_malloc0(sizeof(uam_scanner_info_t));
4553         if (!scanner) {
4554                 UAM_ERR("Failed to allocate memory");
4555                 return UAM_ERROR_OUT_OF_MEMORY;
4556         }
4557         scanner->name = g_strdup(sender);
4558         scanner->sensors |= sensors;
4559         scanner->timer = g_timeout_add_seconds(detection_period,
4560                         __scan_completed_cb, scanner);
4561         scanners = g_slist_append(scanners, scanner);
4562         UAM_DBG("sensors = 0x%8.8X - 0x%8.8X", scanner->sensors, sensors);
4563
4564         FUNC_EXIT;
4565         return UAM_ERROR_NONE;
4566 }
4567
4568 int _uam_core_stop_active_device_scan(char *sender, unsigned int sensors)
4569 {
4570         FUNC_ENTRY;
4571         int ret;
4572         uam_scanner_info_t *scanner;
4573         GSList *l;
4574
4575         retv_if(NULL == sender, UAM_ERROR_INVALID_PARAMETER);
4576         retv_if(0 == sensors, UAM_ERROR_INVALID_PARAMETER);
4577
4578         scanner = __uam_find_scanner(sender);
4579         retv_if(NULL == scanner, UAM_ERROR_NOT_IN_OPERATION);
4580
4581         /* Trim sensors to a subset of active sensors for the scanner */
4582         sensors &= scanner->sensors;
4583
4584         /*
4585          * modify scanner's active sensors and if active sensors are NULL
4586          * remove scanner from scanners list
4587          */
4588         scanner->sensors &= ~sensors;
4589         if (0 == scanner->sensors) {
4590                 scanners = g_slist_remove(scanners, scanner);
4591                 g_source_remove(scanner->timer);
4592                 g_free(scanner->name);
4593                 g_free(scanner);
4594         }
4595
4596         for (l = scanners; NULL != l; l = g_slist_next(l)) {
4597                 uam_scanner_info_t *scanner_data = l->data;
4598
4599                 if (!scanner_data || !scanner_data->name)
4600                         continue;
4601
4602                 sensors &= ~(scanner_data->sensors);
4603         }
4604
4605         if (0 != sensors) {
4606                 ret = _uam_pm_stop_active_device_scan(sensors);
4607                 if (UAM_ERROR_NONE != ret) {
4608                         UAM_ERR("Failed with error: %s (0x%4.4X)",
4609                                         _uam_manager_error_to_str(ret), ret);
4610                         return ret;
4611                 }
4612         }
4613
4614         FUNC_EXIT;
4615         return UAM_ERROR_NONE;
4616 }
4617
4618 void _uam_core_handle_active_device(uam_active_scan_event_e event,
4619                 unsigned int sensor, const uam_device_info_s *dev_info)
4620 {
4621         FUNC_ENTRY;
4622         GSList *l;
4623
4624         ret_if((UAM_ACTIVE_SCAN_COMPLETED != event) && (NULL == dev_info));
4625
4626         for (l = scanners; NULL != l;) {
4627                 uam_scanner_info_t *scanner = l->data;
4628
4629                 if (!scanner || !scanner->name) {
4630                         l = g_slist_next(l);
4631                         continue;
4632                 }
4633
4634                 if (0 == (scanner->sensors & sensor)) {
4635                         l = g_slist_next(l);
4636                         continue;
4637                 }
4638
4639                 if (event == UAM_ACTIVE_SCAN_COMPLETED) {
4640                         scanner->sensors &= ~(sensor);
4641                         UAM_DBG("sensors = 0x%8.8X", scanner->sensors);
4642                         if (0 != scanner->sensors) {
4643                                 l = g_slist_next(l);
4644                                 continue;
4645                         }
4646
4647                         if (UAM_ERROR_NONE != _uam_manager_send_event(
4648                                                 scanner->name, UAM_EVENT_SCAN_COMPLETED, NULL))
4649                                 UAM_ERR("Failed to send UAM_EVENT_SCAN_COMPLETED");
4650                         else
4651                                 UAM_INFO_C("Sent UAM_EVENT_SCAN_COMPLETED to [%s]", scanner->name);
4652
4653                         /* Free scanner */
4654                         l = g_slist_next(l);
4655                         scanners = g_slist_remove(scanners, scanner);
4656                         g_source_remove(scanner->timer);
4657                         g_free(scanner->name);
4658                         g_free(scanner);
4659                 } else {
4660                         GVariant *param = g_variant_new("(iiisss)",
4661                                         UAM_ERROR_NONE,
4662                                         dev_info->operating_system,
4663                                         dev_info->type,
4664                                         dev_info->mac,
4665                                         dev_info->ipv4_addr,
4666                                         dev_info->device_id);
4667                         if (UAM_ERROR_NONE != _uam_manager_send_event(
4668                                                 scanner->name, UAM_EVENT_DEVICE_FOUND, param))
4669                                 UAM_ERR("Failed to send %s", _uam_manager_event_to_str(event));
4670                         else
4671                                 UAM_INFO_C("Sent UAM_EVENT_DEVICE_FOUND to [%s]", scanner->name);
4672
4673                         l = g_slist_next(l);
4674                 }
4675         }
4676
4677         FUNC_EXIT;
4678 }
4679
4680 int _uam_core_register_service(uam_service_info_s *svc, const int app_num)
4681 {
4682         FUNC_ENTRY;
4683         GSList *l;
4684         uam_db_service_info_t *service;
4685         int service_number = 0;
4686
4687         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
4688
4689         /* Retrieve service from list */
4690         UAM_INFO("Registering for : service name->[%s] and app_num->[%d]",
4691                         svc->name, app_num);
4692
4693         l = __search_service(services, svc->name, app_num);
4694         retv_if((NULL != l) && (l->data != NULL), UAM_ERROR_ALREADY_REGISTERED);
4695
4696         service = g_new0(uam_db_service_info_t, 1);
4697         __uam_copy_uam_service_info(service, svc);
4698         service->cycle = UAM_DETECTION_CYCLE_DEFAULT;
4699
4700         /* Add service to database */
4701         if (UAM_ERROR_NONE != _uam_db_insert_service_info(&service_number,
4702                                         svc, service->cycle, app_num)) {
4703                 UAM_ERR("_uam_db_insert_service_info failed");
4704                 __free_service_info(service);
4705                 return UAM_ERROR_DB_FAILED;
4706         }
4707
4708         services = g_slist_append(services, service);
4709
4710         /* Send service registered event to application */
4711         /* <TO-DO> send event only to particular sender */
4712         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
4713                                 UAM_EVENT_SERVICE_REGISTERED, g_variant_new("(is)",
4714                                         UAM_ERROR_NONE, service->name)))
4715                 UAM_ERR("Failed to send UAM_EVENT_SERVICE_REGISTERED");
4716
4717         FUNC_EXIT;
4718         return UAM_ERROR_NONE;
4719 }
4720
4721 int _uam_core_update_service(uam_service_info_s *svc)
4722 {
4723         FUNC_ENTRY;
4724         GSList *l;
4725         uam_db_service_info_t *service;
4726
4727         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
4728
4729         /* Retrieve service from list */
4730         l = __search_service(services, svc->name, svc->app_num);
4731         retv_if((NULL == l) || (l->data == NULL), UAM_ERROR_NOT_REGISTERED);
4732
4733         service = l->data;
4734         service->presence_threshold = svc->presence_threshold;
4735         service->absence_threshold = svc->absence_threshold;
4736
4737         /* Update service to database */
4738         if (UAM_ERROR_NONE != _uam_db_update_service_info(service, svc->app_num)) {
4739                 UAM_ERR("_uam_db_update_service_info failed");
4740                 return UAM_ERROR_DB_FAILED;
4741         }
4742
4743         FUNC_EXIT;
4744         return UAM_ERROR_NONE;
4745 }
4746
4747 int _uam_core_get_default_service(uam_service_info_s *service_info,
4748                                 const int app_num)
4749 {
4750         FUNC_ENTRY;
4751         int ret = UAM_ERROR_NONE;
4752         GSList *l;
4753         uam_db_service_info_t *service;
4754         gchar *default_service_name = NULL;
4755
4756         retv_if(NULL == service_info, UAM_ERROR_INVALID_PARAMETER);
4757         retv_if(app_num <= 0, UAM_ERROR_INVALID_PARAMETER);
4758
4759         /* Get the default service name specific to app */
4760         __get_default_service_name(app_num, &default_service_name);
4761         UAM_DBG("default_service_name is [%s]", default_service_name);
4762
4763         l = __search_service(services, default_service_name, app_num);
4764         if (NULL == l) {
4765                 /* Register default service */
4766                 memset(service_info, 0x00, sizeof(uam_service_info_s));
4767
4768                 service_info->app_num = app_num;
4769                 g_strlcpy(service_info->name, default_service_name, UAM_SERVICE_MAX_STRING_LEN);
4770                 service_info->presence_threshold = UAM_PRESENCE_THRESHOLD_DEFAULT;
4771                 service_info->absence_threshold = UAM_ABSENCE_THRESHOLD_DEFAULT;
4772
4773                 ret = _uam_core_register_service(service_info, service_info->app_num);
4774                 if ((UAM_ERROR_NONE != ret) && (UAM_ERROR_ALREADY_REGISTERED != ret)) {
4775                         UAM_ERR("_uam_core_register_service failed with %s", _uam_manager_error_to_str(ret));
4776                         goto done;
4777                 }
4778         } else {
4779                 service = l->data;
4780                 __uam_copy_uam_db_service_info(service_info, service);
4781         }
4782
4783 done:
4784         free_n_null(&default_service_name);
4785         FUNC_EXIT;
4786         return ret;
4787 }
4788
4789 int _uam_core_unregister_service(const char *svc_name, const int app_num)
4790 {
4791         FUNC_ENTRY;
4792         GSList *l;
4793         uam_db_service_info_t *service;
4794
4795         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
4796
4797         /* Retrieve service from list */
4798         l = __search_service(services, svc_name, app_num);
4799         retv_if((NULL == l), UAM_ERROR_NOT_REGISTERED);
4800         service = l->data;
4801
4802         /* Check if service is being used*/
4803         if (service->monitors) {
4804                 UAM_ERR("service monitoring in progress");
4805                 return UAM_ERROR_PERMISSION_DENIED;
4806         }
4807
4808         /* Remove service from database */
4809         if (UAM_ERROR_NONE != _uam_db_delete_service_info(service->name, app_num)) {
4810                 UAM_ERR("_uam_db_delete_service_info failed");
4811                 return UAM_ERROR_DB_FAILED;
4812         }
4813
4814         /* Remove service mapping from devices*/
4815         for (l = service->dev_techs; NULL != l; l = g_slist_next(l)) {
4816                 uam_db_tech_info_t *tech = l->data;
4817                 if (!tech || !tech->addresses)
4818                         continue;
4819                 tech->svc_list = g_slist_remove(tech->svc_list, service);
4820         }
4821         services = g_slist_remove(services, service);
4822
4823         /* Send service unregistered event to application */
4824         if (UAM_ERROR_NONE != _uam_manager_send_event(NULL,
4825                                 UAM_EVENT_SERVICE_UNREGISTERED, g_variant_new("(is)",
4826                                         UAM_ERROR_NONE, service->name)))
4827                 UAM_ERR("Failed to send UAM_EVENT_SERVICE_UNREGISTERED");
4828
4829         FUNC_EXIT;
4830         return UAM_ERROR_NONE;
4831 }
4832
4833 static int __get_service_dev_list(
4834                 uam_db_service_info_t* service, uam_device_info_s **device_list, int *count)
4835 {
4836         FUNC_ENTRY;
4837         GSList *l1;
4838         GSList *s;
4839         int indx = 0;
4840         int ret = UAM_ERROR_NONE;
4841         uam_svc_dev_info_t *svc_dev = NULL;
4842         uam_device_info_s *dev = NULL;
4843
4844         *count = 0;
4845         /* Calculate number of devices */
4846         for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
4847                 uam_db_tech_info_t *tech = l1->data;
4848                 if (!tech || !tech->addresses)
4849                         continue;
4850
4851                 (*count)++;
4852         }
4853
4854         *device_list = g_new0(uam_device_info_s, *count);
4855
4856         /* Copy devices */
4857         for (l1 = service->dev_techs; NULL != l1; l1 = g_slist_next(l1)) {
4858                 uam_db_tech_info_t *tech = l1->data;
4859
4860                 if (!tech || !tech->addresses)
4861                         continue;
4862
4863                 /* Copy tech info to device info */
4864                 ret = __copy_tech_info_to_device_info(tech, &((*device_list)[indx]));
4865                 if (UAM_ERROR_NONE != ret) {
4866                         UAM_ERR("__copy_tech_info_to_device_info failed");
4867                         return ret;
4868                 }
4869
4870                 (*device_list)[indx].last_seen = 0;
4871                 indx++;
4872         }
4873
4874         UAM_INFO("Count = %d, indx = %d", *count, indx);
4875
4876         /* Update service specific device last time */
4877         for (s = svc_devs; s; s = g_slist_next(s)) {
4878                 svc_dev = s->data;
4879
4880                 if (!svc_dev || !svc_dev->device_id || !svc_dev->service)
4881                         continue;
4882                 if (g_strcmp0(svc_dev->service, service->name))
4883                         continue;
4884
4885                 for (indx = 0; indx < *count; indx++) {
4886                         dev = &((*device_list)[indx]);
4887
4888                         if (svc_dev->tech_type != dev->type ||
4889                                         g_strcmp0(svc_dev->device_id, dev->device_id))
4890                                 continue;
4891
4892                         dev->last_seen = svc_dev->last_seen;
4893                 }
4894         }
4895
4896         FUNC_EXIT;
4897         return ret;
4898 }
4899
4900 int _uam_core_get_service_devices(const char *svc_name,
4901                 int *count, uam_device_info_s **device_list, const int app_num)
4902 {
4903         FUNC_ENTRY;
4904         uam_db_service_info_t *service;
4905         GSList *l;
4906         int ret = UAM_ERROR_NONE;
4907
4908         l = __search_service(services, svc_name, app_num);
4909         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
4910         service = l->data;
4911
4912         ret = __get_service_dev_list(service, device_list, count);
4913
4914         FUNC_EXIT;
4915         return ret;
4916 }
4917
4918 static void __get_service_user_list(
4919                 const char* svc_name, uam_user_info_s **user_list, int *count, const int app_num)
4920 {
4921         FUNC_ENTRY;
4922         GSList *l, *ll;
4923         int indx = 0;
4924         GSList *svc_user_list = NULL;
4925
4926         *count = 0;
4927         /* Calculate number of users */
4928         for (l = svc_users; NULL != l; l = g_slist_next(l)) {
4929                 uam_svc_user_info_t *svc_user = l->data;
4930                 if (!svc_user || !svc_user->svc_name || !svc_user->account)
4931                         continue;
4932
4933                 if (g_strcmp0(svc_user->svc_name, svc_name) == 0)
4934                         if (svc_user->app_num == app_num)
4935                                 svc_user_list = g_slist_append(svc_user_list, svc_user);
4936
4937         }
4938
4939         *count = g_slist_length(svc_user_list);
4940         *user_list = g_new0(uam_user_info_s, *count);
4941
4942         /* Copy users */
4943         for (l = svc_user_list; l; l = g_slist_next(l)) {
4944                 uam_svc_user_info_t *svc_user = l->data;
4945                 uam_db_user_info_t *user;
4946
4947                 if (!svc_user || !svc_user->svc_name || !svc_user->account)
4948                         continue;
4949
4950                 /* Retrieve user from list */
4951                 ll = __search_user(svc_user->account, app_num);
4952                 if (NULL == ll)
4953                         continue;
4954
4955                 user = ll->data;
4956
4957                 g_strlcpy((*user_list)[indx].account,
4958                                 svc_user->account, UAM_USER_ACCOUNT_MAX_STRING_LEN);
4959
4960                 g_strlcpy((*user_list)[indx].name,
4961                                 user->name, UAM_USER_NAME_MAX_STRING_LEN);
4962
4963                 (*user_list)[indx].app_num = app_num;
4964
4965                 indx += 1;
4966         }
4967
4968         UAM_INFO("Count = %d, indx = %d", *count, indx);
4969         FUNC_EXIT;
4970 }
4971
4972 int _uam_core_get_service_users(const char *svc_name,
4973                 int *count, uam_user_info_s **user_list, const int app_num)
4974 {
4975         FUNC_ENTRY;
4976
4977         __get_service_user_list(svc_name, user_list, count, app_num);
4978
4979         FUNC_EXIT;
4980         return UAM_ERROR_NONE;
4981 }
4982
4983 int _uam_core_get_services(int *count, uam_service_info_s **service_list, const int app_num)
4984 {
4985         FUNC_ENTRY;
4986         guint size;
4987         GSList *l;
4988
4989         size = g_slist_length(services);
4990         *service_list = g_new0(uam_service_info_s, size);
4991         *count = 0;
4992
4993         /* fetch services list from DB */
4994         for (l = services; l; l = g_slist_next(l)) {
4995                 uam_db_service_info_t *db_info = l->data;
4996
4997                 if (!db_info || !db_info->name || db_info->app_num != app_num)
4998                         continue;
4999
5000                 g_strlcpy((*service_list)[*count].name,
5001                                 db_info->name, UAM_SERVICE_MAX_STRING_LEN);
5002                 (*service_list)[*count].presence_threshold = db_info->presence_threshold;
5003                 (*service_list)[*count].absence_threshold = db_info->absence_threshold;
5004                 *count += 1;
5005         }
5006
5007         UAM_INFO("Count: %d", *count);
5008         FUNC_EXIT;
5009         return UAM_ERROR_NONE;
5010 }
5011
5012 int _uam_core_add_ibeacon_adv(unsigned int adv_len, const char *iadv, const int app_num)
5013 {
5014         FUNC_ENTRY;
5015         int ret;
5016
5017         UAM_INFO("adv_len = %u, iadv = 0x%0x:0x%0x:0x%0x", adv_len,
5018                 iadv[0], iadv[1], iadv[2]);
5019
5020         ret = _uam_db_insert_adv_info(adv_len, iadv, app_num);
5021         if (UAM_ERROR_NONE != ret) {
5022                 UAM_ERR("_uam_db_insert_adv_info failed");
5023                 return ret;
5024         }
5025
5026         ret = _uam_pm_add_ibeacon_adv(adv_len, iadv);
5027         if (UAM_ERROR_NONE != ret) {
5028                 UAM_ERR("Failed with error: %s (0x%4.4X)",
5029                                 _uam_manager_error_to_str(ret), ret);
5030                 return ret;
5031         }
5032
5033         FUNC_EXIT;
5034         return UAM_ERROR_NONE;
5035 }
5036
5037 void _uam_core_handle_status_changed(unsigned int sensor, void *info)
5038 {
5039         FUNC_ENTRY;
5040
5041         uam_sensor_info_s *sensor_info = info;
5042
5043         ret_if(NULL == info);
5044
5045         UAM_INFO("sensor: 0x%8.8X %s", sensor, sensor_info->status == UAS_ABSENCE ?
5046                 "UAM_EVENT_ABSENCE_DETECTED" : "UAM_EVENT_PRESENCE_DETECTED");
5047         UAM_DBG("%llu %d %d", sensor_info->timestamp,
5048                 sensor_info->accuracy, sensor_info->count);
5049
5050         _uam_manager_send_event(NULL, UAM_EVENT_SENSOR_STATUS_CHANGED,
5051                 g_variant_new("(uutiidddd)", sensor, sensor_info->status, sensor_info->timestamp,
5052                 sensor_info->accuracy, sensor_info->count, sensor_info->values[0],
5053                 sensor_info->values[1], sensor_info->values[2], sensor_info->values[3]));
5054
5055         FUNC_EXIT;
5056 }
5057
5058 int _uam_core_add_payload(uam_ble_payload_s *payload,
5059                 const char *device_id, int tech_type, const int app_num)
5060 {
5061         FUNC_ENTRY;
5062         int ret = UAM_ERROR_NONE;
5063         uam_db_tech_info_t *tech_info;
5064         uam_db_payload_info_t *db_payload;
5065         char *mac;
5066
5067         retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
5068         retv_if(NULL == device_id, UAM_ERROR_INVALID_PARAMETER);
5069         retv_if(UAM_TECH_TYPE_NONE >= tech_type, UAM_ERROR_INVALID_PARAMETER);
5070         retv_if(UAM_TECH_TYPE_MAX <= tech_type, UAM_ERROR_INVALID_PARAMETER);
5071
5072         /* <TO-DO> check if payload already exist */
5073         __print_payload(payload);
5074
5075         tech_info = __uam_core_get_dev_tech_info(device_id, tech_type);
5076         retv_if(NULL == tech_info, UAM_ERROR_INVALID_PARAMETER);
5077         mac = __get_mac_addr(tech_info);
5078
5079         db_payload = g_new0(uam_db_payload_info_t, 1);
5080         __uam_copy_uam_payload_info(db_payload, payload);
5081         db_payload->device_id = g_strdup(device_id);
5082         db_payload->tech_type = tech_type;
5083         db_payload->app_num = app_num;
5084         payloads = g_slist_append(payloads, db_payload);
5085
5086         /*** Add payload to database ***/
5087         ret = _uam_db_insert_payload_info(device_id, tech_type, mac, payload, app_num);
5088         if (UAM_ERROR_NONE != ret) {
5089                 UAM_ERR("_uam_db_insert_payload_info failed");
5090                 return ret;
5091         }
5092
5093         FUNC_EXIT;
5094         return UAM_ERROR_NONE;
5095 }
5096
5097 int _uam_core_service_add_payload(uam_ble_payload_s *payload,
5098                 const char *svc_name, const int app_num)
5099 {
5100         FUNC_ENTRY;
5101         int ret = UAM_ERROR_NONE;
5102         uam_db_service_info_t *service;
5103         uam_db_payload_info_t *db_payload;
5104         uam_svc_dev_info_t *svc_dev;
5105         GSList *l;
5106
5107         retv_if(NULL == payload, UAM_ERROR_INVALID_PARAMETER);
5108         retv_if(NULL == svc_name, UAM_ERROR_INVALID_PARAMETER);
5109
5110         /* Retrieve service from list */
5111         l = __search_service(services, svc_name, app_num);
5112         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
5113         service = l->data;
5114
5115         /* Retrieve payload from list */
5116         l = g_slist_find_custom(payloads, payload, __compare_payload);
5117         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
5118         db_payload = l->data;
5119
5120         /* Retrieve device from list */
5121         l = g_slist_find_custom(devices, db_payload->device_id, __compare_device_id);
5122         retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
5123
5124         svc_dev = _uam_core_find_svc_dev_info(db_payload->device_id,
5125                 db_payload->tech_type, service->name, app_num);
5126         retv_if(NULL == svc_dev, UAM_ERROR_INVALID_PARAMETER);
5127
5128         /**Update svc_dev*/
5129         _uam_core_update_svc_dev_info(db_payload->device_id, db_payload->tech_type,
5130                 service->name, -1, -1, payload, app_num);
5131
5132         /* Set/update registered device list to plugins */
5133         if (UAM_ERROR_NONE != _uam_pm_set_registered_devices(devices,
5134                         __uam_core_tech_type_to_sensor(db_payload->tech_type)))
5135                 UAM_ERR("_uam_pm_set_registered_devices failed");
5136
5137         /*** Add payload service mapping to database ***/
5138         ret = _uam_db_update_device_service_payload_info(payload, service->name, app_num);
5139         if (UAM_ERROR_NONE != ret) {
5140                 UAM_ERR("_uam_db_update_device_service_payload_info failed");
5141                 return ret;
5142         }
5143
5144         FUNC_EXIT;
5145         return UAM_ERROR_NONE;
5146 }
5147
5148 int _uam_core_get_payloads(int *count, uam_ble_payload_s **payload_list, const int app_num)
5149 {
5150         FUNC_ENTRY;
5151         guint size;
5152         GSList *l;
5153
5154         size = g_slist_length(payloads);
5155         *payload_list = g_new0(uam_ble_payload_s, size);
5156         *count = 0;
5157
5158         /* fetch payloads list from DB */
5159         for (l = payloads; l; l = g_slist_next(l)) {
5160                 uam_db_payload_info_t *db_info = l->data;
5161
5162                 if (!db_info)
5163                         continue;
5164                 UAM_DBG("db_info->app_num is [%d]", db_info->app_num);
5165                 if (db_info->app_num != app_num)
5166                         continue;
5167                 __uam_copy_db_payload_info(&((*payload_list)[*count]), db_info);
5168                 __print_db_payload(db_info);
5169                 *count += 1;
5170         }
5171
5172         UAM_INFO("Count: %d", *count);
5173         FUNC_EXIT;
5174         return UAM_ERROR_NONE;
5175 }