Add ua-manager core APIs to insert payload information
[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         case UAM_REQUEST_ADD_PAYLOAD: {
694                 uam_ble_payload_s *payload;
695                 const char *device_id;
696                 int tech_type;
697
698                 __uam_manager_copy_params(in_param1, &payload, sizeof(uam_ble_payload_s));
699                 device_id = (char *)g_variant_get_data(in_param2);
700                 __uam_manager_copy_params(in_param3, &tech_type, sizeof(int));
701                 UAM_DBG("Payload primary key: [%d] device_id: [%s], tech_type: %d",
702                                 payload->primary_key, device_id, tech_type);
703
704                 result = _uam_core_add_payload(payload, device_id, tech_type);
705
706                 break;
707         }
708         default:
709                 UAM_WARN("UnSupported function [%s(0x%4.4X)]",
710                                 _uam_manager_request_to_str(function), function);
711                 result = UAM_ERROR_NOT_SUPPORTED;
712                 break;
713         }
714
715         FUNC_EXIT;
716         return result;
717 }
718
719 static gboolean __uam_manager_is_request_pending(int function, void *data)
720 {
721         FUNC_ENTRY;
722         GSList *l;
723
724         for (l = request_list; l; l = g_slist_next(l)) {
725                 uam_request_context_t *info = l->data;
726
727                 if (!info)
728                         continue;
729
730                 if (info->function == function) {
731                         switch (function) {
732                         case UAM_REQUEST_ADD_DEVICE:
733                         {
734                                 const char *device_id = (const char *)data;
735                                 uam_device_info_s *dev_info = (uam_device_info_s *)info->data;
736
737                                 if (!g_strcmp0(device_id,
738                                                dev_info->device_id))
739                                         return TRUE;
740                         }
741                         break;
742                         default:
743                                 return TRUE;
744                         };
745                 }
746         }
747
748         FUNC_EXIT;
749         return FALSE;
750 }
751
752 static gboolean __uam_request_context_timeout_cb(gpointer p)
753 {
754         FUNC_ENTRY;
755
756         uam_request_context_t *info = p;
757         retv_if(info == NULL, G_SOURCE_REMOVE);
758
759         /* Remove unhandled async-request */
760         _uam_manager_remove_req_ctxt_from_list(info);
761
762         FUNC_EXIT;
763         return G_SOURCE_REMOVE;
764 }
765
766 static void __uam_manager_save_request_context(
767                 GDBusMethodInvocation *context, int result,
768                 char *sender, int function, gpointer data)
769 {
770         FUNC_ENTRY;
771         uam_request_context_t *info;
772
773         UAM_DBG("Save the request context for [%s(0x%4.4X)]",
774                         _uam_manager_request_to_str(function), function);
775
776         info = g_malloc0(sizeof(uam_request_context_t));
777         if (!info) {
778                 UAM_ERR("Failed to allocated memory [%s][%d]", sender, function);
779                 return;
780         }
781         info->context = context;
782         info->result = result;
783         info->sender = g_strdup(sender);
784         if (!info->sender) {
785                 g_free(info);
786                 info = NULL;
787                 UAM_ERR("Failed to allocated memory [%s][%d]", sender, function);
788                 return;
789         }
790         info->function = function;
791         info->data = data;
792         request_list = g_slist_append(request_list, info);
793
794         info->tid = _uam_add_timer_full(TIMER_RES_SEC, G_PRIORITY_DEFAULT,
795                 UAM_ASYNC_REQUEST_TIMEOUT, __uam_request_context_timeout_cb, info, NULL);
796
797         FUNC_EXIT;
798 }
799
800 static int __uam_manager_async_request_handler(
801                 GDBusMethodInvocation *context,
802                 int function,
803                 GVariant *in_param1,
804                 GVariant *in_param2,
805                 GVariant *in_param3,
806                 GVariant *in_param4,
807                 GArray **out_param1)
808 {
809         FUNC_ENTRY;
810         int result = UAM_ERROR_NOT_SUPPORTED;
811         char *sender = NULL;
812
813         sender = (char*)g_dbus_method_invocation_get_sender(context);
814
815         switch (function) {
816         case UAM_REQUEST_ADD_DEVICE: {
817                 const char *account;
818                 uam_device_info_s dev_info;
819
820                 account = (char *)g_variant_get_data(in_param1);
821                 __uam_manager_copy_params(in_param2,
822                                 &dev_info, sizeof(uam_device_info_s));
823                 UAM_DBG("Account: [%s], Type: %d, MAC: [%s] IP: [%s], ID: [%s], Discriminant: [%s]",
824                                 account, dev_info.type, dev_info.mac,
825                                 dev_info.ipv4_addr, dev_info.device_id,
826                                 dev_info.discriminant ? "true" : "false");
827
828                 if (__uam_manager_is_request_pending(UAM_REQUEST_ADD_DEVICE,
829                                                      dev_info.device_id)) {
830                         UAM_ERR("Another request is already in progress");
831                         result = UAM_ERROR_NOW_IN_PROGRESS;
832                         break;
833                 }
834
835                 result = _uam_core_add_device(account, &dev_info);
836                 if (UAM_ERROR_NONE == result) {
837                         __uam_manager_save_request_context(
838                                         context, result, sender, function,
839                                         g_memdup(&dev_info, sizeof(uam_device_info_s)));
840                 }
841                 break;
842         }
843         default:
844                 UAM_WARN("UnSupported function [%s(0x%4.4X)]",
845                                 _uam_manager_request_to_str(function), function);
846                 result = UAM_ERROR_NOT_SUPPORTED;
847                 break;
848         }
849
850         FUNC_EXIT;
851         return result;
852 }
853
854 static gboolean __uam_manager_is_sync_function(int function)
855 {
856         switch (function) {
857         case UAM_REQUEST_GET_AVAILABLE_SENSORS:
858         case UAM_REQUEST_IS_SENSOR_READY:
859         case UAM_REQUEST_GET_DEFAULT_USER:
860         case UAM_REQUEST_ADD_USER:
861         case UAM_REQUEST_DELETE_USER:
862         case UAM_REQUEST_UPDATE_USER:
863         case UAM_REQUEST_GET_USER_BY_ACCOUNT:
864         case UAM_REQUEST_GET_USER_BY_DEVICE_ID:
865         case UAM_REQUEST_GET_USER_BY_MAC:
866         case UAM_REQUEST_GET_USERS:
867         case UAM_REQUEST_IS_DEVICE_ADDED:
868         case UAM_REQUEST_DELETE_DEVICE:
869         case UAM_REQUEST_UPDATE_DEVICE:
870         case UAM_REQUEST_DELETE_DEVICE_BY_DEVICE_ID:
871         case UAM_REQUEST_DELETE_DEVICE_BY_MAC:
872         case UAM_REQUEST_GET_DEVICE_BY_DEVICE_ID:
873         case UAM_REQUEST_GET_DEVICE_BY_MAC:
874         case UAM_REQUEST_GET_DEVICES:
875         case UAM_REQUEST_GET_USER_DEVICES:
876         case UAM_REQUEST_SET_DETECTION_THRESHOLD:
877         case UAM_REQUEST_START_PRESENCE_DETECTION:
878         case UAM_REQUEST_STOP_PRESENCE_DETECTION:
879         case UAM_REQUEST_START_ABSENCE_DETECTION:
880         case UAM_REQUEST_STOP_ABSENCE_DETECTION:
881         case UAM_REQUEST_SET_LOW_POWER_MODE:
882         case UAM_REQUEST_START_SEARCH_ACTIVE_DEVICES:
883         case UAM_REQUEST_STOP_SEARCH_ACTIVE_DEVICES:
884         case UAM_REQUEST_REGISTER_APP:
885         case UAM_REQUEST_DEREGISTER_APP:
886         case UAM_REQUEST_ADD_USER_TO_SERVICE:
887         case UAM_REQUEST_REMOVE_USER_FROM_SERVICE:
888         case UAM_REQUEST_ADD_DEVICE_TO_SERVICE:
889         case UAM_REQUEST_REMOVE_DEVICE_FROM_SERVICE:
890         case UAM_REQUEST_SET_DEVICE_SERVICES_DISCRIMINANT:
891         case UAM_REQUEST_GET_DEVICE_SERVICES_DISCRIMINANT:
892         case UAM_REQUEST_SET_SERVICE_DETECTION_CYCLE:
893         case UAM_REQUEST_GET_SERVICE_DETECTION_CYCLE:
894         case UAM_REQUEST_GET_DETECTION_WINDOW:
895         case UAM_REQUEST_SET_DETECTION_WINDOW:
896         case UAM_REQUEST_RESET_DB:
897         case UAM_REQUEST_GET_DEFAULT_SERVICE:
898         case UAM_REQUEST_REGISTER_SERVICE:
899         case UAM_REQUEST_UPDATE_SERVICE:
900         case UAM_REQUEST_UNREGISTER_SERVICE:
901         case UAM_REQUEST_GET_SERVICE_DEVICES:
902         case UAM_REQUEST_GET_SERVICE_USERS:
903         case UAM_REQUEST_GET_SERVICES:
904         case UAM_REQUEST_ADD_IBEACON_ADV:
905         case UAM_REQUEST_ADD_PAYLOAD:
906                 return TRUE;
907         default:
908                 return FALSE;
909         }
910 }
911
912 static void __uam_manager_method(
913                 GDBusConnection *connection,
914                 const gchar *sender,
915                 const gchar *object_path,
916                 const gchar *interface_name,
917                 const gchar *method_name,
918                 GVariant *parameters,
919                 GDBusMethodInvocation *invocation,
920                 gpointer user_data)
921 {
922         FUNC_ENTRY;
923         int result = UAM_ERROR_NONE;
924
925         UAM_DBG("Sender[%s] Method[%s] Path[%s] Interface[%s]",
926                         sender, method_name, object_path, interface_name);
927
928         if (0 == g_strcmp0(method_name, "enable")) {
929                 int enable = FALSE;
930
931                 g_variant_get(parameters, "(i)", &enable);
932                 UAM_INFO("ua-manager %s", enable == TRUE ? "enabled" : "disabled");
933
934                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", result));
935
936         } else if (0 == g_strcmp0(method_name, "uam_request")) {
937                 int function;
938
939                 GVariant *in_param1 = NULL;
940                 GVariant *in_param2 = NULL;
941                 GVariant *in_param3 = NULL;
942                 GVariant *in_param4 = NULL;
943                 GArray *out_param1 = NULL;
944
945                 g_variant_get(parameters, "(i@ay@ay@ay@ay)", &function,
946                                 &in_param1, &in_param2, &in_param3, &in_param4);
947
948                 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
949
950                 UAM_DBG("Request function = [%s (0x%4.4X)]",
951                                 _uam_manager_request_to_str(function), function);
952
953                 if (__uam_manager_is_sync_function(function)) {
954                         result = __uam_manager_sync_request_handler(invocation, function,
955                                         in_param1, in_param2, in_param3, in_param4, &out_param1);
956                 } else {
957                         result = __uam_manager_async_request_handler(invocation, function,
958                                         in_param1, in_param2, in_param3, in_param4, &out_param1);
959                         if (UAM_ERROR_NONE == result) {
960                                 UAM_DBG("Request context is saved, do not send reply over dbus");
961                                 goto done;
962                         }
963                 }
964
965                 if (UAM_ERROR_NONE != result) {
966                         UAM_ERR("Request [%s (0x%4.4X)] is failed with [%s (0x%4.4X])",
967                                         _uam_manager_request_to_str(function), function,
968                                         _uam_manager_error_to_str(result), result);
969                 }
970
971                 _uam_manager_method_return(invocation, out_param1, result);
972
973 done:
974                 g_variant_unref(in_param1);
975                 g_variant_unref(in_param2);
976                 g_variant_unref(in_param3);
977                 g_variant_unref(in_param4);
978                 g_array_unref(out_param1);
979         }
980
981         FUNC_EXIT;
982         return;
983 }
984
985 static GDBusNodeInfo *__uam_manager_create_method_node_info(
986                 const gchar *introspection_data)
987 {
988         FUNC_ENTRY;
989         GError *err = NULL;
990         GDBusNodeInfo *node_info = NULL;
991
992         if (introspection_data == NULL) {
993                 UAM_ERR("Introspection XML not present");
994                 return NULL;
995         }
996
997         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
998         if (err) {
999                 UAM_ERR("Unable to create node: %s", err->message);
1000                 g_clear_error(&err);
1001         }
1002
1003         FUNC_EXIT;
1004         return node_info;
1005 }
1006
1007 static const GDBusInterfaceVTable uam_method_table = {
1008         __uam_manager_method,
1009         NULL,
1010         NULL,
1011         {0}
1012 };
1013
1014 static int __uam_manager_register_object(
1015                 GDBusConnection *conn, GDBusNodeInfo *node_info)
1016 {
1017         FUNC_ENTRY;
1018         GError *error = NULL;
1019
1020         retv_if(NULL == node_info, UAM_ERROR_INTERNAL);
1021
1022         g_dbus_object_id = g_dbus_connection_register_object(conn,
1023                         UAM_DAEMON_PATH,
1024                         node_info->interfaces[0],
1025                         &uam_method_table,
1026                         NULL, NULL, &error);
1027         retv_if(0 == g_dbus_object_id, UAM_ERROR_INTERNAL);
1028
1029         FUNC_EXIT;
1030         return UAM_ERROR_NONE;
1031 }
1032
1033 static int __uam_manager_unregister_object(GDBusConnection *conn)
1034 {
1035         FUNC_ENTRY;
1036
1037         if (g_dbus_object_id > 0) {
1038                 g_dbus_connection_unregister_object(
1039                                 conn, g_dbus_object_id);
1040                 g_dbus_object_id = 0;
1041         }
1042
1043         FUNC_EXIT;
1044         return UAM_ERROR_NONE;
1045 }
1046
1047 static void __uam_manager_name_acquired_cb(
1048                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1049 {
1050         UAM_INFO("DBus name [%s] acquired", name);
1051 }
1052
1053 static void __uam_manager_name_lost_cb(
1054                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1055 {
1056         if (NULL == connection) {
1057                 UAM_ERR("connection to the bus can't be made");
1058                 /*TODO: Terminate daemon */
1059                 return;
1060         }
1061
1062         UAM_ERR("DBus name [%s] lost", name);
1063         /*TODO: Terminate daemon */
1064 }
1065
1066 static void __uam_manager_owner_change_cb(GDBusConnection *connection,
1067                 const gchar *sender_name,
1068                 const gchar *object_path,
1069                 const gchar *interface_name,
1070                 const gchar *signal_name,
1071                 GVariant *parameters,
1072                 gpointer user_data)
1073 {
1074         const char *name = NULL;
1075         const char *old_owner = NULL;
1076         const char *new_owner = NULL;
1077
1078         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
1079
1080         if ('\0' == *new_owner) {
1081                 /* Clean up client info */
1082                 _uam_core_cleanup_monitor((char *)name);
1083         }
1084 }
1085
1086 static void __uam_manager_bus_acquired_cb(
1087                 GDBusConnection *connection, const gchar *name, gpointer user_data)
1088 {
1089         FUNC_ENTRY;
1090
1091         UAM_INFO("DBus %s bus acquired", name);
1092
1093         GDBusNodeInfo *node_info = NULL;
1094
1095         UAM_INFO("DBus bus acquired");
1096
1097         ret_if(connection == NULL);
1098
1099         node_info = __uam_manager_create_method_node_info(
1100                         uam_manager_introspection_xml);
1101         ret_if(node_info == NULL);
1102
1103         __uam_manager_register_object(connection, node_info);
1104         g_dbus_node_info_unref(node_info);
1105
1106         /* Subscribe for name lost signal */
1107         owner_sig_id = g_dbus_connection_signal_subscribe(connection,
1108                         UAM_SERVICE_DBUS, UAM_INTERFACE_DBUS,
1109                         NAME_OWNER_CHANGED, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1110                         __uam_manager_owner_change_cb, NULL, NULL);
1111
1112         UAM_DBG("owner_sig_id: [%d]", owner_sig_id);
1113
1114         uam_manager_conn = connection;
1115
1116         FUNC_EXIT;
1117 }
1118
1119 int _uam_manager_register(void)
1120 {
1121         FUNC_ENTRY;
1122
1123         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1124                         UAM_DBUS_NAME,
1125                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1126                         __uam_manager_bus_acquired_cb,
1127                         __uam_manager_name_acquired_cb,
1128                         __uam_manager_name_lost_cb,
1129                         NULL, NULL);
1130         retv_if(0 == owner_id, UAM_ERROR_INTERNAL);
1131
1132         UAM_DBG("owner_id is [%d]", owner_id);
1133
1134         FUNC_EXIT;
1135         return UAM_ERROR_NONE;
1136 }
1137
1138 void _uam_manager_unregister(void)
1139 {
1140         FUNC_ENTRY;
1141
1142         if (uam_manager_conn) {
1143                 g_dbus_connection_signal_unsubscribe(uam_manager_conn, owner_sig_id);
1144                 __uam_manager_unregister_object(uam_manager_conn);
1145                 g_object_unref(uam_manager_conn);
1146                 g_bus_unown_name(owner_id);
1147         }
1148
1149         FUNC_EXIT;
1150 }
1151
1152 GSList *_uam_manager_get_request_list(void)
1153 {
1154         return request_list;
1155 }
1156
1157 void _uam_manager_remove_req_ctxt_from_list(uam_request_context_t *req_info)
1158 {
1159         FUNC_ENTRY;
1160
1161         ret_if(NULL == req_info);
1162         ret_if(NULL == req_info->sender);
1163
1164         GSList *l = request_list;
1165         while (l) {
1166
1167                 GSList *next = l->next;
1168                 uam_request_context_t *info = l->data;
1169
1170                 if (NULL == info) {
1171                         request_list = g_slist_remove_link(request_list, l);
1172                         l = next;
1173                         continue;
1174                 }
1175
1176                 if (NULL == info->sender) {
1177                         _uam_remove_timer(info->tid);
1178                         g_free(info->data);
1179                         g_free(info);
1180                         request_list = g_slist_remove_link(request_list, l);
1181                         l = next;
1182                         continue;
1183                 }
1184
1185                 if ((strcasecmp(info->sender, req_info->sender) == 0) &&
1186                         req_info->function == info->function) {
1187                         _uam_remove_timer(info->tid);
1188                         g_free(info->sender);
1189                         g_free(info->data);
1190                         g_free(info);
1191
1192                         request_list = g_slist_remove_link(request_list, l);
1193
1194                         break;
1195                 }
1196                 l = next;
1197         }
1198
1199         FUNC_EXIT;
1200 }
1201