r2725 - in trunk/src/target/gsm: include/gsmd include/libgsmd src/gsmd src/libgsmd

laforge at sita.openmoko.org laforge at sita.openmoko.org
Fri Aug 17 10:32:21 CEST 2007


Author: laforge
Date: 2007-08-17 10:32:14 +0200 (Fri, 17 Aug 2007)
New Revision: 2725

Modified:
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/include/libgsmd/misc.h
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
Log:
From: Andrzej Zaborowski <balrog at zabor.org>
Date: Tue, 31 Jul 2007 22:26:36 +0200
Subject: [PATCH] Operations on the preferred operators list.

This makes use of the AT+CPOL variants to add / delete / list entries in the
preferred operators list on the SIM.  There's some inconsistency, similarly as
with operator selection, in that we return operator names in long
alphanumeric format but we take only operators in numeric format as
parameters.  Either the client will have to convert between the formats or
we should always use for example the long alphanumeric format, or maybe
do something else.


Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h	2007-08-17 08:31:49 UTC (rev 2724)
+++ trunk/src/target/gsm/include/gsmd/usock.h	2007-08-17 08:32:14 UTC (rev 2725)
@@ -70,6 +70,11 @@
 	GSMD_NETWORK_OPER_LIST	= 6,
 	GSMD_NETWORK_CIND_GET	= 7,
 	GSMD_NETWORK_DEREGISTER	= 8,
+	GSMD_NETWORK_GET_NUMBER = 9,
+	GSMD_NETWORK_PREF_LIST  = 10,
+	GSMD_NETWORK_PREF_DEL   = 11,
+	GSMD_NETWORK_PREF_ADD   = 12,
+	GSMD_NETWORK_PREF_SPACE = 13,
 };
 
 enum gsmd_msg_sms {
@@ -458,6 +463,12 @@
 	gsmd_oper_numeric opname_num;
 };
 
+struct gsmd_msg_prefoper {
+	int index;
+	int is_last;
+	char opname_longalpha[16];
+};
+
 struct gsmd_msg_hdr {
 	u_int8_t version;
 	u_int8_t msg_type;

Modified: trunk/src/target/gsm/include/libgsmd/misc.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/misc.h	2007-08-17 08:31:49 UTC (rev 2724)
+++ trunk/src/target/gsm/include/libgsmd/misc.h	2007-08-17 08:32:14 UTC (rev 2725)
@@ -62,6 +62,12 @@
 extern int lgsm_get_netreg_state(struct lgsm_handle *lh,
 				 enum lgsm_netreg_state *state);
 
+/* Preferred operator list management */
+extern int lgsm_prefoper_list(struct lgsm_handle *lh);
+extern int lgsm_prefoper_delete(struct lgsm_handle *lh, int index);
+extern int lgsm_prefoper_add(struct lgsm_handle *lh, gsmd_oper_numeric oper);
+extern int lgsm_prefoper_get_space(struct lgsm_handle *lh);
+
 /* CLIP, CLIR, COLP, Call Forwarding, Call Waiting, Call Deflecting */
 /* TBD */
 

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c	2007-08-17 08:31:49 UTC (rev 2724)
+++ trunk/src/target/gsm/src/gsmd/usock.c	2007-08-17 08:32:14 UTC (rev 2725)
@@ -423,6 +423,10 @@
 {
 	int len = 0;
 	int stat, n;
+	char opname_longalpha[16 + 1];
+	char opname_shortalpha[8 + 1];
+	char opname_num[6 + 1];
+
 	if (strncmp(str, "+COPS: ", 7))
 		goto final;
 	str += 7;
@@ -434,12 +438,18 @@
 						"(%i,\"%16[^\"]\","
 						"\"%8[^\"]\",\"%6[0-9]\")%n",
 						&stat,
-						out->opname_longalpha,
-						out->opname_shortalpha,
-						out->opname_num,
+						opname_longalpha,
+						opname_shortalpha,
+						opname_num,
 						&n) < 4)
 				goto final;
 			out->stat = stat;
