r3557 - in trunk/src/target/gsm: include/gsmd include/libgsmd src/gsmd src/libgsmd src/util

tick at sita.openmoko.org tick at sita.openmoko.org
Tue Dec 4 08:22:32 CET 2007


Author: tick
Date: 2007-12-04 08:22:17 +0100 (Tue, 04 Dec 2007)
New Revision: 3557

Modified:
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/include/libgsmd/voicecall.h
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c
   trunk/src/target/gsm/src/util/shell.c
Log:
gsmd: Provide Current Call status (sean_chiang)


Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h	2007-12-04 07:17:13 UTC (rev 3556)
+++ trunk/src/target/gsm/include/gsmd/usock.h	2007-12-04 07:22:17 UTC (rev 3557)
@@ -41,8 +41,46 @@
 	GSMD_VOICECALL_DTMF	= 4,
 	GSMD_VOICECALL_VOL_SET	= 5,
 	GSMD_VOICECALL_VOL_GET	= 6,
+	GSMD_VOICECALL_GET_STAT	= 7,
 };
 
+
+/*  call direction from 3GPP TS 07.07, Clause 7.17 */
+enum gsmd_call_dire {
+	GSMD_CALL_DIRE_MO	= 0,
+	GSMD_CALL_DIRE_MT	= 1,
+};
+
+/*  call state from 3GPP TS 07.07, Clause 7.17 */
+enum gsmd_call_stat {
+	GSMD_CALL_STAT_ACTIVE	= 0,
+	GSMD_CALL_STAT_HELD	= 1,
+	GSMD_CALL_STAT_DIALING	= 2,
+	GSMD_CALL_STAT_ALERTING	= 3,
+	GSMD_CALL_STAT_INCOMING	= 4,
+	GSMD_CALL_STAT_WAITING	= 5,
+};
+
+/*  call mode from 3GPP TS 07.07, Clause 7.17 */
+enum gsmd_call_mode {
+	GSMD_CALL_MODE_VOICE		= 0,
+	GSMD_CALL_MODE_DATA		= 1,
+	GSMD_CALL_MODE_FAX		= 2,
+	GSMD_CALL_MODE_VOICE_DATA	= 3,
+	GSMD_CALL_MODE_VOICE_DATA_ALT	= 4,
+	GSMD_CALL_MODE_VOICE_FAX_ALT	= 5,	
+	GSMD_CALL_MODE_DATA_VOICE	= 6,
+	GSMD_CALL_MODE_DATA_VOICE_ALT	= 7,
+	GSMD_CALL_MODE_FAX_VOICE_ALT	= 8,
+	GSMD_CALL_MODE_UNKNOWN		= 9,
+};
+
+/*  multiparty(conference) from 3GPP TS 07.07, Clause 7.17 */
+enum gsmd_call_mpty {
+	GSMD_CALL_MPTY_NO	= 0,
+	GSMD_CALL_MPTY_YES	= 1,
+};
+
 /* Handset / MT related commands */
 enum gsmd_msg_phone_type {
 	GSMD_PHONE_VOLUME	= 1,
@@ -308,6 +346,19 @@
 	struct gsmd_addr addr;
 } __attribute__ ((packed));
 
+/* call status from 3GPP TS 07.07 clause 07.17 */
+struct gsmd_call_status {
+	int8_t idx;
+	u_int8_t dir;
+	u_int8_t stat;
+	u_int8_t mode;
+	u_int8_t mpty;
+	char number[GSMD_ADDR_MAXLEN+1];	
+	u_int8_t type;
+	char alpha[8+1];
+	int is_last;	
+} __attribute__ ((packed));
+
 #define GSMD_PIN_MAXLEN		8
 struct gsmd_pin {
 	enum gsmd_pin_type type;

Modified: trunk/src/target/gsm/include/libgsmd/voicecall.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/voicecall.h	2007-12-04 07:17:13 UTC (rev 3556)
+++ trunk/src/target/gsm/include/libgsmd/voicecall.h	2007-12-04 07:22:17 UTC (rev 3557)
@@ -18,4 +18,7 @@
 /* Send DTMF character during voice call */
 extern int lgsm_voice_dtmf(struct lgsm_handle *lh, char dtmf_char);
 
+/* Get call status */
+extern int lgsm_voice_get_status(struct lgsm_handle *lh); 
+
 #endif

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c	2007-12-04 07:17:13 UTC (rev 3556)
+++ trunk/src/target/gsm/src/gsmd/usock.c	2007-12-04 07:22:17 UTC (rev 3557)
@@ -114,6 +114,92 @@
 	gu->subscriptions = *evtmask;
 }
 
