Merge "Disconnect all profiles if a device is restricted by DPM" into tizen
[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 char *_bt_convert_alert_level_to_string(int value)
34 {
35         if (value == BT_PXP_ALERT_MILD)
36                 return g_strdup("mild");
37         else if (value == BT_PXP_ALERT_HIGH)
38                 return g_strdup("high");
39         else
40                 return g_strdup("none");
41 }
42
43 int _bt_convert_string_to_alert_level(const char *str)
44 {
45         if (g_strcmp0("high", str) == 0)
46                 return BT_PXP_ALERT_HIGH;
47         else if (g_strcmp0("mild", str) == 0)
48                 return BT_PXP_ALERT_MILD;
49
50         return BT_PXP_ALERT_NONE;
51 }
52
53 char *_bt_convert_property_to_string(int value)
54 {
55         if (value == BT_PXP_PROPERTY_LLS)
56                 return g_strdup("LinkLossAlertLevel");
57         else if (value == BT_PXP_PROPERTY_IAS)
58                 return g_strdup("ImmediateAlertLevel");
59         else if (value == BT_PXP_PROPERTY_TX_POWER)
60                 return g_strdup("SignalLevel");
61
62         return NULL;
63 }
64
65 int bt_set_proximity_property(bluetooth_device_address_t *device_address,
66                 unsigned int property, int alert_level)
67 {
68         GDBusProxy *proxy;
69         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
70
71         GDBusConnection *conn;
72         char *device_path = NULL;
73         GError *error = NULL;
74         GVariant *ret = NULL;
75         char *value_str = NULL;
76         char *property_str = NULL;
77
78         BT_CHECK_PARAMETER(device_address, return);
79
80         conn = _bt_gdbus_get_system_gconn();
81         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
82
83         _bt_convert_addr_type_to_string(address, device_address->addr);
84
85         device_path = _bt_get_device_object_path(address);
86         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
87
88         BT_INFO("device_path is created[%s]", device_path);
89
90         value_str = _bt_convert_alert_level_to_string(alert_level);
91         property_str = _bt_convert_property_to_string(property);
92
93         if (value_str == NULL || property_str == NULL) {
94                 g_free(property_str);
95                 g_free(value_str);
96                 return BLUETOOTH_ERROR_INTERNAL;
97         }
98
99         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
100                                                         NULL, BT_BLUEZ_NAME,
101                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
102
103         g_free(device_path);
104
105         if (proxy == NULL) {
106                 g_free(property_str);
107                 g_free(value_str);
108                 return BLUETOOTH_ERROR_INTERNAL;
109         }
110
111         ret = g_dbus_proxy_call_sync(proxy, "Set",
112                                 g_variant_new("(ssv)", BT_PROXIMITY_MONITOR_INTERFACE,  property_str, g_variant_new("s", value_str)),
113                                 G_DBUS_CALL_FLAGS_NONE,
114                                 -1,
115                                 NULL,
116                                 &error);
117         if (ret)
118                 g_variant_unref(ret);
119         g_object_unref(proxy);
120         g_free(property_str);
121         g_free(value_str);
122
123         if (error) {
124                  BT_ERR("SetProperty error: [%s]", error->message);
125                  g_error_free(error);
126                  return BLUETOOTH_ERROR_INTERNAL;
127         }
128
129         return BLUETOOTH_ERROR_NONE;
130 }
131
132 int bt_get_proximity_property(bluetooth_device_address_t *device_address,
133                 unsigned int property, int *alert_level)
134 {
135         GDBusProxy *proxy;
136         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
137         GDBusConnection *conn;
138         char *device_path = NULL;
139         GError *error = NULL;
140         GVariant *result = NULL;
141         GVariant *tmp_value;
142         GVariant *value;
143         char *value_str = NULL;
144         char *property_str = NULL;
145
146         BT_CHECK_PARAMETER(device_address, return);
147
148         conn = _bt_gdbus_get_system_gconn();
149         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
150
151         _bt_convert_addr_type_to_string(address, device_address->addr);
152
153         device_path = _bt_get_device_object_path(address);
154         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
155
156         BT_INFO("device_path is created[%s]", device_path);
157
158         property_str = _bt_convert_property_to_string(property);
159
160         if (property_str == NULL)
161                 return BLUETOOTH_ERROR_INTERNAL;
162
163         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
164                                                         NULL, BT_BLUEZ_NAME,
165                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
166
167         g_free(device_path);
168         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
169
170         result = g_dbus_proxy_call_sync(proxy, "GetAll",
171                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
172                         G_DBUS_CALL_FLAGS_NONE,
173                         -1,
174                         NULL,
175                         &error);
176         if (result == NULL) {
177                 if (error != NULL) {
178                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
179                         g_error_free(error);
180                 }
181                 g_object_unref(proxy);
182                 return BLUETOOTH_ERROR_INTERNAL;
183         }
184         g_variant_get(result , "(@a{sv})", &value);
185         g_variant_unref(result);
186
187         tmp_value = g_variant_lookup_value(value, property_str, G_VARIANT_TYPE_STRING);
188         if (tmp_value == NULL) {
189                 g_object_unref(proxy);
190                 g_variant_unref(value);
191                 return BLUETOOTH_ERROR_INTERNAL;
192         }
193
194         value_str = (char *)g_variant_get_string(tmp_value, NULL);
195         if (value_str)
196                 *alert_level = _bt_convert_string_to_alert_level(value_str);
197
198         g_variant_unref(tmp_value);
199         g_variant_unref(value);
200         g_object_unref(proxy);
201         g_free(property_str);
202         g_free(value_str);
203
204         return BLUETOOTH_ERROR_NONE;
205 }
206
207 int bt_get_proximity_supported_services(bluetooth_device_address_t *device_address,
208                 unsigned int *supported_services)
209 {
210         GDBusProxy *proxy;
211         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
212
213         GDBusConnection *conn;
214         char *device_path = NULL;
215         GError *error = NULL;
216         GVariant *result = NULL;
217         GVariant *tmp_value;
218         GVariant *value;
219
220         BT_CHECK_PARAMETER(device_address, return);
221
222         conn = _bt_gdbus_get_system_gconn();
223         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
224
225         _bt_convert_addr_type_to_string(address, device_address->addr);
226
227         device_path = _bt_get_device_object_path(address);
228         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
229
230         BT_INFO("device_path is created[%s]", device_path);
231
232         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
233                                                         NULL, BT_BLUEZ_NAME,
234                                                         device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
235
236         g_free(device_path);
237         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
238
239         result = g_dbus_proxy_call_sync(proxy, "GetAll",
240                         g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
241                         G_DBUS_CALL_FLAGS_NONE,
242                         -1,
243                         NULL,
244                         &error);
245         if (result == NULL) {
246                 if (error != NULL) {
247                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
248                         g_error_free(error);
249                 }
250                 g_object_unref(proxy);
251                 return BLUETOOTH_ERROR_INTERNAL;
252         }
253         g_variant_get(result , "(@a{sv})", &value);
254         g_variant_unref(result);
255
256         *supported_services = 0;
257         tmp_value = g_variant_lookup_value(value, "LinkLossAlertLevel", G_VARIANT_TYPE_STRING);
258         if (tmp_value == NULL) {
259                 g_object_unref(proxy);
260                 g_variant_unref(value);
261                 return BLUETOOTH_ERROR_INTERNAL;
262         } else {
263                 *supported_services |= BT_PXP_PROPERTY_LLS;
264                 g_variant_unref(tmp_value);
265         }
266
267         tmp_value = g_variant_lookup_value(value, "ImmediateAlertLevel", G_VARIANT_TYPE_STRING);
268         if (tmp_value == NULL) {
269                 if (*supported_services == 0) {
270                         g_object_unref(proxy);
271                         g_variant_unref(value);
272                         return BLUETOOTH_ERROR_INTERNAL;
273                 }
274         } else {
275                 *supported_services |= BT_PXP_PROPERTY_IAS;
276                 g_variant_unref(tmp_value);
277         }
278
279         tmp_value = g_variant_lookup_value(value, "SignalLevel", G_VARIANT_TYPE_STRING);
280         if (tmp_value == NULL) {
281                 if (*supported_services == 0) {
282                         g_object_unref(proxy);
283                         g_variant_unref(value);
284                         return BLUETOOTH_ERROR_INTERNAL;
285                 }
286         } else {
287                 *supported_services |= BT_PXP_PROPERTY_TX_POWER;
288                 g_variant_unref(tmp_value);
289         }
290
291         g_variant_unref(value);
292         g_object_unref(proxy);
293
294         return BLUETOOTH_ERROR_NONE;
295 }
296
297 int bt_register_proximity_reporter()
298 {
299         GDBusProxy *proxy;
300
301         GDBusConnection *conn;
302         char *adapter_path = NULL;
303         GError *error = NULL;
304         GVariant *result = NULL;
305
306         conn = _bt_gdbus_get_system_gconn();
307         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
308
309         adapter_path = _bt_get_adapter_path();
310         if (adapter_path == NULL) {
311                 BT_ERR("Could not get adapter path\n");
312                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
313         }
314
315         BT_INFO("Adapter path %s", adapter_path);
316
317         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
318                                         NULL, BT_BLUEZ_NAME, adapter_path,
319                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
320
321         g_free(adapter_path);
322         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
323
324         result = g_dbus_proxy_call_sync(proxy, "RegisterProximity",
325                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
326                         NULL, &error);
327         if (result == NULL) {
328                 if (error != NULL) {
329                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
330                         g_error_free(error);
331                 }
332                 g_object_unref(proxy);
333                 return BLUETOOTH_ERROR_INTERNAL;
334         }
335         g_object_unref(proxy);
336
337         return BLUETOOTH_ERROR_NONE;
338 }
339
340 int bt_unregister_proximity_reporter()
341 {
342         GDBusProxy *proxy;
343
344         GDBusConnection *conn;
345         char *adapter_path = NULL;
346         GError *error = NULL;
347         GVariant *result = NULL;
348
349         conn = _bt_gdbus_get_system_gconn();
350         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
351
352         adapter_path = _bt_get_adapter_path();
353         if (adapter_path == NULL) {
354                 BT_ERR("Could not get adapter path\n");
355                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
356         }
357
358         BT_INFO("Adapter path %s", adapter_path);
359
360         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
361                                         NULL, BT_BLUEZ_NAME, adapter_path,
362                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
363
364         g_free(adapter_path);
365         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
366
367         result = g_dbus_proxy_call_sync(proxy, "UnregisterProximity",
368                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
369                         NULL, &error);
370         if (result == NULL) {
371                 if (error != NULL) {
372                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
373                         g_error_free(error);
374                 }
375                 g_object_unref(proxy);
376                 return BLUETOOTH_ERROR_INTERNAL;
377         }
378         g_object_unref(proxy);
379
380         return BLUETOOTH_ERROR_NONE;
381 }