+			memcpy(out->opname_longalpha, opname_longalpha,
+					sizeof(out->opname_longalpha));
+			memcpy(out->opname_shortalpha, opname_shortalpha,
+					sizeof(out->opname_shortalpha));
+			memcpy(out->opname_num, opname_num,
+					sizeof(out->opname_num));
 		} else
 			if (sscanf(str,
 						"(%*i,\"%*[^\"]\","
@@ -480,6 +490,64 @@
 	return 0;
 }
 
+static int network_pref_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+	struct gsmd_user *gu = (struct gsmd_user *) ctx;
+	struct gsmd_ucmd *ucmd;
+	struct gsmd_msg_prefoper *entry;
+	int index;
+	char opname[17];
+
+	if (cmd->ret && cmd->ret != -255)
+		return 0;
+
+	if (sscanf(resp, "+CPOL: %i,0,\"%16[^\"]\"", &index, opname) < 2)
+		return -EINVAL;
+
+	ucmd = gsmd_ucmd_fill(sizeof(*entry), GSMD_MSG_NETWORK,
+			GSMD_NETWORK_PREF_LIST, cmd->id);
+	if (!ucmd)
+		return -ENOMEM;
+
+	entry = (struct gsmd_msg_prefoper *) ucmd->buf;
+	entry->index = index;
+	entry->is_last = (cmd->ret == 0);
+	memcpy(entry->opname_longalpha, opname,
+			sizeof(entry->opname_longalpha));
+
+	usock_cmd_enqueue(ucmd, gu);
+
+	return 0;
+}
+
+static int network_pref_num_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+	struct gsmd_user *gu = (struct gsmd_user *) ctx;
+	struct gsmd_ucmd *ucmd;
+	int min_index, max_index, size;
+
+	if (cmd->ret)
+		return 0;
+
+	/* This is not a full general case, theoretically the range string
+	 * can include commas and more dashes, but we have no full parser for
+	 * ranges yet.  */
+	if (sscanf(resp, "+CPOL: (%i-%i)", &min_index, &max_index) < 2)
+		return -EINVAL;
+
+	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_NETWORK,
+			GSMD_NETWORK_PREF_SPACE, cmd->id);
+	if (!ucmd)
+		return -ENOMEM;
+
+	size = max_index - min_index + 1;
+	memcpy(ucmd->buf, &size, sizeof(int));
+
+	usock_cmd_enqueue(ucmd, gu);
+
+	return 0;
+}
+
 static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
 			     int len)
 {
@@ -519,6 +587,26 @@
 	case GSMD_NETWORK_OPER_LIST:
 		cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0);
 		break;
+	case GSMD_NETWORK_PREF_LIST:
+		/* Set long alphanumeric format */
+		atcmd_submit(gu->gsmd, atcmd_fill("AT+CPOL=,0", 10 + 1,
+					&null_cmd_cb, gu, 0));
+		cmd = atcmd_fill("AT+CPOL?", 8 + 1,
+				&network_pref_opers_cb, gu, 0);
+		break;
+	case GSMD_NETWORK_PREF_DEL:
+		cmdlen = sprintf(buffer, "AT+CPOL=%i", *(int *) gph->data);
+		cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0);
+		break;
+	case GSMD_NETWORK_PREF_ADD:
+		cmdlen = sprintf(buffer, "AT+CPOL=,2,\"%.*s\"",
+				sizeof(gsmd_oper_numeric), oper);
+		cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0);
+		break;
+	case GSMD_NETWORK_PREF_SPACE:
+		cmd = atcmd_fill("AT+CPOL=?", 9 + 1,
+				&network_pref_num_cb, gu, 0);
+		break;
 	default:
 		return -EINVAL;
 	}

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_network.c	2007-08-17 08:31:49 UTC (rev 2724)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_network.c	2007-08-17 08:32:14 UTC (rev 2725)
@@ -78,3 +78,53 @@
 {
 	return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET);
 }
+
+int lgsm_prefoper_list(struct lgsm_handle *lh)
+{
+	return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_LIST);
+}
+
+int lgsm_prefoper_delete(struct lgsm_handle *lh, int index)
+{
+	struct gsmd_msg_hdr *gmh;
+
+	gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_DEL,
+			sizeof(int));
+	if (!gmh)
+		return -ENOMEM;
+
+	memcpy(gmh->data, &index, sizeof(int));
+
+	if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+		lgsm_gmh_free(gmh);
+		return -EIO;
+	}
+
+	lgsm_gmh_free(gmh);
+	return 0;
+}
+
+int lgsm_prefoper_add(struct lgsm_handle *lh, gsmd_oper_numeric oper)
+{
+	struct gsmd_msg_hdr *gmh;
+
+	gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_ADD,
+			sizeof(gsmd_oper_numeric));
+	if (!gmh)
+		return -ENOMEM;
+
+	memcpy(gmh->data, oper, sizeof(gsmd_oper_numeric));
+
+	if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+		lgsm_gmh_free(gmh);
+		return -EIO;
+	}
+
+	lgsm_gmh_free(gmh);
+	return 0;
+}
+
+int lgsm_prefoper_get_space(struct lgsm_handle *lh)
+{
+	return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_SPACE);
+}





More information about the commitlog mailing list