Open Source Telephony
 help / color / mirror / Atom feed
* [PATCH v4 0/4] lte atom auth and IP protocol
@ 2018-10-13  5:48 Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 1/4] lte-api: protocol and authentication properties Giacinto Cifelli
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  5:48 UTC (permalink / raw)
  To: ofono

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

 would like to submit this patch for the lte atom

This patch adds:
-  the protocol for the default LTE APN, ip, ipv6 and both
- the authentication handling, with 3 properties:
	method, username, password

The behavior of the patch is described in the api document (part 1/4),
and in the core atom header (part 2/4). The same description is
duplicated for convenience in the core atom source (part 3/4).
The part 4/4 is the driver/atmodem reflex of these changes.

This patch implements these extended parameters as described by the
3GPP TS 27.007.


Related to the v3, this new version fixes:
- a missing return in case of error in at_lte_set_default_attach_info_cb
- discards the use of lte_driver_data in favour of its member chat
	for passing among callbacks, as the persistence of the first
	cannot be guaranteed, or at least controlled by the driver atom
- fixes the memory management of the object passed among callbacks
	by using a reference counted structure


Giacinto Cifelli (4):
  lte-api: protocol and authentication properties
  lte.h: added proto and authentication handling
  src/lte: added proto and authentication handling
  atmodem/lte: proto and authentication handling

 doc/lte-api.txt       |  39 +++++++
 drivers/atmodem/lte.c | 133 ++++++++++++++++++++++--
 include/lte.h         |   5 +
 src/lte.c             | 236 ++++++++++++++++++++++++++++++++----------
 4 files changed, 347 insertions(+), 66 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 1/4] lte-api: protocol and authentication properties
  2018-10-13  5:48 [PATCH v4 0/4] lte atom auth and IP protocol Giacinto Cifelli
@ 2018-10-13  5:48 ` Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 2/4] lte.h: added proto and authentication handling Giacinto Cifelli
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  5:48 UTC (permalink / raw)
  To: ofono

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

added 4 properties for handling the type of context and the
authentication method, exactly like in any gprs context handling.
The properties are named after the equivalent gprs-context one, for
compatibility and uniformity.

Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
---
 doc/lte-api.txt | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/doc/lte-api.txt b/doc/lte-api.txt
index 8a2a97d9..c9544f60 100644
--- a/doc/lte-api.txt
+++ b/doc/lte-api.txt
@@ -33,3 +33,42 @@ Properties	string DefaultAccessPointName [readwrite]
 
 			Setting this property to an empty string clears the
 			default APN from the modem.
+
+		string Protocol [readwrite]
+
+			Holds the protocol for this context.  Valid values
+			are: "ip", "ipv6" and "dual". Default value is "ip".
+
+		string AuthenticationMethod [readwrite]
+
+			Sets the Method used for the authentication
+			for the default APN.
+
+			Available values are "none", "pap" and "chap".
+			Default is "none".
+
+			If the AuthenticationMethod is set to 'none' it remove
+			the authentication for the DefaultAPN.
+			In case of AuthenticationMethod 'none',
+			if the Username and Password properties are not empty,
+			the values are preserved in the properties, but they
+			are not used or transmitted to the module.
+			Conversely, if Username or Password are empty, the
+			authentication method selected internally is 'none',
+			but the property AuthenticationMethod is left unchanged.
+
+			If the default APN supports authentication and it
+			fails, then it is up to the network how to proceed.
+			In general LTE access is denied and the modem can
+			fallback to a legacy technology if capable and another
+			radio technology is available.
+
+		string Username [readwrite]
+
+			Holds the username to be used for authentication
+			purposes.
+
+		string Password [readwrite]
+
+			Holds the password to be used for authentication
+			purposes.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 2/4] lte.h: added proto and authentication handling
  2018-10-13  5:48 [PATCH v4 0/4] lte atom auth and IP protocol Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 1/4] lte-api: protocol and authentication properties Giacinto Cifelli
@ 2018-10-13  5:48 ` Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 3/4] src/lte: " Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 4/4] atmodem/lte: " Giacinto Cifelli
  3 siblings, 0 replies; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  5:48 UTC (permalink / raw)
  To: ofono

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

The ofono_lte_default_attach_info is extended with protocol,
authentication method, username and password.
The transmission of this info from the src to the atom happens
through the existing set_default_attach_info.
A signal is emitted when one of these properties changes

Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
---
 include/lte.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/lte.h b/include/lte.h
index 0f2501c0..2f12ac29 100644
--- a/include/lte.h
+++ b/include/lte.h
@@ -3,6 +3,7 @@
  *  oFono - Open Source Telephony
  *
  *  Copyright (C) 2016  Endocode AG. All rights reserved.
+ *  Copyright (C) 2018 Gemalto M2M
  *
  *  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
@@ -32,6 +33,10 @@ struct ofono_lte;
 
 struct ofono_lte_default_attach_info {
 	char apn[OFONO_GPRS_MAX_APN_LENGTH + 1];
+	enum ofono_gprs_proto proto;
+	enum ofono_gprs_auth_method auth_method;
+	char username[OFONO_GPRS_MAX_USERNAME_LENGTH + 1];
+	char password[OFONO_GPRS_MAX_PASSWORD_LENGTH + 1];
 };
 
 typedef void (*ofono_lte_cb_t)(const struct ofono_error *error, void *data);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 3/4] src/lte: added proto and authentication handling
  2018-10-13  5:48 [PATCH v4 0/4] lte atom auth and IP protocol Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 1/4] lte-api: protocol and authentication properties Giacinto Cifelli
  2018-10-13  5:48 ` [PATCH v4 2/4] lte.h: added proto and authentication handling Giacinto Cifelli
@ 2018-10-13  5:48 ` Giacinto Cifelli
  2018-10-13  6:50   ` Jonas Bonn
  2018-10-13  5:48 ` [PATCH v4 4/4] atmodem/lte: " Giacinto Cifelli
  3 siblings, 1 reply; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  5:48 UTC (permalink / raw)
  To: ofono

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

The ofono_lte_default_attach_info is extended with protocol,
authentication method, username and password.
The transmission of this info from the src to the atom happens
through the existing set_default_attach_info.
A signal is emitted when one of these properties changes

Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
---
 src/lte.c | 236 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 180 insertions(+), 56 deletions(-)

diff --git a/src/lte.c b/src/lte.c
index 23fe8e1c..c1f6d86a 100644
--- a/src/lte.c
+++ b/src/lte.c
@@ -3,6 +3,7 @@
  *  oFono - Open Source Telephony
  *
  *  Copyright (C) 2016  Endocode AG. All rights reserved.
+ *  Copyright (C) 2018 Gemalto M2M
  *
  *  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
@@ -39,7 +40,11 @@
 
 #define SETTINGS_STORE "lte"
 #define SETTINGS_GROUP "Settings"
-#define DEFAULT_APN_KEY "DefaultAccessPointName"
+#define LTE_APN "DefaultAccessPointName"
+#define LTE_PROTO "Protocol"
+#define LTE_USERNAME "Username"
+#define LTE_PASSWORD "Password"
+#define LTE_AUTH_METHOD "AuthenticationMethod"
 
 struct ofono_lte {
 	const struct ofono_lte_driver *driver;
@@ -57,6 +62,10 @@ static GSList *g_drivers = NULL;
 static void lte_load_settings(struct ofono_lte *lte)
 {
 	char *apn;
+	char *proto_str;
+	char *auth_method_str;
+	char *username;
+	char *password;
 
 	if (lte->imsi == NULL)
 		return;
@@ -69,19 +78,57 @@ static void lte_load_settings(struct ofono_lte *lte)
 		return;
 	}
 
-	apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP ,
-					DEFAULT_APN_KEY, NULL);
-	if (apn) {
+	apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
+				LTE_APN, NULL);
+	proto_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
+				LTE_PROTO, NULL);
+	auth_method_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
+				LTE_AUTH_METHOD, NULL);
+	username = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
+				LTE_USERNAME, NULL);
+	password = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
+				LTE_PASSWORD, NULL);
+	if (apn && is_valid_apn(apn))
 		strcpy(lte->info.apn, apn);
