Fix progress percentage on DUT while waiting for remote authorization
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-proximity.c
1 /*
2  * Copyright (c) 2011 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 <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <syspopup_caller.h>
23 #include <vconf.h>
24 #include <bundle_internal.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28
29 #include "bt-service-common.h"
30 #include "bt-service-device.h"
31 #include "bt-service-proximity.h"
32
33 GSList *reporter_list = NULL;
34
35 static char *_bt_convert_alert_level_to_string(int value)
36 {
37         if (value == BT_PXP_ALERT_MILD)
38                 return g_strdup("mild");
39         else if (value == BT_PXP_ALERT_HIGH)
40                 return g_strdup("high");
41         else
42                 return g_strdup("none");
43 }
44
45 static int _bt_convert_string_to_alert_level(const char *str)
46 {
47         if (g_strcmp0("high", str) == 0)
48                 return BT_PXP_ALERT_HIGH;
49         else if (g_strcmp0("mild", str) == 0)
50                 return BT_PXP_ALERT_MILD;
51
52         return BT_PXP_ALERT_NONE;
53 }
54
55 static int _bt_convert_string_to_signal_level(const char *str)
56 {
57         if (g_strcmp0("good", str) == 0)
58                 return BT_PXP_SIGNAL_GOOD;
59         else if (g_strcmp0("regular", str) == 0)
60                 return BT_PXP_SIGNAL_REGULAR;
61         else if (g_strcmp0("weak", str) == 0)
62                 return BT_PXP_SIGNAL_WEAK;
63
64         return BT_PXP_SIGNAL_NONE;
65 }
66
67 static char *_bt_convert_property_to_string(int value)
68 {
69         if (value == BT_PXP_PROPERTY_LLS)
70                 return g_strdup("LinkLossAlertLevel");
71         else if (value == BT_PXP_PROPERTY_IAS)
72                 return g_strdup("ImmediateAlertLevel");
73         else if (value == BT_PXP_PROPERTY_TX_POWER)
74                 return g_strdup("SignalLevel");
75
76         return NULL;
77 }
78
79 static char *_bt_proximity_reporter_find_from_list(const char *reporter_name)
80 {
81         GSList *l;
82         char *reporter = NULL;
83
84         for (l = reporter_list; l != NULL; l = g_slist_next(l)) {
85                 reporter = l->data;
86                 if (reporter && g_strcmp0(reporter, reporter_name) == 0)
87                         return reporter;
88         }
89         return NULL;
90 }
91
92 int _bt_proximity_monitor_set_property(bluetooth_device_address_t *device_address,
93                 unsigned int property, int alert_level)
94 {
95         GDBusProxy *proxy;
96         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
97
98         GDBusConnection *conn;
99         char *device_path = NULL;
100         GError *error = NULL;
101         GVariant *ret = NULL;
102         char *value_str = NULL;
103         char *property_str = NULL;
104
105         BT_CHECK_PARAMETER(device_address, return);
106
107         conn = _bt_gdbus_get_system_gconn();
108         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
109
110         _bt_convert_addr_type_to_string(address, device_address->addr);
111
112         device_path = _bt_get_device_object_path(address);
113         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
114
115         BT_INFO("device_path is created[%s]", device_path);
116
117         value_str = _bt_convert_alert_level_to_string(alert_level);
118         property_str = _bt_convert_property_to_string(property);
119
120         if (value_str == NULL || property_str == NULL) {
121                 g_free(property_str);
122                 g_free(value_str);
123                 return BLUETOOTH_ERROR_INTERNAL;
124         }
125
126         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
127                                                         NULL, BT_BLUEZ_NAME,
128                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
129
130         g_free(device_path);
131
132         if (proxy == NULL) {
133                 g_free(property_str);
134                 g_free(value_str);
135                 return BLUETOOTH_ERROR_INTERNAL;
136         }
137
138         ret = g_dbus_proxy_call_sync(proxy, "Set",
139                                 g_variant_new("(ssv)", BT_PROXIMITY_MONITOR_INTERFACE,  property_str, g_variant_new("s", value_str)),
140                                 G_DBUS_CALL_FLAGS_NONE,
141                                 -1,
142                                 NULL,
143                                 &error);
144         if (ret)
145                 g_variant_unref(ret);
146         g_object_unref(proxy);
147         g_free(property_str);
148         g_free(value_str);
149
150         if (error) {
151                  BT_ERR("SetProperty error: [%s]", error->message);
152                  g_error_free(error);
153                  return BLUETOOTH_ERROR_INTERNAL;
154         }
155
156         return BLUETOOTH_ERROR_NONE;
157 }
158
159 int _bt_proximity_monitor_get_property(bluetooth_device_address_t *device_address,
160                 unsigned int property, int *level)
161 {
162         GDBusProxy *proxy;
163         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
164         GDBusConnection *conn;
165         char *device_path = NULL;
166         GError *error = NULL;
167         GVariant *result = NULL;
168         GVariant *tmp_value;
169         GVariant *value;
170         char *value_str = NULL;
171         char *property_str = NULL;
172
173         BT_CHECK_PARAMETER(device_address, return);
174
175         conn = _bt_gdbus_get_system_gconn();
176         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
177
178         _bt_convert_addr_type_to_string(address, device_address->addr);
179
180         device_path = _bt_get_device_object_path(address);
181         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
182
183         BT_INFO("device_path is created[%s]", device_path);
184
185         property_str = _bt_convert_property_to_string(property);
186
187         if (property_str == NULL)
188                 return BLUETOOTH_ERROR_INTERNAL;
189
190         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
191                                                         NULL, BT_BLUEZ_NAME,
192                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
193
194         g_free(device_path);
195         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
196
197         result = g_dbus_proxy_call_sync(proxy, "GetAll",
198                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
199                         G_DBUS_CALL_FLAGS_NONE,
200                         -1,
201                         NULL,
202                         &error);
203         if (result == NULL) {
204                 if (error != NULL) {
205                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
206                         g_error_free(error);
207                 }
208                 g_object_unref(proxy);
209                 return BLUETOOTH_ERROR_INTERNAL;
210         }
211         g_variant_get(result , "(@a{sv})", &value);
212         g_variant_unref(result);
213
214         tmp_value = g_variant_lookup_value(value, property_str, G_VARIANT_TYPE_STRING);
215         if (tmp_value == NULL) {
216                 g_object_unref(proxy);
217                 g_variant_unref(value);
218                 return BLUETOOTH_ERROR_INTERNAL;
219         }
220
221         value_str = (char *)g_variant_get_string(tmp_value, NULL);
222         if (value_str) {
223                 if (property != BT_PXP_PROPERTY_TX_POWER)
224                         *level = _bt_convert_string_to_alert_level(value_str);
225                 else
226                         *level = _bt_convert_string_to_signal_level(value_str);
227         }
228
229         g_variant_unref(tmp_value);
230         g_variant_unref(value);
231         g_object_unref(proxy);
232         g_free(property_str);
233
234         return BLUETOOTH_ERROR_NONE;
235 }
236
237 int _bt_proximity_reporter_get_property(bluetooth_device_address_t *device_address,
238                 unsigned int property, int *level)
239 {
240         GDBusProxy *proxy;
241         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
242         GDBusConnection *conn;
243         char *device_path = NULL;
244         GError *error = NULL;
245         GVariant *result = NULL;
246         GVariant *tmp_value;
247         GVariant *value;
248         char *value_str = NULL;
249         char *property_str = NULL;
250
251         BT_CHECK_PARAMETER(device_address, return);
252
253         conn = _bt_gdbus_get_system_gconn();
254         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
255
256         _bt_convert_addr_type_to_string(address, device_address->addr);
257
258         device_path = _bt_get_device_object_path(address);
259         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
260
261         BT_INFO("device_path is created[%s]", device_path);
262
263         property_str = _bt_convert_property_to_string(property);
264
265         if (property_str == NULL)
266                 return BLUETOOTH_ERROR_INTERNAL;
267
268         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
269                                                         NULL, BT_BLUEZ_NAME,
270                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
271
272         g_free(device_path);
273         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
274
275         result = g_dbus_proxy_call_sync(proxy, "GetAll",
276                         g_variant_new("(s)", BT_PROXIMITY_REPORTER_INTERFACE),
277                         G_DBUS_CALL_FLAGS_NONE,
278                         -1,
279                         NULL,
280                         &error);
281         if (result == NULL) {
282                 if (error != NULL) {
283                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
284                         g_error_free(error);
285                 }
286                 g_object_unref(proxy);
287                 return BLUETOOTH_ERROR_INTERNAL;
288         }
289         g_variant_get(result , "(@a{sv})", &value);
290         g_variant_unref(result);
291
292         tmp_value = g_variant_lookup_value(value, property_str, G_VARIANT_TYPE_STRING);
293         if (tmp_value == NULL) {
294                 g_object_unref(proxy);
295                 g_variant_unref(value);
296                 return BLUETOOTH_ERROR_INTERNAL;
297         }
298
299         value_str = (char *)g_variant_get_string(tmp_value, NULL);
300         if (value_str)
301                 *level = _bt_convert_string_to_alert_level(value_str);
302
303         g_variant_unref(tmp_value);
304         g_variant_unref(value);
305         g_object_unref(proxy);
306         g_free(property_str);
307
308         return BLUETOOTH_ERROR_NONE;
309 }
310
311 int _bt_proximity_monitor_get_supported_services(bluetooth_device_address_t *device_address,
312                 unsigned int *supported_services)
313 {
314         GDBusProxy *proxy;
315         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
316
317         GDBusConnection *conn;
318         char *device_path = NULL;
319         GError *error = NULL;
320         GVariant *result = NULL;
321         GVariant *tmp_value;
322         GVariant *value;
323
324         BT_CHECK_PARAMETER(device_address, return);
325
326         conn = _bt_gdbus_get_system_gconn();
327         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
328
329         _bt_convert_addr_type_to_string(address, device_address->addr);
330
331         device_path = _bt_get_device_object_path(address);
332         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
333
334         BT_INFO("device_path is created[%s]", device_path);
335
336         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
337                                                         NULL, BT_BLUEZ_NAME,
338                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
339
340         g_free(device_path);
341         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
342
343         result = g_dbus_proxy_call_sync(proxy, "GetAll",
344                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
345                         G_DBUS_CALL_FLAGS_NONE,
346                         -1,
347                         NULL,
348                         &error);
349         if (result == NULL) {
350                 if (error != NULL) {
351                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
352                         g_error_free(error);
353                 }
354                 g_object_unref(proxy);
355                 return BLUETOOTH_ERROR_INTERNAL;
356         }
357         g_variant_get(result , "(@a{sv})", &value);
358         g_variant_unref(result);
359
360         *supported_services = 0;
361         tmp_value = g_variant_lookup_value(value, "LinkLossAlertLevel", G_VARIANT_TYPE_STRING);
362         if (tmp_value == NULL) {
363                 g_object_unref(proxy);
364                 g_variant_unref(value);
365                 return BLUETOOTH_ERROR_INTERNAL;
366         } else {
367                 *supported_services |= BT_PXP_PROPERTY_LLS;
368                 g_variant_unref(tmp_value);
369         }
370
371         tmp_value = g_variant_lookup_value(value, "ImmediateAlertLevel", G_VARIANT_TYPE_STRING);
372         if (tmp_value == NULL) {
373                 if (*supported_services == 0) {
374                         g_object_unref(proxy);
375                         g_variant_unref(value);
376                         return BLUETOOTH_ERROR_INTERNAL;
377                 }
378         } else {
379                 *supported_services |= BT_PXP_PROPERTY_IAS;
380                 g_variant_unref(tmp_value);
381         }
382
383         tmp_value = g_variant_lookup_value(value, "SignalLevel", G_VARIANT_TYPE_STRING);
384         if (tmp_value == NULL) {
385                 if (*supported_services == 0) {
386                         g_object_unref(proxy);
387                         g_variant_unref(value);
388                         return BLUETOOTH_ERROR_INTERNAL;
389                 }
390         } else {
391                 *supported_services |= BT_PXP_PROPERTY_TX_POWER;
392                 g_variant_unref(tmp_value);
393         }
394
395         g_variant_unref(value);
396         g_object_unref(proxy);
397
398         return BLUETOOTH_ERROR_NONE;
399 }
400
401 int _bt_proximity_reporter_register(const char *sender)
402 {
403         GDBusProxy *proxy;
404
405         GDBusConnection *conn;
406         char *adapter_path = NULL;
407         char *reporter = NULL;
408         GError *error = NULL;
409         GVariant *result = NULL;
410
411         conn = _bt_gdbus_get_system_gconn();
412         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
413
414         if (_bt_proximity_reporter_find_from_list(sender))
415                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
416
417         adapter_path = _bt_get_adapter_path();
418         if (adapter_path == NULL) {
419                 BT_ERR("Could not get adapter path\n");
420                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
421         }
422
423         BT_INFO("Adapter path %s", adapter_path);
424
425         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
426                                         NULL, BT_BLUEZ_NAME, adapter_path,
427                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
428
429         g_free(adapter_path);
430         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
431
432         result = g_dbus_proxy_call_sync(proxy, "RegisterProximity",
433                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
434                         NULL, &error);
435         if (result == NULL) {
436                 if (error != NULL) {
437                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
438                         g_error_free(error);
439                 }
440                 g_object_unref(proxy);
441                 return BLUETOOTH_ERROR_INTERNAL;
442         }
443         reporter = g_strdup(sender);
444         reporter_list = g_slist_append(reporter_list, reporter);
445
446         g_object_unref(proxy);
447
448         return BLUETOOTH_ERROR_NONE;
449 }
450
451 int _bt_proximity_reporter_unregister(const char *sender)
452 {
453         GDBusProxy *proxy;
454
455         GDBusConnection *conn;
456         char *adapter_path = NULL;
457         GError *error = NULL;
458         GVariant *result = NULL;
459         char *reporter = NULL;
460
461         conn = _bt_gdbus_get_system_gconn();
462         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
463
464         reporter = _bt_proximity_reporter_find_from_list(sender);
465         if (!reporter)
466                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
467
468         adapter_path = _bt_get_adapter_path();
469         if (adapter_path == NULL) {
470                 BT_ERR("Could not get adapter path\n");
471                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
472         }
473
474         BT_INFO("Adapter path %s", adapter_path);
475
476         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
477                                         NULL, BT_BLUEZ_NAME, adapter_path,
478                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
479
480         g_free(adapter_path);
481         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
482
483         result = g_dbus_proxy_call_sync(proxy, "UnregisterProximity",
484                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
485                         NULL, &error);
486         if (result == NULL) {
487                 if (error != NULL) {
488                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
489                         g_error_free(error);
490                 }
491                 g_object_unref(proxy);
492                 return BLUETOOTH_ERROR_INTERNAL;
493         }
494         reporter_list = g_slist_remove(reporter_list, reporter);
495         g_free(reporter);
496
497         g_object_unref(proxy);
498
499         return BLUETOOTH_ERROR_NONE;
500 }
501
502 void _bt_proximity_reporter_stop_by_terminated_process(const char *terminated_name)
503 {
504         if (!_bt_proximity_reporter_find_from_list(terminated_name))
505                 return;
506         BT_ERR("Stop Proximity Reporter by terminated process(%s).", terminated_name);
507         _bt_proximity_reporter_unregister(terminated_name);
508 }