2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <syspopup_caller.h>
24 #include <bundle_internal.h>
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-device.h"
31 #include "bt-service-proximity.h"
33 GSList *reporter_list = NULL;
35 static char *_bt_convert_alert_level_to_string(int value)
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");
42 return g_strdup("none");
45 static int _bt_convert_string_to_alert_level(const char *str)
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;
52 return BT_PXP_ALERT_NONE;
55 static int _bt_convert_string_to_signal_level(const char *str)
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;
64 return BT_PXP_SIGNAL_NONE;
67 static char *_bt_convert_property_to_string(int value)
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");
79 static char *_bt_proximity_reporter_find_from_list(const char *reporter_name)
82 char *reporter = NULL;
84 for (l = reporter_list; l != NULL; l = g_slist_next(l)) {
86 if (reporter && g_strcmp0(reporter, reporter_name) == 0)
92 int _bt_proximity_monitor_set_property(bluetooth_device_address_t *device_address,
93 unsigned int property, int alert_level)
96 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
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;
105 BT_CHECK_PARAMETER(device_address, return);
107 conn = _bt_gdbus_get_system_gconn();
108 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
110 _bt_convert_addr_type_to_string(address, device_address->addr);
112 device_path = _bt_get_device_object_path(address);
113 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
115 BT_INFO("device_path is created[%s]", device_path);
117 value_str = _bt_convert_alert_level_to_string(alert_level);
118 property_str = _bt_convert_property_to_string(property);
120 if (value_str == NULL || property_str == NULL) {
121 g_free(property_str);
123 return BLUETOOTH_ERROR_INTERNAL;
126 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
128 device_path, BT_PROPERTIES_INTERFACE, NULL, NULL);
133 g_free(property_str);
135 return BLUETOOTH_ERROR_INTERNAL;
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,
145 g_variant_unref(ret);
146 g_object_unref(proxy);
147 g_free(property_str);
151 BT_ERR("SetProperty error: [%s]", error->message);
153 return BLUETOOTH_ERROR_INTERNAL;
156 return BLUETOOTH_ERROR_NONE;
159 int _bt_proximity_monitor_get_property(bluetooth_device_address_t *device_address,
160 unsigned int property, int *level)
163 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
164 GDBusConnection *conn;
165 char *device_path = NULL;
166 GError *error = NULL;
167 GVariant *result = NULL;
170 char *value_str = NULL;
171 char *property_str = NULL;
173 BT_CHECK_PARAMETER(device_address, return);
175 conn = _bt_gdbus_get_system_gconn();
176 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
178 _bt_convert_addr_type_to_string(address, device_address->addr);
180 device_path = _bt_get_device_object_path(address);
181 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
183 BT_INFO("device_path is created[%s]", device_path);
185 property_str = _bt_convert_property_to_string(property);
186 if (property_str == NULL) {
188 return BLUETOOTH_ERROR_INTERNAL;
191 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
193 device_path, BT_PROPERTIES_INTERFACE, NULL, NULL);
197 g_free(property_str);
198 return BLUETOOTH_ERROR_INTERNAL;
201 result = g_dbus_proxy_call_sync(proxy, "GetAll",
202 g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
203 G_DBUS_CALL_FLAGS_NONE,
207 if (result == NULL) {
209 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
212 g_object_unref(proxy);
213 g_free(property_str);
214 return BLUETOOTH_ERROR_INTERNAL;
216 g_variant_get(result , "(@a{sv})", &value);
217 g_variant_unref(result);
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;
227 value_str = (char *)g_variant_get_string(tmp_value, NULL);
229 if (property != BT_PXP_PROPERTY_TX_POWER)
230 *level = _bt_convert_string_to_alert_level(value_str);
232 *level = _bt_convert_string_to_signal_level(value_str);
235 g_variant_unref(tmp_value);
236 g_variant_unref(value);
237 g_object_unref(proxy);
238 g_free(property_str);
240 return BLUETOOTH_ERROR_NONE;
243 int _bt_proximity_reporter_get_property(bluetooth_device_address_t *device_address,
244 unsigned int property, int *level)
247 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
248 GDBusConnection *conn;
249 char *device_path = NULL;
250 GError *error = NULL;
251 GVariant *result = NULL;
254 char *value_str = NULL;
255 char *property_str = NULL;
257 BT_CHECK_PARAMETER(device_address, return);
259 conn = _bt_gdbus_get_system_gconn();
260 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
262 _bt_convert_addr_type_to_string(address, device_address->addr);
264 device_path = _bt_get_device_object_path(address);
265 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
267 BT_INFO("device_path is created[%s]", device_path);
269 property_str = _bt_convert_property_to_string(property);
270 if (property_str == NULL) {
272 return BLUETOOTH_ERROR_INTERNAL;
275 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
277 device_path, BT_PROPERTIES_INTERFACE, NULL, NULL);
281 g_free(property_str);
282 return BLUETOOTH_ERROR_INTERNAL;
285 result = g_dbus_proxy_call_sync(proxy, "GetAll",
286 g_variant_new("(s)", BT_PROXIMITY_REPORTER_INTERFACE),
287 G_DBUS_CALL_FLAGS_NONE,
291 if (result == NULL) {
293 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
296 g_object_unref(proxy);
297 g_free(property_str);
298 return BLUETOOTH_ERROR_INTERNAL;
300 g_variant_get(result , "(@a{sv})", &value);
301 g_variant_unref(result);
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;
311 value_str = (char *)g_variant_get_string(tmp_value, NULL);
313 *level = _bt_convert_string_to_alert_level(value_str);
315 g_variant_unref(tmp_value);
316 g_variant_unref(value);
317 g_object_unref(proxy);
318 g_free(property_str);
320 return BLUETOOTH_ERROR_NONE;
323 int _bt_proximity_monitor_get_supported_services(bluetooth_device_address_t *device_address,
324 unsigned int *supported_services)
327 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
329 GDBusConnection *conn;
330 char *device_path = NULL;
331 GError *error = NULL;
332 GVariant *result = NULL;
336 BT_CHECK_PARAMETER(device_address, return);
338 conn = _bt_gdbus_get_system_gconn();
339 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
341 _bt_convert_addr_type_to_string(address, device_address->addr);
343 device_path = _bt_get_device_object_path(address);
344 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
346 BT_INFO("device_path is created[%s]", device_path);
348 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
350 device_path, BT_PROPERTIES_INTERFACE, NULL, NULL);
353 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
355 result = g_dbus_proxy_call_sync(proxy, "GetAll",
356 g_variant_new("(s)", BT_PROXIMITY_MONITOR_INTERFACE),
357 G_DBUS_CALL_FLAGS_NONE,
361 if (result == NULL) {
363 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
366 g_object_unref(proxy);
367 return BLUETOOTH_ERROR_INTERNAL;
369 g_variant_get(result , "(@a{sv})", &value);
370 g_variant_unref(result);
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;
379 *supported_services |= BT_PXP_PROPERTY_LLS;
380 g_variant_unref(tmp_value);
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;
391 *supported_services |= BT_PXP_PROPERTY_IAS;
392 g_variant_unref(tmp_value);
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;
403 *supported_services |= BT_PXP_PROPERTY_TX_POWER;
404 g_variant_unref(tmp_value);
407 g_variant_unref(value);
408 g_object_unref(proxy);
410 return BLUETOOTH_ERROR_NONE;
413 int _bt_proximity_reporter_register(const char *sender)
417 GDBusConnection *conn;
418 char *adapter_path = NULL;
419 char *reporter = NULL;
420 GError *error = NULL;
421 GVariant *result = NULL;
423 conn = _bt_gdbus_get_system_gconn();
424 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
426 if (_bt_proximity_reporter_find_from_list(sender))
427 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
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;
435 BT_INFO("Adapter path %s", adapter_path);
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);
441 g_free(adapter_path);
442 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
444 result = g_dbus_proxy_call_sync(proxy, "RegisterProximity",
445 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
447 if (result == NULL) {
449 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
452 g_object_unref(proxy);
453 return BLUETOOTH_ERROR_INTERNAL;
455 reporter = g_strdup(sender);
456 reporter_list = g_slist_append(reporter_list, reporter);
458 g_object_unref(proxy);
460 return BLUETOOTH_ERROR_NONE;
463 int _bt_proximity_reporter_unregister(const char *sender)
467 GDBusConnection *conn;
468 char *adapter_path = NULL;
469 GError *error = NULL;
470 GVariant *result = NULL;
471 char *reporter = NULL;
473 conn = _bt_gdbus_get_system_gconn();
474 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
476 reporter = _bt_proximity_reporter_find_from_list(sender);
478 return BLUETOOTH_ERROR_NOT_INITIALIZED;
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;
486 BT_INFO("Adapter path %s", adapter_path);
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);
492 g_free(adapter_path);
493 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
495 result = g_dbus_proxy_call_sync(proxy, "UnregisterProximity",
496 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
498 if (result == NULL) {
500 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
503 g_object_unref(proxy);
504 return BLUETOOTH_ERROR_INTERNAL;
506 reporter_list = g_slist_remove(reporter_list, reporter);
509 g_object_unref(proxy);
511 return BLUETOOTH_ERROR_NONE;
514 void _bt_proximity_reporter_stop_by_terminated_process(const char *terminated_name)
516 if (!_bt_proximity_reporter_find_from_list(terminated_name))
518 BT_ERR("Stop Proximity Reporter by terminated process(%s).", terminated_name);
519 _bt_proximity_reporter_unregister(terminated_name);