Rename ble payload service_id to primary_key
[platform/core/connectivity/ua-manager.git] / ua-daemon / src / ua-manager-request-handler.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 "ua-internal.h"
19 #include "ua-manager-common.h"
20 #include "ua-manager-core.h"
21
22 extern GMainLoop *main_loop;
23
24 /* For maintaining Application Sync API call requests */
25 static GSList *request_list = NULL;
26
27 static GDBusConnection *uam_manager_conn;
28 static guint g_dbus_object_id = 0;
29 static guint owner_id = 0;
30 static guint owner_sig_id = 0;
31
32 static const gchar uam_manager_introspection_xml[] =
33 "<node name='/net/uamd'>"
34 "       <interface name='net.uamd'>"
35 "               <method name='enable'>"
36 "               <arg type='i' name='enable' direction='in' />"
37 "               <arg type='i' name='result' direction='out' />"
38 "               </method>"
39 "               <method name='uam_request'>"
40 "                       <arg type='i' name='request_function' direction='in' />"
41 "                       <arg type='ay' name='input_param1' direction='in' />"
42 "                       <arg type='ay' name='input_param2' direction='in' />"
43 "                       <arg type='ay' name='input_param3' direction='in' />"
44 "                       <arg type='ay' name='input_param4' direction='in' />"
45 "                       <arg type='i' name='output_param1' direction='out' />"
46 "                       <arg type='v' name='output_param2' direction='out' />"
47 "               </method>"
48 "       </interface>"
49 "</node>";
50
51 #define UAM_ASYNC_REQUEST_TIMEOUT 11 /* 11 sec */
52
53 static void __uam_manager_copy_params(
54                 GVariant *in_param, void *value, int size)
55 {
56         FUNC_ENTRY;
57
58         void *buf = NULL;
59
60         buf = (void *)g_variant_get_data(in_param);
61         memcpy(value, buf, size);
62
63         FUNC_EXIT;
64 }
65
66 static int __uam_manager_sync_request_handler(
67                 GDBusMethodInvocation *context,
68                 int function,
69                 GVariant *in_param1,
70                 GVariant *in_param2,
71                 GVariant *in_param3,
72                 GVariant *in_param4,
73                 GArray **out_param1)
74 {
75         FUNC_ENTRY;
76         int result = UAM_ERROR_NOT_SUPPORTED;
77         char *sender = NULL;
78
79         sender = (char*)g_dbus_method_invocation_get_sender(context);
80
81         switch (function) {
82         case UAM_REQUEST_GET_AVAILABLE_SENSORS: {
83                 unsigned int sensor_bitmask = 0;
84
85                 result = _uam_core_get_available_sensors(&sensor_bitmask);
86                 g_array_append_vals(*out_param1,
87                                 &sensor_bitmask, sizeof(unsigned int));
88                 break;
89         }
90         case UAM_REQUEST_IS_SENSOR_READY: {
91                 gboolean is_ready;
92                 unsigned int sensor = 0;
93
94                 __uam_manager_copy_params(in_param1,
95                                 &sensor, sizeof(unsigned int));
96
97                 is_ready = _uam_core_is_sensor_ready(sensor);
98                 g_array_append_vals(*out_param1,
99                                 &is_ready, sizeof(gboolean));
100                 result = UAM_ERROR_NONE;
101                 break;
102         }
103         case UAM_REQUEST_GET_DEFAULT_USER: {
104                 uam_user_info_s user;
105
106                 result = _uam_core_get_default_user(&user);
107                 g_array_append_vals(*out_param1,
108                                 &user, sizeof(uam_user_info_s));
109                 break;
110         }
111         case UAM_REQUEST_ADD_USER: {
112                 int user_id;
113                 const char *account;
114                 const char *name;
115
116                 account = (char *)g_variant_get_data(in_param1);
117                 name = (char *)g_variant_get_data(in_param2);
118
119                 result = _uam_core_add_user(&user_id, account, name);
120
121                 UAM_DBG("UserID: [%d] Account: [%s], Name: [%s]", user_id, account, name);
122                 break;
123         }
124         case UAM_REQUEST_DELETE_USER: {
125                 const char *account;
126
127                 account = (char *)g_variant_get_data(in_param1);
128                 UAM_DBG("Account: [%s]", account);
129
130                 result = _uam_core_remove_user(account);
131                 break;
132         }
133         case UAM_REQUEST_UPDATE_USER: {
134                 uam_user_info_s user;
135
136                 __uam_manager_copy_params(in_param1,
137                                 &user, sizeof(uam_user_info_s));
138                 UAM_DBG("Account: [%s] Name: [%s]", user.account, user.name);
139
140                 result = _uam_core_update_user(&user);
141                 break;
142
143         }
144         case UAM_REQUEST_GET_USER_BY_ACCOUNT: {
145                 const char *account;
146                 uam_user_info_s user;
147
148                 account = (char *)g_variant_get_data(in_param1);
149                 UAM_DBG("Account: [%s]", account);
150
151                 result = _uam_core_get_user_by_account(account, &user);
152                 if (UAM_ERROR_NONE == result)
153                         g_array_append_vals(*out_param1,
154                                         &user, sizeof(uam_user_info_s));
155                 break;
156         }
157         case UAM_REQUEST_GET_USER_BY_DEVICE_ID: {
158                 const char *device_id;
159                 uam_user_info_s user;
160
161                 device_id = (char *)g_variant_get_data(in_param1);
162                 UAM_DBG("device_id: [%s]", device_id);
163
164                 result = _uam_core_get_user_by_device_id(device_id, &user);
165                 if (UAM_ERROR_NONE == result)
166                         g_array_append_vals(*out_param1,
167                                         &user, sizeof(uam_user_info_s));
168                 break;
169         }
170         case UAM_REQUEST_GET_USER_BY_MAC: {
171                 const char *mac;
172                 uam_user_info_s user;
173
174                 mac = (char *)g_variant_get_data(in_param1);
175                 UAM_DBG("MAC: [%s]", mac);
176
177                 result = _uam_core_get_user_by_mac(mac, &user);
178                 if (UAM_ERROR_NONE == result)
179                         g_array_append_vals(*out_param1,
180                                         &user, sizeof(uam_user_info_s));
181                 break;
182         }
183         case UAM_REQUEST_GET_USERS: {
184                 int count = 0;
185                 uam_user_info_s *users = NULL;
186
187                 result = _uam_core_get_users(&count, &users);
188                 if (UAM_ERROR_NONE == result) {
189                         int indx;
190
191                         for (indx = 0; indx < count; indx++)
192                                 g_array_append_vals(*out_param1,
193                                                 &(users[indx]), sizeof(uam_user_info_s));
194
195                         g_free(users);
196                 }
197                 break;
198         }
199         case UAM_REQUEST_IS_DEVICE_ADDED: {
200                 gboolean is_added = FALSE;
201                 uam_device_info_s dev_info;
202
203                 __uam_manager_copy_params(in_param1,
204                                 &dev_info, sizeof(uam_device_info_s));
205                 UAM_DBG("DeviceId: [%s], Type: %d, MAC: [%s], discriminant: [%s]",
206                                 dev_info.device_id, dev_info.type, dev_info.mac,
207                                 dev_info.discriminant ? "True" : "False");
208
209                 result = _uam_core_is_device_added(&dev_info, &is_added);
210                 g_array_append_vals(*out_param1,
211                                 &is_added, sizeof(gboolean));
212                 break;
213         }
214         case UAM_REQUEST_DELETE_DEVICE: {
215                 const char *account;
216                 uam_device_info_s dev_info;
217
218                 account = (char *)g_variant_get_data(in_param1);
219                 __uam_manager_copy_params(in_param2,
220                                 &dev_info, sizeof(uam_device_info_s));
221                 UAM_DBG("Account: [%s], Type: %d, MAC: [%s]",
222                                 account, dev_info.type, dev_info.mac);
223
224                 result = _uam_core_remove_device(account, &dev_info);
225                 break;
226         }
227         case UAM_REQUEST_UPDATE_DEVICE: {
228                 uam_device_info_s dev_info;
229
230                 __uam_manager_copy_params(in_param1,
231                                 &dev_info, sizeof(uam_device_info_s));
232                 UAM_DBG("Device ID: [%s], Type: %d, MAC: [%s], discriminant: [%s]",
233                                 dev_info.device_id, dev_info.type, dev_info.mac,
234                                 dev_info.discriminant ? "True" : "False");
235
236                 result = _uam_core_update_device(&dev_info);
237                 break;
238         }
239         case UAM_REQUEST_DELETE_DEVICE_BY_DEVICE_ID: {
240                 const char *device_id;
241                 int tech_type;
242
243                 device_id = (char *)g_variant_get_data(in_param1);
244                 __uam_manager_copy_params(in_param2, &tech_type, sizeof(int));
245                 UAM_DBG("device_id: [%s], tech_type: %d", device_id, tech_type);
246
247                 result = _uam_core_remove_device_by_device_id(device_id, tech_type);
248                 break;
249         }
250         case UAM_REQUEST_DELETE_DEVICE_BY_MAC: {
251                 const char *mac;
252
253                 mac = (char *)g_variant_get_data(in_param1);
254                 UAM_DBG("MAC: [%s]", mac);
255
256                 result = _uam_core_remove_device_by_mac(mac);
257                 break;
258         }
259         case UAM_REQUEST_GET_DEVICE_BY_DEVICE_ID: {
260                 const char *device_id;
261                 int tech_type;
262                 uam_device_info_s device;
263
264                 device_id = (char *)g_variant_get_data(in_param1);
265                 __uam_manager_copy_params(in_param2, &tech_type, sizeof(int));
266                 UAM_DBG("device_id: [%s], tech_type: %d", device_id, tech_type);
267
268                 result = _uam_core_get_devcie_by_device_id(device_id, tech_type, &device);
269                 if (UAM_ERROR_NONE == result)
270                         g_array_append_vals(*out_param1,
271                                         &device, sizeof(uam_device_info_s));
272                 break;
273         }
274         case UAM_REQUEST_GET_DEVICE_BY_MAC: {
275                 const char *mac;
276                 uam_device_info_s device;
277
278                 mac = (char *)g_variant_get_data(in_param1);
279                 UAM_DBG("mac: [%s]", mac);
280
281                 result = _uam_core_get_devcie_by_mac(mac, &device);
282                 if (UAM_ERROR_NONE == result)
283                         g_array_append_vals(*out_param1,
284                                         &device, sizeof(uam_device_info_s));
285                 break;
286         }
287         case UAM_REQUEST_GET_DEVICES: {
288                 int count = 0;
289                 uam_device_info_s *devices = NULL;
290
291                 result = _uam_core_get_devices(&count, &devices);
292                 if (UAM_ERROR_NONE == result) {
293                         int indx;
294
295                         for (indx = 0; indx < count; indx++)
296                                 g_array_append_vals(*out_param1,
297                                                 &(devices[indx]), sizeof(uam_device_info_s));
298
299                         g_free(devices);
300                 }
301                 break;
302         }
303         case UAM_REQUEST_GET_USER_DEVICES: {
304                 const char *account;
305                 int count = 0;
306                 uam_device_info_s *devices = NULL;
307
308                 account = (char *)g_variant_get_data(in_param1);
309                 UAM_DBG("Account: [%s]", account);
310
311                 result = _uam_core_get_user_devices(account, &count, &devices);
312                 if (UAM_ERROR_NONE == result) {
313                         int indx;
314
315                         for (indx = 0; indx < count; indx++)
316                                 g_array_append_vals(*out_param1,
317                                                 &(devices[indx]), sizeof(uam_device_info_s));
318
319                         g_free(devices);
320                 }
321                 break;
322         }
323         case UAM_REQUEST_SET_DETECTION_THRESHOLD: {
324                 unsigned int sensor = 0;
325                 int presence_threshold = 0;
326                 int absence_threshold = 0;
327
328                 __uam_manager_copy_params(in_param1,
329                                 &sensor, sizeof(unsigned int));
330                 __uam_manager_copy_params(in_param2,
331                                 &presence_threshold, sizeof(int));
332                 __uam_manager_copy_params(in_param3,
333                                 &absence_threshold, sizeof(int));
334
335                 result = _uam_core_set_detection_threshold(sensor,
336                                 presence_threshold, absence_threshold);
337                 break;
338         }
339         case UAM_REQUEST_START_PRESENCE_DETECTION: {
340                 unsigned int sensors;
341                 const char *svc_name;
342
343                 __uam_manager_copy_params(in_param1,
344                                 &sensors, sizeof(unsigned int));
345                 svc_name = (char *)g_variant_get_data(in_param2);
346
347                 result = _uam_core_start_presence_detection(svc_name, sender, sensors);
348                 break;
349         }
350         case UAM_REQUEST_STOP_PRESENCE_DETECTION: {
351                 unsigned int sensors;
352                 const char *svc_name;
353
354                 __uam_manager_copy_params(in_param1,
355                                 &sensors, sizeof(unsigned int));
356                 svc_name = (char *)g_variant_get_data(in_param2);
357
358                 result = _uam_core_stop_presence_detection(svc_name, sender, sensors);
359                 break;
360         }
361         case UAM_REQUEST_START_ABSENCE_DETECTION: {
362                 unsigned int sensors;
363                 const char *svc_name;
364
365                 __uam_manager_copy_params(in_param1,
366                                 &sensors, sizeof(unsigned int));
367                 svc_name = (char *)g_variant_get_data(in_param2);
368
369                 result = _uam_core_start_absence_detection(svc_name, sender, sensors);
370                 break;
371         }
372         case UAM_REQUEST_STOP_ABSENCE_DETECTION: {
373                 unsigned int sensors;
374                 const char *svc_name;
375
376                 __uam_manager_copy_params(in_param1,
377                                 &sensors, sizeof(unsigned int));
378                 svc_name = (char *)g_variant_get_data(in_param2);
379
380                 result = _uam_core_stop_absence_detection(svc_name, sender, sensors);
381                 break;
382         }
383         case UAM_REQUEST_SET_LOW_POWER_MODE: {
384                 gboolean mode = FALSE;
385                 unsigned int bitmask = 0;
386
387                 __uam_manager_copy_params(in_param1,
388                                 &bitmask, sizeof(unsigned int));
389                 __uam_manager_copy_params(in_param2,
390                                 &mode, sizeof(gboolean));
391
392                 result = _uam_core_set_low_power_mode(bitmask, mode);
393                 break;
394         }
395         case UAM_REQUEST_START_SEARCH_ACTIVE_DEVICES: {
396                 unsigned int sensors;
397                 int detection_period;
398
399                 __uam_manager_copy_params(in_param1,
400                                 &sensors, sizeof(unsigned int));
401
402                 __uam_manager_copy_params(in_param2,
403                                 &detection_period, sizeof(int));
404
405                 result = _uam_core_start_active_device_scan(sender, sensors, detection_period);
406                 break;
407         }
408         case UAM_REQUEST_STOP_SEARCH_ACTIVE_DEVICES: {
409                 unsigned int sensors;
410
411                 __uam_manager_copy_params(in_param1,
412                                 &sensors, sizeof(unsigned int));
413
414                 result = _uam_core_stop_active_device_scan(sender, sensors);
415                 break;
416         }
417         case UAM_REQUEST_REGISTER_APP: {
418                 uam_app_info_s app_info;
419
420                 __uam_manager_copy_params(in_param1,
421                                 &app_info, sizeof(uam_app_info_s));
422
423                 result = _uam_register_app_info(sender, app_info);
424                 break;
425         }
426         case UAM_REQUEST_DEREGISTER_APP: {
427                 uam_app_info_s app_info;
428
429                 __uam_manager_copy_params(in_param1,
430                                 &app_info, sizeof(uam_app_info_s));
431
432                 result = _uam_deregister_app_info(sender, app_info);
433                 break;
434         }
435         case UAM_REQUEST_ADD_USER_TO_SERVICE: {
436                 const char *svc_name;
437                 const char *account;
438
439                 svc_name = (char *)g_variant_get_data(in_param1);
440                 account = (char *)g_variant_get_data(in_param2);
441                 UAM_DBG("Account: [%s], Service: [%s]", account, svc_name);
442
443                 result = _uam_core_service_add_user(svc_name, account);
444                 break;
445         }
446         case UAM_REQUEST_REMOVE_USER_FROM_SERVICE: {
447                 const char *svc_name;
448                 const char *account;
449
450                 svc_name = (char *)g_variant_get_data(in_param1);
451                 account = (char *)g_variant_get_data(in_param2);
452                 UAM_DBG("Account: [%s], Service: [%s]", account, svc_name);
453
454                 result = _uam_core_service_remove_user(svc_name, account);
455                 break;
456         }
457         case UAM_REQUEST_ADD_DEVICE_TO_SERVICE: {
458                 const char *svc_name;
459                 const char *device_id;
460                 int tech_type;
461
462                 svc_name = (char *)g_variant_get_data(in_param1);
463                 device_id = (char *)g_variant_get_data(in_param2);
464                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
465                 UAM_DBG("Service: [%s] device_id: [%s], tech_type: %d",
466                                 svc_name, device_id, tech_type);
467
468                 result = _uam_core_service_add_device(svc_name, device_id, tech_type);
469                 break;
470         }
471         case UAM_REQUEST_REMOVE_DEVICE_FROM_SERVICE: {
472                 const char *svc_name;
473                 const char *device_id;
474                 int tech_type;
475
476                 svc_name = (char *)g_variant_get_data(in_param1);
477                 device_id = (char *)g_variant_get_data(in_param2);
478                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
479                 UAM_DBG("Service: [%s] device_id: [%s], tech_type: %d",
480                                 svc_name, device_id, tech_type);
481
482                 result = _uam_core_service_remove_device(svc_name, device_id, tech_type);
483                 break;
484         }
485         case UAM_REQUEST_SET_DEVICE_SERVICES_DISCRIMINANT: {
486                 const char *svc_name;
487                 const char *device_id;
488                 int tech_type;
489                 gboolean discriminant;
490
491                 svc_name = (char *)g_variant_get_data(in_param1);
492                 device_id = (char *)g_variant_get_data(in_param2);
493                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
494                 __uam_manager_copy_params(in_param4, &discriminant, sizeof(gboolean));
495                 UAM_DBG("Service: [%s] device_id: [%s], tech_type: %d, discriminant: %d",
496                                 svc_name, device_id, tech_type, discriminant);
497
498                 result = _uam_core_service_set_device_discriminant(svc_name, device_id,
499                                         tech_type, discriminant);
500                 break;
501         }
502         case UAM_REQUEST_GET_DEVICE_SERVICES_DISCRIMINANT: {
503                 const char *svc_name;
504                 const char *device_id;
505                 int tech_type;
506                 gboolean discriminant;
507
508                 svc_name = (char *)g_variant_get_data(in_param1);
509                 device_id = (char *)g_variant_get_data(in_param2);
510                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
511                 result = _uam_core_service_get_device_discriminant(svc_name, device_id,
512                                         tech_type, &discriminant);
513                 if (UAM_ERROR_NONE == result)
514                         g_array_append_vals(*out_param1, &discriminant, sizeof(gboolean));
515
516                 UAM_DBG("Service: [%s] device_id: [%s], tech_type: %d, discriminant: %d",
517                                 svc_name, device_id, tech_type, discriminant);
518                 break;
519         }
520         case UAM_REQUEST_GET_DEVICE_SERVICES_LAST_SEEN: {
521                 const char *svc_name;
522                 const char *device_id;
523                 int tech_type;
524                 unsigned long long last_seen;
525
526                 svc_name = (char *)g_variant_get_data(in_param1);
527                 device_id = (char *)g_variant_get_data(in_param2);
528                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
529                 result = _uam_core_service_get_device_last_seen(svc_name, device_id,
530                                         tech_type, &last_seen);
531                 if (UAM_ERROR_NONE == result)
532                         g_array_append_vals(*out_param1, &last_seen, sizeof(unsigned long long));
533
534                 UAM_DBG("Service: [%s] device_id: [%s], tech_type: %d, last_seen: %llu",
535                                 svc_name, device_id, tech_type, last_seen);
536                 break;
537         }
538         case UAM_REQUEST_SET_SERVICE_DETECTION_CYCLE: {
539                 const char *svc_name;
540                 unsigned int cycle;
541
542                 svc_name = (char *)g_variant_get_data(in_param1);
543                 __uam_manager_copy_params(in_param2, &cycle, sizeof(unsigned int));
544                 UAM_DBG("Service: [%s], Cycle [%d]", svc_name, cycle);
545
546                 result = _uam_core_set_service_detection_cycle(svc_name, cycle);
547                 break;
548         }
549         case UAM_REQUEST_GET_SERVICE_DETECTION_CYCLE: {
550                 const char *svc_name;
551                 unsigned int cycle;
552
553                 svc_name = (char *)g_variant_get_data(in_param1);
554                 UAM_DBG("Service: [%s]", svc_name);
555
556                 result = _uam_core_get_service_detection_cycle(svc_name, &cycle);
557                 if (UAM_ERROR_NONE == result)
558                         g_array_append_vals(*out_param1, &cycle, sizeof(unsigned int));
559
560                 break;
561         }
562         case UAM_REQUEST_GET_DETECTION_WINDOW: {
563                 unsigned int detection_window = 0;
564
565                 result = _uam_core_get_detection_window(&detection_window);
566                 if (UAM_ERROR_NONE == result)
567                         g_array_append_vals(*out_param1,
568                                         &detection_window, sizeof(unsigned int));
569                 break;
570         }
571         case UAM_REQUEST_SET_DETECTION_WINDOW: {
572                 unsigned int detection_window = 0;
573
574                 __uam_manager_copy_params(in_param1,
575                                 &detection_window, sizeof(unsigned int));
576
577                 result = _uam_core_set_detection_window(detection_window);
578                 break;
579         }
580         case UAM_REQUEST_RESET_DB: {
581                 _uam_core_reset_database();
582                 result = UAM_ERROR_NONE;
583                 break;
584         }
585         case UAM_REQUEST_GET_DEFAULT_SERVICE: {
586                 uam_service_info_s service;
587
588                 result = _uam_core_get_default_service(&service);
589                 g_array_append_vals(*out_param1,
590                                 &service, sizeof(uam_service_info_s));
591                 break;
592         }
593         case UAM_REQUEST_REGISTER_SERVICE: {
594                 uam_service_info_s svc;
595
596                 __uam_manager_copy_params(in_param1,
597                                 &svc, sizeof(uam_service_info_s));
598                 UAM_DBG("Name: [%s] Threshold presence: [%d] absence: [%d]",
599                                 svc.name, svc.presence_threshold, svc.absence_threshold);
600
601                 result = _uam_core_register_service(&svc);
602                 break;
603
604         }
605         case UAM_REQUEST_UPDATE_SERVICE: {
606                 uam_service_info_s svc;
607
608                 __uam_manager_copy_params(in_param1,
609                                 &svc, sizeof(uam_service_info_s));
610                 UAM_DBG("Name: [%s] Threshold presence: [%d] absence: [%d]",
611                                 svc.name, svc.presence_threshold, svc.absence_threshold);
612
613                 result = _uam_core_update_service(&svc);
614                 break;
615
616         }
617         case UAM_REQUEST_UNREGISTER_SERVICE: {
618                 const char *svc_name;
619
620                 svc_name = (char *)g_variant_get_data(in_param1);
621                 UAM_DBG("Name: [%s]", svc_name);
622
623                 result = _uam_core_unregister_service(svc_name);
624                 break;
625
626         }
627         case UAM_REQUEST_GET_SERVICE_DEVICES: {
628                 const char *svc_name;
629                 int count = 0;
630                 uam_device_info_s *devices = NULL;
631
632                 svc_name = (char *)g_variant_get_data(in_param1);
633                 UAM_DBG("Service: [%s]", svc_name);
634
635                 result = _uam_core_get_service_devices(svc_name, &count, &devices);
636                 if (UAM_ERROR_NONE == result) {
637                         int indx;
638
639                         for (indx = 0; indx < count; indx++)
640                                 g_array_append_vals(*out_param1,
641                                                 &(devices[indx]), sizeof(uam_device_info_s));
642
643                         g_free(devices);
644                 }
645                 break;
646         }
647         case UAM_REQUEST_GET_SERVICE_USERS: {
648                 const char *svc_name;
649                 int count = 0;
650                 uam_user_info_s *users = NULL;
651
652                 svc_name = (char *)g_variant_get_data(in_param1);
653                 UAM_DBG("Service: [%s]", svc_name);
654
655                 result = _uam_core_get_service_users(svc_name, &count, &users);
656                 if (UAM_ERROR_NONE == result) {
657                         int indx;
658
659                         for (indx = 0; indx < count; indx++)
660                                 g_array_append_vals(*out_param1,
661                                                 &(users[indx]), sizeof(uam_user_info_s));
662
663                         g_free(users);
664                 }
665                 break;
666         }
667         case UAM_REQUEST_GET_SERVICES: {
668                 int count = 0;
669                 uam_service_info_s *services = NULL;
670
671                 result = _uam_core_get_services(&count, &services);
672                 if (UAM_ERROR_NONE == result) {
673                         int indx;
674
675                         for (indx = 0; indx < count; indx++)
676                                 g_array_append_vals(*out_param1,
677                                                 &(services[indx]), sizeof(uam_service_info_s));
678
679                         g_free(services);
680                 }
681                 break;
682         }
683         case UAM_REQUEST_ADD_IBEACON_ADV: {
684                 unsigned int adv_len;
685                 const char *iadv;
686
687                 __uam_manager_copy_params(in_param1, &adv_len, sizeof(unsigned int));
688                 iadv = (char *)g_variant_get_data(in_param2);
689
690                 result = _uam_core_add_ibeacon_adv(adv_len, iadv);
691                 break;
692         }
693         default:
694                 UAM_WARN("UnSupported function [%s(0x%4.4X)]",
695                                 _uam_manager_request_to_str(function), function);
696                 result = UAM_ERROR_NOT_SUPPORTED;
697                 break;
698         }
699
700         FUNC_EXIT;
701         return result;
702 }
703
704 static gboolean __uam_manager_is_request_pending(int function, void *data)
705 {
706         FUNC_ENTRY;
707         GSList *l;
708
709         for (l = request_list; l; l = g_slist_next(l)) {
710                 uam_request_context_t *info = l->data;
711
712                 if (!info)
713                         continue;
714
715                 if (info->function == function) {
716                         switch (function) {
717                         case UAM_REQUEST_ADD_DEVICE:
718                         {
719                                 const char *device_id = (const char *)data;
720                                 uam_device_info_s *dev_info = (uam_device_info_s *)info->data;
721
722                                 if (!g_strcmp0(device_id,
723                                                dev_info->device_id))
724                                         return TRUE;
725                         }
726                         break;
727                         default:
728                                 return TRUE;
729                         };
730                 }
731         }
732
733         FUNC_EXIT;
734         return FALSE;
735 }
736
737 static gboolean __uam_request_context_timeout_cb(gpointer p)
738 {
739         FUNC_ENTRY;
740
741         uam_request_context_t *info = p;
742         retv_if(info == NULL, G_SOURCE_REMOVE);
743
744         /* Remove unhandled async-request */
745         _uam_manager_remove_req_ctxt_from_list(info);
746
747         FUNC_EXIT;
748         return G_SOURCE_REMOVE;
749 }
750
751 static void __uam_manager_save_request_context(
752                 GDBusMethodInvocation *context, int result,
753                 char *sender, int function, gpointer data)
754 {
755         FUNC_ENTRY;
756         uam_request_context_t *info;
757
758         UAM_DBG("Save the request context for [%s(0x%4.4X)]",
759                         _uam_manager_request_to_str(function), function);
760
761         info = g_malloc0(sizeof(uam_request_context_t));
762         if (!info) {
763                 UAM_ERR("Failed to allocated memory [%s][%d]", sender, function);
764                 return;
765         }
766         info->context = context;
767         info->result = result;
768         info->sender = g_strdup(sender);
769         if (!info->sender) {
770                 g_free(info);
771                 info = NULL;
772                 UAM_ERR("Failed to allocated memory [%s][%d]", sender, function);
773                 return;
774         }
775         info->function = function;
776         info->data = data;
777         request_list = g_slist_append(request_list, info);
778
779         info->tid = _uam_add_timer_full(TIMER_RES_SEC, G_PRIORITY_DEFAULT,
780                 UAM_ASYNC_REQUEST_TIMEOUT, __uam_request_context_timeout_cb, info, NULL);
781
782         FUNC_EXIT;
783 }
784
785 static int __uam_manager_async_request_handler(
786                 GDBusMethodInvocation *context,
787                 int function,
788                 GVariant *in_param1,
789                 GVariant *in_param2,
790                 GVariant *in_param3,
791                 GVariant *in_param4,
792                 GArray **out_param1)
793 {
794         FUNC_ENTRY;
795         int result = UAM_ERROR_NOT_SUPPORTED;
796         char *sender = NULL;
797
798         sender = (char*)g_dbus_method_invocation_get_sender(context);
799
800         switch (function) {
801         case UAM_REQUEST_ADD_DEVICE: {
802                 const char *account;
803                 uam_device_info_s dev_info;
804
805                 account = (char *)g_variant_get_data(in_param1);
806                 __uam_manager_copy_params(in_param2,
807                                 &dev_info, sizeof(uam_device_info_s));
808                 UAM_DBG("Account: [%s], Type: %d, MAC: [%s] IP: [%s], ID: [%s], Discriminant: [%s]," \
809                         " Payload ServiceId: [0x%2.2X], Purpose: [0x%2.2X], DUID: [%s]," \
810                         " Device Icon: [0x%2.2X], BT MAC Address: [%s]",
811                                 account, dev_info.type, dev_info.mac,
812                                 dev_info.ipv4_addr, dev_info.device_id,
813                                 dev_info.discriminant ? "true" : "false",
814                                 dev_info.payload.primary_key, dev_info.payload.purpose,
815                                 dev_info.payload.duid, dev_info.payload.device_icon,
816                                 dev_info.payload.bt_mac);
817
818                 if (__uam_manager_is_request_pending(UAM_REQUEST_ADD_DEVICE,
819                                                      dev_info.device_id)) {
820                         UAM_ERR("Another request is already in progress");
821                         result = UAM_ERROR_NOW_IN_PROGRESS;
822                         break;
823                 }
824
825                 result = _uam_core_add_device(account, &dev_info);
826                 if (UAM_ERROR_NONE == result) {
827                         __uam_manager_save_request_context(
828                                         context, result, sender, function,
829                                         g_memdup(&dev_info, sizeof(uam_device_info_s)));
830                 }
831                 break;
832         }
833         default:
834                 UAM_WARN("UnSupported function [%s(0x%4.4X)]",
835                                 _uam_manager_request_to_str(function), function);
836                 result = UAM_ERROR_NOT_SUPPORTED;
837                 break;
838         }
839
840         FUNC_EXIT;
841         return result;
842 }
843
844 static gboolean __uam_manager_is_sync_function(int function)
845 {
846         switch (function) {
847         case UAM_REQUEST_GET_AVAILABLE_SENSORS:
848         case UAM_REQUEST_IS_SENSOR_READY:
849         case UAM_REQUEST_GET_DEFAULT_USER:
850         case UAM_REQUEST_ADD_USER:
851         case UAM_REQUEST_DELETE_USER:
852         case UAM_REQUEST_UPDATE_USER:
853         case UAM_REQUEST_GET_USER_BY_ACCOUNT:
854         case UAM_REQUEST_GET_USER_BY_DEVICE_ID:
855         case UAM_REQUEST_GET_USER_BY_MAC:
856         case UAM_REQUEST_GET_USERS:
857         case UAM_REQUEST_IS_DEVICE_ADDED:
858         case UAM_REQUEST_DELETE_DEVICE:
859         case UAM_REQUEST_UPDATE_DEVICE:
860         case UAM_REQUEST_DELETE_DEVICE_BY_DEVICE_ID:
861         case UAM_REQUEST_DELETE_DEVICE_BY_MAC:
862         case UAM_REQUEST_GET_DEVICE_BY_DEVICE_ID:
863         case UAM_REQUEST_GET_DEVICE_BY_MAC:
864         case UAM_REQUEST_GET_DEVICES:
865         case UAM_REQUEST_GET_USER_DEVICES:
866         case UAM_REQUEST_SET_DETECTION_THRESHOLD:
867         case UAM_REQUEST_START_PRESENCE_DETECTION:
868         case UAM_REQUEST_STOP_PRESENCE_DETECTION:
869         case UAM_REQUEST_START_ABSENCE_DETECTION:
870         case UAM_REQUEST_STOP_ABSENCE_DETECTION:
871         case UAM_REQUEST_SET_LOW_POWER_MODE:
872         case UAM_REQUEST_START_SEARCH_ACTIVE_DEVICES:
873         case UAM_REQUEST_STOP_SEARCH_ACTIVE_DEVICES:
874         case UAM_REQUEST_REGISTER_APP:
875         case UAM_REQUEST_DEREGISTER_APP:
876         case UAM_REQUEST_ADD_USER_TO_SERVICE:
877         case UAM_REQUEST_REMOVE_USER_FROM_SERVICE:
878         case UAM_REQUEST_ADD_DEVICE_TO_SERVICE:
879         case UAM_REQUEST_REMOVE_DEVICE_FROM_SERVICE:
880         case UAM_REQUEST_SET_DEVICE_SERVICES_DISCRIMINANT:
881         case UAM_REQUEST_GET_DEVICE_SERVICES_DISCRIMINANT:
882         case UAM_REQUEST_SET_SERVICE_DETECTION_CYCLE:
883         case UAM_REQUEST_GET_SERVICE_DETECTION_CYCLE:
884         case UAM_REQUEST_GET_DETECTION_WINDOW:
885         case UAM_REQUEST_SET_DETECTION_WINDOW:
886         case UAM_REQUEST_RESET_DB:
887         case UAM_REQUEST_GET_DEFAULT_SERVICE:
888         case UAM_REQUEST_REGISTER_SERVICE:
889         case UAM_REQUEST_UPDATE_SERVICE:
890         case UAM_REQUEST_UNREGISTER_SERVICE:
891         case UAM_REQUEST_GET_SERVICE_DEVICES:
892         case UAM_REQUEST_GET_SERVICE_USERS:
893         case UAM_REQUEST_GET_SERVICES:
894         case UAM_REQUEST_ADD_IBEACON_ADV:
895                 return TRUE;
896         default:
897                 return FALSE;
898         }
899 }
900
901 static void __uam_manager_method(
902                 GDBusConnection *connection,
903                 const gchar *sender,
904                 const gchar *object_path,
905                 const gchar *interface_name,
906                 const gchar *method_name,
907                 GVariant *parameters,
908                 GDBusMethodInvocation *invocation,
909                 gpointer user_data)
910 {
911         FUNC_ENTRY;
912         int result = UAM_ERROR_NONE;
913
914         UAM_DBG("Sender[%s] Method[%s] Path[%s] Interface[%s]",
915                         sender, method_name, object_path, interface_name);
916
917         if (0 == g_strcmp0(method_name, "enable")) {
918                 int enable = FALSE;
919
920                 g_variant_get(parameters, "(i)", &enable);
921                 UAM_INFO("ua-manager %s", enable == TRUE ? "enabled" : "disabled");
922
923                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", result));
924
925         } else if (0 == g_strcmp0(method_name, "uam_request")) {
926                 int function;
927
928                 GVariant *in_param1 = NULL;
929                 GVariant *in_param2 = NULL;
930                 GVariant *in_param3 = NULL;
931                 GVariant *in_param4 = NULL;
932                 GArray *out_param1 = NULL;
933
934                 g_variant_get(parameters, "(i@ay@ay@ay@ay)", &function,
935                                 &in_param1, &in_param2, &in_param3, &in_param4);
936
937                 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
938
939                 UAM_DBG("Request function = [%s (0x%4.4X)]",
940                                 _uam_manager_request_to_str(function), function);
941
942                 if (__uam_manager_is_sync_function(function)) {
943                         result = __uam_manager_sync_request_handler(invocation, function,
944                                         in_param1, in_param2, in_param3, in_param4, &out_param1);
945                 } else {
946                         result = __uam_manager_async_request_handler(invocation, function,
947                                         in_param1, in_param2, in_param3, in_param4, &out_param1);
948                         if (UAM_ERROR_NONE == result) {
949                                 UAM_DBG("Request context is saved, do not send reply over dbus");
950                                 goto done;
951                         }
952                 }
953
954                 if (UAM_ERROR_NONE != result) {
955                         UAM_ERR("Request [%s (0x%4.4X)] is failed with [%s (0x%4.4X])",
956                                         _uam_manager_request_to_str(function), function,
957                                         _uam_manager_error_to_str(result), result);
958                 }
959
960                 _uam_manager_method_return(invocation, out_param1, result);
961
962 done:
963                 g_variant_unref(in_param1);
964                 g_variant_unref(in_param2);
965                 g_variant_unref(in_param3);
966                 g_variant_unref(in_param4);
967                 g_array_unref(out_param1);
968         }
969
970         FUNC_EXIT;
971         return;
972 }
973
974 static GDBusNodeInfo *__uam_manager_create_method_node_info(
975                 const gchar *introspection_data)
976 {
977         FUNC_ENTRY;
978         GError *err = NULL;
979         GDBusNodeInfo *node_info = NULL;
980
981         if (introspection_data == NULL) {
982                 UAM_ERR("Introspection XML not present");
983                 return NULL;
984         }
985
986         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
987         if (err) {
988                 UAM_ERR("Unable to create node: %s", err->message);
989                 g_clear_error(&err);
990         }
991
992         FUNC_EXIT;
993         return node_info;
994 }
995
996 static const GDBusInterfaceVTable uam_method_table = {
997         __uam_manager_method,
998         NULL,
999         NULL,
1000         {0}
1001 };
1002
1003 static int __uam_manager_register_object(
1004                 GDBusConnection *conn, GDBusNodeInfo *node_info)
1005 {
1006         FUNC_ENTRY;
1007         GError *error = NULL;
1008
1009         retv_if(NULL == node_info, UAM_ERROR_INTERNAL);
1010
1011         g_dbus_object_id = g_dbus_connection_register_object(conn,
1012                         UAM_DAEMON_PATH,
1013                         node_info->interfaces[0],
1014                         &uam_method_table,
1015                         NULL, NULL, &error);
1016         retv_if(0 == g_dbus_object_id, UAM_ERROR_INTERNAL);
1017
1018         FUNC_EXIT;
1019         return UAM_ERROR_NONE;
1020 }
1021
1022 static int __uam_manager_unregister_object(GDBusConnection *conn)
1023 {
1024         FUNC_ENTRY;
1025
1026         if (g_dbus_object_id > 0) {
1027                 g_dbus_connection_unregister_object(
1028                                 conn, g_dbus_object_id);
1029                 g_dbus_object_id = 0;
1030         }
1031
1032         FUNC_EXIT;
1033         return UAM_ERROR_NONE;
1034 }
1035
1036 static void __uam_manager_name_acquired_cb(
1037                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1038 {
1039         UAM_INFO("DBus name [%s] acquired", name);
1040 }
1041
1042 static void __uam_manager_name_lost_cb(
1043                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1044 {
1045         if (NULL == connection) {
1046                 UAM_ERR("connection to the bus can't be made");
1047                 /*TODO: Terminate daemon */
1048                 return;
1049         }
1050
1051         UAM_ERR("DBus name [%s] lost", name);
1052         /*TODO: Terminate daemon */
1053 }
1054
1055 static void __uam_manager_owner_change_cb(GDBusConnection *connection,
1056                 const gchar *sender_name,
1057                 const gchar *object_path,
1058                 const gchar *interface_name,
1059                 const gchar *signal_name,
1060                 GVariant *parameters,
1061                 gpointer user_data)
1062 {
1063         const char *name = NULL;
1064         const char *old_owner = NULL;
1065         const char *new_owner = NULL;
1066
1067         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
1068
1069         if ('\0' == *new_owner) {
1070                 /* Clean up client info */
1071                 _uam_core_cleanup_monitor((char *)name);
1072         }
1073 }
1074
1075 static void __uam_manager_bus_acquired_cb(
1076                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1077 {
1078         FUNC_ENTRY;
1079
1080         UAM_INFO("DBus %s bus acquired", name);
1081
1082         GDBusNodeInfo *node_info = NULL;
1083
1084         UAM_INFO("DBus bus acquired");
1085
1086         ret_if(connection == NULL);
1087
1088         node_info = __uam_manager_create_method_node_info(
1089                         uam_manager_introspection_xml);
1090         ret_if(node_info == NULL);
1091
1092         __uam_manager_register_object(connection, node_info);
1093         g_dbus_node_info_unref(node_info);
1094
1095         /* Subscribe for name lost signal */
1096         owner_sig_id = g_dbus_connection_signal_subscribe(connection,
1097                         UAM_SERVICE_DBUS, UAM_INTERFACE_DBUS,
1098                         NAME_OWNER_CHANGED, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1099                         __uam_manager_owner_change_cb, NULL, NULL);
1100
1101         UAM_DBG("owner_sig_id: [%d]", owner_sig_id);
1102
1103         uam_manager_conn = connection;
1104
1105         FUNC_EXIT;
1106 }
1107
1108 int _uam_manager_register(void)
1109 {
1110         FUNC_ENTRY;
1111
1112         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1113                         UAM_DBUS_NAME,
1114                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1115                         __uam_manager_bus_acquired_cb,
1116                         __uam_manager_name_acquired_cb,
1117                         __uam_manager_name_lost_cb,
1118                         NULL, NULL);
1119         retv_if(0 == owner_id, UAM_ERROR_INTERNAL);
1120
1121         UAM_DBG("owner_id is [%d]", owner_id);
1122
1123         FUNC_EXIT;
1124         return UAM_ERROR_NONE;
1125 }
1126
1127 void _uam_manager_unregister(void)
1128 {
1129         FUNC_ENTRY;
1130
1131         if (uam_manager_conn) {
1132                 g_dbus_connection_signal_unsubscribe(uam_manager_conn, owner_sig_id);
1133                 __uam_manager_unregister_object(uam_manager_conn);
1134                 g_object_unref(uam_manager_conn);
1135                 g_bus_unown_name(owner_id);
1136         }
1137
1138         FUNC_EXIT;
1139 }
1140
1141 GSList *_uam_manager_get_request_list(void)
1142 {
1143         return request_list;
1144 }
1145
1146 void _uam_manager_remove_req_ctxt_from_list(uam_request_context_t *req_info)
1147 {
1148         FUNC_ENTRY;
1149
1150         ret_if(NULL == req_info);
1151         ret_if(NULL == req_info->sender);
1152
1153         GSList *l = request_list;
1154         while (l) {
1155
1156                 GSList *next = l->next;
1157                 uam_request_context_t *info = l->data;
1158
1159                 if (NULL == info) {
1160                         request_list = g_slist_remove_link(request_list, l);
1161                         l = next;
1162                         continue;
1163                 }
1164
1165                 if (NULL == info->sender) {
1166                         _uam_remove_timer(info->tid);
1167                         g_free(info->data);
1168                         g_free(info);
1169                         request_list = g_slist_remove_link(request_list, l);
1170                         l = next;
1171                         continue;
1172                 }
1173
1174                 if ((strcasecmp(info->sender, req_info->sender) == 0) &&
1175                         req_info->function == info->function) {
1176                         _uam_remove_timer(info->tid);
1177                         g_free(info->sender);
1178                         g_free(info->data);
1179                         g_free(info);
1180
1181                         request_list = g_slist_remove_link(request_list, l);
1182
1183                         break;
1184                 }
1185                 l = next;
1186         }
1187
1188         FUNC_EXIT;
1189 }
1190