+static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
+{
+	struct gsmd_user *gu = ctx;
+	struct gsmd_call_status gcs;
+	struct gsm_extrsp *er;
+
+	DEBUGP("resp: %s\n", resp);
+
+	er = extrsp_parse(cmd, resp);
+
+	if ( !er )
+		return -ENOMEM;
+
+	gcs.is_last = (cmd->ret == 0 || cmd->ret == 4)? 1:0;
+	
+	if ( !strncmp(resp, "OK", 2) ) {
+		/* No existing call */
+		gcs.idx = 0;
+	}
+	else if ( !strncmp(resp, "+CME", 4) ) {
+		/* +CME ERROR: <err> */
+		DEBUGP("+CME error\n");
+		gcs.idx = 0 - atoi(strpbrk(resp, "0123456789"));
+	}
+	else if ( er->num_tokens == 7 &&
+			er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[3].type == GSMD_ECMD_RTT_NUMERIC && 
+			er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[5].type == GSMD_ECMD_RTT_STRING &&
+			er->tokens[6].type == GSMD_ECMD_RTT_NUMERIC ) {
+		/*
+		 * [+CLCC: <id1>,<dir>,<stat>,<mode>,<mpty>[,
+		 * <number>,<type>[,<alpha>]]
+		 * [<CR><LF>+CLCC: <id2>,<dir>,<stat>,<mode>,<mpty>[,
+		 * <number>,<type>[,<alpha>]]
+		 * [...]]]
+		 */
+
+		gcs.idx = er->tokens[0].u.numeric;
+		gcs.dir = er->tokens[1].u.numeric;
+		gcs.stat = er->tokens[2].u.numeric;
+		gcs.mode = er->tokens[3].u.numeric;
+		gcs.mpty = er->tokens[4].u.numeric;
+		strcpy(gcs.number, er->tokens[5].u.string);
+		gcs.type = er->tokens[6].u.numeric;
+	}
+	else if ( er->num_tokens == 8 &&
+			er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[3].type == GSMD_ECMD_RTT_NUMERIC && 
+			er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[5].type == GSMD_ECMD_RTT_STRING &&
+			er->tokens[6].type == GSMD_ECMD_RTT_NUMERIC &&
+			er->tokens[7].type == GSMD_ECMD_RTT_STRING ) {
+
+		/*
+		 * [+CLCC: <id1>,<dir>,<stat>,<mode>,<mpty>[,
+		 * <number>,<type>[,<alpha>]]
+		 * [<CR><LF>+CLCC: <id2>,<dir>,<stat>,<mode>,<mpty>[,
+		 * <number>,<type>[,<alpha>]]
+		 * [...]]]
+		 */
+
+		gcs.idx = er->tokens[0].u.numeric;
+		gcs.dir = er->tokens[1].u.numeric;
+		gcs.stat = er->tokens[2].u.numeric;
+		gcs.mode = er->tokens[3].u.numeric;
+		gcs.mpty = er->tokens[4].u.numeric;
+		strcpy(gcs.number, er->tokens[5].u.string);
+		gcs.type = er->tokens[6].u.numeric;
+		strncpy(gcs.alpha, er->tokens[7].u.string, 8+1);
+	}
+	else {
+		DEBUGP("Invalid Input : Parse error\n");
+		return -EINVAL;
+	}
+	
+	talloc_free(er);
+
+	return gsmd_ucmd_submit(gu, GSMD_MSG_VOICECALL, GSMD_VOICECALL_GET_STAT,
+			cmd->id, sizeof(gcs), &gcs);
+}
+
 static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
 				int len)
 {
@@ -121,7 +207,7 @@
 	struct gsmd_addr *ga;
 	struct gsmd_dtmf *gd;
 	int atcmd_len;
-
+		
 	switch (gph->msg_subtype) {
 	case GSMD_VOICECALL_DIAL:
 		if (len < sizeof(*gph) + sizeof(*ga))
@@ -168,6 +254,12 @@
 
 		sprintf(cmd->buf, "AT+VTS=%c;", gd->dtmf[0]);
 		break;
+	case GSMD_VOICECALL_GET_STAT:
+		cmd = atcmd_fill("AT+CLCC", 7+1, &voicecall_get_stat_cb, 
+				 gu, gph->id, NULL);
+		if (!cmd)
+			return -ENOMEM;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -731,7 +823,7 @@
 		gp.index = 0;
 	}
 	else if ( !strncmp(resp, "+CME", 4) ) {
-		DEBUGP("== +CME error\n");
+		DEBUGP("+CME error\n");
 		/* +CME ERROR: 21 */
 		gp.index = 0 - atoi(strpbrk(resp, "0123456789"));
 	}
@@ -782,7 +874,7 @@
 		gps.pb.index = 0;
 	}
 	else if ( !strncmp(resp, "+CME", 4) ) {
-		DEBUGP("== +CME error\n");
+		DEBUGP("+CME error\n");
 		/* +CME ERROR: 21 */
 		gps.pb.index = 0 - atoi(strpbrk(resp, "0123456789"));
 	}

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c	2007-12-04 07:17:13 UTC (rev 3556)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c	2007-12-04 07:22:17 UTC (rev 3557)
@@ -95,3 +95,8 @@
 	/* FIXME: we need to pass along the parameter */
 	return lgsm_send_simple(lh, GSMD_MSG_VOICECALL, GSMD_VOICECALL_VOL_SET);
 }
