81e45e46d3ef8d79a5787e7441be527346fc7a38
[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
202         return BLUETOOTH_ERROR_NONE;
203 }
204
205 int bt_get_proximity_supported_services(bluetooth_device_address_t *device_address,
206                 unsigned int *supported_services)
207 {
208         GDBusProxy *proxy;
209         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
210
211         GDBusConnection *conn;
212         char *device_path = NULL;
213         GError *error = NULL;
214         GVariant *result = NULL;
215         GVariant *tmp_value;
216         GVariant *value;
217
218         BT_CHECK_PARAMETER(device_address, return);
219
220         conn = _bt_gdbus_get_system_gconn();
221         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
222
223         _bt_convert_addr_type_to_string(address, device_address->addr);
224
225         device_path = _bt_get_device_object_path(address);
226
227         if (device_path == NULL)
228                 return BLUETOOTH_ERROR_NOT_CONNECTED;
229         else
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         } else {
335                 g_variant_unref(result);
336         }
337         g_object_unref(proxy);
338
339         return BLUETOOTH_ERROR_NONE;
340 }
341
342 int bt_unregister_proximity_reporter()
343 {
344         GDBusProxy *proxy;
345
346         GDBusConnection *conn;
347         char *adapter_path = NULL;
348         GError *error = NULL;
349         GVariant *result = NULL;
350
351         conn = _bt_gdbus_get_system_gconn();
352         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
353
354         adapter_path = _bt_get_adapter_path();
355         if (adapter_path == NULL) {
356                 BT_ERR("Could not get adapter path\n");
357                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
358         }
359
360         BT_INFO("Adapter path %s", adapter_path);
361
362         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
363                                         NULL, BT_BLUEZ_NAME, adapter_path,
364                                         BT_PROXIMITY_REPORTER_INTERFACE, NULL, NULL);
365
366         g_free(adapter_path);
367         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
368
369         result = g_dbus_proxy_call_sync(proxy, "UnregisterProximity",
370                         NULL, G_DBUS_CALL_FLAGS_NONE, -1,
371                         NULL, &error);
372         if (result == NULL) {
373                 if (error != NULL) {
374                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
375                         g_error_free(error);
376                 }
377                 g_object_unref(proxy);
378                 return BLUETOOTH_ERROR_INTERNAL;
379         } else {
380                 g_variant_unref(result);
381         }
382         g_object_unref(proxy);
383
384         return BLUETOOTH_ERROR_NONE;
385 }