Open Source Telephony
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCH v0 1/8] hfp_hf: Add NewConnection arguments parsing
Date: Thu, 17 Jan 2013 11:10:32 -0600	[thread overview]
Message-ID: <50F83088.2080502@gmail.com> (raw)
In-Reply-To: <1358435591-14757-2-git-send-email-claudio.takahasi@openbossa.org>

[-- Attachment #1: Type: text/plain, Size: 13232 bytes --]

Hi Claudio,

On 01/17/2013 09:13 AM, Claudio Takahasi wrote:
> This patch adds NewConnection message arguments parsing: features,
> version and Media Endpoints included in the fd_properties dictionary.
> ---
>   Makefile.am             |   3 +-
>   plugins/bluez5.c        |  81 +++++++++++++++++++++++++++
>   plugins/bluez5.h        |   3 +
>   plugins/hfp_hf_bluez5.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++-
>   plugins/media.c         |  63 +++++++++++++++++++++
>   plugins/media.h         |  29 ++++++++++

Please separate this into three patches, one for bluez5.[ch] changes, 
one for media.[ch] changes and one for the hfp_hf_bluez5.c changes. 
Also, is there a compelling reason to not roll media.[ch] into 
bluez5.[ch]?  It is being put into plugins directory and it is not 
really a plugin.  We made a couple exceptions (e.g. for mbpi.c) but I do 
not really want to make this into a habit.

>   6 files changed, 319 insertions(+), 4 deletions(-)
>   create mode 100644 plugins/media.c
>   create mode 100644 plugins/media.h
>
> diff --git a/Makefile.am b/Makefile.am
> index f24cac7..f1d241f 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -438,7 +438,8 @@ builtin_modules += bluez5
>   builtin_sources += plugins/bluez5.c plugins/bluez5.h
>
>   builtin_modules += hfp_bluez5
> -builtin_sources += plugins/hfp_hf_bluez5.c plugins/bluez5.h
> +builtin_sources += plugins/bluez5.h plugins/media.h \
> +			plugins/media.c plugins/hfp_hf_bluez5.c
>   endif
>   endif
>   endif
> diff --git a/plugins/bluez5.c b/plugins/bluez5.c
> index 84ba47d..6ba5ea1 100644
> --- a/plugins/bluez5.c
> +++ b/plugins/bluez5.c
> @@ -36,6 +36,87 @@
>
>   #define BLUEZ_PROFILE_MGMT_INTERFACE   BLUEZ_SERVICE ".ProfileManager1"
>
> +typedef void (*PropertyHandler)(DBusMessageIter *iter, gpointer user_data);

In general we prefer not to use CamelCase outside of GLib-like code.

> +
> +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 g_strcmp0(handler->property, property);
> +}
> +
> +void bluetooth_iter_parse_properties(DBusMessageIter *array,
> +						const char *property, ...)
> +{
> +	va_list args;
> +	GSList *prop_handlers = NULL;
> +	DBusMessageIter dict;
> +
> +	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
> +		goto done;
> +
> +	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);
> +
> +	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);
> +}
> +

Is this a copy-paste job out of bluez4.c?

