4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
26 #include <vconf-keys.h>
28 #include "bt-core-adapter.h"
29 #include "bt-core-common.h"
30 #include "bt-core-dbus-handler.h"
31 #include "bt-internal-types.h"
32 #include "bt-request-service.h"
33 #include "bt-core-noti-handler.h"
34 #include "bt-core-main.h"
36 #define BT_SERVICE_NAME "org.projectx.bt"
37 #define BT_SERVICE_PATH "/org/projectx/bt_service"
39 DBusGProxy *service_proxy = NULL;
40 DBusGConnection *service_conn = NULL;
42 static GDBusConnection *service_gconn;
43 static GDBusProxy *service_gproxy;
45 void _bt_core_fill_garray_from_variant(GVariant *var, GArray *param)
50 size = g_variant_get_size(var);
52 data = (char *)g_variant_get_data(var);
54 param = g_array_append_vals(param, data, size);
59 static GDBusProxy *__bt_core_gdbus_init_service_proxy(void)
66 if (service_gconn == NULL)
67 service_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
71 BT_ERR("Unable to connect to dbus: %s", err->message);
77 proxy = g_dbus_proxy_new_sync(service_gconn,
78 G_DBUS_PROXY_FLAGS_NONE, NULL,
85 BT_ERR("Unable to create proxy: %s", err->message);
89 g_object_unref(service_gconn);
94 service_gproxy = proxy;
99 GDBusProxy *_bt_core_gdbus_get_service_proxy(void)
101 return (service_gproxy) ? service_gproxy : __bt_core_gdbus_init_service_proxy();
104 void _bt_core_gdbus_deinit_proxys(void)
106 if (service_gproxy) {
107 g_object_unref(service_proxy);
108 service_proxy = NULL;
112 g_object_unref(service_gconn);
113 service_gconn = NULL;
117 int _bt_core_service_request(int service_type, int service_function,
118 GArray *in_param1, GArray *in_param2,
119 GArray *in_param3, GArray *in_param4,
130 int result = BLUETOOTH_ERROR_NONE;
131 GError *error = NULL;
132 GArray *in_param5 = NULL;
133 GArray *out_param2 = NULL;
135 proxy = _bt_core_gdbus_get_service_proxy();
137 return BLUETOOTH_ERROR_INTERNAL;
138 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
140 param1 = g_variant_new_from_data((const GVariantType *)"ay",
141 in_param1->data, in_param1->len,
143 param2 = g_variant_new_from_data((const GVariantType *)"ay",
144 in_param2->data, in_param2->len,
146 param3 = g_variant_new_from_data((const GVariantType *)"ay",
147 in_param3->data, in_param3->len,
149 param4 = g_variant_new_from_data((const GVariantType *)"ay",
150 in_param4->data, in_param4->len,
152 param5 = g_variant_new_from_data((const GVariantType *)"ay",
153 in_param5->data, in_param5->len,
156 ret = g_dbus_proxy_call_sync(proxy, "service_request",
157 g_variant_new("(iii@ay@ay@ay@ay@ay)",
158 service_type, service_function,
162 G_DBUS_CALL_FLAGS_NONE, -1,
165 g_array_free(in_param5, TRUE);
168 /* dBUS-RPC is failed */
169 BT_ERR("dBUS-RPC is failed");
172 /* dBUS gives error cause */
173 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
174 error->code, error->message);
176 g_clear_error(&error);
178 /* dBUS does not give error cause dBUS-RPC is failed */
179 BT_ERR("error returned was NULL");
182 return BLUETOOTH_ERROR_INTERNAL;
188 g_variant_get(ret, "(@ay@ay)", ¶m1, ¶m2);
191 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
192 _bt_core_fill_garray_from_variant(param1, *out_param1);
193 g_variant_unref(param1);
197 out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
198 _bt_core_fill_garray_from_variant(param2, out_param2);
199 result = g_array_index(out_param2, int, 0);
200 g_variant_unref(param2);
201 g_array_free(out_param2, TRUE);
203 result = BLUETOOTH_ERROR_INTERNAL;
206 g_variant_unref(ret);
212 static int __bt_core_get_object_path(DBusMessage *msg, char **path)
214 DBusMessageIter item_iter;
216 dbus_message_iter_init(msg, &item_iter);
218 if (dbus_message_iter_get_arg_type(&item_iter)
219 != DBUS_TYPE_OBJECT_PATH) {
220 BT_ERR("This is bad format dbus");
221 return BLUETOOTH_ERROR_INTERNAL;
224 dbus_message_iter_get_basic(&item_iter, path);
227 return BLUETOOTH_ERROR_INTERNAL;
229 return BLUETOOTH_ERROR_NONE;
232 static int __bt_core_get_owner_info(DBusMessage *msg, char **name,
233 char **previous, char **current)
235 DBusMessageIter item_iter;
237 dbus_message_iter_init(msg, &item_iter);
239 if (dbus_message_iter_get_arg_type(&item_iter)
240 != DBUS_TYPE_STRING) {
241 BT_ERR("This is bad format dbus");
242 return BLUETOOTH_ERROR_INTERNAL;
245 dbus_message_iter_get_basic(&item_iter, name);
248 return BLUETOOTH_ERROR_INTERNAL;
250 dbus_message_iter_next(&item_iter);
252 if (dbus_message_iter_get_arg_type(&item_iter)
253 != DBUS_TYPE_STRING) {
254 BT_ERR("This is bad format dbus");
255 return BLUETOOTH_ERROR_INTERNAL;
258 dbus_message_iter_get_basic(&item_iter, previous);
260 if (*previous == NULL)
261 return BLUETOOTH_ERROR_INTERNAL;
263 dbus_message_iter_next(&item_iter);
265 if (dbus_message_iter_get_arg_type(&item_iter)
266 != DBUS_TYPE_STRING) {
267 BT_ERR("This is bad format dbus");
268 return BLUETOOTH_ERROR_INTERNAL;
271 dbus_message_iter_get_basic(&item_iter, current);
273 if (*current == NULL)
274 return BLUETOOTH_ERROR_INTERNAL;
276 return BLUETOOTH_ERROR_NONE;
279 static DBusHandlerResult __bt_core_event_filter(DBusConnection *conn,
280 DBusMessage *msg, void *data)
282 char *object_path = NULL;
283 const char *member = dbus_message_get_member(msg);
285 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
286 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
289 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
291 if (strcasecmp(member, "InterfacesAdded") == 0) {
292 if (__bt_core_get_object_path(msg, &object_path)) {
293 BT_ERR("Fail to get the path");
294 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
297 if (strcasecmp(object_path, "/org/bluez/hci0") == 0) {
298 _bt_core_adapter_added_cb();
300 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
301 if (__bt_core_get_object_path(msg, &object_path)) {
302 BT_ERR("Fail to get the path");
303 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
306 if (strcasecmp(object_path, "/org/bluez/hci0") == 0) {
307 _bt_core_adapter_removed_cb();
309 } else if (strcasecmp(member, "NameOwnerChanged") == 0) {
311 char *previous = NULL;
312 char *current = NULL;
313 gboolean flight_mode_status;
315 if (__bt_core_get_owner_info(msg, &name, &previous, ¤t)) {
316 BT_ERR("Fail to get the owner info");
317 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
320 if (*current != '\0')
321 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
323 if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &flight_mode_status) != 0)
324 BT_ERR("Fail to get the flight_mode status value");
325 if (flight_mode_status == FALSE && _bt_is_flightmode_request() == TRUE) {
326 BT_DBG("flightmode requested");
327 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
330 if (strcasecmp(name, "org.bluez") == 0) {
331 BT_DBG("Bluetoothd is terminated");
332 if (_bt_check_terminating_condition() == TRUE) {
333 _bt_disable_adapter();
334 _bt_disable_adapter_le();
335 _bt_core_terminate();
337 } else if (strcasecmp(name, "org.projectx.bt") == 0) {
338 BT_DBG("bt-service is terminated");
339 if (_bt_check_terminating_condition() == TRUE) {
340 _bt_disable_adapter();
341 _bt_disable_adapter_le();
342 _bt_core_terminate();
347 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
350 DBusGProxy *_bt_core_register_event_filter(DBusGConnection *g_conn,
353 DBusError dbus_error;
354 DBusConnection *conn;
362 conn = dbus_g_connection_get_connection(g_conn);
366 proxy = dbus_g_proxy_new_for_name(g_conn, DBUS_SERVICE_DBUS,
367 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
369 BT_ERR("proxy is NULL");
373 if (!dbus_g_proxy_call(proxy, "RequestName", &err, G_TYPE_STRING,
374 BT_CORE_NAME, G_TYPE_UINT, 0, G_TYPE_INVALID,
375 G_TYPE_UINT, &result, G_TYPE_INVALID)) {
377 BT_ERR("RequestName RPC failed[%s]\n", err->message);
380 g_object_unref(proxy);
384 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
385 BT_ERR("Failed to get the primary well-known name.\n");
386 g_object_unref(proxy);
390 if (!dbus_connection_add_filter(conn, __bt_core_event_filter,
392 BT_ERR("Fail to add filter");
393 g_object_unref(proxy);
397 dbus_error_init(&dbus_error);
399 dbus_bus_add_match(conn,
400 "type='signal',interface='org.freedesktop.DBus'"
401 ",member='NameOwnerChanged'",
404 if (dbus_error_is_set(&dbus_error)) {
405 BT_ERR("Fail to add match: %s\n", dbus_error.message);
406 dbus_error_free(&dbus_error);
407 g_object_unref(proxy);
411 dbus_bus_add_match(conn,
412 "type='signal',interface='org.freedesktop.DBus.ObjectManager'"
413 ",member='InterfacesAdded'",
416 if (dbus_error_is_set(&dbus_error)) {
417 BT_ERR("Fail to add match: %s\n", dbus_error.message);
418 dbus_error_free(&dbus_error);
419 g_object_unref(proxy);
423 dbus_bus_add_match(conn,
424 "type='signal',interface='org.freedesktop.DBus.ObjectManager'"
425 ",member='InterfacesRemoved'",
428 if (dbus_error_is_set(&dbus_error)) {
429 BT_ERR("Fail to add match: %s\n", dbus_error.message);
430 dbus_error_free(&dbus_error);
431 g_object_unref(proxy);
435 dbus_g_connection_register_g_object(g_conn, BT_CORE_PATH,
441 void _bt_unregister_event_filter(DBusGConnection *g_conn,
443 DBusGProxy *dbus_proxy)
445 DBusConnection *conn;
447 if (g_conn == NULL ||
449 dbus_proxy == NULL) {
450 BT_ERR("Invalid parameter");
454 conn = dbus_g_connection_get_connection(g_conn);
456 dbus_connection_remove_filter(conn, __bt_core_event_filter, NULL);
458 dbus_g_connection_unregister_g_object(g_conn, G_OBJECT(bt_core));
460 g_object_unref(bt_core);
461 g_object_unref(dbus_proxy);