All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Read own numbers from EFmsisdn instead of AT+CNUM.
@ 2009-06-18  3:44 Andrzej Zaborowski
  2009-06-18  8:32 ` Denis Kenzior
  0 siblings, 1 reply; 2+ messages in thread
From: Andrzej Zaborowski @ 2009-06-18  3:44 UTC (permalink / raw)
  To: ofono

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

This was found to be more portable.  On the other hand this doesn't give
the service type or speed information per number.

Depends on "[PATCH] Change sim_ops plugin interface to allow acces to linear fixed files."
---
 drivers/atmodem/sim.c |    1 +
 src/driver.h          |   22 +++++++++++
 src/sim.c             |   99 +++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 107 insertions(+), 15 deletions(-)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 66e951e..165bb65 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -430,6 +430,7 @@ static void at_cnum_cb(gboolean ok, GAtResult *result, gpointer user_data)
 		numbers[count].speed = -1;
 		numbers[count].service = -1;
 		numbers[count].itc = -1;
+		numbers[count].npi = -1;
 
 		g_at_result_iter_skip_next(&iter);
 		g_at_result_iter_next_number(&iter, &numbers[count].service);
diff --git a/src/driver.h b/src/driver.h
index 36b9a08..793414e 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -96,6 +96,28 @@ struct ofono_own_number {
 	int speed;
 	int service;
 	int itc;
+	int npi;
+};
+
+/* 24.008 Section 10.5.4.7 */
+enum ofono_number_type {
+	OFONO_NUMBER_TYPE_UNKNOWN = 0,
+	OFONO_NUMBER_TYPE_INTERNATIONAL = 1,
+	OFONO_NUMBER_TYPE_NATIONAL = 2,
+	OFONO_NUMBER_TYPE_NETWORK_SPECIFIC = 3,
+	OFONO_NUMBER_TYPE_DEDICATED_ACCESS = 4,
+	OFONO_NUMBER_TYPE_RESERVED = 7
+};
+
+enum ofono_numbering_plan {
+	OFONO_NUMBERING_PLAN_UNKNOWN = 0,
+	OFONO_NUMBERING_PLAN_ISDN = 1,
+	OFONO_NUMBERING_PLAN_DATA = 3,
+	OFONO_NUMBERING_PLAN_TELEX = 4,
+	OFONO_NUMBERING_PLAN_NATIONAL = 8,
+	OFONO_NUMBERING_PLAN_PRIVATE = 9,
+	OFONO_NUMBERING_PLAN_RESERVED_CTS = 11,
+	OFONO_NUMBERING_PLAN_RESERVED = 15
 };
 
 /* 51.011 Section 9.3 */
diff --git a/src/sim.c b/src/sim.c
index 9c85292..e25b210 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -51,6 +51,10 @@ struct sim_manager_data {
 	int dcbyte;
 
 	GSList *update_spn_notify;
+
+	int own_numbers_num;
+	int own_numbers_size;
+	int own_numbers_current;
 };
 
 static char **own_numbers_by_type(GSList *own_numbers, int type)
@@ -181,6 +185,7 @@ static GDBusMethodTable sim_manager_methods[] = {
 static GDBusSignalTable sim_manager_signals[] = { { } };
 
 enum sim_fileids {
+	SIM_EFMSISDN_FILEID = 0x6f40,
 	SIM_EFSPN_FILEID = 0x6f46,
 };
 
@@ -285,31 +290,94 @@ static gboolean sim_retrieve_imsi(void *user_data)
 	return FALSE;
 }
 
-static void sim_own_number_cb(const struct ofono_error *error, int num,
-			const struct ofono_own_number *own, void *data)
+static void sim_msisdn_read_cb(const struct ofono_error *error,
+		const unsigned char *sdata, int length, void *data)
 {
 	struct ofono_modem *modem = data;
 	struct sim_manager_data *sim = modem->sim_manager;
-	int i;
+	struct ofono_own_number *ph;
+	int number_len;
+	int ton_npi;
+	int i, digit;
 
 	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
-		return;
+		goto skip;
 
-	for (i = 0; i < num; i++) {
-		struct ofono_own_number *ph;
+	if (length < sim->own_numbers_size)
+		goto skip;
 
-		if (own[i].phone_number.number[0] == '\0')
-			continue;
+	/* Skip Alpha-Identifier field */
+	sdata += sim->own_numbers_size - 14;
+
+	number_len = *sdata++;
+	ton_npi = *sdata++;
+
+	if (number_len > 11 || ton_npi == 0xff)
+		goto skip;
+
+	ph = g_new(struct ofono_own_number, 1);
+
+	ph->speed = -1;
+	ph->service = -1;
+	ph->itc = -1;
+	ph->npi = (ton_npi >> 0) & 15;
+	ph->phone_number.type = (ton_npi >> 4) & 7;
 
-		ph = g_new(struct ofono_own_number, 1);
+	if (number_len > 10)
+		number_len = 10;
+	number_len *= 2;
+	if (number_len > OFONO_MAX_PHONE_NUMBER_LENGTH)
+		number_len = OFONO_MAX_PHONE_NUMBER_LENGTH;
 
-		memcpy(ph, &own[i], sizeof(struct ofono_own_number));
+	for (i = 0; i < number_len; i ++) {
+		digit = *sdata;
+		/* BCD coded */
+		if (i & 1) {
+			sdata ++;
+			digit >>= 4;
+		}
+		digit &= 0xf;
 
-		sim->own_numbers = g_slist_prepend(sim->own_numbers, ph);
+		if (digit > 9)
+			break;
+
+		ph->phone_number.number[i] = '0' + digit;
 	}
+	memset(&ph->phone_number.number[i], 0,
+			OFONO_MAX_PHONE_NUMBER_LENGTH - i);
+
+	sim->own_numbers = g_slist_prepend(sim->own_numbers, ph);
+
+skip:
+	sim->own_numbers_current ++;
+	if (sim->own_numbers_current < sim->own_numbers_num)
+		sim->ops->read_file_linear(modem, SIM_EFMSISDN_FILEID,
+				sim->own_numbers_current,
+				sim->own_numbers_size,
+				sim_msisdn_read_cb, modem);
+	else
+		/* All records retrieved */
+		if (sim->own_numbers)
+			sim->own_numbers = g_slist_reverse(sim->own_numbers);
+}
+
+static void sim_msisdn_info_cb(const struct ofono_error *error,
+		int length, enum ofono_simfile_struct structure,
+		int record_length, void *data)
+{
+	struct ofono_modem *modem = data;
+	struct sim_manager_data *sim = modem->sim_manager;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length < 14 ||
+			record_length < 14 ||
+			structure != OFONO_SIM_FILE_FIXED)
+		return;
 
-	if (sim->own_numbers)
-		sim->own_numbers = g_slist_reverse(sim->own_numbers);
+	sim->own_numbers_current = 0;
+	sim->own_numbers_size = record_length;
+	sim->own_numbers_num = length / record_length;
+	sim->ops->read_file_linear(modem, SIM_EFMSISDN_FILEID, 0,
+			record_length, sim_msisdn_read_cb, modem);
 }
 
 static gboolean sim_retrieve_own_number(void *user_data)
@@ -317,7 +385,8 @@ static gboolean sim_retrieve_own_number(void *user_data)
 	struct ofono_modem *modem = user_data;
 	struct sim_manager_data *sim = modem->sim_manager;
 
-	sim->ops->read_own_numbers(modem, sim_own_number_cb, modem);
+	sim->ops->read_file_info(modem, SIM_EFMSISDN_FILEID,
+			sim_msisdn_info_cb, modem);
 
 	return FALSE;
 }
@@ -349,7 +418,7 @@ static void initialize_sim_manager(struct ofono_modem *modem)
 	if (modem->sim_manager->ops->read_imsi)
 		g_timeout_add(0, sim_retrieve_imsi, modem);
 
-	if (modem->sim_manager->ops->read_own_numbers)
+	if (modem->sim_manager->ops->read_file_linear)
 		g_timeout_add(0, sim_retrieve_own_number, modem);
 }
 
-- 
1.6.0


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

* Re: [PATCH] Read own numbers from EFmsisdn instead of AT+CNUM.
  2009-06-18  3:44 [PATCH] Read own numbers from EFmsisdn instead of AT+CNUM Andrzej Zaborowski
@ 2009-06-18  8:32 ` Denis Kenzior
  0 siblings, 0 replies; 2+ messages in thread
From: Denis Kenzior @ 2009-06-18  8:32 UTC (permalink / raw)
  To: ofono

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

Hi,

On Wednesday 17 June 2009 22:44:56 Andrzej Zaborowski wrote:
> This was found to be more portable.  On the other hand this doesn't give
> the service type or speed information per number.
>

Patch has been applied.  The service type and speed information is mostly 
fudged by the modems anyway.  This can still be obtained by parsing the EFccp2 
record if one is provided in the EFmsisdn.

Regards,
-Denis

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

end of thread, other threads:[~2009-06-18  8:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-18  3:44 [PATCH] Read own numbers from EFmsisdn instead of AT+CNUM Andrzej Zaborowski
2009-06-18  8:32 ` 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.