-		g_free(apn);
-	}
+
+	if (proto_str == NULL)
+		proto_str = g_strdup("ip");
+
+	/* this must have a valid default */
+	if (!gprs_proto_from_string(proto_str, &lte->info.proto))
+		lte->info.proto = OFONO_GPRS_PROTO_IP;
+
+	if (auth_method_str == NULL)
+		auth_method_str = g_strdup("none");
+
+	/* this must have a valid default */
+	if (!gprs_auth_method_from_string(auth_method_str,
+							&lte->info.auth_method))
+		lte->info.auth_method = OFONO_GPRS_AUTH_METHOD_NONE;
+
+	if (username && strlen(username) <= OFONO_GPRS_MAX_USERNAME_LENGTH)
+		strcpy(lte->info.username, username);
+
+	if (password && strlen(password) <= OFONO_GPRS_MAX_PASSWORD_LENGTH)
+		strcpy(lte->info.password, password);
+
+	g_free(apn);
+	g_free(proto_str);
+	g_free(auth_method_str);
+	g_free(username);
+	g_free(password);
 }
 
 static DBusMessage *lte_get_properties(DBusConnection *conn,
 					DBusMessage *msg, void *data)
 {
 	struct ofono_lte *lte = data;
+	const char *proto = gprs_proto_to_string(lte->info.proto);
 	const char *apn = lte->info.apn;
+	const char* auth_method =
+			gprs_auth_method_to_string(lte->info.auth_method);
+	const char *username = lte->info.username;
+	const char *password = lte->info.password;
 	DBusMessage *reply;
 	DBusMessageIter iter;
 	DBusMessageIter dict;
@@ -95,20 +142,28 @@ static DBusMessage *lte_get_properties(DBusConnection *conn,
 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
 					OFONO_PROPERTIES_ARRAY_SIGNATURE,
 					&dict);
-	ofono_dbus_dict_append(&dict, DEFAULT_APN_KEY, DBUS_TYPE_STRING, &apn);
+	ofono_dbus_dict_append(&dict, LTE_APN, DBUS_TYPE_STRING, &apn);
+	ofono_dbus_dict_append(&dict, LTE_PROTO, DBUS_TYPE_STRING, &proto);
+	ofono_dbus_dict_append(&dict, LTE_AUTH_METHOD, DBUS_TYPE_STRING,
+					&auth_method);
+	ofono_dbus_dict_append(&dict, LTE_USERNAME, DBUS_TYPE_STRING,
+					&username);
+	ofono_dbus_dict_append(&dict, LTE_PASSWORD, DBUS_TYPE_STRING,
+					&password);
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
 }
 
 static void lte_set_default_attach_info_cb(const struct ofono_error *error,
-						void *data)
+								void *data)
 {
 	struct ofono_lte *lte = data;
 	const char *path = __ofono_atom_get_path(lte->atom);
 	DBusConnection *conn = ofono_dbus_get_connection();
 	DBusMessage *reply;
-	const char *apn = lte->info.apn;
+	const char *key;
+	const char *propstr = NULL;
 
 	DBG("%s error %d", path, error->type);
 
@@ -118,55 +173,65 @@ static void lte_set_default_attach_info_cb(const struct ofono_error *error,
 		return;
 	}
 
-	g_strlcpy(lte->info.apn, lte->pending_info.apn,
-			OFONO_GPRS_MAX_APN_LENGTH + 1);
+	if (!g_str_equal(lte->pending_info.apn, lte->info.apn)) {
+		g_strlcpy(lte->info.apn, lte->pending_info.apn,
+					OFONO_GPRS_MAX_APN_LENGTH + 1);
+		key = LTE_APN;
+		propstr = lte->info.apn;
+	} else if (lte->pending_info.proto != lte->info.proto) {
+		lte->info.proto = lte->pending_info.proto;
+		key = LTE_PROTO;
+		propstr = gprs_proto_to_string(lte->info.proto);
+	} else if (lte->pending_info.auth_method != lte->info.auth_method) {
+		lte->info.auth_method = lte->pending_info.auth_method;
+		key = LTE_AUTH_METHOD;
+		propstr = gprs_auth_method_to_string(lte->info.auth_method);
+
+	} else if (!g_str_equal(lte->pending_info.username,
+							lte->info.username)) {
+		g_strlcpy(lte->info.username, lte->pending_info.username,
+					OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
+		key = LTE_USERNAME;
+		propstr = lte->info.username;
+	} else if (!g_str_equal(lte->pending_info.password,
+							lte->info.password)) {
+		g_strlcpy(lte->info.password, lte->pending_info.password,
+					OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
+		key = LTE_PASSWORD;
+		propstr = lte->info.password;
+	} else {
+		/*
+		 * this should never happen, because no property change is
+		 * checked before.
+		 * Neverthelss, in this case it will answer the D-Bus message
+		 * but emit no signal
+		 */
+		ofono_error("unexpected property change: ignored");
+		key = NULL;
+	}
+
+	reply = dbus_message_new_method_return(lte->pending);
+	__ofono_dbus_pending_reply(&lte->pending, reply);
+
+	if(!key)
+		return;
 
 	if (lte->settings) {
-		if (strlen(lte->info.apn) == 0)
-			/* Clear entry on empty APN. */
-			g_key_file_remove_key(lte->settings, SETTINGS_GROUP,
-						DEFAULT_APN_KEY, NULL);
+		if (!*propstr)
+			/* Clear entry on empty string. */
+			g_key_file_remove_key(lte->settings,
+				SETTINGS_GROUP, key, NULL);
 		else
-			g_key_file_set_string(lte->settings, SETTINGS_GROUP,
-						DEFAULT_APN_KEY, lte->info.apn);
+			g_key_file_set_string(lte->settings,
+				SETTINGS_GROUP, key, propstr);
 
 		storage_sync(lte->imsi, SETTINGS_STORE, lte->settings);
 	}
 
-	reply = dbus_message_new_method_return(lte->pending);
-	__ofono_dbus_pending_reply(&lte->pending, reply);
-
 	ofono_dbus_signal_property_changed(conn, path,
 					OFONO_CONNECTION_CONTEXT_INTERFACE,
-					DEFAULT_APN_KEY,
-					DBUS_TYPE_STRING, &apn);
-}
-
-static DBusMessage *lte_set_default_apn(struct ofono_lte *lte,
-				DBusConnection *conn, DBusMessage *msg,
-				const char *apn)
-{
-	if (lte->driver->set_default_attach_info == NULL)
-		return __ofono_error_not_implemented(msg);
-
-	if (lte->pending)
-		return __ofono_error_busy(msg);
-
-	if (g_str_equal(apn, lte->info.apn))
-		return dbus_message_new_method_return(msg);
-
-	/* We do care about empty value: it can be used for reset. */
-	if (is_valid_apn(apn) == FALSE && apn[0] != '\0')
-		return __ofono_error_invalid_format(msg);
-
-	lte->pending = dbus_message_ref(msg);
-
-	g_strlcpy(lte->pending_info.apn, apn, OFONO_GPRS_MAX_APN_LENGTH + 1);
-
-	lte->driver->set_default_attach_info(lte, &lte->pending_info,
-					lte_set_default_attach_info_cb, lte);
-
-	return NULL;
+					key,
+					DBUS_TYPE_STRING, &propstr);
 }
 
 static DBusMessage *lte_set_property(DBusConnection *conn,
@@ -177,6 +242,14 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
 	DBusMessageIter var;
 	const char *property;
 	const char *str;
+	enum ofono_gprs_auth_method auth_method;
+	enum ofono_gprs_proto proto;
+
+	if (lte->driver->set_default_attach_info == NULL)
+		return __ofono_error_not_implemented(msg);
+
+	if (lte->pending)
+		return __ofono_error_busy(msg);
 
 	if (!dbus_message_iter_init(msg, &iter))
 		return __ofono_error_invalid_args(msg);
@@ -192,16 +265,67 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
 
 	dbus_message_iter_recurse(&iter, &var);
 
-	if (!strcmp(property, DEFAULT_APN_KEY)) {
-		if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
-			return __ofono_error_invalid_args(msg);
+	if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
+		return __ofono_error_invalid_args(msg);
 
-		dbus_message_iter_get_basic(&var, &str);
+	dbus_message_iter_get_basic(&var, &str);
 
-		return lte_set_default_apn(lte, conn, msg, str);
-	}
+	if ((strcmp(property, LTE_APN) == 0)) {
+
+		if (g_str_equal(str, lte->info.apn))
+			return dbus_message_new_method_return(msg);
+
+		/* We do care about empty value: it can be used for reset. */
+		if (is_valid_apn(str) == FALSE && str[0] != '\0')
+			return __ofono_error_invalid_format(msg);
+
+		g_strlcpy(lte->pending_info.apn, str,
+					OFONO_GPRS_MAX_APN_LENGTH + 1);
+
+	} else if ((strcmp(property, LTE_PROTO) == 0)) {
+
+		if (!gprs_proto_from_string(str, &proto))
+			return __ofono_error_invalid_format(msg);
+
+		if (proto == lte->info.proto)
+			return dbus_message_new_method_return(msg);
+
+		lte->pending_info.proto = proto;
 
-	return __ofono_error_invalid_args(msg);
+	} else if (strcmp(property, LTE_AUTH_METHOD) == 0) {
+
+		if (!gprs_auth_method_from_string(str, &auth_method))
+			return __ofono_error_invalid_format(msg);
+
+		if (auth_method == lte->info.auth_method)
+			return dbus_message_new_method_return(msg);
+
+		lte->pending_info.auth_method = auth_method;
+
+	} else if (strcmp(property, LTE_USERNAME) == 0) {
+
+		if (g_str_equal(str, lte->info.username))
+			return dbus_message_new_method_return(msg);
+
+		g_strlcpy(lte->pending_info.username, str,
+					OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
+
+	} else if (strcmp(property, LTE_PASSWORD) == 0) {
+
+		if (g_str_equal(str, lte->info.password))
+			return dbus_message_new_method_return(msg);
+
+		g_strlcpy(lte->pending_info.password, str,
+					OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
+
+	} else
+		return __ofono_error_invalid_args(msg);
+
+	lte->pending = dbus_message_ref(msg);
+	lte->driver->set_default_attach_info(lte, &lte->pending_info,
+					lte_set_default_attach_info_cb, lte);
+
+	return NULL;
 }
 
 static const GDBusMethodTable lte_methods[] = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 4/4] atmodem/lte: proto and authentication handling
  2018-10-13  5:48 [PATCH v4 0/4] lte atom auth and IP protocol Giacinto Cifelli
                   ` (2 preceding siblings ...)
  2018-10-13  5:48 ` [PATCH v4 3/4] src/lte: " Giacinto Cifelli
@ 2018-10-13  5:48 ` Giacinto Cifelli
  2018-10-13  6:23   ` Jonas Bonn
  3 siblings, 1 reply; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  5:48 UTC (permalink / raw)
  To: ofono

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

The ofono_lte_default_attach_info now handles also the protocol and the
authentication method, username and password.

Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
---
 drivers/atmodem/lte.c | 133 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 123 insertions(+), 10 deletions(-)

diff --git a/drivers/atmodem/lte.c b/drivers/atmodem/lte.c
index efa4e5fe..72e0a6ef 100644
--- a/drivers/atmodem/lte.c
+++ b/drivers/atmodem/lte.c
@@ -3,6 +3,7 @@
  *  oFono - Open Source Telephony
  *
  *  Copyright (C) 2017  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2018 Gemalto M2M
  *
  *  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
@@ -45,10 +46,57 @@ struct lte_driver_data {
 	GAtChat *chat;
 };
 
-static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
+struct lte_cbd {
+	gint ref_count; /* Ref count */
+	ofono_lte_cb_t cb;
+	void *data;
+	GAtChat *chat;
+	const struct ofono_lte_default_attach_info *info;
+};
+
+static struct lte_cbd *lte_cb_data_new0(void *cb, void *data,
+		GAtChat *chat, const struct ofono_lte_default_attach_info *info)
+{
+	struct lte_cbd *cbd = g_new0(struct lte_cbd, 1);
+
+	cbd->ref_count = 1;
+	cbd->cb = cb;
+	cbd->data = data;
+	cbd->chat = chat;
+	cbd->info = info;
+
+	return cbd;
+}
+
+static inline struct lte_cbd *lte_cb_data_ref(struct lte_cbd *cbd)
+{
+	if (cbd == NULL)
+		return NULL;
+
+	g_atomic_int_inc(&cbd->ref_count);
+
+	return cbd;
+}
+
+static void lte_cb_data_unref(gpointer user_data)
+{
+	gboolean is_zero;
+	struct lte_cbd *cbd = user_data;
+
+	if (cbd == NULL)
+		return;
+
+	is_zero = g_atomic_int_dec_and_test(&cbd->ref_count);
+
+	if (is_zero == TRUE)
+		g_free(cbd);
+}
+
+
+static void at_lte_set_auth_cb(gboolean ok, GAtResult *result,
 							gpointer user_data)
 {
-	struct cb_data *cbd = user_data;
+	struct lte_cbd *cbd = user_data;
 	ofono_lte_cb_t cb = cbd->cb;
 	struct ofono_error error;
 
@@ -58,27 +106,92 @@ static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
 	cb(&error, cbd->data);
 }
 
+static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
+							gpointer user_data)
+{
+	struct lte_cbd *cbd = user_data;
+	ofono_lte_cb_t cb = cbd->cb;
+	void *data = cbd->data;
+	struct ofono_error error;
+	char buf[32 + OFONO_GPRS_MAX_USERNAME_LENGTH +
+					OFONO_GPRS_MAX_PASSWORD_LENGTH  + 1];
+	size_t buflen = sizeof(buf);
+	size_t len;
+	enum ofono_gprs_auth_method auth_method;
+
+	if (!ok) {
+		lte_cb_data_unref(cbd);
+		decode_at_error(&error, g_at_result_final_response(result));
+		cb(&error, data);
+		return;
+	}
+
+	len = snprintf(buf, buflen, "AT+CGAUTH=0,");
+	buflen -= len;
+	auth_method = cbd->info->auth_method;
+
+	/* change the authentication method if the  parameters are invalid */
+	if (!*cbd->info->username || !*cbd->info->password)
+		auth_method = OFONO_GPRS_AUTH_METHOD_NONE;
+
+	switch (auth_method) {
+	case OFONO_GPRS_AUTH_METHOD_PAP:
+		snprintf(buf + len, buflen, "1,\"%s\",\"%s\"",
+				cbd->info->username, cbd->info->password);
+		break;
+	case OFONO_GPRS_AUTH_METHOD_CHAP:
+		snprintf(buf + len, buflen, "2,\"%s\",\"%s\"",
+				cbd->info->username, cbd->info->password);
+		break;
+	case OFONO_GPRS_AUTH_METHOD_NONE:
+		snprintf(buf + len, buflen, "0");
+		break;
+	}
+
+	cbd = lte_cb_data_ref(cbd);
+	if (g_at_chat_send(cbd->chat, buf, NULL,
+			at_lte_set_auth_cb, cbd, lte_cb_data_unref) > 0)
+		return;
+
+	lte_cb_data_unref(cbd);
+	CALLBACK_WITH_FAILURE(cb, data);
+}
+
 static void at_lte_set_default_attach_info(const struct ofono_lte *lte,
 			const struct ofono_lte_default_attach_info *info,
 			ofono_lte_cb_t cb, void *data)
 {
 	struct lte_driver_data *ldd = ofono_lte_get_data(lte);
 	char buf[32 + OFONO_GPRS_MAX_APN_LENGTH + 1];
-	struct cb_data *cbd = cb_data_new(cb, data);
+	const char *proto;
+	size_t len;
+	struct lte_cbd *cbd = lte_cb_data_new0(cb, data, ldd->chat, info);
 
 	DBG("LTE config with APN: %s", info->apn);
 
-	if (strlen(info->apn) > 0)
-		snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\",\"%s\"",
-				info->apn);
-	else
-		snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\"");
+	switch (info->proto) {
+	case OFONO_GPRS_PROTO_IPV6:
+		proto = "IPV6";
+		break;
+	case OFONO_GPRS_PROTO_IPV4V6:
+		proto = "IPV4V6";
+		break;
+	case OFONO_GPRS_PROTO_IP:
+		proto = "IP";
+		break;
+	}
+
+	len = snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"%s\"", proto);
+
+	if (*info->apn)
+		snprintf(buf+len, sizeof(buf)-len, ",\"%s\"", info->apn);
 
