Add SmackProcessLabel option in systemd service files
[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         if (property_str == NULL) {
187                 g_free(device_path);
188                 return BLUETOOTH_ERROR_INTERNAL;
189         }
190
191         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
192                                                         NULL, BT_BLUEZ_NAME,
193                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
194
195         g_free(device_path);
196         if (proxy == NULL) {
197                 g_free(property_str);
198                 return BLUETOOTH_ERROR_INTERNAL;
199         }
200
201         result = g_dbus_proxy_call_sync(proxy, "GetAll",
202                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
203                         G_DBUS_CALL_FLAGS_NONE,
204                         -1,
205                         NULL,
206                         &error);
207         if (result == NULL) {
208                 if (error != NULL) {
209                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
210                         g_error_free(error);
211                 }
212                 g_object_unref(proxy);
213                 g_free(property_str);
214                 return BLUETOOTH_ERROR_INTERNAL;
215         }
216         g_variant_get(result , "(@a{sv})", &value);
217         g_variant_unref(result);
218
219         tmp_value = g_variant_lookup_value(value, property_str, G_VARIANT_TYPE_STRING);
220         if (tmp_value == NULL) {
221                 g_object_unref(proxy);
222                 g_variant_unref(value);
223                 g_free(property_str);
224                 return BLUETOOTH_ERROR_INTERNAL;
225         }
226
227         value_str = (char *)g_variant_get_string(tmp_value, NULL);
228         if (value_str) {
229                 if (property != BT_PXP_PROPERTY_TX_POWER)
230                         *level = _bt_convert_string_to_alert_level(value_str);
231                 else
232                         *level = _bt_convert_string_to_signal_level(value_str);
233         }
234
235         g_variant_unref(tmp_value);
236         g_variant_unref(value);
237         g_object_unref(proxy);
238         g_free(property_str);
239
240         return BLUETOOTH_ERROR_NONE;
241 }
242
243 int _bt_proximity_reporter_get_property(bluetooth_device_address_t *device_address,
244                 unsigned int property, int *level)
245 {
246         GDBusProxy *proxy;
247         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
248         GDBusConnection *conn;
249         char *device_path = NULL;
250         GError *error = NULL;
251         GVariant *result = NULL;
252         GVariant *tmp_value;
253         GVariant *value;
254         char *value_str = NULL;
255         char *property_str = NULL;
256
257         BT_CHECK_PARAMETER(device_address, return);
258
259         conn = _bt_gdbus_get_system_gconn();
260         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
261
262         _bt_convert_addr_type_to_string(address, device_address->addr);
263
264         device_path = _bt_get_device_object_path(address);
265         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
266
267         BT_INFO("device_path is created[%s]", device_path);
268
269         property_str = _bt_convert_property_to_string(property);
270         if (property_str == NULL) {
271                 g_free(device_path);
272                 return BLUETOOTH_ERROR_INTERNAL;
273         }
274
275         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
276                                                         NULL, BT_BLUEZ_NAME,
277                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
278
279         g_free(device_path);
280         if (proxy == NULL) {
281                 g_free(property_str);
282                 return BLUETOOTH_ERROR_INTERNAL;
283         }
284
285         result = g_dbus_proxy_call_sync(proxy, "GetAll",
286                         g_variant_new("(s)", BT_PROXIMITY_REPORTER_INTERFACE),
287                         G_DBUS_CALL_FLAGS_NONE,
288                         -1,
289                         NULL,
290                         &error);
291         if (result == NULL) {
292                 if (error != NULL) {
293                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
294                         g_error_free(error);
295                 }
296                 g_object_unref(proxy);
297                 g_free(property_str);
298                 return BLUETOOTH_ERROR_INTERNAL;
299         }
300         g_variant_get(result , "(@a{sv})", &value);
301         g_variant_unref(result);
302
303         tmp_value = g_variant_lookup_value(value, property_str, G_VARIANT_TYPE_STRING);
304         if (tmp_value == NULL) {
305                 g_object_unref(proxy);
306                 g_variant_unref(value);
307                 g_free(property_str);
308                 return BLUETOOTH_ERROR_INTERNAL;
309         }
310
311         value_str = (char *)g_variant_get_string(tmp_value, NULL);
312         if (value_str)
313                 *level = _bt_convert_string_to_alert_level(value_str);
314
315         g_variant_unref(tmp_value);
316         g_variant_unref(value);
317         g_object_unref(proxy);
318         g_free(property_str);
319
320         return BLUETOOTH_ERROR_NONE;
321 }
322
323 int _bt_proximity_monitor_get_supported_services(bluetooth_device_address_t *device_address,
324                 unsigned int *supported_services)
325 {
326         GDBusProxy *proxy;
327         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
328
329         GDBusConnection *conn;
330         char *device_path = NULL;
331         GError *error = NULL;
332         GVariant *result = NULL;
333         GVariant *tmp_value;
334         GVariant *value;
335
336         BT_CHECK_PARAMETER(device_address, return);
337
338         conn = _bt_gdbus_get_system_gconn();
339         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
340
341         _bt_convert_addr_type_to_string(address, device_address->addr);
342
343         device_path = _bt_get_device_object_path(address);
344         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
345
346         BT_INFO("device_path is created[%s]", device_path);
347
348         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
349                                                         NULL, BT_BLUEZ_NAME,
350                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
351
352         g_free(device_path);
353         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
354
355         result = g_dbus_proxy_call_sync(proxy, "GetAll",
356                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
357                         G_DBUS_CALL_FLAGS_NONE,
358                         -1,
359                         NULL,
360                         &error);
361         if (result == NULL) {
362                 if (error != NULL) {
363                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
364                         g_error_free(error);
365                 }
366                 g_object_unref(proxy);
367                 return BLUETOOTH_ERROR_INTERNAL;
368         }
369         g_variant_get(result , "(@a{sv})", &value);
370         g_variant_unref(result);
371
372         *supported_services = 0;
373         tmp_value = g_variant_lookup_value(value, "LinkLossAlertLevel", G_VARIANT_TYPE_STRING);
374         if (tmp_value == NULL) {
375                 g_object_unref(proxy);
376                 g_variant_unref(value);
377                 return BLUETOOTH_ERROR_INTERNAL;
378         } else {
379                 *supported_services |= BT_PXP_PROPERTY_LLS;
380                 g_variant_unref(tmp_value);
381         }
382
383         tmp_value = g_variant_lookup_value(value, "ImmediateAlertLevel", 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_IAS;
392                 g_variant_unref(tmp_value);
393         }
394
395         tmp_value = g_variant_lookup_value(value, "SignalLevel", G_VARIANT_TYPE_STRING);
396         if (tmp_value == NULL) {
397                 if (*supported_services == 0) {
398                         g_object_unref(proxy);
399                         g_variant_unref(value);
400                         return BLUETOOTH_ERROR_INTERNAL;
401                 }
402         } else {
403                 *supported_services |= BT_PXP_PROPERTY_TX_POWER;
404                 g_variant_unref(tmp_value);
405         }
406
407         g_variant_unref(value);
408         g_object_unref(proxy);
409
410         return BLUETOOTH_ERROR_NONE;
411 }
412
413 int _bt_proximity_reporter_register(const char *sender)
414 {
415         GDBusProxy *proxy;
416
417         GDBusConnection *conn;
418         char *adapter_path = NULL;
419         char *reporter = NULL;
420         GError *error = NULL;
421         GVariant *result = NULL;
422
423         conn = _bt_gdbus_get_system_gconn();
424         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
425
426         if (_bt_proximity_reporter_find_from_list(sender))
427                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
428
429         adapter_path = _bt_get_adapter_path();
430         if (adapter_path == NULL) {
431                 BT_ERR("Could not get adapter path\n");
432                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
433         }
434
435         BT_INFO("Adapter path %s", adapter_path);
436
437         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
438                                         NULL, BT_BLUEZ_NAME, adapter_path,
439                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
440
441         g_free(adapter_path);
442         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
443
444         result = g_dbus_proxy_call_sync(proxy, "RegisterProximity",
445                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
446                         NULL, &error);
447         if (result == NULL) {
448                 if (error != NULL) {
449                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
450                         g_error_free(error);
451                 }
452                 g_object_unref(proxy);
453                 return BLUETOOTH_ERROR_INTERNAL;
454         }
455         reporter = g_strdup(sender);
456         reporter_list = g_slist_append(reporter_list, reporter);
457
458         g_object_unref(proxy);
459
460         return BLUETOOTH_ERROR_NONE;
461 }
462
463 int _bt_proximity_reporter_unregister(const char *sender)
464 {
465         GDBusProxy *proxy;
466
467         GDBusConnection *conn;
468         char *adapter_path = NULL;
469         GError *error = NULL;
470         GVariant *result = NULL;
471         char *reporter = NULL;
472
473         conn = _bt_gdbus_get_system_gconn();
474         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
475
476         reporter = _bt_proximity_reporter_find_from_list(sender);
477         if (!reporter)
478                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
479
480         adapter_path = _bt_get_adapter_path();
481         if (adapter_path == NULL) {
482                 BT_ERR("Could not get adapter path\n");
483                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
484         }
485
486         BT_INFO("Adapter path %s", adapter_path);
487
488         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
489                                         NULL, BT_BLUEZ_NAME, adapter_path,
490                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
491
492         g_free(adapter_path);
493         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
494
495         result = g_dbus_proxy_call_sync(proxy, "UnregisterProximity",
496                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
497                         NULL, &error);
498         if (result == NULL) {
499                 if (error != NULL) {
500                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
501                         g_error_free(error);
502                 }
503                 g_object_unref(proxy);
504                 return BLUETOOTH_ERROR_INTERNAL;
505         }
506         reporter_list = g_slist_remove(reporter_list, reporter);
507         g_free(reporter);
508
509         g_object_unref(proxy);
510
511         return BLUETOOTH_ERROR_NONE;
512 }
513
514 void _bt_proximity_reporter_stop_by_terminated_process(const char *terminated_name)
515 {
516         if (!_bt_proximity_reporter_find_from_list(terminated_name))
517                 return;
518         BT_ERR("Stop Proximity Reporter by terminated process(%s).", terminated_name);
519         _bt_proximity_reporter_unregister(terminated_name);
520 }