All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2 v2] netreg: Add CPHS CSP implementation
@ 2011-02-04 13:44 Aki Niemi
  2011-04-14 22:43 ` Denis Kenzior
  0 siblings, 1 reply; 2+ messages in thread
From: Aki Niemi @ 2011-02-04 13:44 UTC (permalink / raw)
  To: ofono

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

---
 src/network.c |  122 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 96 insertions(+), 26 deletions(-)

diff --git a/src/network.c b/src/network.c
index bf61472..07f9cdf 100644
--- a/src/network.c
+++ b/src/network.c
@@ -42,7 +42,8 @@
 
 enum network_registration_mode {
 	NETWORK_REGISTRATION_MODE_AUTO =	0,
-	NETWORK_REGISTRATION_MODE_MANUAL =	1,
+	NETWORK_REGISTRATION_MODE_AUTO_ONLY =	1,
+	NETWORK_REGISTRATION_MODE_MANUAL =	2,
 };
 
 #define SETTINGS_STORE "netreg"
@@ -98,6 +99,8 @@ static const char *registration_mode_to_string(int mode)
 	switch (mode) {
 	case NETWORK_REGISTRATION_MODE_AUTO:
 		return "auto";
+	case NETWORK_REGISTRATION_MODE_AUTO_ONLY:
+		return "auto-only";
 	case NETWORK_REGISTRATION_MODE_MANUAL:
 		return "manual";
 	}
@@ -143,6 +146,42 @@ static char **network_operator_technologies(struct network_operator_data *opd)
 	return techs;
 }
 
+static void registration_status_callback(const struct ofono_error *error,
+					int status, int lac, int ci, int tech,
+					void *data)
+{
+	struct ofono_netreg *netreg = data;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error during registration status query");
+		return;
+	}
+
+	ofono_netreg_status_notify(netreg, status, lac, ci, tech);
+}
+
+static void init_register(const struct ofono_error *error, void *data)
+{
+	struct ofono_netreg *netreg = data;
+
+	if (netreg->driver->registration_status == NULL)
+		return;
+
+	netreg->driver->registration_status(netreg,
+					registration_status_callback, netreg);
+}
+
+static void enforce_auto_only(struct ofono_netreg *netreg)
+{
+	if (netreg->mode != NETWORK_REGISTRATION_MODE_MANUAL)
+		return;
+
+	if (netreg->driver->register_auto == NULL)
+		return;
+
+	netreg->driver->register_auto(netreg, init_register, netreg);
+}
+
 static void set_registration_mode(struct ofono_netreg *netreg, int mode)
 {
 	DBusConnection *conn;
@@ -152,6 +191,9 @@ static void set_registration_mode(struct ofono_netreg *netreg, int mode)
 	if (netreg->mode == mode)
 		return;
 
+	if (mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
+		enforce_auto_only(netreg);
+
 	netreg->mode = mode;
 
 	if (netreg->settings) {
@@ -170,20 +212,6 @@ static void set_registration_mode(struct ofono_netreg *netreg, int mode)
 					"Mode", DBUS_TYPE_STRING, &strmode);
 }
 
-static void registration_status_callback(const struct ofono_error *error,
-					int status, int lac, int ci, int tech,
-					void *data)
-{
-	struct ofono_netreg *netreg = data;
-
-	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
-		DBG("Error during registration status query");
-		return;
-	}
-
-	ofono_netreg_status_notify(netreg, status, lac, ci, tech);
-}
-
 static void register_callback(const struct ofono_error *error, void *data)
 {
 	struct ofono_netreg *netreg = data;
@@ -211,15 +239,6 @@ out:
 					registration_status_callback, netreg);
 }
 
-static void init_register(const struct ofono_error *error, void *data)
-{
-	struct ofono_netreg *netreg = data;
-
-	if (netreg->driver->registration_status)
-		netreg->driver->registration_status(netreg,
-					registration_status_callback, netreg);
-}
-
 static struct network_operator_data *
 	network_operator_create(const struct ofono_network_operator *op)
 {
@@ -586,6 +605,9 @@ static DBusMessage *network_operator_register(DBusConnection *conn,
 	struct network_operator_data *opd = data;
 	struct ofono_netreg *netreg = opd->netreg;
 
+	if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
+		return __ofono_error_access_denied(msg);
+
 	if (netreg->pending)
 		return __ofono_error_busy(msg);
 
@@ -828,6 +850,9 @@ static DBusMessage *network_register(DBusConnection *conn,
 {
 	struct ofono_netreg *netreg = data;
 
+	if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
+		return __ofono_error_access_denied(msg);
+
 	if (netreg->pending)
 		return __ofono_error_busy(msg);
 
@@ -947,6 +972,9 @@ static DBusMessage *network_scan(DBusConnection *conn,
 {
 	struct ofono_netreg *netreg = data;
 
+	if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
+		return __ofono_error_access_denied(msg);
+
 	if (netreg->pending)
 		return __ofono_error_busy(msg);
 
@@ -1364,7 +1392,7 @@ static void init_registration_status(const struct ofono_error *error,
 					signal_strength_callback, netreg);
 	}
 
-	if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO &&
+	if (netreg->mode != NETWORK_REGISTRATION_MODE_MANUAL &&
 		(status == NETWORK_REGISTRATION_STATUS_NOT_REGISTERED ||
 			status == NETWORK_REGISTRATION_STATUS_DENIED ||
 			status == NETWORK_REGISTRATION_STATUS_UNKNOWN)) {
@@ -1574,6 +1602,44 @@ static void sim_spn_read_cb(int ok, int length, int record,
 	}
 }
 
+static void sim_csp_read_cb(int ok, int length, int record,
+				const unsigned char *data,
+				int record_length, void *user_data)
+{
+	struct ofono_netreg *netreg = user_data;
+	int i;
+
+	if (!ok)
+		return;
+
+	if (length < 18 || record_length < 18 || length < record_length)
+		return;
+
+	/*
+	 * According to CPHS 4.2, EFcsp is an array of two-byte service
+	 * entries, each consisting of a one byte service group
+	 * identifier followed by 8 bits; each bit is indicating
+	 * availability of a specific service or feature.
+	 *
+	 * The PLMN mode bit, if present, indicates whether manual
+	 * operator selection should be disabled or enabled. When
+	 * unset, the device is forced to automatic mode; when set,
+	 * manual selection is to be enabled. The latter is also the
+	 * default.
+	 */
+	for (i = 0; i < record_length / 2; i++) {
+
+		if (data[i * 2] != SIM_CSP_ENTRY_VALUE_ADDED_SERVICES)
+			continue;
+
+		if ((data[i * 2 + 1] & 0x80) != 0)
+			return;
+
+		set_registration_mode(netreg,
+					NETWORK_REGISTRATION_MODE_AUTO_ONLY);
+	}
+}
+
 int ofono_netreg_get_location(struct ofono_netreg *netreg)
 {
 	if (netreg == NULL)
@@ -1769,7 +1835,8 @@ static void netreg_load_settings(struct ofono_netreg *netreg)
 	mode = g_key_file_get_integer(netreg->settings, SETTINGS_GROUP,
 					"Mode", NULL);
 
-	if (mode >= 0 && mode <= 1)
+	if (mode == NETWORK_REGISTRATION_MODE_AUTO ||
+			mode == NETWORK_REGISTRATION_MODE_MANUAL)
 		netreg->mode = mode;
 
 	g_key_file_set_integer(netreg->settings, SETTINGS_GROUP,
@@ -1816,6 +1883,9 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
 		ofono_sim_read(netreg->sim, SIM_EFSPN_FILEID,
 				OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 				sim_spn_read_cb, netreg);
+		ofono_sim_read(netreg->sim, SIM_EF_CPHS_CSP_FILEID,
+				OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+				sim_csp_read_cb, netreg);
 	}
 
 	__ofono_atom_register(netreg->atom, netreg_unregister);
-- 
1.7.1


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

end of thread, other threads:[~2011-04-14 22:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-04 13:44 [PATCH 1/2 v2] netreg: Add CPHS CSP implementation Aki Niemi
2011-04-14 22:43 ` Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.