All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Hedberg <johan.hedberg@gmail.com>
To: "Frédéric Danis" <frederic.danis@linux.intel.com>
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [PATCH v15 02/14] audio: Move telephony drivers to D-Bus interface
Date: Mon, 30 Jul 2012 10:58:52 +0300	[thread overview]
Message-ID: <20120730075852.GA5208@x220> (raw)
In-Reply-To: <1343292324-959-3-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Thu, Jul 26, 2012, Frédéric Danis wrote:
> +static int parse_properties(DBusMessageIter *props, const char **uuid,
> +				uint16_t *version, uint16_t *features)
> +{
> +	gboolean has_uuid = FALSE;
> +
> +	while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) {
> +		const char *key;
> +		DBusMessageIter value, entry;
> +		int var;
> +
> +		dbus_message_iter_recurse(props, &entry);
> +		dbus_message_iter_get_basic(&entry, &key);
> +
> +		dbus_message_iter_next(&entry);
> +		dbus_message_iter_recurse(&entry, &value);
> +
> +		var = dbus_message_iter_get_arg_type(&value);
> +		if (strcasecmp(key, "UUID") == 0) {
> +			if (var != DBUS_TYPE_STRING)
> +				return -EINVAL;
> +			dbus_message_iter_get_basic(&value, uuid);
> +			has_uuid = TRUE;
> +		} else if (strcasecmp(key, "Version") == 0) {
> +			if (var != DBUS_TYPE_UINT16)
> +				return -EINVAL;
> +			dbus_message_iter_get_basic(&value, version);
> +		} else if (strcasecmp(key, "Features") == 0) {
> +			if (var != DBUS_TYPE_UINT16)
> +				return -EINVAL;
> +			dbus_message_iter_get_basic(&value, features);
> +		}
> +
> +		dbus_message_iter_next(props);
> +	}
> +
> +	return (has_uuid) ? 0 : -EINVAL;
> +}

I suppose you could just make the above function return gboolean as it
only has two possible return values.

> +static int dev_close(struct telephony_device *tel_dev)
> +{
> +	int sock;
> +
> +	if (tel_dev->rfcomm) {
> +		sock = g_io_channel_unix_get_fd(tel_dev->rfcomm);
> +		shutdown(sock, SHUT_RDWR);
> +		tel_dev->rfcomm = NULL;
> +	}

Looks like you're missing a g_io_channel_unref there.

> +static void hs_newconnection_reply(DBusPendingCall *call, void *user_data)
> +{
> +	struct telephony_device *tel_dev = user_data;
> +	DBusMessage *reply = dbus_pending_call_steal_reply(call);
> +	DBusError derr;
> +
> +	dbus_error_init(&derr);
> +	if (!dbus_set_error_from_message(&derr, reply)) {
> +		DBG("Agent reply: file descriptor passed successfully");
> +		g_io_add_watch(tel_dev->rfcomm, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> +				(GIOFunc) hs_dev_disconnect_cb, tel_dev);
> +		headset_slc_complete(tel_dev->au_dev);
> +		goto done;
> +	}

Firstly, a more common way would be to test for positive return of
dbus_set_error_from_message and handle the error reply within the
if-clause. Secondly, please don't do callback typecasts (GIOFunc) but
instead just assign to the right type inside the callback function
itself.

> +static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
> +{
> +	struct telephony_device *tel_dev = user_data;

Here you do the right kind of handling of callback types. Why the
inconsistency?

> +	sdp_get_profile_descs(recs->data, &profiles);
> +	if (profiles == NULL)
> +		goto failed;

I think it'd be cleaner/simpler to do:

	if (sdp_get_profile_descs(...) < 0)
		goto failed;


> +	desc = profiles->data;
> +
> +	if (sdp_uuid16_cmp(&desc->uuid, &uuid) == 0)
> +		tel_dev->version = desc->version;

I don't think it's safe to assume that what's returned by
sdp_get_profile_descs is always a uuid16. Instead using sdp_uuid_cmp()
would seem more appropriate.

> +struct telephony_device *telephony_device_connecting(GIOChannel *io,
> +					struct btd_device *btd_dev,
> +					struct audio_device *au_dev,
> +					const char *uuid)
> +{
> +	struct btd_adapter *adapter;
> +	struct telephony_agent *agent;
> +	struct telephony_device *tel_dev;
> +	uuid_t r_uuid;
> +	int err;
> +
> +	adapter = device_get_adapter(btd_dev);
> +	agent = find_agent(adapter, NULL, NULL, uuid);
> +	if (agent == NULL)
> +		return NULL;
> +
> +	tel_dev = g_new0(struct telephony_device, 1);
> +	tel_dev->btd_dev = btd_device_ref(btd_dev);
> +	tel_dev->name = g_strdup(agent->name);
> +	tel_dev->path = g_strdup(agent->path);
> +	tel_dev->config = agent->config;
> +	tel_dev->au_dev = au_dev;
> +	tel_dev->rfcomm = io;

Missing g_io_channel_ref here.

> +	err = bt_search_service(&au_dev->src, &au_dev->dst, &r_uuid,
> +				get_record_cb, tel_dev, NULL);
> +	if (err < 0) {
> +		telephony_device_disconnect(tel_dev);
> +		return NULL;
> +	}
> +	tel_dev->pending_sdp = TRUE;

An empty line should follow after }

> +void telephony_device_disconnect(struct telephony_device *device)
> +{
> +	dev_close(device);
> +
> +	if (device->pending_sdp)
> +		return;

Shouldn't you cancel the SDP operation here with bt_cancel_discovery?

> +gboolean telephony_get_ready_state(struct btd_adapter *adapter)
> +{
> +	return find_agent(adapter, NULL, NULL, HFP_AG_UUID) ? TRUE : FALSE;
> +}

If such a function is needed just call it telephony_is_ready. It makes
the calling side look more natural: "if (telephony_is_ready(adapter))".

> +static int register_interface(struct btd_adapter *adapter)
> +{
> +	const char *path;
> +
> +	path = adapter_get_path(adapter);
> +
> +	if (!g_dbus_register_interface(connection, path,
> +					AUDIO_TELEPHONY_INTERFACE,
> +					telsrv_methods, NULL,
> +					NULL, adapter, path_unregister)) {
> +		error("D-Bus failed to register %s interface",
> +				AUDIO_TELEPHONY_INTERFACE);
> +		return -1;
> +	}
> +
> +	DBG("Registered interface %s", AUDIO_TELEPHONY_INTERFACE);
> +
> +	return 0;
> +}
> +
> +static void unregister_interface(struct btd_adapter *adapter)
> +{
> +	g_dbus_unregister_interface(connection, adapter_get_path(adapter),
> +			AUDIO_TELEPHONY_INTERFACE);
> +}
> +
> +int telephony_adapter_init(struct btd_adapter *adapter)
> +{
> +	DBG("adapter: %p", adapter);
> +
> +	return register_interface(adapter);
> +}
> +
> +void telephony_adapter_exit(struct btd_adapter *adapter)
> +{
> +	struct telephony_agent *agent;
> +
> +	DBG("adapter: %p", adapter);
> +
> +	unregister_interface(adapter);
> +
> +	while ((agent = find_agent(adapter, NULL, NULL, NULL)) != NULL) {
> +		agents = g_slist_remove(agents, agent);
> +		free_agent(agent);
> +	}
> +}

The register_interface and unregister_interface functions above seem
unnecessary to me. Just include their code directly within
telephony_adapter_init and telephony_adapter_exit.

Johan

  parent reply	other threads:[~2012-07-30  7:58 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-26  8:45 [PATCH v15 00/14] Add org.bluez.Telephony interface Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 01/14] doc: Add telephony interface documents Frédéric Danis
2012-07-27  7:52   ` Mikel Astiz
2012-07-27  8:30     ` Frederic Danis
2012-07-26  8:45 ` [PATCH v15 02/14] audio: Move telephony drivers to D-Bus interface Frédéric Danis
2012-07-27  8:25   ` Mikel Astiz
2012-07-27  9:33     ` Frederic Danis
2012-07-30  7:58   ` Johan Hedberg [this message]
2012-07-26  8:45 ` [PATCH v15 03/14] audio: Simplify org.bluez.Headset Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 04/14] audio: Remove dummy telephony driver Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 05/14] audio: Remove maemo5 " Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 06/14] audio: Remove maemo6 " Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 07/14] audio: Remove oFono " Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 08/14] audio: Move HFP/HSP AG servers to telephony.c Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 09/14] audio: Send transport path to telephony agent Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 10/14] audio: Move HFP HF server to telephony.c Frédéric Danis
2012-07-27  8:50   ` Mikel Astiz
2012-07-27 12:44     ` Frederic Danis
2012-07-26  8:45 ` [PATCH v15 11/14] audio: Add DUN GW to org.bluez.Telephony Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 12/14] audio: Add SAP " Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 13/14] adapter: Add API to get fast connectable mode Frédéric Danis
2012-07-26  8:45 ` [PATCH v15 14/14] audio: Add fast connectable to telephony interface Frédéric Danis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120730075852.GA5208@x220 \
    --to=johan.hedberg@gmail.com \
    --cc=frederic.danis@linux.intel.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.