[PATCH 2/5] Move bluetooth utils from hfp.c to bluetooth.c
Denis Kenzior
denkenz at gmail.com
Thu Jun 10 14:17:12 PDT 2010
Hi Gustavo,
Please break this patch up more. You're moving functions but also modifying
them in between. I'm getting lost.
> +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;
> +}
So this should be in a separate patch...
> +
> +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);
> +}
And this one too...
> +
> +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;
> +
> + 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);
No checking of profile NULL-ness or profile->create NULL-ness? I noticed a few
instances of this.
Regards,
-Denis
More information about the ofono
mailing list