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