* patches for DUN, HFP and gdbus @ 2010-05-25 7:17 Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 1/9] Add g_dbus_interface_is_registered() Gustavo F. Padovan 0 siblings, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:17 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 255 bytes --] Hi all, Patch 1/9 adds a new function to gdbus to fix a hack in HFP code (patch 2/9). 3/9 add optional argument to the -d oFono option Patches from 4 to 9 are the same I sent last week, and they apply cleanly without the first 3. Regards, ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/9] Add g_dbus_interface_is_registered() 2010-05-25 7:17 patches for DUN, HFP and gdbus Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 0 siblings, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 1516 bytes --] This funcion checks if a DBus interface is registered and return TRUE case yes, otherwise it returns FALSE. --- gdbus/gdbus.h | 2 ++ gdbus/object.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index 47e18cf..13c015a 100644 --- a/gdbus/gdbus.h +++ b/gdbus/gdbus.h @@ -98,6 +98,8 @@ gboolean g_dbus_register_interface(DBusConnection *connection, GDBusDestroyFunction destroy); gboolean g_dbus_unregister_interface(DBusConnection *connection, const char *path, const char *name); +gboolean g_dbus_interface_is_registered(DBusConnection *connection, + const char *path, const char *name); DBusMessage *g_dbus_create_error(DBusMessage *message, const char *name, const char *format, ...); diff --git a/gdbus/object.c b/gdbus/object.c index ff69641..7cad0b4 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -556,6 +556,21 @@ gboolean g_dbus_unregister_interface(DBusConnection *connection, return TRUE; } +gboolean g_dbus_interface_is_registered(DBusConnection *connection, + const char *path, const char *name) +{ + struct generic_data *data; + + data = object_path_ref(connection, path); + if (data == NULL) + return FALSE; + + if (find_interface(data->interfaces, name)) + return TRUE; + else + return FALSE; +} + DBusMessage *g_dbus_create_error_valist(DBusMessage *message, const char *name, const char *format, va_list args) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/9] Remove hack around hfp agent interface 2010-05-25 7:18 ` [PATCH 1/9] Add g_dbus_interface_is_registered() Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 3/9] Bring back -d option without need for argument Gustavo F. Padovan 2010-05-25 7:49 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 0 siblings, 2 replies; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 2262 bytes --] In the past we did this dirty hack to quickly fix HFP for the release, now fixing it in a proper way. --- drivers/hfpmodem/hfpmodem.h | 1 - plugins/hfp.c | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h index c95ea3f..6ec8a7c 100644 --- a/drivers/hfpmodem/hfpmodem.h +++ b/drivers/hfpmodem/hfpmodem.h @@ -71,7 +71,6 @@ struct hfp_data { unsigned int hf_features; unsigned char cind_pos[HFP_INDICATOR_LAST]; unsigned int cind_val[HFP_INDICATOR_LAST]; - gboolean agent_registered; }; extern void hfp_netreg_init(); diff --git a/plugins/hfp.c b/plugins/hfp.c index e37c9fc..b253781 100644 --- a/plugins/hfp.c +++ b/plugins/hfp.c @@ -552,11 +552,9 @@ static DBusMessage *hfp_agent_release(DBusConnection *conn, DBusMessage *msg, void *data) { struct ofono_modem *modem = data; - struct hfp_data *hfp_data = ofono_modem_get_data(modem); const char *obj_path = ofono_modem_get_path(modem); g_dbus_unregister_interface(connection, obj_path, HFP_AGENT_INTERFACE); - hfp_data->agent_registered = FALSE; ofono_modem_remove(modem); @@ -950,16 +948,10 @@ static int hfp_unregister_ofono_handsfree(struct ofono_modem *modem) static int hfp_probe(struct ofono_modem *modem) { const char *obj_path = ofono_modem_get_path(modem); - struct hfp_data *data = ofono_modem_get_data(modem); - - if (!data) - return -EINVAL; g_dbus_register_interface(connection, obj_path, HFP_AGENT_INTERFACE, agent_methods, NULL, NULL, modem, NULL); - data->agent_registered = TRUE; - if (hfp_register_ofono_handsfree(modem) != 0) return -EINVAL; @@ -1062,13 +1054,15 @@ done: static int hfp_disable(struct ofono_modem *modem) { struct hfp_data *data = ofono_modem_get_data(modem); + const char *obj_path = ofono_modem_get_path(modem); int status; DBG("%p", modem); clear_data(modem); - if (data->agent_registered) { + if (g_dbus_interface_is_registered(connection, obj_path, + HFP_AGENT_INTERFACE)) { status = send_method_call_with_reply(BLUEZ_SERVICE, data->handsfree_path, BLUEZ_GATEWAY_INTERFACE, "Disconnect", -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/9] Bring back -d option without need for argument 2010-05-25 7:18 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 4/9] Add bluetooth plugin skeleton Gustavo F. Padovan 2010-05-25 7:49 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 1 sibling, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 897 bytes --] --- src/main.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/src/main.c b/src/main.c index 8e686ac..8f4092c 100644 --- a/src/main.c +++ b/src/main.c @@ -96,8 +96,19 @@ static gchar *option_debug = NULL; static gboolean option_detach = TRUE; static gboolean option_version = FALSE; +static gboolean parse_debug(const char *key, const char *value, gpointer user_data, GError **error) +{ + if (value) + option_debug = g_strdup(value); + else + option_debug = g_strdup("*"); + + return TRUE; +} + static GOptionEntry options[] = { - { "debug", 'd', 0, G_OPTION_ARG_STRING, &option_debug, + { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG, + G_OPTION_ARG_CALLBACK, parse_debug, "Specify debug options to enable", "DEBUG" }, { "nodetach", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &option_detach, -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/9] Add bluetooth plugin skeleton. 2010-05-25 7:18 ` [PATCH 3/9] Bring back -d option without need for argument Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Gustavo F. Padovan 0 siblings, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 5909 bytes --] The bluetooth plugin has bluetooth_resgister_uuid() and bluetooth_unresgister_uuid() where bluetooth profiles plugins such as HFP and DUN can register themselves to get know about BlueZ stuff ( new devices, bluetoothd shutdown, etc..) --- Makefile.am | 3 ++ plugins/bluetooth.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/bluetooth.h | 47 ++++++++++++++++++++++++++++++++ plugins/hfp.c | 8 +---- 4 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 plugins/bluetooth.c create mode 100644 plugins/bluetooth.h diff --git a/Makefile.am b/Makefile.am index ed13346..e0083ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -231,6 +231,9 @@ builtin_sources += plugins/em770.c builtin_modules += novatel builtin_sources += plugins/novatel.c +builtin_modules += bluetooth +builtin_sources += plugins/bluetooth.c + builtin_modules += hfp builtin_sources += plugins/hfp.c diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c new file mode 100644 index 0000000..b4fe676 --- /dev/null +++ b/plugins/bluetooth.c @@ -0,0 +1,75 @@ +/* + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 ProFUSION embedded systems + * Copyright (C) 2010 Gustavo F. Padovan <gustavo@padovan.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <glib.h> +#include <gdbus.h> +#include <ofono.h> + +#include <ofono/dbus.h> + +#include "bluetooth.h" + +static DBusConnection *connection; +static GHashTable *uuid_hash = NULL; +static GHashTable *adapter_address_hash = NULL; + +int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile) +{ + if (uuid_hash) + goto done; + + connection = ofono_dbus_get_connection(); + + uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + + adapter_address_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); + +done: + g_hash_table_insert(uuid_hash, g_strdup(uuid), profile); + + return 0; +} + +void bluetooth_unregister_uuid(const char *uuid) +{ + g_hash_table_remove(uuid_hash, uuid); + + if (g_hash_table_size(uuid_hash)) + return; + + g_hash_table_destroy(uuid_hash); + g_hash_table_destroy(adapter_address_hash); + uuid_hash = NULL; +} + +OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION, + OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL) diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h new file mode 100644 index 0000000..99bd617 --- /dev/null +++ b/plugins/bluetooth.h @@ -0,0 +1,47 @@ +/* + * oFono - Open Source Telephony + * + * Copyright (C) 2010 Gustavo F. Padovan <gustavo@padovan.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __BLUETOOTH_H +#define __BLUETOOTH_H + +#define BLUEZ_SERVICE "org.bluez" +#define BLUEZ_MANAGER_INTERFACE BLUEZ_SERVICE ".Manager" +#define BLUEZ_ADAPTER_INTERFACE BLUEZ_SERVICE ".Adapter" +#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device" + +#define HFP_AG_UUID "0000111F-0000-1000-8000-00805F9B34FB" +#define DUN_GW_UUID "00001103-0000-1000-8000-00805F9B34FB" + +/* Profiles bitfield */ +#define HFP_AG 0x01 +#define DUN_GW 0x02 + +struct bluetooth_profile { + const char *name; + int (*create)(const char *device, const char *dev_addr, const char *adapter_addr, const char *alias); + void (*remove_all)(); + void (*set_alias)(const char *device, const char *); +}; + +int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile); +void bluetooth_unregister_uuid(const char *uuid); + + +#endif /* __BLUETOOTH_H */ diff --git a/plugins/hfp.c b/plugins/hfp.c index b253781..aca6b4e 100644 --- a/plugins/hfp.c +++ b/plugins/hfp.c @@ -45,17 +45,13 @@ #include <ofono/dbus.h> -#define BLUEZ_SERVICE "org.bluez" -#define BLUEZ_MANAGER_INTERFACE BLUEZ_SERVICE ".Manager" -#define BLUEZ_ADAPTER_INTERFACE BLUEZ_SERVICE ".Adapter" -#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device" +#include "bluetooth.h" + #define BLUEZ_GATEWAY_INTERFACE BLUEZ_SERVICE ".HandsfreeGateway" #define HFP_AGENT_INTERFACE "org.bluez.HandsfreeAgent" #define HFP_AGENT_ERROR_INTERFACE "org.bluez.Error" -#define HFP_AG_UUID "0000111F-0000-1000-8000-00805F9B34FB" - #ifndef DBUS_TYPE_UNIX_FD #define DBUS_TYPE_UNIX_FD -1 #endif -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c 2010-05-25 7:18 ` [PATCH 4/9] Add bluetooth plugin skeleton Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 6/9] Remove send_method_call from hfp.c Gustavo F. Padovan 2010-05-25 10:17 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Zhang, Zhenhua 0 siblings, 2 replies; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 29447 bytes --] The new Bluetooth plugin will be responsible for handle DBus for the Bluetooth profiles implemented by oFono. Each Bluetooth profile can register callbacks to create a modem, remove all modems and set alias. The idea is to have here soon code the handle Bluetooth Agent stuff too. --- plugins/bluetooth.c | 482 +++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/hfp.c | 458 ++++-------------------------------------------- 2 files changed, 518 insertions(+), 422 deletions(-) diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index b4fe676..fc89579 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -40,13 +40,478 @@ static DBusConnection *connection; static GHashTable *uuid_hash = NULL; static GHashTable *adapter_address_hash = NULL; +static int send_method_call_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + DBusPendingCallNotifyFunction cb, + void *user_data, DBusFreeFunction free_func, + int timeout, int type, ...) +{ + DBusMessage *msg; + DBusPendingCall *call; + va_list args; + int err; + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + ofono_error("Unable to allocate new D-Bus %s message", method); + err = -ENOMEM; + goto fail; + } + + va_start(args, type); + + if (!dbus_message_append_args_valist(msg, type, args)) { + va_end(args); + err = -EIO; + goto fail; + } + + va_end(args); + + if (timeout > 0) + timeout *=1000; + + if (!dbus_connection_send_with_reply(connection, msg, &call, timeout)) { + ofono_error("Sending %s failed", method); + err = -EIO; + goto fail; + } + + dbus_pending_call_set_notify(call, cb, user_data, free_func); + dbus_pending_call_unref(call); + dbus_message_unref(msg); + + return 0; + +fail: + if (free_func && user_data) + free_func(user_data); + + if (msg) + dbus_message_unref(msg); + + return err; +} + +typedef void (*PropertyHandler)(DBusMessageIter *iter, gpointer user_data); + +struct property_handler { + const char *property; + PropertyHandler callback; + gpointer user_data; +}; + +static gint property_handler_compare(gconstpointer a, gconstpointer b) +{ + const struct property_handler *handler = a; + const char *property = b; + + return strcmp(handler->property, property); +} + +static void parse_properties_reply(DBusMessage *reply, + const char *property, ...) +{ + va_list args; + GSList *prop_handlers = NULL; + DBusMessageIter array, dict; + + va_start(args, property); + + while (property != NULL) { + struct property_handler *handler = + g_new0(struct property_handler, 1); + + handler->property = property; + handler->callback = va_arg(args, PropertyHandler); + handler->user_data = va_arg(args, gpointer); + + property = va_arg(args, const char *); + + prop_handlers = g_slist_prepend(prop_handlers, handler); + } + + va_end(args); + + if (dbus_message_iter_init(reply, &array) == FALSE) + goto done; + + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY) + goto done; + + dbus_message_iter_recurse(&array, &dict); + + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, value; + const char *key; + GSList *l; + + dbus_message_iter_recurse(&dict, &entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) + goto done; + + dbus_message_iter_get_basic(&entry, &key); + + dbus_message_iter_next(&entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) + goto done; + + dbus_message_iter_recurse(&entry, &value); + + l = g_slist_find_custom(prop_handlers, key, + property_handler_compare); + + if (l) { + struct property_handler *handler = l->data; + + handler->callback(&value, handler->user_data); + } + + dbus_message_iter_next(&dict); + } + +done: + g_slist_foreach(prop_handlers, (GFunc)g_free, NULL); + g_slist_free(prop_handlers); +} + +static void has_uuid(DBusMessageIter *array, gpointer user_data) +{ + gboolean *profiles = user_data; + DBusMessageIter value; + + if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(array, &value); + + while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { + const char *uuid; + + dbus_message_iter_get_basic(&value, &uuid); + + if (!strcasecmp(uuid, HFP_AG_UUID)) + *profiles |= HFP_AG; + + if (!strcasecmp(uuid, DUN_GW_UUID)) + *profiles |= DUN_GW; + + dbus_message_iter_next(&value); + } +} + +static void parse_string(DBusMessageIter *iter, gpointer user_data) +{ + char **str = user_data; + int arg_type = dbus_message_iter_get_arg_type(iter); + + if (arg_type != DBUS_TYPE_OBJECT_PATH && arg_type != DBUS_TYPE_STRING) + return; + + dbus_message_iter_get_basic(iter, str); +} + +static void device_properties_cb(DBusPendingCall *call, gpointer user_data) +{ + DBusMessage *reply; + int have_uuid = 0; + const char *path = user_data; + const char *adapter = NULL; + const char *adapter_addr = NULL; + const char *device_addr = NULL; + const char *alias = NULL; + struct bluetooth_profile *profile; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + DBG("Bluetooth daemon is apparently not available."); + goto done; + } + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + if (!dbus_message_is_error(reply, DBUS_ERROR_UNKNOWN_METHOD)) + ofono_info("Error from GetProperties reply: %s", + dbus_message_get_error_name(reply)); + + goto done; + } + + parse_properties_reply(reply, "UUIDs", has_uuid, &have_uuid, + "Adapter", parse_string, &adapter, + "Address", parse_string, &device_addr, + "Alias", parse_string, &alias, NULL); + + if (adapter) + adapter_addr = g_hash_table_lookup(adapter_address_hash, + adapter); + + if ((have_uuid & HFP_AG) && device_addr && adapter_addr) { + profile = g_hash_table_lookup(uuid_hash, HFP_AG_UUID); + profile->create(path, device_addr, adapter_addr, alias); + } + +done: + dbus_message_unref(reply); +} + +static void parse_devices(DBusMessageIter *array, gpointer user_data) +{ + DBusMessageIter value; + GSList **device_list = user_data; + + DBG(""); + + if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(array, &value); + + while (dbus_message_iter_get_arg_type(&value) + == DBUS_TYPE_OBJECT_PATH) { + const char *path; + + dbus_message_iter_get_basic(&value, &path); + + *device_list = g_slist_prepend(*device_list, (gpointer) path); + + dbus_message_iter_next(&value); + } +} + +static gboolean property_changed(DBusConnection *connection, DBusMessage *msg, + void *user_data) +{ + const char *property; + DBusMessageIter iter; + + dbus_message_iter_init(msg, &iter); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return FALSE; + + dbus_message_iter_get_basic(&iter, &property); + if (g_str_equal(property, "UUIDs") == TRUE) { + int profiles = 0; + const char *path = dbus_message_get_path(msg); + DBusMessageIter variant; + + + if (!dbus_message_iter_next(&iter)) + return FALSE; + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) + return FALSE; + + dbus_message_iter_recurse(&iter, &variant); + + has_uuid(&variant, &profiles); + + /* We need the full set of properties to be able to create + * the modem properly, including Adapter and Alias, so + * refetch everything again + */ + if (profiles) + send_method_call_with_reply(BLUEZ_SERVICE, path, + BLUEZ_DEVICE_INTERFACE, "GetProperties", + device_properties_cb, g_strdup(path), g_free, + -1, DBUS_TYPE_INVALID); + } else if (g_str_equal(property, "Alias") == TRUE) { + const char *path = dbus_message_get_path(msg); + struct bluetooth_profile *profile; + const char *alias = NULL; + DBusMessageIter variant; + GHashTableIter hash_iter; + gpointer key, value; + + if (!dbus_message_iter_next(&iter)) + return FALSE; + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) + return FALSE; + + dbus_message_iter_recurse(&iter, &variant); + + parse_string(&variant, &alias); + + g_hash_table_iter_init (&hash_iter, uuid_hash); + while (g_hash_table_iter_next(&hash_iter, &key, &value)) + { + profile = value; + profile->set_alias(path, alias); + } + } + + return TRUE; +} + +static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data) +{ + const char *path = user_data; + DBusMessage *reply; + GSList *device_list = NULL; + GSList *l; + const char *addr; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + DBG("Bluetooth daemon is apparently not available."); + goto done; + } + + parse_properties_reply(reply, "Devices", parse_devices, &device_list, + "Address", parse_string, &addr, NULL); + + DBG("Adapter Address: %s, Path: %s", addr, path); + g_hash_table_insert(adapter_address_hash, + g_strdup(path), g_strdup(addr)); + + for (l = device_list; l; l = l->next) { + const char *device = l->data; + + send_method_call_with_reply(BLUEZ_SERVICE, device, + BLUEZ_DEVICE_INTERFACE, "GetProperties", + device_properties_cb, g_strdup(device), g_free, + -1, DBUS_TYPE_INVALID); + } + +done: + g_slist_free(device_list); + dbus_message_unref(reply); +} + +static gboolean adapter_added(DBusConnection *connection, DBusMessage *message, + void *user_data) +{ + const char *path; + int ret; + + dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID); + + ret = send_method_call_with_reply(BLUEZ_SERVICE, path, + BLUEZ_ADAPTER_INTERFACE, "GetProperties", + adapter_properties_cb, g_strdup(path), g_free, + -1, DBUS_TYPE_INVALID); + + return TRUE; +} + +static gboolean adapter_removed(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + const char *path; + + if (dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID) == TRUE) + g_hash_table_remove(adapter_address_hash, path); + + return TRUE; +} + +static void parse_adapters(DBusMessageIter *array, gpointer user_data) +{ + DBusMessageIter value; + + DBG(""); + + if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(array, &value); + + while (dbus_message_iter_get_arg_type(&value) + == DBUS_TYPE_OBJECT_PATH) { + const char *path; + + dbus_message_iter_get_basic(&value, &path); + + DBG("Calling GetProperties on %s", path); + + send_method_call_with_reply(BLUEZ_SERVICE, path, + BLUEZ_ADAPTER_INTERFACE, "GetProperties", + adapter_properties_cb, g_strdup(path), g_free, + -1, DBUS_TYPE_INVALID); + + dbus_message_iter_next(&value); + } +} + +static void manager_properties_cb(DBusPendingCall *call, gpointer user_data) +{ + DBusMessage *reply; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + DBG("Bluetooth daemon is apparently not available."); + goto done; + } + + DBG(""); + + parse_properties_reply(reply, "Adapters", parse_adapters, NULL, NULL); + +done: + dbus_message_unref(reply); +} + +static void bluetooth_remove_all_modem(gpointer key, gpointer value, gpointer user_data) +{ + struct bluetooth_profile *profile = value; + + profile->remove_all(); +} + +static void bluetooth_disconnect(DBusConnection *connection, void *user_data) +{ + if (!uuid_hash) + return; + + g_hash_table_foreach(uuid_hash, bluetooth_remove_all_modem, NULL); +} + +static guint bluetooth_watch; +static guint adapter_added_watch; +static guint adapter_removed_watch; +static guint property_watch; + int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile) { + int err; + if (uuid_hash) goto done; connection = ofono_dbus_get_connection(); + bluetooth_watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE, + NULL, bluetooth_disconnect, NULL, NULL); + + adapter_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + BLUEZ_MANAGER_INTERFACE, + "AdapterAdded", + adapter_added, NULL, NULL); + + adapter_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + BLUEZ_MANAGER_INTERFACE, + "AdapterRemoved", + adapter_removed, NULL, NULL); + + property_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + BLUEZ_DEVICE_INTERFACE, + "PropertyChanged", + property_changed, NULL, NULL); + + if (bluetooth_watch == 0 || adapter_added_watch == 0 || + adapter_removed_watch == 0 || property_watch == 0) { + err = -EIO; + goto remove; + } + uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); @@ -56,7 +521,19 @@ int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile) done: g_hash_table_insert(uuid_hash, g_strdup(uuid), profile); + send_method_call_with_reply(BLUEZ_SERVICE, "/", + BLUEZ_MANAGER_INTERFACE, "GetProperties", + manager_properties_cb, NULL, NULL, -1, + DBUS_TYPE_INVALID); + return 0; + +remove: + g_dbus_remove_watch(connection, bluetooth_watch); + g_dbus_remove_watch(connection, adapter_added_watch); + g_dbus_remove_watch(connection, adapter_removed_watch); + g_dbus_remove_watch(connection, property_watch); + return err; } void bluetooth_unregister_uuid(const char *uuid) @@ -66,6 +543,11 @@ void bluetooth_unregister_uuid(const char *uuid) if (g_hash_table_size(uuid_hash)) return; + g_dbus_remove_watch(connection, bluetooth_watch); + g_dbus_remove_watch(connection, adapter_added_watch); + g_dbus_remove_watch(connection, adapter_removed_watch); + g_dbus_remove_watch(connection, property_watch); + g_hash_table_destroy(uuid_hash); g_hash_table_destroy(adapter_address_hash); uuid_hash = NULL; diff --git a/plugins/hfp.c b/plugins/hfp.c index aca6b4e..12e7daf 100644 --- a/plugins/hfp.c +++ b/plugins/hfp.c @@ -62,8 +62,7 @@ static const char *cmer_prefix[] = { "+CMER:", NULL }; static const char *chld_prefix[] = { "+CHLD:", NULL }; static DBusConnection *connection; -static GHashTable *uuid_hash = NULL; -static GHashTable *adapter_address_hash; +static GHashTable *modem_hash = NULL; static void hfp_debug(const char *str, void *user_data) { @@ -259,101 +258,6 @@ fail: return err; } -typedef void (*PropertyHandler)(DBusMessageIter *iter, gpointer user_data); - -struct property_handler { - const char *property; - PropertyHandler callback; - gpointer user_data; -}; - -static gint property_handler_compare(gconstpointer a, gconstpointer b) -{ - const struct property_handler *handler = a; - const char *property = b; - - return strcmp(handler->property, property); -} - -static void parse_properties_reply(DBusMessage *reply, - const char *property, ...) -{ - va_list args; - GSList *prop_handlers = NULL; - DBusMessageIter array, dict; - - va_start(args, property); - - while (property != NULL) { - struct property_handler *handler = - g_new0(struct property_handler, 1); - - handler->property = property; - handler->callback = va_arg(args, PropertyHandler); - handler->user_data = va_arg(args, gpointer); - - property = va_arg(args, const char *); - - prop_handlers = g_slist_prepend(prop_handlers, handler); - } - - va_end(args); - - if (dbus_message_iter_init(reply, &array) == FALSE) - goto done; - - if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY) - goto done; - - dbus_message_iter_recurse(&array, &dict); - - while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter entry, value; - const char *key; - GSList *l; - - dbus_message_iter_recurse(&dict, &entry); - - if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) - goto done; - - dbus_message_iter_get_basic(&entry, &key); - - dbus_message_iter_next(&entry); - - if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) - goto done; - - dbus_message_iter_recurse(&entry, &value); - - l = g_slist_find_custom(prop_handlers, key, - property_handler_compare); - - if (l) { - struct property_handler *handler = l->data; - - handler->callback(&value, handler->user_data); - } - - dbus_message_iter_next(&dict); - } - -done: - g_slist_foreach(prop_handlers, (GFunc)g_free, NULL); - g_slist_free(prop_handlers); -} - -static void parse_string(DBusMessageIter *iter, gpointer user_data) -{ - char **str = user_data; - int arg_type = dbus_message_iter_get_arg_type(iter); - - if (arg_type != DBUS_TYPE_OBJECT_PATH && arg_type != DBUS_TYPE_STRING) - return; - - dbus_message_iter_get_basic(iter, str); -} - static void cind_status_cb(gboolean ok, GAtResult *result, gpointer user_data) { @@ -594,6 +498,10 @@ static int hfp_create_modem(const char *device, const char *dev_addr, struct hfp_data *data; char buf[256]; + /* We already have this device in our hash, ignore */ + if (g_hash_table_lookup(modem_hash, device) != NULL) + return -EALREADY; + ofono_info("Using device: %s, devaddr: %s, adapter: %s", device, dev_addr, adapter_addr); @@ -622,7 +530,7 @@ static int hfp_create_modem(const char *device, const char *dev_addr, ofono_modem_set_name(modem, alias); ofono_modem_register(modem); - g_hash_table_insert(uuid_hash, g_strdup(device), modem); + g_hash_table_insert(modem_hash, g_strdup(device), modem); return 0; @@ -633,286 +541,35 @@ free: return -ENOMEM; } -static void has_hfp_uuid(DBusMessageIter *array, gpointer user_data) -{ - gboolean *hfp = user_data; - DBusMessageIter value; - - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) - return; - - dbus_message_iter_recurse(array, &value); - - while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { - const char *uuid; - - dbus_message_iter_get_basic(&value, &uuid); - - if (!strcasecmp(uuid, HFP_AG_UUID)) { - *hfp = TRUE; - return; - } - - dbus_message_iter_next(&value); - } -} - -static void device_properties_cb(DBusPendingCall *call, gpointer user_data) -{ - DBusMessage *reply; - char *path = user_data; - gboolean have_hfp = FALSE; - const char *adapter = NULL; - const char *adapter_addr = NULL; - const char *device_addr = NULL; - const char *alias = NULL; - - reply = dbus_pending_call_steal_reply(call); - - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { - DBG("Bluetooth daemon is apparently not available."); - goto done; - } - - if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { - if (!dbus_message_is_error(reply, DBUS_ERROR_UNKNOWN_METHOD)) - ofono_info("Error from GetProperties reply: %s", - dbus_message_get_error_name(reply)); - - goto done; - } - - parse_properties_reply(reply, "UUIDs", has_hfp_uuid, &have_hfp, - "Adapter", parse_string, &adapter, - "Address", parse_string, &device_addr, - "Alias", parse_string, &alias, NULL); - - if (adapter) - adapter_addr = g_hash_table_lookup(adapter_address_hash, - adapter); - - if (have_hfp && device_addr && adapter_addr) - hfp_create_modem(path, device_addr, adapter_addr, alias); - -done: - dbus_message_unref(reply); -} - -static void parse_devices(DBusMessageIter *array, gpointer user_data) -{ - DBusMessageIter value; - GSList **device_list = user_data; - - DBG(""); - - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) - return; - - dbus_message_iter_recurse(array, &value); - - while (dbus_message_iter_get_arg_type(&value) - == DBUS_TYPE_OBJECT_PATH) { - const char *path; - - dbus_message_iter_get_basic(&value, &path); - - *device_list = g_slist_prepend(*device_list, (gpointer) path); - - dbus_message_iter_next(&value); - } -} - -static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data) -{ - const char *path = user_data; - DBusMessage *reply; - GSList *device_list = NULL; - GSList *l; - const char *addr; - - reply = dbus_pending_call_steal_reply(call); - - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { - DBG("Bluetooth daemon is apparently not available."); - goto done; - } - - parse_properties_reply(reply, "Devices", parse_devices, &device_list, - "Address", parse_string, &addr, NULL); - - DBG("Adapter Address: %s, Path: %s", addr, path); - g_hash_table_insert(adapter_address_hash, - g_strdup(path), g_strdup(addr)); - - for (l = device_list; l; l = l->next) { - const char *device = l->data; - - send_method_call_with_reply(BLUEZ_SERVICE, device, - BLUEZ_DEVICE_INTERFACE, "GetProperties", - device_properties_cb, g_strdup(device), g_free, - -1, DBUS_TYPE_INVALID); - } - -done: - g_slist_free(device_list); - dbus_message_unref(reply); -} - -static gboolean adapter_added(DBusConnection *connection, DBusMessage *message, - void *user_data) -{ - const char *path; - int ret; - - dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID); - - ret = send_method_call_with_reply(BLUEZ_SERVICE, path, - BLUEZ_ADAPTER_INTERFACE, "GetProperties", - adapter_properties_cb, g_strdup(path), g_free, - -1, DBUS_TYPE_INVALID); - - return TRUE; -} - -static gboolean adapter_removed(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - const char *path; - - if (dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID) == TRUE) - g_hash_table_remove(adapter_address_hash, path); - - return TRUE; -} - -static gboolean property_changed(DBusConnection *connection, DBusMessage *msg, - void *user_data) +static gboolean hfp_remove_each_modem(gpointer key, gpointer value, gpointer user_data) { - const char *property; - DBusMessageIter iter; - - dbus_message_iter_init(msg, &iter); - - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return FALSE; - - dbus_message_iter_get_basic(&iter, &property); - if (g_str_equal(property, "UUIDs") == TRUE) { - gboolean have_hfp = FALSE; - const char *path = dbus_message_get_path(msg); - DBusMessageIter variant; - - /* We already have this device in our hash, ignore */ - if (g_hash_table_lookup(uuid_hash, path) != NULL) - return TRUE; - - if (!dbus_message_iter_next(&iter)) - return FALSE; - - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) - return FALSE; - - dbus_message_iter_recurse(&iter, &variant); - - has_hfp_uuid(&variant, &have_hfp); - - /* We need the full set of properties to be able to create - * the modem properly, including Adapter and Alias, so - * refetch everything again - */ - if (have_hfp) - send_method_call_with_reply(BLUEZ_SERVICE, path, - BLUEZ_DEVICE_INTERFACE, "GetProperties", - device_properties_cb, g_strdup(path), g_free, - -1, DBUS_TYPE_INVALID); - } else if (g_str_equal(property, "Alias") == TRUE) { - const char *path = dbus_message_get_path(msg); - struct ofono_modem *modem = - g_hash_table_lookup(uuid_hash, path); - const char *alias = NULL; - DBusMessageIter variant; - - if (modem == NULL) - return TRUE; - - if (!dbus_message_iter_next(&iter)) - return FALSE; - - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) - return FALSE; - - dbus_message_iter_recurse(&iter, &variant); - - parse_string(&variant, &alias); + struct ofono_modem *modem = value; - ofono_modem_set_name(modem, alias); - } + ofono_modem_remove(modem); return TRUE; } -static void parse_adapters(DBusMessageIter *array, gpointer user_data) +static void hfp_remove_all_modem() { - DBusMessageIter value; - - DBG(""); - - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) + if (modem_hash == NULL) return; - dbus_message_iter_recurse(array, &value); - - while (dbus_message_iter_get_arg_type(&value) - == DBUS_TYPE_OBJECT_PATH) { - const char *path; - - dbus_message_iter_get_basic(&value, &path); - - DBG("Calling GetProperties on %s", path); - - send_method_call_with_reply(BLUEZ_SERVICE, path, - BLUEZ_ADAPTER_INTERFACE, "GetProperties", - adapter_properties_cb, g_strdup(path), g_free, - -1, DBUS_TYPE_INVALID); - - dbus_message_iter_next(&value); - } -} - -static void manager_properties_cb(DBusPendingCall *call, gpointer user_data) -{ - DBusMessage *reply; - - reply = dbus_pending_call_steal_reply(call); - - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { - DBG("Bluetooth daemon is apparently not available."); - goto done; - } - - parse_properties_reply(reply, "Adapters", parse_adapters, NULL, NULL); - -done: - dbus_message_unref(reply); + g_hash_table_foreach_remove(modem_hash, hfp_remove_each_modem, NULL); } -static gboolean hfp_remove_each_modem(gpointer key, gpointer value, gpointer user_data) +static void hfp_set_alias(const char *device, const char *alias) { - struct ofono_modem *modem = value; - - ofono_modem_remove(modem); + struct ofono_modem *modem; - return TRUE; -} + if (!device || !alias) + return; -static void bluetooth_disconnect(DBusConnection *connection, void *user_data) -{ - if (uuid_hash == NULL) + modem = g_hash_table_lookup(modem_hash, device); + if (!modem) return; - g_hash_table_foreach_remove(uuid_hash, hfp_remove_each_modem, NULL); + ofono_modem_set_name(modem, alias); } static int hfp_register_ofono_handsfree(struct ofono_modem *modem) @@ -963,7 +620,7 @@ static void hfp_remove(struct ofono_modem *modem) HFP_AGENT_INTERFACE)) hfp_unregister_ofono_handsfree(modem); - g_hash_table_remove(uuid_hash, data->handsfree_path); + g_hash_table_remove(modem_hash, data->handsfree_path); g_free(data->handsfree_path); g_free(data); @@ -1098,10 +755,12 @@ static struct ofono_modem_driver hfp_driver = { .post_sim = hfp_post_sim, }; -static guint bluetooth_exit_watch; -static guint adapter_added_watch; -static guint adapter_removed_watch; -static guint uuid_watch; +static struct bluetooth_profile hfp_profile = { + .name = "hfp", + .create = hfp_create_modem, + .remove_all = hfp_remove_all_modem, + .set_alias = hfp_set_alias, +}; static int hfp_init() { @@ -1112,73 +771,28 @@ static int hfp_init() connection = ofono_dbus_get_connection(); - bluetooth_exit_watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE, - NULL, bluetooth_disconnect, NULL, NULL); - - adapter_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, - BLUEZ_MANAGER_INTERFACE, - "AdapterAdded", - adapter_added, NULL, NULL); - - adapter_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, - BLUEZ_MANAGER_INTERFACE, - "AdapterRemoved", - adapter_removed, NULL, NULL); - - uuid_watch = g_dbus_add_signal_watch(connection, NULL, NULL, - BLUEZ_DEVICE_INTERFACE, - "PropertyChanged", - property_changed, NULL, NULL); + err = ofono_modem_driver_register(&hfp_driver); + if (err < 0) + return err; - if (bluetooth_exit_watch == 0 || adapter_added_watch == 0 || - adapter_removed_watch == 0|| uuid_watch == 0) { - err = -EIO; - goto remove; + err = bluetooth_register_uuid(HFP_AG_UUID, &hfp_profile); + if (err < 0) { + ofono_modem_driver_unregister(&hfp_driver); + return err; } - uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - adapter_address_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); - - err = ofono_modem_driver_register(&hfp_driver); - if (err < 0) - goto remove; - - send_method_call_with_reply(BLUEZ_SERVICE, "/", - BLUEZ_MANAGER_INTERFACE, "GetProperties", - manager_properties_cb, NULL, NULL, -1, - DBUS_TYPE_INVALID); - return 0; - -remove: - g_dbus_remove_watch(connection, bluetooth_exit_watch); - g_dbus_remove_watch(connection, adapter_added_watch); - g_dbus_remove_watch(connection, adapter_removed_watch); - g_dbus_remove_watch(connection, uuid_watch); - - if (uuid_hash) - g_hash_table_destroy(uuid_hash); - - if (adapter_address_hash) - g_hash_table_destroy(adapter_address_hash); - - return err; } static void hfp_exit() { - g_dbus_remove_watch(connection, bluetooth_exit_watch); - g_dbus_remove_watch(connection, adapter_added_watch); - g_dbus_remove_watch(connection, adapter_removed_watch); - g_dbus_remove_watch(connection, uuid_watch); - + bluetooth_unregister_uuid(HFP_AG_UUID); ofono_modem_driver_unregister(&hfp_driver); - g_hash_table_destroy(uuid_hash); - g_hash_table_destroy(adapter_address_hash); + g_hash_table_destroy(modem_hash); } OFONO_PLUGIN_DEFINE(hfp, "Hands-Free Profile Plugins", VERSION, -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/9] Remove send_method_call from hfp.c 2010-05-25 7:18 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 7/9] Move create_path() to bluetooth plugin Gustavo F. Padovan 2010-05-25 10:17 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Zhang, Zhenhua 1 sibling, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 4142 bytes --] That function should be only in the bluetooth plugin, then we can avoid code duplication. There is a plan to remove send_method_call_with_reply too once the Bluetooth agent moves to the bluetooth plugin. --- plugins/hfp.c | 73 +++++++++++++++++++++++++------------------------------- 1 files changed, 33 insertions(+), 40 deletions(-) diff --git a/plugins/hfp.c b/plugins/hfp.c index 12e7daf..ea34f4c 100644 --- a/plugins/hfp.c +++ b/plugins/hfp.c @@ -178,33 +178,11 @@ static void cmer_cb(gboolean ok, GAtResult *result, gpointer user_data) sevice_level_conn_established(modem); } -static int send_method_call(const char *dest, const char *path, - const char *interface, const char *method, - int type, ...) -{ - DBusMessage *msg; - va_list args; - - msg = dbus_message_new_method_call(dest, path, interface, method); - if (!msg) { - ofono_error("Unable to allocate new D-Bus %s message", method); - return -ENOMEM; - } - - va_start(args, type); - - if (!dbus_message_append_args_valist(msg, type, args)) { - dbus_message_unref(msg); - va_end(args); - return -EIO; - } - - va_end(args); - - g_dbus_send_message(connection, msg); - return 0; -} - +/* + * FIXME: Group all agent stuff DBus calls in bluetooth.c + * then we can reuse common agent code for all Bluetooth plugins. + * That will remove this function from hfp.c + */ static int send_method_call_with_reply(const char *dest, const char *path, const char *interface, const char *method, DBusPendingCallNotifyFunction cb, @@ -576,26 +554,40 @@ static int hfp_register_ofono_handsfree(struct ofono_modem *modem) { const char *obj_path = ofono_modem_get_path(modem); struct hfp_data *data = ofono_modem_get_data(modem); + DBusMessage *msg; DBG("Registering oFono Agent to bluetooth daemon"); - return send_method_call(BLUEZ_SERVICE, data->handsfree_path, - BLUEZ_GATEWAY_INTERFACE, "RegisterAgent", - DBUS_TYPE_OBJECT_PATH, &obj_path, + msg = dbus_message_new_method_call(BLUEZ_SERVICE, data->handsfree_path, + BLUEZ_GATEWAY_INTERFACE, "RegisterAgent"); + if (!msg) + return -ENOMEM; + + dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &obj_path, DBUS_TYPE_INVALID); + + g_dbus_send_message(connection, msg); + return 0; } static int hfp_unregister_ofono_handsfree(struct ofono_modem *modem) { const char *obj_path = ofono_modem_get_path(modem); struct hfp_data *data = ofono_modem_get_data(modem); + DBusMessage *msg; DBG("Unregistering oFono Agent from bluetooth daemon"); - return send_method_call(BLUEZ_SERVICE, data->handsfree_path, - BLUEZ_GATEWAY_INTERFACE, "UnregisterAgent", - DBUS_TYPE_OBJECT_PATH, &obj_path, + msg = dbus_message_new_method_call(BLUEZ_SERVICE, data->handsfree_path, + BLUEZ_GATEWAY_INTERFACE, "UnregisterAgent"); + if (!msg) + return -ENOMEM; + + dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &obj_path, DBUS_TYPE_INVALID); + + g_dbus_send_message(connection, msg); + return 0; } static int hfp_probe(struct ofono_modem *modem) @@ -633,8 +625,7 @@ static void hfp_connect_reply(DBusPendingCall *call, gpointer user_data) struct ofono_modem *modem = user_data; struct hfp_data *data = ofono_modem_get_data(modem); DBusError derr; - DBusMessage *reply; - int ret; + DBusMessage *reply, *msg; reply = dbus_pending_call_steal_reply(call); @@ -648,11 +639,13 @@ static void hfp_connect_reply(DBusPendingCall *call, gpointer user_data) DBG("Connect reply: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { - ret = send_method_call(BLUEZ_SERVICE, data->handsfree_path, - BLUEZ_GATEWAY_INTERFACE, "Disconnect", - DBUS_TYPE_INVALID); - if (ret < 0) - ofono_error("Disconnect failed(%d)", ret); + msg = dbus_message_new_method_call(BLUEZ_SERVICE, + data->handsfree_path, + BLUEZ_GATEWAY_INTERFACE, "Disconnect"); + if (!msg) + ofono_error("Disconnect failed"); + else + g_dbus_send_message(connection, msg); } ofono_modem_set_powered(modem, FALSE); -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/9] Move create_path() to bluetooth plugin 2010-05-25 7:18 ` [PATCH 6/9] Remove send_method_call from hfp.c Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 8/9] Change hfpmodem's header define Gustavo F. Padovan 0 siblings, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 3143 bytes --] --- plugins/bluetooth.c | 22 ++++++++++++++++++++++ plugins/bluetooth.h | 1 + plugins/hfp.c | 25 +------------------------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index fc89579..49d1b5e 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -40,6 +40,28 @@ static DBusConnection *connection; static GHashTable *uuid_hash = NULL; static GHashTable *adapter_address_hash = NULL; +void bluetooth_create_path(const char *dev_addr, const char *adapter_addr, char *buf, int size) +{ + int i, j; + + for (i = 0, j = 0; adapter_addr[j] && i < size - 1; j++) + if (adapter_addr[j] >= '0' && adapter_addr[j] <= '9') + buf[i++] = adapter_addr[j]; + else if (adapter_addr[j] >= 'A' && adapter_addr[j] <= 'F') + buf[i++] = adapter_addr[j]; + + if (i < size - 1) + buf[i++] = '_'; + + for (j = 0; dev_addr[j] && i < size - 1; j++) + if (dev_addr[j] >= '0' && dev_addr[j] <= '9') + buf[i++] = dev_addr[j]; + else if (dev_addr[j] >= 'A' && dev_addr[j] <= 'F') + buf[i++] = dev_addr[j]; + + buf[i] = '\0'; +} + static int send_method_call_with_reply(const char *dest, const char *path, const char *interface, const char *method, DBusPendingCallNotifyFunction cb, diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h index 99bd617..4019daa 100644 --- a/plugins/bluetooth.h +++ b/plugins/bluetooth.h @@ -43,5 +43,6 @@ struct bluetooth_profile { int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile); void bluetooth_unregister_uuid(const char *uuid); +void bluetooth_create_path(const char *dev_addr, const char *adapter_addr, char *buf, int size); #endif /* __BLUETOOTH_H */ diff --git a/plugins/hfp.c b/plugins/hfp.c index ea34f4c..13439d9 100644 --- a/plugins/hfp.c +++ b/plugins/hfp.c @@ -446,29 +446,6 @@ static GDBusMethodTable agent_methods[] = { { NULL, NULL, NULL, NULL } }; -static void create_path(const char *dev_addr, const char *adapter_addr, - char *buf, int size) -{ - int i, j; - - for (i = 0, j = 0; adapter_addr[j] && i < size - 1; j++) - if (adapter_addr[j] >= '0' && adapter_addr[j] <= '9') - buf[i++] = adapter_addr[j]; - else if (adapter_addr[j] >= 'A' && adapter_addr[j] <= 'F') - buf[i++] = adapter_addr[j]; - - if (i < size - 1) - buf[i++] = '_'; - - for (j = 0; dev_addr[j] && i < size - 1; j++) - if (dev_addr[j] >= '0' && dev_addr[j] <= '9') - buf[i++] = dev_addr[j]; - else if (dev_addr[j] >= 'A' && dev_addr[j] <= 'F') - buf[i++] = dev_addr[j]; - - buf[i] = '\0'; -} - static int hfp_create_modem(const char *device, const char *dev_addr, const char *adapter_addr, const char *alias) { @@ -484,7 +461,7 @@ static int hfp_create_modem(const char *device, const char *dev_addr, device, dev_addr, adapter_addr); strcpy(buf, "hfp/"); - create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4); + bluetooth_create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4); modem = ofono_modem_create(buf, "hfp"); if (modem == NULL) -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/9] Change hfpmodem's header define 2010-05-25 7:18 ` [PATCH 7/9] Move create_path() to bluetooth plugin Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 9/9] Bluetooth DUN modem prototype Gustavo F. Padovan 0 siblings, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 567 bytes --] --- drivers/hfpmodem/hfpmodem.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h index 6ec8a7c..46d2dc8 100644 --- a/drivers/hfpmodem/hfpmodem.h +++ b/drivers/hfpmodem/hfpmodem.h @@ -18,8 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ -#ifndef __BLUETOOTH_H__ -#define __BLUETOOTH_H__ +#ifndef __HFPMODEM_H__ +#define __HFPMODEM_H__ #include <drivers/atmodem/atutil.h> #include <ofono/dbus.h> -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 9/9] Bluetooth DUN modem prototype 2010-05-25 7:18 ` [PATCH 8/9] Change hfpmodem's header define Gustavo F. Padovan @ 2010-05-25 7:18 ` Gustavo F. Padovan 0 siblings, 0 replies; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:18 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 9833 bytes --] Add a still dummy DUN code, now it can only creates and removes modems. The DUN plugin follows the HFP one a lot, the is basics a copy of some HFP plugin's parts. --- Makefile.am | 6 + drivers/dunmodem/dunmodem.c | 51 ++++++++++ drivers/dunmodem/dunmodem.h | 29 ++++++ plugins/bluetooth.c | 5 + plugins/dun.c | 214 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 305 insertions(+), 0 deletions(-) create mode 100644 drivers/dunmodem/dunmodem.c create mode 100644 drivers/dunmodem/dunmodem.h create mode 100644 plugins/dun.c diff --git a/Makefile.am b/Makefile.am index e0083ef..20a30d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -172,6 +172,9 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/hfpmodem/network-registration.c \ drivers/hfpmodem/call-volume.c +builtin_modules += dunmodem +builtin_sources += drivers/dunmodem/dunmodem.h drivers/dunmodem/dunmodem.c + builtin_modules += mbmmodem builtin_sources += drivers/atmodem/atutil.h \ drivers/mbmmodem/mbmmodem.h \ @@ -237,6 +240,9 @@ builtin_sources += plugins/bluetooth.c builtin_modules += hfp builtin_sources += plugins/hfp.c +builtin_modules += dun +builtin_sources += plugins/dun.c + builtin_modules += palmpre builtin_sources += plugins/palmpre.c diff --git a/drivers/dunmodem/dunmodem.c b/drivers/dunmodem/dunmodem.c new file mode 100644 index 0000000..8658bee --- /dev/null +++ b/drivers/dunmodem/dunmodem.c @@ -0,0 +1,51 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 Gustavo F. Padovan <gustavo@padovan.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <glib.h> + +#define OFONO_API_SUBJECT_TO_CHANGE +#include <ofono/plugin.h> +#include <ofono/log.h> +#include <ofono/modem.h> + +#include "dunmodem.h" + +static int dunmodem_init(void) +{ + return 0; +} + +static void dunmodem_exit(void) +{ +} + +OFONO_PLUGIN_DEFINE(dunmodem, "Dial-up Networking Driver", VERSION, + OFONO_PLUGIN_PRIORITY_DEFAULT, dunmodem_init, dunmodem_exit) + diff --git a/drivers/dunmodem/dunmodem.h b/drivers/dunmodem/dunmodem.h new file mode 100644 index 0000000..6bbf7b9 --- /dev/null +++ b/drivers/dunmodem/dunmodem.h @@ -0,0 +1,29 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 Gustavo F. Padovan <gustavo@padovan.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef __DUN_MODEM_H__ +#define __DUN_MODEM_H__ + +struct dun_data { + char *dun_path; +}; + +#endif + diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index 49d1b5e..6f42ac7 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -275,6 +275,11 @@ static void device_properties_cb(DBusPendingCall *call, gpointer user_data) profile->create(path, device_addr, adapter_addr, alias); } + if ((have_uuid & DUN_GW) && device_addr && adapter_addr) { + profile = g_hash_table_lookup(uuid_hash, DUN_GW_UUID); + profile->create(path, device_addr, adapter_addr, alias); + } + done: dbus_message_unref(reply); } diff --git a/plugins/dun.c b/plugins/dun.c new file mode 100644 index 0000000..9c8d9ce --- /dev/null +++ b/plugins/dun.c @@ -0,0 +1,214 @@ +/* + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 Gustavo F. Padovan <gustavo@padovan.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <glib.h> +#include <ofono.h> + +#define OFONO_API_SUBJECT_TO_CHANGE +#include <ofono/plugin.h> +#include <ofono/log.h> +#include <ofono/modem.h> + +#include <drivers/dunmodem/dunmodem.h> + +#include <ofono/dbus.h> + +#include "bluetooth.h" + +#ifndef DBUS_TYPE_UNIX_FD +#define DBUS_TYPE_UNIX_FD -1 +#endif + +static DBusConnection *connection; +static GHashTable *modem_hash = NULL; + +static int dun_create_modem(const char *device, const char *dev_addr, + const char *adapter_addr, const char *alias) +{ + struct ofono_modem *modem; + struct dun_data *data; + char buf[256]; + + /* We already have this device in our hash, ignore */ + if (g_hash_table_lookup(modem_hash, device) != NULL) + return -EALREADY; + + ofono_info("Using device: %s, devaddr: %s, adapter: %s", + device, dev_addr, adapter_addr); + + strcpy(buf, "dun/"); + bluetooth_create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4); + + modem = ofono_modem_create(buf, "dun"); + if (modem == NULL) + return -ENOMEM; + + data = g_try_new0(struct dun_data, 1); + if (!data) + goto free; + + data->dun_path = g_strdup(device); + if (data->dun_path == NULL) + goto free; + + ofono_modem_set_data(modem, data); + ofono_modem_set_name(modem, alias); + ofono_modem_register(modem); + + g_hash_table_insert(modem_hash, g_strdup(device), modem); + return 0; + +free: + g_free(data); + ofono_modem_remove(modem); + + return -ENOMEM; +} + +static gboolean dun_remove_each_modem(gpointer key, gpointer value, gpointer user_data) +{ + struct ofono_modem *modem = value; + + ofono_modem_remove(modem); + + return TRUE; +} + +static void dun_remove_all_modem() +{ + if (modem_hash == NULL) + return; + + g_hash_table_foreach_remove(modem_hash, dun_remove_each_modem, NULL); +} + +static void dun_set_alias(const char *device, const char *alias) +{ + struct ofono_modem *modem; + + if (!device || !alias) + return; + + modem = g_hash_table_lookup(modem_hash, device); + if (!modem) + return; + + ofono_modem_set_name(modem, alias); +} + +static int dun_probe(struct ofono_modem *modem) +{ + DBG("%p", modem); + return 0; +} + +static void dun_remove(struct ofono_modem *modem) +{ + struct dun_data *data = ofono_modem_get_data(modem); + + g_hash_table_remove(modem_hash, data->dun_path); + + g_free(data->dun_path); + g_free(data); + + ofono_modem_set_data(modem, NULL); +} + +static int dun_enable(struct ofono_modem *modem) +{ + DBG("%p", modem); + return 0; +} + +static int dun_disable(struct ofono_modem *modem) +{ + DBG("%p", modem); + return 0; +} + +static void dun_pre_sim(struct ofono_modem *modem) +{ + DBG("%p", modem); +} + +static void dun_post_sim(struct ofono_modem *modem) +{ + DBG("%p", modem); +} + +static struct ofono_modem_driver dun_driver = { + .name = "dun", + .probe = dun_probe, + .remove = dun_remove, + .enable = dun_enable, + .disable = dun_disable, + .pre_sim = dun_pre_sim, + .post_sim = dun_post_sim, +}; + +static struct bluetooth_profile dun_profile = { + .name = "dun", + .create = dun_create_modem, + .remove_all = dun_remove_all_modem, + .set_alias = dun_set_alias, +}; + +static int dun_init() +{ + int err; + + if (DBUS_TYPE_UNIX_FD < 0) + return -EBADF; + + connection = ofono_dbus_get_connection(); + + err = ofono_modem_driver_register(&dun_driver); + if (err < 0) + return err; + + err = bluetooth_register_uuid(DUN_GW_UUID, &dun_profile); + if (err < 0) { + ofono_modem_driver_unregister(&dun_driver); + return err; + } + + modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + + return 0; +} + +static void dun_exit() +{ + bluetooth_unregister_uuid(DUN_GW_UUID); + ofono_modem_driver_unregister(&dun_driver); + + g_hash_table_destroy(modem_hash); +} + +OFONO_PLUGIN_DEFINE(dun, "Dial-up Networking Profile Plugins", VERSION, + OFONO_PLUGIN_PRIORITY_DEFAULT, dun_init, dun_exit) -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* RE: [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c 2010-05-25 7:18 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 6/9] Remove send_method_call from hfp.c Gustavo F. Padovan @ 2010-05-25 10:17 ` Zhang, Zhenhua 1 sibling, 0 replies; 13+ messages in thread From: Zhang, Zhenhua @ 2010-05-25 10:17 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 23100 bytes --] Hi Padovan, Gustavo F. Padovan wrote: > --- plugins/bluetooth.c | 482 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > plugins/hfp.c | 458 > ++++-------------------------------------------- > 2 files changed, 518 insertions(+), 422 deletions(-) > > diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c > index b4fe676..fc89579 100644 > --- a/plugins/bluetooth.c > +++ b/plugins/bluetooth.c > + > int bluetooth_register_uuid(const char *uuid, struct > bluetooth_profile *profile) { > + int err; > + > if (uuid_hash) > goto done; > > connection = ofono_dbus_get_connection(); > > + bluetooth_watch = g_dbus_add_service_watch(connection, > BLUEZ_SERVICE, + NULL, > bluetooth_disconnect, NULL, NULL); > + > + adapter_added_watch = > g_dbus_add_signal_watch(connection, NULL, NULL, > + BLUEZ_MANAGER_INTERFACE, > + "AdapterAdded", > + adapter_added, > NULL, NULL); > + > + adapter_removed_watch = > g_dbus_add_signal_watch(connection, NULL, NULL, > + BLUEZ_MANAGER_INTERFACE, > + "AdapterRemoved", > + > adapter_removed, NULL, NULL); > + > + property_watch = g_dbus_add_signal_watch(connection, NULL, NULL, > + BLUEZ_DEVICE_INTERFACE, > + "PropertyChanged", > + > property_changed, NULL, NULL); > + > + if (bluetooth_watch == 0 || adapter_added_watch == 0 || > + adapter_removed_watch == 0 || > property_watch == 0) { > + err = -EIO; > + goto remove; > + } I may introduce API to register service like bluetooth_register_service() later. So I wonder if we could put above the initialization code into bluetooth_init(). I'd like to introduce a hash table similar with uuid_hash so uuid_hash is NULL in my case. > uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, > g_free, NULL); > > @@ -56,7 +521,19 @@ int bluetooth_register_uuid(const char > *uuid, struct bluetooth_profile *profile) > done: > g_hash_table_insert(uuid_hash, g_strdup(uuid), profile); > > + send_method_call_with_reply(BLUEZ_SERVICE, "/", > + BLUEZ_MANAGER_INTERFACE, > "GetProperties", > + manager_properties_cb, NULL, NULL, -1, > + DBUS_TYPE_INVALID); > + > return 0; > + > +remove: > + g_dbus_remove_watch(connection, bluetooth_watch); > + g_dbus_remove_watch(connection, adapter_added_watch); > + g_dbus_remove_watch(connection, adapter_removed_watch); > + g_dbus_remove_watch(connection, property_watch); > + return err; > } > > void bluetooth_unregister_uuid(const char *uuid) > @@ -66,6 +543,11 @@ void bluetooth_unregister_uuid(const char *uuid) > if (g_hash_table_size(uuid_hash)) > return; > > + g_dbus_remove_watch(connection, bluetooth_watch); > + g_dbus_remove_watch(connection, adapter_added_watch); > + g_dbus_remove_watch(connection, adapter_removed_watch); > + g_dbus_remove_watch(connection, property_watch); > + > g_hash_table_destroy(uuid_hash); > g_hash_table_destroy(adapter_address_hash); > uuid_hash = NULL; Can we move g_dbus_remove_watch() to bluetooth_exit() as well? > diff --git a/plugins/hfp.c b/plugins/hfp.c > index aca6b4e..12e7daf 100644 > --- a/plugins/hfp.c > +++ b/plugins/hfp.c > @@ -62,8 +62,7 @@ static const char *cmer_prefix[] = { "+CMER:", NULL > }; static const char *chld_prefix[] = { "+CHLD:", NULL }; > > static DBusConnection *connection; > -static GHashTable *uuid_hash = NULL; > -static GHashTable *adapter_address_hash; > +static GHashTable *modem_hash = NULL; > > static void hfp_debug(const char *str, void *user_data) { > @@ -259,101 +258,6 @@ fail: > return err; > } > > -typedef void (*PropertyHandler)(DBusMessageIter *iter, > gpointer user_data); > - > -struct property_handler { > - const char *property; > - PropertyHandler callback; > - gpointer user_data; > -}; > - > -static gint property_handler_compare(gconstpointer a, gconstpointer > b) -{ > - const struct property_handler *handler = a; > - const char *property = b; > - > - return strcmp(handler->property, property); > -} > - > -static void parse_properties_reply(DBusMessage *reply, > - const char *property, ...) > -{ > - va_list args; > - GSList *prop_handlers = NULL; > - DBusMessageIter array, dict; > - > - va_start(args, property); > - > - while (property != NULL) { > - struct property_handler *handler = > - g_new0(struct > property_handler, 1); > - > - handler->property = property; > - handler->callback = va_arg(args, PropertyHandler); > - handler->user_data = va_arg(args, gpointer); > - > - property = va_arg(args, const char *); > - > - prop_handlers = g_slist_prepend(prop_handlers, handler); > - } > - > - va_end(args); > - > - if (dbus_message_iter_init(reply, &array) == FALSE) > - goto done; > - > - if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY) > - goto done; > - > - dbus_message_iter_recurse(&array, &dict); > - > - while (dbus_message_iter_get_arg_type(&dict) == > DBUS_TYPE_DICT_ENTRY) { > - DBusMessageIter entry, value; > - const char *key; > - GSList *l; > - > - dbus_message_iter_recurse(&dict, &entry); > - > - if (dbus_message_iter_get_arg_type(&entry) != > DBUS_TYPE_STRING) > - goto done; > - > - dbus_message_iter_get_basic(&entry, &key); > - > - dbus_message_iter_next(&entry); > - > - if (dbus_message_iter_get_arg_type(&entry) != > DBUS_TYPE_VARIANT) > - goto done; > - > - dbus_message_iter_recurse(&entry, &value); > - > - l = g_slist_find_custom(prop_handlers, key, > - property_handler_compare); > - > - if (l) { > - struct property_handler *handler = l->data; > - > - handler->callback(&value, handler->user_data); > - } > - > - dbus_message_iter_next(&dict); > - } > - > -done: > - g_slist_foreach(prop_handlers, (GFunc)g_free, NULL); > - g_slist_free(prop_handlers); > -} > - > -static void parse_string(DBusMessageIter *iter, gpointer user_data) > -{ > - char **str = user_data; > - int arg_type = dbus_message_iter_get_arg_type(iter); - > - if (arg_type != DBUS_TYPE_OBJECT_PATH && arg_type != > DBUS_TYPE_STRING) > - return; > - > - dbus_message_iter_get_basic(iter, str); > -} > - > static void cind_status_cb(gboolean ok, GAtResult *result, > gpointer user_data) { > @@ -594,6 +498,10 @@ static int hfp_create_modem(const char > *device, const char *dev_addr, > struct hfp_data *data; > char buf[256]; > > + /* We already have this device in our hash, ignore */ > + if (g_hash_table_lookup(modem_hash, device) != NULL) + return > -EALREADY; + > ofono_info("Using device: %s, devaddr: %s, adapter: %s", > device, dev_addr, adapter_addr); > > @@ -622,7 +530,7 @@ static int hfp_create_modem(const char > *device, const char *dev_addr, > ofono_modem_set_name(modem, alias); > ofono_modem_register(modem); > > - g_hash_table_insert(uuid_hash, g_strdup(device), modem); > + g_hash_table_insert(modem_hash, g_strdup(device), modem); > > return 0; > > @@ -633,286 +541,35 @@ free: > return -ENOMEM; > } > > -static void has_hfp_uuid(DBusMessageIter *array, gpointer user_data) > -{ > - gboolean *hfp = user_data; > - DBusMessageIter value; > - > - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) > - return; > - > - dbus_message_iter_recurse(array, &value); > - > - while (dbus_message_iter_get_arg_type(&value) == > DBUS_TYPE_STRING) { > - const char *uuid; > - > - dbus_message_iter_get_basic(&value, &uuid); > - > - if (!strcasecmp(uuid, HFP_AG_UUID)) { > - *hfp = TRUE; > - return; > - } > - > - dbus_message_iter_next(&value); > - } > -} > - > -static void device_properties_cb(DBusPendingCall *call, > gpointer user_data) > -{ > - DBusMessage *reply; > - char *path = user_data; > - gboolean have_hfp = FALSE; > - const char *adapter = NULL; > - const char *adapter_addr = NULL; > - const char *device_addr = NULL; > - const char *alias = NULL; > - > - reply = dbus_pending_call_steal_reply(call); > - > - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { > - DBG("Bluetooth daemon is apparently not available."); > - goto done; > - } > - > - if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { > - if (!dbus_message_is_error(reply, > DBUS_ERROR_UNKNOWN_METHOD)) > - ofono_info("Error from GetProperties reply: %s", - > dbus_message_get_error_name(reply)); > - > - goto done; > - } > - > - parse_properties_reply(reply, "UUIDs", has_hfp_uuid, &have_hfp, > - "Adapter", parse_string, &adapter, > - "Address", parse_string, &device_addr, > - "Alias", parse_string, &alias, NULL); > - > - if (adapter) > - adapter_addr = g_hash_table_lookup(adapter_address_hash, > - adapter); > - > - if (have_hfp && device_addr && adapter_addr) > - hfp_create_modem(path, device_addr, > adapter_addr, alias); > - > -done: > - dbus_message_unref(reply); > -} > - > -static void parse_devices(DBusMessageIter *array, gpointer > user_data) -{ > - DBusMessageIter value; > - GSList **device_list = user_data; > - > - DBG(""); > - > - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) > - return; > - > - dbus_message_iter_recurse(array, &value); > - > - while (dbus_message_iter_get_arg_type(&value) > - == DBUS_TYPE_OBJECT_PATH) { > - const char *path; > - > - dbus_message_iter_get_basic(&value, &path); > - > - *device_list = g_slist_prepend(*device_list, > (gpointer) path); > - > - dbus_message_iter_next(&value); > - } > -} > - > -static void adapter_properties_cb(DBusPendingCall *call, > gpointer user_data) > -{ > - const char *path = user_data; > - DBusMessage *reply; > - GSList *device_list = NULL; > - GSList *l; > - const char *addr; > - > - reply = dbus_pending_call_steal_reply(call); > - > - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { > - DBG("Bluetooth daemon is apparently not available."); > - goto done; > - } > - > - parse_properties_reply(reply, "Devices", parse_devices, > &device_list, > - "Address", parse_string, &addr, NULL); > - > - DBG("Adapter Address: %s, Path: %s", addr, path); > - g_hash_table_insert(adapter_address_hash, > - g_strdup(path), g_strdup(addr)); > - > - for (l = device_list; l; l = l->next) { > - const char *device = l->data; > - > - send_method_call_with_reply(BLUEZ_SERVICE, device, > - BLUEZ_DEVICE_INTERFACE, "GetProperties", > - device_properties_cb, > g_strdup(device), g_free, > - -1, DBUS_TYPE_INVALID); > - } > - > -done: > - g_slist_free(device_list); > - dbus_message_unref(reply); > -} > - > -static gboolean adapter_added(DBusConnection *connection, > DBusMessage *message, > - void *user_data) > -{ > - const char *path; > - int ret; > - > - dbus_message_get_args(message, NULL, > DBUS_TYPE_OBJECT_PATH, &path, > - DBUS_TYPE_INVALID); > - > - ret = send_method_call_with_reply(BLUEZ_SERVICE, path, > - BLUEZ_ADAPTER_INTERFACE, "GetProperties", > - adapter_properties_cb, g_strdup(path), g_free, > - -1, DBUS_TYPE_INVALID); > - > - return TRUE; > -} > - > -static gboolean adapter_removed(DBusConnection *connection, > - DBusMessage *message, void *user_data) > -{ > - const char *path; > - > - if (dbus_message_get_args(message, NULL, > DBUS_TYPE_OBJECT_PATH, &path, > - DBUS_TYPE_INVALID) == TRUE) > - g_hash_table_remove(adapter_address_hash, path); - > - return TRUE; > -} > - > -static gboolean property_changed(DBusConnection *connection, > DBusMessage *msg, > - void *user_data) > +static gboolean hfp_remove_each_modem(gpointer key, gpointer > value, gpointer user_data) > { > - const char *property; > - DBusMessageIter iter; > - > - dbus_message_iter_init(msg, &iter); > - > - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) > - return FALSE; > - > - dbus_message_iter_get_basic(&iter, &property); > - if (g_str_equal(property, "UUIDs") == TRUE) { > - gboolean have_hfp = FALSE; > - const char *path = dbus_message_get_path(msg); > - DBusMessageIter variant; > - > - /* We already have this device in our hash, ignore */ > - if (g_hash_table_lookup(uuid_hash, path) != NULL) > - return TRUE; > - > - if (!dbus_message_iter_next(&iter)) > - return FALSE; > - > - if (dbus_message_iter_get_arg_type(&iter) != > DBUS_TYPE_VARIANT) > - return FALSE; > - > - dbus_message_iter_recurse(&iter, &variant); > - > - has_hfp_uuid(&variant, &have_hfp); > - > - /* We need the full set of properties to be > able to create > - * the modem properly, including Adapter and Alias, so > - * refetch everything again > - */ > - if (have_hfp) > - send_method_call_with_reply(BLUEZ_SERVICE, path, > - BLUEZ_DEVICE_INTERFACE, "GetProperties", > - device_properties_cb, > g_strdup(path), g_free, > - -1, DBUS_TYPE_INVALID); > - } else if (g_str_equal(property, "Alias") == TRUE) { > - const char *path = dbus_message_get_path(msg); > - struct ofono_modem *modem = > - g_hash_table_lookup(uuid_hash, path); > - const char *alias = NULL; > - DBusMessageIter variant; > - > - if (modem == NULL) > - return TRUE; > - > - if (!dbus_message_iter_next(&iter)) > - return FALSE; > - > - if (dbus_message_iter_get_arg_type(&iter) != > DBUS_TYPE_VARIANT) > - return FALSE; > - > - dbus_message_iter_recurse(&iter, &variant); > - > - parse_string(&variant, &alias); > + struct ofono_modem *modem = value; > > - ofono_modem_set_name(modem, alias); > - } > + ofono_modem_remove(modem); > > return TRUE; > } > > -static void parse_adapters(DBusMessageIter *array, gpointer > user_data) +static void hfp_remove_all_modem() > { > - DBusMessageIter value; > - > - DBG(""); > - > - if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) + if > (modem_hash == NULL) return; > > - dbus_message_iter_recurse(array, &value); > - > - while (dbus_message_iter_get_arg_type(&value) > - == DBUS_TYPE_OBJECT_PATH) { > - const char *path; > - > - dbus_message_iter_get_basic(&value, &path); > - > - DBG("Calling GetProperties on %s", path); > - > - send_method_call_with_reply(BLUEZ_SERVICE, path, > - BLUEZ_ADAPTER_INTERFACE, > "GetProperties", > - adapter_properties_cb, > g_strdup(path), g_free, > - -1, DBUS_TYPE_INVALID); > - > - dbus_message_iter_next(&value); > - } > -} > - > -static void manager_properties_cb(DBusPendingCall *call, > gpointer user_data) > -{ > - DBusMessage *reply; > - > - reply = dbus_pending_call_steal_reply(call); > - > - if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { > - DBG("Bluetooth daemon is apparently not available."); > - goto done; > - } > - > - parse_properties_reply(reply, "Adapters", > parse_adapters, NULL, NULL); > - > -done: > - dbus_message_unref(reply); > + g_hash_table_foreach_remove(modem_hash, > hfp_remove_each_modem, NULL); > } > > -static gboolean hfp_remove_each_modem(gpointer key, gpointer > value, gpointer user_data) > +static void hfp_set_alias(const char *device, const char *alias) { > - struct ofono_modem *modem = value; > - > - ofono_modem_remove(modem); > + struct ofono_modem *modem; > > - return TRUE; > -} > + if (!device || !alias) > + return; > > -static void bluetooth_disconnect(DBusConnection *connection, > void *user_data) > -{ > - if (uuid_hash == NULL) > + modem = g_hash_table_lookup(modem_hash, device); > + if (!modem) > return; > > - g_hash_table_foreach_remove(uuid_hash, > hfp_remove_each_modem, NULL); > + ofono_modem_set_name(modem, alias); > } > > static int hfp_register_ofono_handsfree(struct ofono_modem *modem) > @@ -963,7 +620,7 @@ static void hfp_remove(struct ofono_modem *modem) > HFP_AGENT_INTERFACE)) hfp_unregister_ofono_handsfree(modem); > > - g_hash_table_remove(uuid_hash, data->handsfree_path); > + g_hash_table_remove(modem_hash, data->handsfree_path); > > g_free(data->handsfree_path); > g_free(data); > @@ -1098,10 +755,12 @@ static struct ofono_modem_driver hfp_driver = > { .post_sim = hfp_post_sim, }; > > -static guint bluetooth_exit_watch; > -static guint adapter_added_watch; > -static guint adapter_removed_watch; > -static guint uuid_watch; > +static struct bluetooth_profile hfp_profile = { > + .name = "hfp", > + .create = hfp_create_modem, > + .remove_all = hfp_remove_all_modem, > + .set_alias = hfp_set_alias, > +}; > > static int hfp_init() > { > @@ -1112,73 +771,28 @@ static int hfp_init() > > connection = ofono_dbus_get_connection(); > > - bluetooth_exit_watch = > g_dbus_add_service_watch(connection, BLUEZ_SERVICE, > - NULL, bluetooth_disconnect, NULL, NULL); > - > - adapter_added_watch = > g_dbus_add_signal_watch(connection, NULL, NULL, > - BLUEZ_MANAGER_INTERFACE, > - "AdapterAdded", > - adapter_added, > NULL, NULL); > - > - adapter_removed_watch = > g_dbus_add_signal_watch(connection, NULL, NULL, > - BLUEZ_MANAGER_INTERFACE, > - "AdapterRemoved", > - > adapter_removed, NULL, NULL); > - > - uuid_watch = g_dbus_add_signal_watch(connection, NULL, NULL, > - BLUEZ_DEVICE_INTERFACE, > - "PropertyChanged", > - > property_changed, NULL, NULL); > + err = ofono_modem_driver_register(&hfp_driver); > + if (err < 0) > + return err; > > - if (bluetooth_exit_watch == 0 || adapter_added_watch == 0 || > - adapter_removed_watch == 0|| uuid_watch == 0) { > - err = -EIO; > - goto remove; > + err = bluetooth_register_uuid(HFP_AG_UUID, &hfp_profile); + if (err > < 0) { + ofono_modem_driver_unregister(&hfp_driver); > + return err; > } > > - uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, > + modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal, > g_free, NULL); > > - adapter_address_hash = > g_hash_table_new_full(g_str_hash, g_str_equal, > - g_free, g_free); > - > - err = ofono_modem_driver_register(&hfp_driver); > - if (err < 0) > - goto remove; > - > - send_method_call_with_reply(BLUEZ_SERVICE, "/", > - BLUEZ_MANAGER_INTERFACE, > "GetProperties", > - manager_properties_cb, NULL, NULL, -1, > - DBUS_TYPE_INVALID); > - > return 0; > - > -remove: > - g_dbus_remove_watch(connection, bluetooth_exit_watch); > - g_dbus_remove_watch(connection, adapter_added_watch); > - g_dbus_remove_watch(connection, adapter_removed_watch); > - g_dbus_remove_watch(connection, uuid_watch); > - > - if (uuid_hash) > - g_hash_table_destroy(uuid_hash); > - > - if (adapter_address_hash) > - g_hash_table_destroy(adapter_address_hash); > - > - return err; > } > > static void hfp_exit() > { > - g_dbus_remove_watch(connection, bluetooth_exit_watch); > - g_dbus_remove_watch(connection, adapter_added_watch); > - g_dbus_remove_watch(connection, adapter_removed_watch); > - g_dbus_remove_watch(connection, uuid_watch); > - > + bluetooth_unregister_uuid(HFP_AG_UUID); > ofono_modem_driver_unregister(&hfp_driver); > > - g_hash_table_destroy(uuid_hash); > - g_hash_table_destroy(adapter_address_hash); > + g_hash_table_destroy(modem_hash); > } > > OFONO_PLUGIN_DEFINE(hfp, "Hands-Free Profile Plugins", VERSION, -- > 1.7.1 > > _______________________________________________ > ofono mailing list > ofono(a)ofono.org > http://lists.ofono.org/listinfo/ofono Regards, Zhenhua ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/9] Remove hack around hfp agent interface 2010-05-25 7:18 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 3/9] Bring back -d option without need for argument Gustavo F. Padovan @ 2010-05-25 7:49 ` Gustavo F. Padovan 2010-05-25 7:53 ` Marcel Holtmann 1 sibling, 1 reply; 13+ messages in thread From: Gustavo F. Padovan @ 2010-05-25 7:49 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 475 bytes --] * Gustavo F. Padovan <gustavo@padovan.org> [2010-05-25 04:18:01 -0300]: > In the past we did this dirty hack to quickly fix HFP for the release, now > fixing it in a proper way. > --- > drivers/hfpmodem/hfpmodem.h | 1 - > plugins/hfp.c | 12 +++--------- > 2 files changed, 3 insertions(+), 10 deletions(-) > The first two were refused. The following patches still apply cleanly from here. -- Gustavo F. Padovan http://padovan.org ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/9] Remove hack around hfp agent interface 2010-05-25 7:49 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan @ 2010-05-25 7:53 ` Marcel Holtmann 0 siblings, 0 replies; 13+ messages in thread From: Marcel Holtmann @ 2010-05-25 7:53 UTC (permalink / raw) To: ofono [-- Attachment #1: Type: text/plain, Size: 633 bytes --] Hi Gustavo, > > In the past we did this dirty hack to quickly fix HFP for the release, now > > fixing it in a proper way. > > --- > > drivers/hfpmodem/hfpmodem.h | 1 - > > plugins/hfp.c | 12 +++--------- > > 2 files changed, 3 insertions(+), 10 deletions(-) > > > > > The first two were refused. The following patches still apply cleanly from > here. send the debug option change separately (and also for ConnMan of course) and then the rest as its own series. Intermixing multiple patches of different types is a bad idea since everybody gets lost at some point. Regards Marcel ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-05-25 10:17 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-25 7:17 patches for DUN, HFP and gdbus Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 1/9] Add g_dbus_interface_is_registered() Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 3/9] Bring back -d option without need for argument Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 4/9] Add bluetooth plugin skeleton Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 6/9] Remove send_method_call from hfp.c Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 7/9] Move create_path() to bluetooth plugin Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 8/9] Change hfpmodem's header define Gustavo F. Padovan 2010-05-25 7:18 ` [PATCH 9/9] Bluetooth DUN modem prototype Gustavo F. Padovan 2010-05-25 10:17 ` [PATCH 5/9] Move bluetooth utils from hfp.c to bluetooth.c Zhang, Zhenhua 2010-05-25 7:49 ` [PATCH 2/9] Remove hack around hfp agent interface Gustavo F. Padovan 2010-05-25 7:53 ` Marcel Holtmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox