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