+
+int lgsm_voice_get_status(struct lgsm_handle *lh)
+{
+	return lgsm_send_simple(lh, GSMD_MSG_VOICECALL, GSMD_VOICECALL_GET_STAT);
+}

Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c	2007-12-04 07:17:13 UTC (rev 3556)
+++ trunk/src/target/gsm/src/util/shell.c	2007-12-04 07:22:17 UTC (rev 3557)
@@ -387,6 +387,37 @@
 	return 0;
 }
 
+static int call_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+	struct gsmd_call_status *gcs;
+
+	switch (gmh->msg_subtype) {
+	case GSMD_VOICECALL_GET_STAT:
+		gcs = (struct  gsmd_call_status*) ((char *)gmh + sizeof(*gmh));
+		
+		if (gcs->idx > 0)
+			printf("%d, %d, %d, %d, %d, %s, %d\n",
+					gcs->idx, gcs->dir,
+					gcs->stat, gcs->mode,
+					gcs->mpty, gcs->number,
+					gcs->type);
+		else if (gcs->idx < 0)
+			/* If index < 0, error happens */
+			printf("+CME ERROR %d\n", (0-(gcs->idx)));
+		else
+			/* No existing call */
+			printf("Doesn't exist\n");
+
+		if (gcs->is_last)
+			pending_responses --;
+		break;
+	default:
+		return -EINVAL;
+	}
+	pending_responses --;
+	return 0;
+}
+
 static const struct msghandler_s {
 	int type;
 	lgsm_msg_handler *fn;
@@ -397,6 +428,7 @@
 	{ GSMD_MSG_NETWORK,	net_msghandler },
 	{ GSMD_MSG_PHONE,	phone_msghandler },
 	{ GSMD_MSG_PIN,		pin_msghandler },
+	{ GSMD_MSG_VOICECALL,	call_msghandler },
 
 	{ 0, 0 }
 };
@@ -437,6 +469,7 @@
 		"\tsc\tSMS Show Service Centre\n"
 		"\tsC\tSMS Set Service Centre (sC=number)\n"
 		"\tim\tGet imsi\n"
+		"\tcs\tGet Call status\n"
 		"\tq\tQuit\n"
 		);
 }
@@ -724,6 +757,10 @@
 				printf("Modem Power Off\n");
 				lgsm_modem_power(lgsmh, 0);
 				pending_responses ++;
+			} else if ( !strncmp(buf, "cs", 2)) {
+				printf("List current call status\n");
+				lgsm_voice_get_status(lgsmh);
+				pending_responses ++;
 			} else {
 				printf("Unknown command `%s'\n", buf);
 			}





More information about the commitlog mailing list