Skip to contentSkip to conversation

lte atom proto and authentication

PATCH Superseded Giacinto Cifelli 2 participants 8 messages Oct 12, 2018

v2 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v2 cover lte atom proto and authentication

Second version of the lte atom, with selection of protocol and authentication. In this version the settings are applied as soon as a property is changed.

Giacinto Cifelli (5):
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 Gemalto contributors so far

 AUTHORS               |   2 +
 doc/lte-api.txt       |  39 +++++++
 drivers/atmodem/lte.c |  92 ++++++++++++++--
 include/lte.h         |   5 +
 src/lte.c             | 236 ++++++++++++++++++++++++++++++++----------
 5 files changed, 307 insertions(+), 67 deletions(-)
Signature · 1 line
2.17.1
#1 lore raw

PATCH v2 1/5 lte-api: protocol and authentication properties

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.

---
 doc/lte-api.txt | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
doc/lte-api.txt +39 -0
index 8a2a97d9..c9544f60 100644
@@ -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.
Signature · 1 line
2.17.1
#2 lore raw

PATCH v2 2/5 lte.h: added proto and authentication handling

In reply to Giacinto Cifelli

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

---
 include/lte.h | 5 +++++
 1 file changed, 5 insertions(+)
include/lte.h +5 -0
index 0f2501c0..2f12ac29 100644
@@ -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);
Signature · 1 line
2.17.1
#3 lore raw

PATCH v2 3/5 src/lte: added proto and authentication handling

In reply to Giacinto Cifelli

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

---
 src/lte.c | 236 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 180 insertions(+), 56 deletions(-)
src/lte.c +180 -56
index 23fe8e1c..c1f6d86a 100644
@@ -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[] = {
Signature · 1 line
2.17.1
#4 lore raw

PATCH v2 4/5 atmodem/lte: proto and authentication handling

In reply to Giacinto Cifelli

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

---
 drivers/atmodem/lte.c | 92 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 81 insertions(+), 11 deletions(-)
drivers/atmodem/lte.c +80 -8
index efa4e5fe..e02864ea 100644
@@ -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,17 @@ struct lte_driver_data {
 	GAtChat *chat;
 };
 
-static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
+struct lte_callbackdata {
+	ofono_lte_cb_t cb;
+	void *data;
+	struct lte_driver_data *ldd;
+	const struct ofono_lte_default_attach_info *info;
+};
+
+static void at_lte_set_auth_cb(gboolean ok, GAtResult *result,
 							gpointer user_data)
 {
-	struct cb_data *cbd = user_data;
+	struct lte_callbackdata *cbd = user_data;
 	ofono_lte_cb_t cb = cbd->cb;
 	struct ofono_error error;
 
@@ -58,25 +66,89 @@ static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
 	cb(&error, cbd->data);
 }
 
+static void at_lte_set_auth(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct lte_callbackdata *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];
+	guint buflen = sizeof(buf);
+	guint len;
+	enum ofono_gprs_auth_method auth_method;
+
+	if (!ok) {
+		g_free(cbd);
+		decode_at_error(&error, g_at_result_final_response(result));
+		cb(&error, data);
+	}
+
+	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;
+	}
+
+	if (g_at_chat_send(cbd->ldd->chat, buf, NULL,
+			at_lte_set_auth_cb, cbd, g_free) > 0)
+		return;
+
+	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);
+	struct lte_callbackdata *cbd = g_new0(struct lte_callbackdata ,1);
+	const char *proto;
 
 	DBG("LTE config with APN: %s", info->apn);
 
+	cbd->cb = cb;
+	cbd->data = data;
+	cbd->ldd = ldd;
+	cbd->info = info;
+
+	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;
+	}
+
 	if (strlen(info->apn) > 0)
-		snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\",\"%s\"",
-				info->apn);
+		snprintf(buf, sizeof(buf),
+				"AT+CGDCONT=0,\"%s\",\"%s\"", proto, info->apn);
 	else
-		snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\"");
+		snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"%s\"", proto);
 
-	/* 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_auth, cbd, NULL) > 0)
 		return;
 
 	CALLBACK_WITH_FAILURE(cb, data);
Signature · 1 line
2.17.1
#5 lore raw

PATCH v2 5/5 Gemalto contributors so far

In reply to Giacinto Cifelli
---
 AUTHORS | 2 ++
 1 file changed, 2 insertions(+)
AUTHORS +2 -0
index 2d360e6e..f64cc03c 100644
@@ -138,3 +138,5 @@ Florent Beillonnet <[email protected]>
 Martin Hundebøll <[email protected]>
 Julien Tournier <[email protected]>
 Nandini Rebello <[email protected]>
+Martin Baschin <[email protected]>
+Giacinto Cifelli <[email protected]>
Signature · 1 line
2.17.1
#6 lore raw
In reply to Giacinto Cifelli

Wow... 45 minutes since your last submission and two minutes since I sent my last review email.  Impressive speed! ;)  Like I said, slow down...

Since I doubt any of my comments are incorporated here, I'll just wait for v3 before reading them again...

Quoted 2 lines · Giacinto Cifelli

Second version of the lte atom, with selection of protocol and authentication. In this version the settings are applied as soon as a property is changed.

Include a long description here of what problem you are trying to solve and what approach you are using to solve that problem. Reading this description should be sufficient for me to be able to understand where the following sequence of patches is taking me.

For follow-up versions, include a little section "Changes in v2" that tells me how v2 differs from the series v1 that I, possibly, have already reviewed.

/Jonas

Quoted 15 lines

Giacinto Cifelli (5):
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 Gemalto contributors so far

  AUTHORS               |   2 +
  doc/lte-api.txt       |  39 +++++++
  drivers/atmodem/lte.c |  92 ++++++++++++++--
  include/lte.h         |   5 +
  src/lte.c             | 236 ++++++++++++++++++++++++++++++++----------
  5 files changed, 307 insertions(+), 67 deletions(-)
#7 lore raw

Hi,

Quoted 3 lines · Jonas Bonn

Wow... 45 minutes since your last submission and two minutes since I sent my last review email. Impressive speed! ;) Like I said, slow down...

yes, I think we were writing in parallel.

Quoted 9 lines

Since I doubt any of my comments are incorporated here, I'll just wait for v3 before reading them again...

Quoted 2 lines · Giacinto Cifelli

Second version of the lte atom, with selection of protocol and authentication. In this version the settings are applied as soon as a property is changed.

Quoted 8 lines

Include a long description here of what problem you are trying to solve and what approach you are using to solve that problem. Reading this description should be sufficient for me to be able to understand where the following sequence of patches is taking me.

For follow-up versions, include a little section "Changes in v2" that tells me how v2 differs from the series v1 that I, possibly, have already reviewed.

ok. I will do all of this for the v3.

Quoted 3 lines

/Jonas

Giacinto