-	/* We can't do much in case of failure so don't check response. */
 	if (g_at_chat_send(ldd->chat, buf, NULL,
-			at_lte_set_default_attach_info_cb, cbd, g_free) > 0)
+			at_lte_set_default_attach_info_cb,
+			cbd, lte_cb_data_unref) > 0)
 		return;
 
+	lte_cb_data_unref(cbd);
 	CALLBACK_WITH_FAILURE(cb, data);
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/4] atmodem/lte: proto and authentication handling
  2018-10-13  5:48 ` [PATCH v4 4/4] atmodem/lte: " Giacinto Cifelli
@ 2018-10-13  6:23   ` Jonas Bonn
  2018-10-15 17:08     ` Denis Kenzior
  0 siblings, 1 reply; 11+ messages in thread
From: Jonas Bonn @ 2018-10-13  6:23 UTC (permalink / raw)
  To: ofono

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

Hi,


On 13/10/18 07:48, Giacinto Cifelli wrote:
> The ofono_lte_default_attach_info now handles also the protocol and the
> authentication method, username and password.
>
> Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
> ---
>   drivers/atmodem/lte.c | 133 ++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 123 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/atmodem/lte.c b/drivers/atmodem/lte.c
> index efa4e5fe..72e0a6ef 100644
> --- a/drivers/atmodem/lte.c
> +++ b/drivers/atmodem/lte.c
> @@ -3,6 +3,7 @@
>    *  oFono - Open Source Telephony
>    *
>    *  Copyright (C) 2017  Intel Corporation. All rights reserved.
> + *  Copyright (C) 2018 Gemalto M2M
>    *
>    *  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
> @@ -45,10 +46,57 @@ struct lte_driver_data {
>   	GAtChat *chat;
>   };
>   
> -static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
> +struct lte_cbd {
> +	gint ref_count; /* Ref count */
> +	ofono_lte_cb_t cb;
> +	void *data;
> +	GAtChat *chat;
> +	const struct ofono_lte_default_attach_info *info;
> +};
> +
> +static struct lte_cbd *lte_cb_data_new0(void *cb, void *data,
> +		GAtChat *chat, const struct ofono_lte_default_attach_info *info)
> +{
> +	struct lte_cbd *cbd = g_new0(struct lte_cbd, 1);
> +
> +	cbd->ref_count = 1;
> +	cbd->cb = cb;
> +	cbd->data = data;
> +	cbd->chat = chat;
> +	cbd->info = info;
> +
> +	return cbd;
> +}
> +
> +static inline struct lte_cbd *lte_cb_data_ref(struct lte_cbd *cbd)
> +{
> +	if (cbd == NULL)
> +		return NULL;
> +
> +	g_atomic_int_inc(&cbd->ref_count);
> +
> +	return cbd;
> +}
> +
> +static void lte_cb_data_unref(gpointer user_data)
> +{
> +	gboolean is_zero;
> +	struct lte_cbd *cbd = user_data;
> +
> +	if (cbd == NULL)
> +		return;
> +
> +	is_zero = g_atomic_int_dec_and_test(&cbd->ref_count);
> +
> +	if (is_zero == TRUE)
> +		g_free(cbd);
> +}
> +

The above isn't wrong, but I question the need for the atomic 
constructs.  ofono isn't a thread-safe library.

I see that there other uses of atomic accessors in the codebase, but I 
believe these are remnants of a past approach with other ambitions... 
Denis will set me right if I'm wrong about this because this mostly 
predates my involvement with ofono. :)

/Jonas


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 3/4] src/lte: added proto and authentication handling
  2018-10-13  5:48 ` [PATCH v4 3/4] src/lte: " Giacinto Cifelli
@ 2018-10-13  6:50   ` Jonas Bonn
  2018-10-13  7:08     ` Giacinto Cifelli
  0 siblings, 1 reply; 11+ messages in thread
From: Jonas Bonn @ 2018-10-13  6:50 UTC (permalink / raw)
  To: ofono

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

Better subject line might be:

lte: add protocol and auth parameters to default context


On 13/10/18 07:48, Giacinto Cifelli wrote:
> The ofono_lte_default_attach_info is extended with protocol,
> authentication method, username and password.
> The transmission of this info from the src to the atom happens
> through the existing set_default_attach_info.
> A signal is emitted when one of these properties changes

Don't just copy and paste the same description into every patch. 
Describe _this_ patch, not the series... (The way ofono does this, with 
one patch per subdirectory, is sub-optimal in this regard, I know).

Something like:

Many LTE networks require user authentication, even for the default 
context.  As such, we add these parameters to the default context 
settings that will attempt to use when registering to the network.

The additional parameters added by this patch are:  protocol, user, and 
password.  These are sufficient to allow to connect to networks 
available to the patch author where ofono previously failed to register 
to the network at all.

/Jonas

>
> Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
> ---
>   src/lte.c | 236 +++++++++++++++++++++++++++++++++++++++++-------------
>   1 file changed, 180 insertions(+), 56 deletions(-)
>
> diff --git a/src/lte.c b/src/lte.c
> index 23fe8e1c..c1f6d86a 100644
> --- a/src/lte.c
> +++ b/src/lte.c
> @@ -3,6 +3,7 @@
>    *  oFono - Open Source Telephony
>    *
>    *  Copyright (C) 2016  Endocode AG. All rights reserved.
> + *  Copyright (C) 2018 Gemalto M2M
>    *
>    *  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
> @@ -39,7 +40,11 @@
>   
>   #define SETTINGS_STORE "lte"
>   #define SETTINGS_GROUP "Settings"
> -#define DEFAULT_APN_KEY "DefaultAccessPointName"
> +#define LTE_APN "DefaultAccessPointName"
> +#define LTE_PROTO "Protocol"
> +#define LTE_USERNAME "Username"
> +#define LTE_PASSWORD "Password"
> +#define LTE_AUTH_METHOD "AuthenticationMethod"
>   
>   struct ofono_lte {
>   	const struct ofono_lte_driver *driver;
> @@ -57,6 +62,10 @@ static GSList *g_drivers = NULL;
>   static void lte_load_settings(struct ofono_lte *lte)
>   {
>   	char *apn;
> +	char *proto_str;
> +	char *auth_method_str;
> +	char *username;
> +	char *password;
>   
>   	if (lte->imsi == NULL)
>   		return;
> @@ -69,19 +78,57 @@ static void lte_load_settings(struct ofono_lte *lte)
>   		return;
>   	}
>   
> -	apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP ,
> -					DEFAULT_APN_KEY, NULL);
> -	if (apn) {
> +	apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> +				LTE_APN, NULL);
> +	proto_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> +				LTE_PROTO, NULL);
> +	auth_method_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> +				LTE_AUTH_METHOD, NULL);
> +	username = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> +				LTE_USERNAME, NULL);
> +	password = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> +				LTE_PASSWORD, NULL);
> +	if (apn && is_valid_apn(apn))
>   		strcpy(lte->info.apn, apn);
> -		g_free(apn);
> -	}
> +
> +	if (proto_str == NULL)
> +		proto_str = g_strdup("ip");
> +
> +	/* this must have a valid default */
> +	if (!gprs_proto_from_string(proto_str, &lte->info.proto))
> +		lte->info.proto = OFONO_GPRS_PROTO_IP;
> +
> +	if (auth_method_str == NULL)
> +		auth_method_str = g_strdup("none");
> +
> +	/* this must have a valid default */
> +	if (!gprs_auth_method_from_string(auth_method_str,
> +							&lte->info.auth_method))
> +		lte->info.auth_method = OFONO_GPRS_AUTH_METHOD_NONE;
> +
> +	if (username && strlen(username) <= OFONO_GPRS_MAX_USERNAME_LENGTH)
> +		strcpy(lte->info.username, username);
> +
> +	if (password && strlen(password) <= OFONO_GPRS_MAX_PASSWORD_LENGTH)
> +		strcpy(lte->info.password, password);
> +
> +	g_free(apn);
> +	g_free(proto_str);
> +	g_free(auth_method_str);
> +	g_free(username);
> +	g_free(password);
>   }
>   
>   static DBusMessage *lte_get_properties(DBusConnection *conn,
>   					DBusMessage *msg, void *data)
>   {
>   	struct ofono_lte *lte = data;
> +	const char *proto = gprs_proto_to_string(lte->info.proto);
>   	const char *apn = lte->info.apn;
> +	const char* auth_method =
> +			gprs_auth_method_to_string(lte->info.auth_method);
> +	const char *username = lte->info.username;
> +	const char *password = lte->info.password;
>   	DBusMessage *reply;
>   	DBusMessageIter iter;
>   	DBusMessageIter dict;
> @@ -95,20 +142,28 @@ static DBusMessage *lte_get_properties(DBusConnection *conn,
>   	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
>   					OFONO_PROPERTIES_ARRAY_SIGNATURE,
>   					&dict);
> -	ofono_dbus_dict_append(&dict, DEFAULT_APN_KEY, DBUS_TYPE_STRING, &apn);
> +	ofono_dbus_dict_append(&dict, LTE_APN, DBUS_TYPE_STRING, &apn);
> +	ofono_dbus_dict_append(&dict, LTE_PROTO, DBUS_TYPE_STRING, &proto);
> +	ofono_dbus_dict_append(&dict, LTE_AUTH_METHOD, DBUS_TYPE_STRING,
> +					&auth_method);
> +	ofono_dbus_dict_append(&dict, LTE_USERNAME, DBUS_TYPE_STRING,
> +					&username);
> +	ofono_dbus_dict_append(&dict, LTE_PASSWORD, DBUS_TYPE_STRING,
> +					&password);
>   	dbus_message_iter_close_container(&iter, &dict);
>   
>   	return reply;
>   }
>   
>   static void lte_set_default_attach_info_cb(const struct ofono_error *error,
> -						void *data)
> +								void *data)
>   {
>   	struct ofono_lte *lte = data;
>   	const char *path = __ofono_atom_get_path(lte->atom);
>   	DBusConnection *conn = ofono_dbus_get_connection();
>   	DBusMessage *reply;
> -	const char *apn = lte->info.apn;
> +	const char *key;
> +	const char *propstr = NULL;
>   
>   	DBG("%s error %d", path, error->type);
>   
> @@ -118,55 +173,65 @@ static void lte_set_default_attach_info_cb(const struct ofono_error *error,
>   		return;
>   	}
>   
> -	g_strlcpy(lte->info.apn, lte->pending_info.apn,
> -			OFONO_GPRS_MAX_APN_LENGTH + 1);
> +	if (!g_str_equal(lte->pending_info.apn, lte->info.apn)) {
> +		g_strlcpy(lte->info.apn, lte->pending_info.apn,
> +					OFONO_GPRS_MAX_APN_LENGTH + 1);
> +		key = LTE_APN;
> +		propstr = lte->info.apn;
> +	} else if (lte->pending_info.proto != lte->info.proto) {
> +		lte->info.proto = lte->pending_info.proto;
> +		key = LTE_PROTO;
> +		propstr = gprs_proto_to_string(lte->info.proto);
> +	} else if (lte->pending_info.auth_method != lte->info.auth_method) {
> +		lte->info.auth_method = lte->pending_info.auth_method;
> +		key = LTE_AUTH_METHOD;
> +		propstr = gprs_auth_method_to_string(lte->info.auth_method);
> +
> +	} else if (!g_str_equal(lte->pending_info.username,
> +							lte->info.username)) {
> +		g_strlcpy(lte->info.username, lte->pending_info.username,
> +					OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
> +		key = LTE_USERNAME;
> +		propstr = lte->info.username;
> +	} else if (!g_str_equal(lte->pending_info.password,
> +							lte->info.password)) {
> +		g_strlcpy(lte->info.password, lte->pending_info.password,
> +					OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
> +		key = LTE_PASSWORD;
> +		propstr = lte->info.password;
> +	} else {
> +		/*
> +		 * this should never happen, because no property change is
> +		 * checked before.
> +		 * Neverthelss, in this case it will answer the D-Bus message
> +		 * but emit no signal
> +		 */
> +		ofono_error("unexpected property change: ignored");
> +		key = NULL;
> +	}
> +
> +	reply = dbus_message_new_method_return(lte->pending);
> +	__ofono_dbus_pending_reply(&lte->pending, reply);
> +
> +	if(!key)
> +		return;
>   
>   	if (lte->settings) {
> -		if (strlen(lte->info.apn) == 0)
> -			/* Clear entry on empty APN. */
> -			g_key_file_remove_key(lte->settings, SETTINGS_GROUP,
> -						DEFAULT_APN_KEY, NULL);
> +		if (!*propstr)
> +			/* Clear entry on empty string. */
> +			g_key_file_remove_key(lte->settings,
> +				SETTINGS_GROUP, key, NULL);
>   		else
> -			g_key_file_set_string(lte->settings, SETTINGS_GROUP,
> -						DEFAULT_APN_KEY, lte->info.apn);
> +			g_key_file_set_string(lte->settings,
> +				SETTINGS_GROUP, key, propstr);
>   
>   		storage_sync(lte->imsi, SETTINGS_STORE, lte->settings);
>   	}
>   
> -	reply = dbus_message_new_method_return(lte->pending);
> -	__ofono_dbus_pending_reply(&lte->pending, reply);
> -
>   	ofono_dbus_signal_property_changed(conn, path,
>   					OFONO_CONNECTION_CONTEXT_INTERFACE,
> -					DEFAULT_APN_KEY,
> -					DBUS_TYPE_STRING, &apn);
> -}
> -
> -static DBusMessage *lte_set_default_apn(struct ofono_lte *lte,
> -				DBusConnection *conn, DBusMessage *msg,
> -				const char *apn)
> -{
> -	if (lte->driver->set_default_attach_info == NULL)
> -		return __ofono_error_not_implemented(msg);
> -
> -	if (lte->pending)
> -		return __ofono_error_busy(msg);
> -
> -	if (g_str_equal(apn, lte->info.apn))
> -		return dbus_message_new_method_return(msg);
> -
> -	/* We do care about empty value: it can be used for reset. */
> -	if (is_valid_apn(apn) == FALSE && apn[0] != '\0')
> -		return __ofono_error_invalid_format(msg);
> -
> -	lte->pending = dbus_message_ref(msg);
> -
> -	g_strlcpy(lte->pending_info.apn, apn, OFONO_GPRS_MAX_APN_LENGTH + 1);
> -
> -	lte->driver->set_default_attach_info(lte, &lte->pending_info,
> -					lte_set_default_attach_info_cb, lte);
> -
> -	return NULL;
> +					key,
> +					DBUS_TYPE_STRING, &propstr);
>   }
>   
>   static DBusMessage *lte_set_property(DBusConnection *conn,
> @@ -177,6 +242,14 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
>   	DBusMessageIter var;
>   	const char *property;
>   	const char *str;
> +	enum ofono_gprs_auth_method auth_method;
> +	enum ofono_gprs_proto proto;
> +
> +	if (lte->driver->set_default_attach_info == NULL)
> +		return __ofono_error_not_implemented(msg);
> +
> +	if (lte->pending)
> +		return __ofono_error_busy(msg);
>   
>   	if (!dbus_message_iter_init(msg, &iter))
>   		return __ofono_error_invalid_args(msg);
> @@ -192,16 +265,67 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
>   
>   	dbus_message_iter_recurse(&iter, &var);
>   
> -	if (!strcmp(property, DEFAULT_APN_KEY)) {
> -		if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
> -			return __ofono_error_invalid_args(msg);
> +	if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
> +		return __ofono_error_invalid_args(msg);
>   
> -		dbus_message_iter_get_basic(&var, &str);
> +	dbus_message_iter_get_basic(&var, &str);
>   
> -		return lte_set_default_apn(lte, conn, msg, str);
> -	}
> +	if ((strcmp(property, LTE_APN) == 0)) {
> +
> +		if (g_str_equal(str, lte->info.apn))
> +			return dbus_message_new_method_return(msg);
> +
> +		/* We do care about empty value: it can be used for reset. */
> +		if (is_valid_apn(str) == FALSE && str[0] != '\0')
> +			return __ofono_error_invalid_format(msg);
> +
> +		g_strlcpy(lte->pending_info.apn, str,
> +					OFONO_GPRS_MAX_APN_LENGTH + 1);
> +
> +	} else if ((strcmp(property, LTE_PROTO) == 0)) {
> +
> +		if (!gprs_proto_from_string(str, &proto))
> +			return __ofono_error_invalid_format(msg);
> +
> +		if (proto == lte->info.proto)
> +			return dbus_message_new_method_return(msg);
> +
> +		lte->pending_info.proto = proto;
>   
> -	return __ofono_error_invalid_args(msg);
> +	} else if (strcmp(property, LTE_AUTH_METHOD) == 0) {
> +
> +		if (!gprs_auth_method_from_string(str, &auth_method))
> +			return __ofono_error_invalid_format(msg);
> +
> +		if (auth_method == lte->info.auth_method)
> +			return dbus_message_new_method_return(msg);
> +
> +		lte->pending_info.auth_method = auth_method;
> +
> +	} else if (strcmp(property, LTE_USERNAME) == 0) {
> +
> +		if (g_str_equal(str, lte->info.username))
> +			return dbus_message_new_method_return(msg);
> +
> +		g_strlcpy(lte->pending_info.username, str,
> +					OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
> +
> +	} else if (strcmp(property, LTE_PASSWORD) == 0) {
> +
> +		if (g_str_equal(str, lte->info.password))
> +			return dbus_message_new_method_return(msg);
> +
> +		g_strlcpy(lte->pending_info.password, str,
> +					OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
> +
> +	} else
> +		return __ofono_error_invalid_args(msg);
> +
> +	lte->pending = dbus_message_ref(msg);
> +	lte->driver->set_default_attach_info(lte, &lte->pending_info,
> +					lte_set_default_attach_info_cb, lte);
> +
> +	return NULL;
>   }
>   
>   static const GDBusMethodTable lte_methods[] = {


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 3/4] src/lte: added proto and authentication handling
  2018-10-13  6:50   ` Jonas Bonn
@ 2018-10-13  7:08     ` Giacinto Cifelli
  0 siblings, 0 replies; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-13  7:08 UTC (permalink / raw)
  To: ofono

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

Hi,

On Sat, Oct 13, 2018 at 8:50 AM Jonas Bonn <jonas@southpole.se> wrote:
>
> Better subject line might be:
>
> lte: add protocol and auth parameters to default context
>
>
> On 13/10/18 07:48, Giacinto Cifelli wrote:
> > The ofono_lte_default_attach_info is extended with protocol,
> > authentication method, username and password.
> > The transmission of this info from the src to the atom happens
> > through the existing set_default_attach_info.
> > A signal is emitted when one of these properties changes
>
> Don't just copy and paste the same description into every patch.
> Describe _this_ patch, not the series... (The way ofono does this, with
> one patch per subdirectory, is sub-optimal in this regard, I know).
>
> Something like:
>
> Many LTE networks require user authentication, even for the default
> context.  As such, we add these parameters to the default context
> settings that will attempt to use when registering to the network.
>
> The additional parameters added by this patch are:  protocol, user, and
> password.  These are sufficient to allow to connect to networks
> available to the patch author where ofono previously failed to register
> to the network at all.
>
> /Jonas

I like it, extended a litte and shortened the subjet to fit in the
50-char limit:

lte: protocol and authentication for default ctx

Many LTE networks require user authentication, even for the default
context. In particular, most of the private APNs use this facility
to add some control on top of the MNO providing the service, so that
another user of the same network cannot access the private one.
As such, we add these parameters to the default context
settings that will attempt to use when registering to the network.

The additional parameters added by this patch are:  protocol, user, and
password.  These are sufficient to allow to connect to networks
available to the patch author where ofono previously failed to register
to the network at all.


>
> >
> > Co-authored-by: Martin Baschin <martin.baschin@googlemail.com>
> > ---
> >   src/lte.c | 236 +++++++++++++++++++++++++++++++++++++++++-------------
> >   1 file changed, 180 insertions(+), 56 deletions(-)
> >
> > diff --git a/src/lte.c b/src/lte.c
> > index 23fe8e1c..c1f6d86a 100644
> > --- a/src/lte.c
> > +++ b/src/lte.c
> > @@ -3,6 +3,7 @@
> >    *  oFono - Open Source Telephony
> >    *
> >    *  Copyright (C) 2016  Endocode AG. All rights reserved.
> > + *  Copyright (C) 2018 Gemalto M2M
> >    *
> >    *  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
> > @@ -39,7 +40,11 @@
> >
> >   #define SETTINGS_STORE "lte"
> >   #define SETTINGS_GROUP "Settings"
> > -#define DEFAULT_APN_KEY "DefaultAccessPointName"
> > +#define LTE_APN "DefaultAccessPointName"
> > +#define LTE_PROTO "Protocol"
> > +#define LTE_USERNAME "Username"
> > +#define LTE_PASSWORD "Password"
> > +#define LTE_AUTH_METHOD "AuthenticationMethod"
> >
> >   struct ofono_lte {
> >       const struct ofono_lte_driver *driver;
> > @@ -57,6 +62,10 @@ static GSList *g_drivers = NULL;
> >   static void lte_load_settings(struct ofono_lte *lte)
> >   {
> >       char *apn;
> > +     char *proto_str;
> > +     char *auth_method_str;
> > +     char *username;
> > +     char *password;
> >
> >       if (lte->imsi == NULL)
> >               return;
> > @@ -69,19 +78,57 @@ static void lte_load_settings(struct ofono_lte *lte)
> >               return;
> >       }
> >
> > -     apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP ,
> > -                                     DEFAULT_APN_KEY, NULL);
> > -     if (apn) {
> > +     apn = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> > +                             LTE_APN, NULL);
> > +     proto_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> > +                             LTE_PROTO, NULL);
> > +     auth_method_str = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> > +                             LTE_AUTH_METHOD, NULL);
> > +     username = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> > +                             LTE_USERNAME, NULL);
> > +     password = g_key_file_get_string(lte->settings, SETTINGS_GROUP,
> > +                             LTE_PASSWORD, NULL);
> > +     if (apn && is_valid_apn(apn))
> >               strcpy(lte->info.apn, apn);
> > -             g_free(apn);
> > -     }
> > +
> > +     if (proto_str == NULL)
> > +             proto_str = g_strdup("ip");
> > +
> > +     /* this must have a valid default */
> > +     if (!gprs_proto_from_string(proto_str, &lte->info.proto))
> > +             lte->info.proto = OFONO_GPRS_PROTO_IP;
> > +
> > +     if (auth_method_str == NULL)
> > +             auth_method_str = g_strdup("none");
> > +
> > +     /* this must have a valid default */
> > +     if (!gprs_auth_method_from_string(auth_method_str,
> > +                                                     &lte->info.auth_method))
> > +             lte->info.auth_method = OFONO_GPRS_AUTH_METHOD_NONE;
> > +
> > +     if (username && strlen(username) <= OFONO_GPRS_MAX_USERNAME_LENGTH)
> > +             strcpy(lte->info.username, username);
> > +
> > +     if (password && strlen(password) <= OFONO_GPRS_MAX_PASSWORD_LENGTH)
> > +             strcpy(lte->info.password, password);
> > +
> > +     g_free(apn);
> > +     g_free(proto_str);
> > +     g_free(auth_method_str);
> > +     g_free(username);
> > +     g_free(password);
> >   }
> >
> >   static DBusMessage *lte_get_properties(DBusConnection *conn,
> >                                       DBusMessage *msg, void *data)
> >   {
> >       struct ofono_lte *lte = data;
> > +     const char *proto = gprs_proto_to_string(lte->info.proto);
> >       const char *apn = lte->info.apn;
> > +     const char* auth_method =
> > +                     gprs_auth_method_to_string(lte->info.auth_method);
> > +     const char *username = lte->info.username;
> > +     const char *password = lte->info.password;
> >       DBusMessage *reply;
> >       DBusMessageIter iter;
> >       DBusMessageIter dict;
> > @@ -95,20 +142,28 @@ static DBusMessage *lte_get_properties(DBusConnection *conn,
> >       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> >                                       OFONO_PROPERTIES_ARRAY_SIGNATURE,
> >                                       &dict);
> > -     ofono_dbus_dict_append(&dict, DEFAULT_APN_KEY, DBUS_TYPE_STRING, &apn);
> > +     ofono_dbus_dict_append(&dict, LTE_APN, DBUS_TYPE_STRING, &apn);
> > +     ofono_dbus_dict_append(&dict, LTE_PROTO, DBUS_TYPE_STRING, &proto);
> > +     ofono_dbus_dict_append(&dict, LTE_AUTH_METHOD, DBUS_TYPE_STRING,
> > +                                     &auth_method);
> > +     ofono_dbus_dict_append(&dict, LTE_USERNAME, DBUS_TYPE_STRING,
> > +                                     &username);
> > +     ofono_dbus_dict_append(&dict, LTE_PASSWORD, DBUS_TYPE_STRING,
> > +                                     &password);
> >       dbus_message_iter_close_container(&iter, &dict);
> >
> >       return reply;
> >   }
> >
> >   static void lte_set_default_attach_info_cb(const struct ofono_error *error,
> > -                                             void *data)
> > +                                                             void *data)
> >   {
> >       struct ofono_lte *lte = data;
> >       const char *path = __ofono_atom_get_path(lte->atom);
> >       DBusConnection *conn = ofono_dbus_get_connection();
> >       DBusMessage *reply;
> > -     const char *apn = lte->info.apn;
> > +     const char *key;
> > +     const char *propstr = NULL;
> >
> >       DBG("%s error %d", path, error->type);
> >
> > @@ -118,55 +173,65 @@ static void lte_set_default_attach_info_cb(const struct ofono_error *error,
> >               return;
> >       }
> >
> > -     g_strlcpy(lte->info.apn, lte->pending_info.apn,
> > -                     OFONO_GPRS_MAX_APN_LENGTH + 1);
> > +     if (!g_str_equal(lte->pending_info.apn, lte->info.apn)) {
> > +             g_strlcpy(lte->info.apn, lte->pending_info.apn,
> > +                                     OFONO_GPRS_MAX_APN_LENGTH + 1);
> > +             key = LTE_APN;
> > +             propstr = lte->info.apn;
> > +     } else if (lte->pending_info.proto != lte->info.proto) {
> > +             lte->info.proto = lte->pending_info.proto;
> > +             key = LTE_PROTO;
> > +             propstr = gprs_proto_to_string(lte->info.proto);
> > +     } else if (lte->pending_info.auth_method != lte->info.auth_method) {
> > +             lte->info.auth_method = lte->pending_info.auth_method;
> > +             key = LTE_AUTH_METHOD;
> > +             propstr = gprs_auth_method_to_string(lte->info.auth_method);
> > +
> > +     } else if (!g_str_equal(lte->pending_info.username,
> > +                                                     lte->info.username)) {
> > +             g_strlcpy(lte->info.username, lte->pending_info.username,
> > +                                     OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
> > +             key = LTE_USERNAME;
> > +             propstr = lte->info.username;
> > +     } else if (!g_str_equal(lte->pending_info.password,
> > +                                                     lte->info.password)) {
> > +             g_strlcpy(lte->info.password, lte->pending_info.password,
> > +                                     OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
> > +             key = LTE_PASSWORD;
> > +             propstr = lte->info.password;
> > +     } else {
> > +             /*
> > +              * this should never happen, because no property change is
> > +              * checked before.
> > +              * Neverthelss, in this case it will answer the D-Bus message
> > +              * but emit no signal
> > +              */
> > +             ofono_error("unexpected property change: ignored");
> > +             key = NULL;
> > +     }
> > +
> > +     reply = dbus_message_new_method_return(lte->pending);
> > +     __ofono_dbus_pending_reply(&lte->pending, reply);
> > +
> > +     if(!key)
> > +             return;
> >
> >       if (lte->settings) {
> > -             if (strlen(lte->info.apn) == 0)
> > -                     /* Clear entry on empty APN. */
> > -                     g_key_file_remove_key(lte->settings, SETTINGS_GROUP,
> > -                                             DEFAULT_APN_KEY, NULL);
> > +             if (!*propstr)
> > +                     /* Clear entry on empty string. */
> > +                     g_key_file_remove_key(lte->settings,
> > +                             SETTINGS_GROUP, key, NULL);
> >               else
> > -                     g_key_file_set_string(lte->settings, SETTINGS_GROUP,
> > -                                             DEFAULT_APN_KEY, lte->info.apn);
> > +                     g_key_file_set_string(lte->settings,
> > +                             SETTINGS_GROUP, key, propstr);
> >
> >               storage_sync(lte->imsi, SETTINGS_STORE, lte->settings);
> >       }
> >
> > -     reply = dbus_message_new_method_return(lte->pending);
> > -     __ofono_dbus_pending_reply(&lte->pending, reply);
> > -
> >       ofono_dbus_signal_property_changed(conn, path,
> >                                       OFONO_CONNECTION_CONTEXT_INTERFACE,
> > -                                     DEFAULT_APN_KEY,
> > -                                     DBUS_TYPE_STRING, &apn);
> > -}
> > -
> > -static DBusMessage *lte_set_default_apn(struct ofono_lte *lte,
> > -                             DBusConnection *conn, DBusMessage *msg,
> > -                             const char *apn)
> > -{
> > -     if (lte->driver->set_default_attach_info == NULL)
> > -             return __ofono_error_not_implemented(msg);
> > -
> > -     if (lte->pending)
> > -             return __ofono_error_busy(msg);
> > -
> > -     if (g_str_equal(apn, lte->info.apn))
> > -             return dbus_message_new_method_return(msg);
> > -
> > -     /* We do care about empty value: it can be used for reset. */
> > -     if (is_valid_apn(apn) == FALSE && apn[0] != '\0')
> > -             return __ofono_error_invalid_format(msg);
> > -
> > -     lte->pending = dbus_message_ref(msg);
> > -
> > -     g_strlcpy(lte->pending_info.apn, apn, OFONO_GPRS_MAX_APN_LENGTH + 1);
> > -
> > -     lte->driver->set_default_attach_info(lte, &lte->pending_info,
> > -                                     lte_set_default_attach_info_cb, lte);
> > -
> > -     return NULL;
> > +                                     key,
> > +                                     DBUS_TYPE_STRING, &propstr);
> >   }
> >
> >   static DBusMessage *lte_set_property(DBusConnection *conn,
> > @@ -177,6 +242,14 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
> >       DBusMessageIter var;
> >       const char *property;
> >       const char *str;
> > +     enum ofono_gprs_auth_method auth_method;
> > +     enum ofono_gprs_proto proto;
> > +
> > +     if (lte->driver->set_default_attach_info == NULL)
> > +             return __ofono_error_not_implemented(msg);
> > +
> > +     if (lte->pending)
> > +             return __ofono_error_busy(msg);
> >
> >       if (!dbus_message_iter_init(msg, &iter))
> >               return __ofono_error_invalid_args(msg);
> > @@ -192,16 +265,67 @@ static DBusMessage *lte_set_property(DBusConnection *conn,
> >
> >       dbus_message_iter_recurse(&iter, &var);
> >
> > -     if (!strcmp(property, DEFAULT_APN_KEY)) {
> > -             if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
> > -                     return __ofono_error_invalid_args(msg);
> > +     if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
> > +             return __ofono_error_invalid_args(msg);
> >
> > -             dbus_message_iter_get_basic(&var, &str);
> > +     dbus_message_iter_get_basic(&var, &str);
> >
> > -             return lte_set_default_apn(lte, conn, msg, str);
> > -     }
> > +     if ((strcmp(property, LTE_APN) == 0)) {
> > +
> > +             if (g_str_equal(str, lte->info.apn))
> > +                     return dbus_message_new_method_return(msg);
> > +
> > +             /* We do care about empty value: it can be used for reset. */
> > +             if (is_valid_apn(str) == FALSE && str[0] != '\0')
> > +                     return __ofono_error_invalid_format(msg);
> > +
> > +             g_strlcpy(lte->pending_info.apn, str,
> > +                                     OFONO_GPRS_MAX_APN_LENGTH + 1);
> > +
> > +     } else if ((strcmp(property, LTE_PROTO) == 0)) {
> > +
> > +             if (!gprs_proto_from_string(str, &proto))
> > +                     return __ofono_error_invalid_format(msg);
> > +
> > +             if (proto == lte->info.proto)
> > +                     return dbus_message_new_method_return(msg);
> > +
> > +             lte->pending_info.proto = proto;
> >
> > -     return __ofono_error_invalid_args(msg);
> > +     } else if (strcmp(property, LTE_AUTH_METHOD) == 0) {
> > +
> > +             if (!gprs_auth_method_from_string(str, &auth_method))
> > +                     return __ofono_error_invalid_format(msg);
> > +
> > +             if (auth_method == lte->info.auth_method)
> > +                     return dbus_message_new_method_return(msg);
> > +
> > +             lte->pending_info.auth_method = auth_method;
> > +
> > +     } else if (strcmp(property, LTE_USERNAME) == 0) {
> > +
> > +             if (g_str_equal(str, lte->info.username))
> > +                     return dbus_message_new_method_return(msg);
> > +
> > +             g_strlcpy(lte->pending_info.username, str,
> > +                                     OFONO_GPRS_MAX_USERNAME_LENGTH + 1);
> > +
> > +     } else if (strcmp(property, LTE_PASSWORD) == 0) {
> > +
> > +             if (g_str_equal(str, lte->info.password))
> > +                     return dbus_message_new_method_return(msg);
> > +
> > +             g_strlcpy(lte->pending_info.password, str,
> > +                                     OFONO_GPRS_MAX_PASSWORD_LENGTH + 1);
> > +
> > +     } else
> > +             return __ofono_error_invalid_args(msg);
> > +
> > +     lte->pending = dbus_message_ref(msg);
> > +     lte->driver->set_default_attach_info(lte, &lte->pending_info,
> > +                                     lte_set_default_attach_info_cb, lte);
> > +
> > +     return NULL;
> >   }
> >
> >   static const GDBusMethodTable lte_methods[] = {
>

Thank you,
Giacinto

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/4] atmodem/lte: proto and authentication handling
  2018-10-13  6:23   ` Jonas Bonn
@ 2018-10-15 17:08     ` Denis Kenzior
  2018-10-15 17:30       ` Giacinto Cifelli
  0 siblings, 1 reply; 11+ messages in thread
From: Denis Kenzior @ 2018-10-15 17:08 UTC (permalink / raw)
  To: ofono

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

Hi Jonas,

>> +
> 
> The above isn't wrong, but I question the need for the atomic 
> constructs.  ofono isn't a thread-safe library.
> 
> I see that there other uses of atomic accessors in the codebase, but I 
> believe these are remnants of a past approach with other ambitions... 
> Denis will set me right if I'm wrong about this because this mostly 
> predates my involvement with ofono. :)

oFono was never thread safe, and as you point out, atomic operations are 
not really necessary.  But glib uses atomics for reference counting, so 
we stuck to that.  Also Marcel at some point evangelized that g_atomic 
is the one true way (TM) of implementing reference counting.

With ell we don't use atomics at all.

So given the above, I find both approaches acceptable.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/4] atmodem/lte: proto and authentication handling
  2018-10-15 17:08     ` Denis Kenzior
@ 2018-10-15 17:30       ` Giacinto Cifelli
  2018-10-15 18:43         ` Giacinto Cifelli
  0 siblings, 1 reply; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-15 17:30 UTC (permalink / raw)
  To: ofono

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

Hi Denis & Jonas,

On Mon, Oct 15, 2018 at 7:27 PM Denis Kenzior <denkenz@gmail.com> wrote:
>
> Hi Jonas,
>
> >> +
> >
> > The above isn't wrong, but I question the need for the atomic
> > constructs.  ofono isn't a thread-safe library.
> >
> > I see that there other uses of atomic accessors in the codebase, but I
> > believe these are remnants of a past approach with other ambitions...
> > Denis will set me right if I'm wrong about this because this mostly
> > predates my involvement with ofono. :)
>
> oFono was never thread safe, and as you point out, atomic operations are
> not really necessary.  But glib uses atomics for reference counting, so
> we stuck to that.  Also Marcel at some point evangelized that g_atomic
> is the one true way (TM) of implementing reference counting.
>
> With ell we don't use atomics at all.
>
> So given the above, I find both approaches acceptable.
>
> Regards,
> -Denis

Thank you both. I think I will keep this as it is then, and change the rest.
I will re-submit the series later.

Regards,
Giacinto

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/4] atmodem/lte: proto and authentication handling
  2018-10-15 17:30       ` Giacinto Cifelli
@ 2018-10-15 18:43         ` Giacinto Cifelli
  0 siblings, 0 replies; 11+ messages in thread
From: Giacinto Cifelli @ 2018-10-15 18:43 UTC (permalink / raw)
  To: ofono

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

Hi Denis,

would you please comment also on the mail series with subject:
  [RFC PATCH v6 x/1] lte: protocol and authentication for default ctx
which is the core atom for the lte series discussed here, so that I
don't resubmit the series just for spam.

Also, I would really appreciate a comment on the series:
  [RFC PATCH x/1] atmodem/lte: Gemalto vendor specific extension

and possibly the introduction of germaltomodem/voicecall. Series:
  [PATCH v3 x/2] Gemalto: support for voicecall

thank you,
Giacinto


On Mon, Oct 15, 2018 at 7:30 PM Giacinto Cifelli <gciofono@gmail.com> wrote:
>
> Hi Denis & Jonas,
>
> On Mon, Oct 15, 2018 at 7:27 PM Denis Kenzior <denkenz@gmail.com> wrote:
> >
> > Hi Jonas,
> >
> > >> +
> > >
> > > The above isn't wrong, but I question the need for the atomic
> > > constructs.  ofono isn't a thread-safe library.
> > >
> > > I see that there other uses of atomic accessors in the codebase, but I
> > > believe these are remnants of a past approach with other ambitions...
> > > Denis will set me right if I'm wrong about this because this mostly
> > > predates my involvement with ofono. :)
> >
> > oFono was never thread safe, and as you point out, atomic operations are
> > not really necessary.  But glib uses atomics for reference counting, so
> > we stuck to that.  Also Marcel at some point evangelized that g_atomic
> > is the one true way (TM) of implementing reference counting.
> >
> > With ell we don't use atomics at all.
> >
> > So given the above, I find both approaches acceptable.
> >
> > Regards,
> > -Denis
>
> Thank you both. I think I will keep this as it is then, and change the rest.
> I will re-submit the series later.
>
> Regards,
> Giacinto

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-10-15 18:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-13  5:48 [PATCH v4 0/4] lte atom auth and IP protocol Giacinto Cifelli
2018-10-13  5:48 ` [PATCH v4 1/4] lte-api: protocol and authentication properties Giacinto Cifelli
2018-10-13  5:48 ` [PATCH v4 2/4] lte.h: added proto and authentication handling Giacinto Cifelli
2018-10-13  5:48 ` [PATCH v4 3/4] src/lte: " Giacinto Cifelli
2018-10-13  6:50   ` Jonas Bonn
2018-10-13  7:08     ` Giacinto Cifelli
2018-10-13  5:48 ` [PATCH v4 4/4] atmodem/lte: " Giacinto Cifelli
2018-10-13  6:23   ` Jonas Bonn
2018-10-15 17:08     ` Denis Kenzior
2018-10-15 17:30       ` Giacinto Cifelli
2018-10-15 18:43         ` Giacinto Cifelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox