Open Source Telephony
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCHv8 4/6] plugins: mobile-broadband-provider-info parser changes
Date: Fri, 30 Sep 2011 10:20:57 -0500	[thread overview]
Message-ID: <4E85DE59.2090403@gmail.com> (raw)
In-Reply-To: <1317389474-16566-5-git-send-email-oleg.zhurakivskyy@intel.com>

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

On 09/30/2011 08:31 AM, Oleg Zhurakivskyy wrote:
> ---
>  plugins/mbpi.c |  339 ++++++++++++++++++++++++++++++++++++--------------------
>  1 files changed, 221 insertions(+), 118 deletions(-)
> 
> diff --git a/plugins/mbpi.c b/plugins/mbpi.c
> index 683ce03..0ae18d4 100644
> --- a/plugins/mbpi.c
> +++ b/plugins/mbpi.c
> @@ -23,12 +23,12 @@
>  #include <config.h>
>  #endif
>  
> -#include <string.h>
> -#include <fcntl.h>
>  #include <sys/mman.h>
>  #include <sys/stat.h>
> -#include <sys/types.h>
> +
> +#include <fcntl.h>
>  #include <errno.h>
> +#include <string.h>
>  #include <unistd.h>
>  
>  #include <glib.h>
> @@ -44,8 +44,11 @@
>  
>  #include "mbpi.h"
>  
> +#define _(x) case x: return (#x)
> +
>  enum MBPI_ERROR {
>  	MBPI_ERROR_DUPLICATE,
> +	MBPI_ERROR_ENOMEM,

There's no point in introducing this one, just use
g_file_error_from_errno(ENOMEM)

>  };
>  
>  struct gsm_data {
> @@ -56,21 +59,75 @@ struct gsm_data {
>  	gboolean allow_duplicates;
>  };
>  
> +const char *mbpi_ap_type(enum ofono_gprs_context_type type)
> +{
> +	switch (type) {
> +		_(OFONO_GPRS_CONTEXT_TYPE_ANY);
> +		_(OFONO_GPRS_CONTEXT_TYPE_INTERNET);
> +		_(OFONO_GPRS_CONTEXT_TYPE_MMS);
> +		_(OFONO_GPRS_CONTEXT_TYPE_WAP);
> +		_(OFONO_GPRS_CONTEXT_TYPE_IMS);
> +	}
> +
> +	return "OFONO_GPRS_CONTEXT_TYPE_<UNKNOWN>";
> +}
> +

As previously mentioned, this part belongs in a separate patch

>  static GQuark mbpi_error_quark(void)
>  {
>  	return g_quark_from_static_string("ofono-mbpi-error-quark");
>  }
>  
> -void mbpi_provision_data_free(struct ofono_gprs_provision_data *data)
> +static void mbpi_g_set_error(GMarkupParseContext *context, GError **error,
> +				GQuark domain, gint code, const gchar *fmt, ...)
>  {
> -	g_free(data->name);
> -	g_free(data->apn);
> -	g_free(data->username);
> -	g_free(data->password);
> -	g_free(data->message_proxy);
> -	g_free(data->message_center);
> -
> -	g_free(data);
> +	va_list ap;
> +	gint line_number, char_number;
> +
> +	g_markup_parse_context_get_position(context, &line_number,
> +						&char_number);
> +	va_start(ap, fmt);
> +
> +	*error = g_error_new_valist(domain, code, fmt, ap);
> +
> +	va_end(ap);
> +
> +	g_prefix_error(error, "%s:%d ", MBPI_DATABASE, line_number);
> +}
> +
> +static struct ofono_gprs_provision_data *mbpi_ap_new(const char *apn)
> +{
> +	struct ofono_gprs_provision_data *ap;
> +	gsize len;
> +
> +	ap = g_try_new0(struct ofono_gprs_provision_data, 1);
> +	if (ap == NULL)
> +		return NULL;
> +
> +	len = strlen(apn) + 1;
> +
> +	ap->apn = g_try_new(char, len);
> +	if (ap->apn == NULL) {
> +		g_free(ap);
> +		return NULL;
> +	}
> +
> +	memcpy(ap->apn, apn, len);

g_strdup would be way cleaner here.

> +
> +	ap->proto = OFONO_GPRS_PROTO_IP;
> +
> +	return ap;
> +}
> +
> +void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
> +{
> +	g_free(ap->name);
> +	g_free(ap->apn);
> +	g_free(ap->username);
> +	g_free(ap->password);
> +	g_free(ap->message_proxy);
> +	g_free(ap->message_center);
> +
> +	g_free(ap);
>  }
>  
>  static void text_handler(GMarkupParseContext *context,
> @@ -79,7 +136,27 @@ static void text_handler(GMarkupParseContext *context,
>  {
>  	char **string = userdata;
>  
> -	*string = g_strndup(text, text_len);
> +	if (*string != NULL) {
> +		/*
> +		 * For now, duplicate entries are just ignored. Since
> +		 * this parser is also used by lookup-apn tool, ofono_warn()
> +		 * can't be used here. As soon as the way is agreed,
> +		 * it might be good to report this.
> +		 */
> +		return;
> +	}

Are you sure you need this, under what circumstances would *string be
not NULL?

> +
> +	*string = g_try_new(char, text_len + 1);
> +	if (*string == NULL) {
> +		mbpi_g_set_error(context, error, mbpi_error_quark(),
> +				MBPI_ERROR_ENOMEM,
> +				"Can't allocate memory, memory exhausted");
> +		return;
> +	}
> +
> +	memcpy(*string, text, text_len);
> +
> +	(*string)[text_len] = '\0';

Why is g_strndup not good enough for you here?

>  }
>  
>  static const GMarkupParser text_parser = {
> @@ -90,33 +167,34 @@ static const GMarkupParser text_parser = {
>  	NULL,
>  };
>  
> -static void usage_handler(GMarkupParseContext *context,
> -				const gchar *text, gsize text_len,
> -				gpointer userdata, GError **error)
> +static void usage_start(GMarkupParseContext *context, const gchar *element_name,
> +			const gchar **attribute_names,
> +			const gchar **attribute_values,
> +			gpointer userdata, GError **error)
>  {
>  	enum ofono_gprs_context_type *type = userdata;
> +	const char *text = NULL;
> +	int i;
> +
> +	for (i = 0; attribute_names[i]; i++)
> +		if (g_str_equal(attribute_names[i], "type") == TRUE)
> +			text = attribute_values[i];
>  
> -	if (strncmp(text, "internet", text_len) == 0)
> +	if (text == NULL)
> +		return;
> +
> +	if (strcmp(text, "internet") == 0)
>  		*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
> -	else if (strncmp(text, "mms", text_len) == 0)
> +	else if (strcmp(text, "mms") == 0)
>  		*type = OFONO_GPRS_CONTEXT_TYPE_MMS;
> -	else if (strncmp(text, "wap", text_len) == 0)
> +	else if (strcmp(text, "wap") == 0)
>  		*type = OFONO_GPRS_CONTEXT_TYPE_WAP;
>  	else
> -		g_set_error(error, G_MARKUP_ERROR,
> -					G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
> -					"Unknown usage attribute: %.*s",
> -					(int) text_len, text);
> +		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
> +				G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
> +				"Unknown usage attribute value: %s", text);
>  }
>  
> -static const GMarkupParser usage_parser = {
> -	NULL,
> -	NULL,
> -	usage_handler,
> -	NULL,
> -	NULL,
> -};
> -
>  static void apn_start(GMarkupParseContext *context, const gchar *element_name,
>  			const gchar **attribute_names,
>  			const gchar **attribute_values,
> @@ -133,8 +211,8 @@ static void apn_start(GMarkupParseContext *context, const gchar *element_name,
>  		g_markup_parse_context_push(context, &text_parser,
>  						&apn->password);
>  	else if (g_str_equal(element_name, "usage"))
> -		g_markup_parse_context_push(context, &usage_parser,
> -						&apn->type);
> +		usage_start(context, element_name, attribute_names,
> +				attribute_values, &apn->type, error);
>  }
>  
>  static void apn_end(GMarkupParseContext *context, const gchar *element_name,
> @@ -142,8 +220,7 @@ static void apn_end(GMarkupParseContext *context, const gchar *element_name,
>  {
>  	if (g_str_equal(element_name, "name") ||
>  			g_str_equal(element_name, "username") ||
> -			g_str_equal(element_name, "password") ||
> -			g_str_equal(element_name, "usage"))
> +			g_str_equal(element_name, "password"))
>  		g_markup_parse_context_pop(context);
>  }
>  
> @@ -155,7 +232,7 @@ static void apn_error(GMarkupParseContext *context, GError *error,
>  	 * be called.  So we always perform cleanup of the allocated
>  	 * provision data
>  	 */
> -	mbpi_provision_data_free(userdata);
> +	mbpi_ap_free(userdata);
>  }
>  
>  static const GMarkupParser apn_parser = {
> @@ -174,115 +251,138 @@ static const GMarkupParser skip_parser = {
>  	NULL,
>  };
>  
> -static void gsm_start(GMarkupParseContext *context, const gchar *element_name,
> -			const gchar **attribute_names,
> -			const gchar **attribute_values,
> -			gpointer userdata, GError **error)
> +static void network_id_handler(GMarkupParseContext *context,
> +				struct gsm_data *gsm,
> +				const gchar **attribute_names,
> +				const gchar **attribute_values,
> +				GError **error)
>  {
> -	struct gsm_data *gsm = userdata;
> -
> -	if (g_str_equal(element_name, "network-id")) {
> -		const char *mcc = NULL, *mnc = NULL;
> -		int i;
> -
> -		/*
> -		 * For entries with multiple network-id elements, don't bother
> -		 * searching if we already have a match
> -		 */
> -		if (gsm->match_found == TRUE)
> -			return;
> -
> -		for (i = 0; attribute_names[i]; i++) {
> -			if (g_str_equal(attribute_names[i], "mcc") == TRUE)
> -				mcc = attribute_values[i];
> -			if (g_str_equal(attribute_names[i], "mnc") == TRUE)
> -				mnc = attribute_values[i];
> -		}
> +	const char *mcc = NULL, *mnc = NULL;
> +	int i;
> +
> +	for (i = 0; attribute_names[i]; i++) {
> +		if (g_str_equal(attribute_names[i], "mcc") == TRUE)
> +			mcc = attribute_values[i];
> +		if (g_str_equal(attribute_names[i], "mnc") == TRUE)
> +			mnc = attribute_values[i];
> +	}
>  
> -		if (mcc == NULL) {
> -			g_set_error(error, G_MARKUP_ERROR,
> +	if (mcc == NULL) {
> +		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
>  					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
>  					"Missing attribute: mcc");
> -			return;
> -		}
> +		return;
> +	}
>  
> -		if (mnc == NULL) {
> -			g_set_error(error, G_MARKUP_ERROR,
> +	if (mnc == NULL) {
> +		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
>  					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
>  					"Missing attribute: mnc");
> -			return;
> -		}
> +		return;
> +	}
>  
> -		if (g_str_equal(mcc, gsm->match_mcc) &&
> -				g_str_equal(mnc, gsm->match_mnc))
> -			gsm->match_found = TRUE;
> -	} else if (g_str_equal(element_name, "apn")) {
> -		int i;
> -		struct ofono_gprs_provision_data *pd;
> -		const char *apn;
> -
> -		if (gsm->match_found == FALSE) {
> -			g_markup_parse_context_push(context,
> -							&skip_parser, NULL);
> -			return;
> -		}
> +	if (g_str_equal(mcc, gsm->match_mcc) &&
> +			g_str_equal(mnc, gsm->match_mnc))
> +		gsm->match_found = TRUE;
> +}
>  
> -		for (i = 0, apn = NULL; attribute_names[i]; i++) {
> -			if (g_str_equal(attribute_names[i], "value") == FALSE)
> -				continue;
> +static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
> +			const gchar **attribute_names,
> +			const gchar **attribute_values,
> +			GError **error)
> +{
> +	struct ofono_gprs_provision_data *ap;
> +	const char *apn;
> +	int i;
>  
> -			apn = attribute_values[i];
> -			break;
> -		}
> +	if (gsm->match_found == FALSE) {
> +		g_markup_parse_context_push(context, &skip_parser, NULL);
> +		return;
> +	}
> +
> +	for (i = 0, apn = NULL; attribute_names[i]; i++) {
> +		if (g_str_equal(attribute_names[i], "value") == FALSE)
> +			continue;
> +
> +		apn = attribute_values[i];
> +		break;
> +	}
>  
> -		if (apn == NULL) {
> -			g_set_error(error, G_MARKUP_ERROR,
> +	if (apn == NULL) {
> +		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
>  					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
>  					"APN attribute missing");
> -			return;
> -		}
> -
> -		pd = g_new0(struct ofono_gprs_provision_data, 1);
> -		pd->apn = g_strdup(apn);
> -		pd->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
> -		pd->proto = OFONO_GPRS_PROTO_IP;
> +		return;
> +	}
>  
> -		g_markup_parse_context_push(context, &apn_parser, pd);
> +	ap = mbpi_ap_new(apn);
> +	if (ap == NULL) {
> +		mbpi_g_set_error(context, error, mbpi_error_quark(),
> +					MBPI_ERROR_ENOMEM,
> +					"Can't allocate memory for APN: '%s', "
> +					"memory exhausted", apn);
> +		return;
>  	}
> +
> +	g_markup_parse_context_push(context, &apn_parser, ap);
> +}
> +
> +static void gsm_start(GMarkupParseContext *context, const gchar *element_name,
> +			const gchar **attribute_names,
> +			const gchar **attribute_values,
> +			gpointer userdata, GError **error)
> +{
> +	if (g_str_equal(element_name, "network-id")) {
> +		struct gsm_data *gsm = userdata;
> +
> +		/*
> +		 * For entries with multiple network-id elements, don't bother
> +		 * searching if we already have a match
> +		 */
> +		if (gsm->match_found == TRUE)
> +			return;
> +
> +		network_id_handler(context, userdata, attribute_names,
> +					attribute_values, error);
> +	} else if (g_str_equal(element_name, "apn"))
> +		apn_handler(context, userdata, attribute_names,
> +				attribute_values, error);
>  }

Separate patch please, something to the effect of mbpi: Split gsm_start
for readability

Add any new functionality after the refactoring patches.

>  
>  static void gsm_end(GMarkupParseContext *context, const gchar *element_name,
>  			gpointer userdata, GError **error)
>  {
> -	struct gsm_data *gsm = userdata;
> +	struct gsm_data *gsm;
> +	struct ofono_gprs_provision_data *ap;
>  
> -	if (g_str_equal(element_name, "apn")) {
> -		struct ofono_gprs_provision_data *apn =
> -					g_markup_parse_context_pop(context);
> +	if (!g_str_equal(element_name, "apn"))
> +		return;
>  
> -		if (apn == NULL)
> -			return;
> +	gsm = userdata;
>  
> -		if (gsm->allow_duplicates == FALSE) {
> -			GSList *l;
> +	ap = g_markup_parse_context_pop(context);
> +	if (ap == NULL)
> +		return;
>  
> -			for (l = gsm->apns; l; l = l->next) {
> -				struct ofono_gprs_provision_data *pd = l->data;
> +	if (gsm->allow_duplicates == FALSE) {
> +		GSList *l;
>  
> -				if (pd->type != apn->type)
> -					continue;
> +		for (l = gsm->apns; l; l = l->next) {
> +			struct ofono_gprs_provision_data *pd = l->data;
> +
> +			if (pd->type != ap->type)
> +				continue;
>  
> -				g_set_error(error, mbpi_error_quark(),
> +			mbpi_g_set_error(context, error, mbpi_error_quark(),
>  						MBPI_ERROR_DUPLICATE,
>  						"Duplicate context detected");
>  
> -				mbpi_provision_data_free(apn);
> -				return;
> -			}
> +			mbpi_ap_free(ap);
> +			return;
>  		}
> -
> -		gsm->apns = g_slist_append(gsm->apns, apn);
>  	}
> +
> +	gsm->apns = g_slist_append(gsm->apns, ap);
>  }

Fair enough, but separate patch please.  Something to the effect of:

mbpi: Reflow gsm_end()

>  
>  static const GMarkupParser gsm_parser = {
> @@ -358,7 +458,8 @@ GSList *mbpi_lookup(const char *mcc, const char *mnc,
>  	if (fd < 0) {
>  		g_set_error(error, G_FILE_ERROR,
>  				g_file_error_from_errno(errno),
> -				"open failed: %s", g_strerror(errno));
> +				"open(%s) failed: %s", MBPI_DATABASE,
> +				g_strerror(errno));

If you want to add filename information to the error, then please group
this as a separate patch.

>  		return NULL;
>  	}
>  
> @@ -366,7 +467,8 @@ GSList *mbpi_lookup(const char *mcc, const char *mnc,
>  		close(fd);
>  		g_set_error(error, G_FILE_ERROR,
>  				g_file_error_from_errno(errno),
> -				"fstat failed: %s", g_strerror(errno));
> +				"fstat(%s) failed: %s", MBPI_DATABASE,
> +				g_strerror(errno));

same comment as above

>  		return NULL;
>  	}
>  
> @@ -375,7 +477,8 @@ GSList *mbpi_lookup(const char *mcc, const char *mnc,
>  		close(fd);
>  		g_set_error(error, G_FILE_ERROR,
>  				g_file_error_from_errno(errno),
> -				"mmap failed: %s", g_strerror(errno));
> +				"mmap(%s) failed: %s", MBPI_DATABASE,
> +				g_strerror(errno));

same comment as above

>  		return NULL;
>  	}
>  
> @@ -386,7 +489,7 @@ GSList *mbpi_lookup(const char *mcc, const char *mnc,
>  
>  	if (mbpi_parse(db, st.st_size, &gsm, error) == FALSE) {
>  		for (l = gsm.apns; l; l = l->next)
> -			mbpi_provision_data_free(l->data);
> +			mbpi_ap_free(l->data);

See my comments to the previous patch, this should be in a separate patch.

>  
>  		g_slist_free(gsm.apns);
>  		gsm.apns = NULL;

Please fix all the comments above, then I can have another look.  It is
too hard for me to tell what exactly you're changing when everything is
in one huge patch.

Regards,
-Denis

  reply	other threads:[~2011-09-30 15:20 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-30 13:31 [PATCHv8 0/6] Provisioning plugin Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 1/6] plugins: Provisioning plugin autoconf support Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 2/6] plugins: Provisioning plugin makefile changes Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 3/6] plugins: mobile-broadband-provider-info parser changes Oleg Zhurakivskyy
2011-09-30 14:57   ` Denis Kenzior
2011-10-04  9:33     ` Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 4/6] " Oleg Zhurakivskyy
2011-09-30 15:20   ` Denis Kenzior [this message]
2011-10-04  9:33     ` Oleg Zhurakivskyy
2011-10-04 14:05       ` Denis Kenzior
2011-10-05  8:07         ` Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 5/6] plugins: Add provisioning plugin Oleg Zhurakivskyy
2011-09-30 13:31 ` [PATCHv8 6/6] tools: lookup-apn update Oleg Zhurakivskyy

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=4E85DE59.2090403@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