>   static void profile_register_cb(DBusPendingCall *call, gpointer user_data)
>   {
>   	DBusMessage *reply;
> diff --git a/plugins/bluez5.h b/plugins/bluez5.h
> index 01ecfe8..7eae8c4 100644
> --- a/plugins/bluez5.h
> +++ b/plugins/bluez5.h
> @@ -29,3 +29,6 @@ int bluetooth_register_profile(DBusConnection *conn, const char *uuid,
>   					const char *name, const char *object);
>
>   void bluetooth_unregister_profile(DBusConnection *conn, const char *object);
> +
> +void bluetooth_iter_parse_properties(DBusMessageIter *array,
> +						const char *property, ...);
> diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
> index e024838..636b1b3 100644
> --- a/plugins/hfp_hf_bluez5.c
> +++ b/plugins/hfp_hf_bluez5.c
> @@ -35,6 +35,7 @@
>   #include<ofono/log.h>
>
>   #include "bluez5.h"
> +#include "media.h"
>
>   #ifndef DBUS_TYPE_UNIX_FD
>   #define DBUS_TYPE_UNIX_FD -1
> @@ -42,6 +43,106 @@
>
>   #define HFP_EXT_PROFILE_PATH   "/bluetooth/profile/hfp_hf"
>
> +static void parse_guint16(DBusMessageIter *iter, gpointer user_data)
> +{
> +	guint16 *value = user_data;
> +
> +	if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_UINT16)
> +		return;
> +
> +	dbus_message_iter_get_basic(iter, 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 parse_byte(DBusMessageIter *iter, gpointer user_data)
> +{
> +	guint8 *value = user_data;
> +
> +	if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_BYTE)
> +		return;
> +
> +	dbus_message_iter_get_basic(iter, value);
> +}
> +
> +static void parse_byte_array(DBusMessageIter *iter, gpointer user_data)
> +{
> +	DBusMessageIter array;
> +	GArray **garray = user_data;
> +	guint8 *data = NULL;
> +	int n = 0;
> +
> +	if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_ARRAY)
> +		return;
> +
> +	dbus_message_iter_recurse(iter,&array);
> +	dbus_message_iter_get_fixed_array(&array,&data,&n);
> +	if (n == 0)
> +		return;
> +
> +	*garray = g_array_sized_new(TRUE, TRUE, sizeof(guint8), n);
> +	*garray = g_array_append_vals(*garray, (gconstpointer) data, n);

Please just use g_memdup instead and stay away from GArray.  oFono does 
not use GArray anywhere else and I do not really want to start.  The 
long-term plan is to get rid of GLib.  So whenever you can use basic types.

> +}
> +
> +static void parse_media_endpoints(DBusMessageIter *array, gpointer user_data)
> +{
> +	const char *path, *owner;
> +	GSList **endpoints = user_data;
> +	GArray *capabilities = NULL;
> +	struct media_endpoint *endpoint;
> +	guint8 codec;
> +	DBusMessageIter dict, variant, entry;
> +
> +	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
> +		return;
> +
> +	dbus_message_iter_recurse(array,&dict);
> +
> +	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
> +		path = NULL;
> +		codec = 0x00;
> +		capabilities = NULL;
> +
> +		dbus_message_iter_recurse(&dict,&entry);
> +		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
> +			return;
> +
> +		dbus_message_iter_get_basic(&entry,&owner);
> +
> +		dbus_message_iter_next(&entry);
> +
> +		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
> +			return;
> +
> +		dbus_message_iter_recurse(&entry,&variant);
> +
> +		bluetooth_iter_parse_properties(&variant,
> +				"Path", parse_string,&path,
> +				"Codec", parse_byte,&codec,
> +				"Capabilities", parse_byte_array,&capabilities,
> +				NULL);

Sounds like you should be passing in the endpoint structure here instead

> +
> +		dbus_message_iter_next(&dict);
> +
> +		endpoint = media_endpoint_new(owner, path, codec, capabilities);
> +		if (capabilities)
> +			g_array_unref(capabilities);
> +
> +		*endpoints = g_slist_append(*endpoints, endpoint);
> +
> +		DBG("Media Endpoint %s %s codec: 0x%02X", owner, path, codec);
> +	}
> +}
> +
>   static int hfp_probe(struct ofono_modem *modem)
>   {
>   	DBG("modem: %p", modem);
> @@ -93,11 +194,48 @@ static struct ofono_modem_driver hfp_driver = {
>   static DBusMessage *profile_new_connection(DBusConnection *conn,
>   					DBusMessage *msg, void *user_data)
>   {
> +	DBusMessageIter entry;
> +	const char *device;
> +	GSList *endpoints = NULL;
> +	guint16 version, features;
> +	int fd;
> +
>   	DBG("Profile handler NewConnection");
>
> -	return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
> -					".NotImplemented",
> -					"Implementation not provided");
> +	if (dbus_message_iter_init(msg,&entry) == FALSE)
> +		goto error;
> +
> +	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_OBJECT_PATH)
> +		goto error;
> +
> +	dbus_message_iter_get_basic(&entry,&device);
> +	dbus_message_iter_next(&entry);
> +	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
> +		goto error;
> +
> +	dbus_message_iter_get_basic(&entry,&fd);
> +	if (fd<  0)
> +		goto error;
> +
> +	dbus_message_iter_next(&entry);
> +
> +	bluetooth_iter_parse_properties(&entry,
> +			"Version", parse_guint16,&version,
> +			"Features", parse_guint16,&features,
> +			"MediaEndpoints", parse_media_endpoints,&endpoints,
> +			NULL);
> +
> +	DBG("%s version: 0x%04x features: 0x%04x", device, version, features);
> +
> +	if (endpoints == NULL) {
> +		ofono_error("Media Endpoint missing");
> +		goto error;
> +	}
> +	return NULL;
> +
> +error:
> +	return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE ".Rejected",
> +					"Invalid arguments in method call");
>   }
>
>   static DBusMessage *profile_release(DBusConnection *conn,
> diff --git a/plugins/media.c b/plugins/media.c
> new file mode 100644
> index 0000000..b4f0650
> --- /dev/null
> +++ b/plugins/media.c
> @@ -0,0 +1,63 @@
> +/*
> + *
> + *  oFono - Open Source Telephony
> + *
> + *  Copyright (C) 2013  Intel Corporation. All rights reserved.
> + *
> + *  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<glib.h>
> +
> +#include "media.h"
> +
> +struct media_endpoint {
> +	char *owner;
> +	char *path;
> +	guint8 codec;
> +	GArray *capabilities;
> +};
> +
> +struct media_endpoint *media_endpoint_new(const char *owner,
> +					const char *path,
> +					guint8 codec,
> +					GArray *capabilities)
> +{
> +	struct media_endpoint *endpoint;
> +
> +	endpoint = g_new0(struct media_endpoint, 1);
> +	endpoint->owner = g_strdup(owner);
> +	endpoint->path = g_strdup(path);
> +	endpoint->codec = codec;
> +	if (capabilities)
> +		endpoint->capabilities = g_array_ref(capabilities);
> +
> +	return endpoint;
> +}
> +
> +void media_endpoint_free(gpointer data)
> +{
> +	struct media_endpoint *endpoint = data;
> +
> +	g_free(endpoint->owner);
> +	g_free(endpoint->path);
> +	if (endpoint->capabilities)
> +		g_array_unref(endpoint->capabilities);
> +	g_free(endpoint);
> +}
> diff --git a/plugins/media.h b/plugins/media.h
> new file mode 100644
> index 0000000..0df107f
> --- /dev/null
> +++ b/plugins/media.h
> @@ -0,0 +1,29 @@
> +/*
> + *
> + *  oFono - Open Source Telephony
> + *
> + *  Copyright (C) 2013  Intel Corporation. All rights reserved.
> + *
> + *  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
> + *
> + */
> +
> +struct media_endpoint;
> +
> +struct media_endpoint *media_endpoint_new(const char *owner,
> +					const char *path,
> +					guint8 codec,
> +					GArray *capabilities);
> +
> +void media_endpoint_free(gpointer data);

Regards,
-Denis


  reply	other threads:[~2013-01-17 17:10 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-17 15:13 [PATCH v0 0/8] HFP HF: Service Level/Codec negotiation Claudio Takahasi
2013-01-17 15:13 ` [PATCH v0 1/8] hfp_hf: Add NewConnection arguments parsing Claudio Takahasi
2013-01-17 17:10   ` Denis Kenzior [this message]
2013-01-17 17:58     ` Claudio Takahasi
2013-01-17 18:38       ` Denis Kenzior
2013-01-17 15:13 ` [PATCH v0 2/8] hfpmodem: Add version defines for HFP 1.6 Claudio Takahasi
2013-01-17 17:22   ` Denis Kenzior
2013-01-17 15:13 ` [PATCH v0 3/8] hfpmodem: Add support for sending the supported codecs Claudio Takahasi
2013-01-17 17:22   ` Denis Kenzior
2013-01-17 15:13 ` [PATCH v0 4/8] hfpmodem: Add support for storing " Claudio Takahasi
2013-01-17 17:29   ` Denis Kenzior
2013-01-17 18:55     ` Vinicius Costa Gomes
2013-01-17 15:13 ` [PATCH v0 5/8] hfpmodem: Send the AT+BAC command with " Claudio Takahasi
2013-01-17 15:13 ` [PATCH v0 6/8] hfp_hf: Register the HFP modem Claudio Takahasi
2013-01-17 15:13 ` [PATCH v0 7/8] hfp_hf: Add service level negotiation Claudio Takahasi
2013-01-17 15:13 ` [PATCH v0 8/8] hfp_hf: Add support for codec negotiation Claudio Takahasi
2013-01-18 23:21 ` [PATCH v1 00/10] HFP HF: Service Level/Codec negotiation Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 01/10] dbus: Add ofono_dbus_iter_parse_properties() Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 02/10] bluez5: Rename register/unregister profile Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 03/10] hfp_hf: Add NewConnection arguments parsing Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 04/10] hfpmodem: Add support for storing the supported codecs Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 05/10] hfpmodem: Implement hfp_slc_info_free Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 06/10] phonesim: Use hfp_slc_info_free() Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 07/10] hfpmodem: Send the AT+BAC command with the supported codecs Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 08/10] hfp_hf: Register the HFP modem Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 09/10] hfp_hf: Add service level negotiation Claudio Takahasi
2013-01-18 23:21   ` [PATCH v1 10/10] hfp_hf: Add support for codec negotiation Claudio Takahasi
2013-01-18 23:38   ` [PATCH v2 00/10] HFP HF: Service Level/Codec negotiation Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 01/10] dbus: Add ofono_dbus_iter_parse_properties() Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 02/10] bluez5: Rename register/unregister profile Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 03/10] hfp_hf: Add NewConnection arguments parsing Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 04/10] hfpmodem: Add support for storing the supported codecs Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 05/10] hfpmodem: Implement hfp_slc_info_free Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 06/10] phonesim: Use hfp_slc_info_free() Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 07/10] hfpmodem: Send the AT+BAC command with the supported codecs Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 08/10] hfp_hf: Register the HFP modem Claudio Takahasi
2013-01-18 23:38     ` [PATCH v2 09/10] hfp_hf: Add service level negotiation Claudio Takahasi
2013-01-18 23:39     ` [PATCH v2 10/10] hfp_hf: Add support for codec negotiation Claudio Takahasi
2013-01-22 21:42     ` [PATCH v2 00/10] HFP HF: Service Level/Codec negotiation Vinicius Costa Gomes

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=50F83088.2080502@gmail.com \
    --to=denkenz@gmail.com \
    --cc=ofono@ofono.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox