r2026 - trunk/src/host/qemu-neo1973/gnokiigsm
andrew at sita.openmoko.org
andrew at sita.openmoko.org
Fri May 18 22:52:49 CEST 2007
Author: andrew
Date: 2007-05-18 22:52:47 +0200 (Fri, 18 May 2007)
New Revision: 2026
Modified:
trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c
trunk/src/host/qemu-neo1973/gnokiigsm/data.h
Log:
Add more dummy AT+C commands in GSM modem.
Modified: trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c 2007-05-18 20:48:49 UTC (rev 2025)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c 2007-05-18 20:52:47 UTC (rev 2026)
@@ -331,7 +331,253 @@
}
}
+struct gn_atem_op {
+ char *op;
+ int writable;
+ enum {
+ gn_var_string, /* "A","B","C" */
+ gn_var_bool, /* 0,1 */
+ gn_var_numbers, /* (1-5),(9-20) */
+ } type;
+ char *default_val;
+ char *string_val[];
+};
+bool gn_atem_parse_option(char *buf, struct gn_atem_op *op, char *val)
+{
+ char buffer[MAX_LINE_LENGTH], **strval;
+ int len;
+ if (buf[0] == 0 || (buf[0] == '?' && buf[1] == 0)) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s: %s\r\n", op->op, val);
+ gn_atem_string_out(buffer);
+ return (false);
+ }
+
+ if (*buf++ != '=')
+ return (true);
+ if (!strcasecmp(buf, "?")) {
+ len = gsprintf(buffer, MAX_LINE_LENGTH, "%s: ", op->op);
+ switch (op->type) {
+ case gn_var_string:
+ strval = op->string_val;
+ len += gsprintf(buffer + len,
+ MAX_LINE_LENGTH - len,
+ "\"%s\"", *strval++);
+ while (*strval)
+ len += gsprintf(buffer + len,
+ MAX_LINE_LENGTH - len,
+ ",\"%s\"", *strval++);
+ break;
+
+ case gn_var_numbers:
+ strval = op->string_val;
+ len += gsprintf(buffer + len,
+ MAX_LINE_LENGTH - len,
+ "\"%s\"", *strval++);
+ /* TODO */
+ break;
+
+ case gn_var_bool:
+ len += gsprintf(buffer + len,
+ MAX_LINE_LENGTH - len, "(0,1)");
+ break;
+ }
+ gsprintf(buffer + len, MAX_LINE_LENGTH - len, "\r\n");
+ return (false);
+ }
+
+ if (!op->writable)
+ return (true);
+
+ switch (op->type) {
+ case gn_var_string:
+ for (strval = op->string_val; *strval; strval++)
+ if (!strcasecmp(buf, *strval)) {
+ gsprintf(val, MAX_LINE_LENGTH,
+ "\"%s\"", *strval);
+ return (false);
+ }
+ break;
+
+ case gn_var_bool:
+ if (!strcasecmp(buf, "0") || !strcasecmp(buf, "1")) {
+ strncpy(val, buf, MAX_LINE_LENGTH);
+ return (false);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (true);
+}
+
+static struct gn_atem_op gn_atem_op_cscs = {
+ .op = "+CSCS",
+ .writable = 1,
+ .type = gn_var_string,
+ .default_val = "IRA",
+ .string_val = {
+ "GSM", "IRA", "PCCP437", "PCDN", "8859-1", "HEX", "UCS2", 0,
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cmux = {
+ .op = "+CMUX",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "1,0,1,10,1,0,2,1,1",
+ .string_val = {
+ "(1),(0),(1-5),(10-100),(1-255),(0-100),(2-255),(1-255),(1-7)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_ws46 = {
+ .op = "+WS46",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "12",
+ .string_val = {
+ "(12)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_csta = {
+ .op = "+CSTA",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "129",
+ .string_val = {
+ "(129,145)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cmod = {
+ .op = "+CMOD",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0",
+ .string_val = {
+ "(0-3)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cbst = {
+ .op = "+CBST",
+ .writable = 0,
+ .type = gn_var_numbers,
+ .default_val = "7,0,1",
+ .string_val = {
+ "(0-7,12,14,65,66,68,70,71,75),(0),(0-3)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_crlp = {
+ .op = "+CRLP",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "61,61,48,6",
+ .string_val = {
+ "(0-61),(0-61),(39-255),(1-255)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cr = {
+ .op = "+CR",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0",
+ .string_val = {
+ "(0,1)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_crc = {
+ .op = "+CRC",
+ .writable = 1,
+ .type = gn_var_bool,
+ .default_val = "0",
+};
+
+static struct gn_atem_op gn_atem_op_csns = {
+ .op = "+CSNS",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0",
+ .string_val = {
+ "(0-7)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_creg = {
+ .op = "+CREG",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0,0",
+ .string_val = {
+ "(0-2)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cops = {
+ .op = "+COPS",
+ .writable = 1,
+ .type = gn_var_bool,
+ .default_val = "0",
+};
+
+static struct gn_atem_op gn_atem_op_cpas = {
+ .op = "+CPAS",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0",
+ .string_val = {
+ "(0-5)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cfun = {
+ .op = "+CFUN",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "1",
+ .string_val = {
+ "(0,1,4),(0)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cbc = {
+ .op = "+CBC",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0,0",
+ .string_val = {
+ "(0-3),(0-100)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_band = {
+ .op = "%BAND",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0",
+ .string_val = {
+ "(0-1),(1-31)",
+ },
+};
+
+static struct gn_atem_op gn_atem_op_cssn = {
+ .op = "CSSN",
+ .writable = 1,
+ .type = gn_var_numbers,
+ .default_val = "0,0",
+ .string_val = {
+ "(0,1),(0,1)",
+ },
+};
+
+
/* Parser for standard AT commands. cmd_buffer must be null terminated. */
void gn_atem_at_parse(char *cmd_buffer)
{
@@ -558,6 +804,14 @@
/* + is the precursor to another set of commands */
case '+':
buf++;
+
+ /* AT+WS46 is wireless network selection */
+ if (strncasecmp(buf, "WS46", 3) == 0) {
+ if (!gn_atem_parse_option(buf + 4,
+ &gn_atem_op_ws46, data.ws46))
+ break;
+ }
+
switch (toupper(*buf)) {
case 'C':
buf++;
@@ -593,6 +847,17 @@
}
break;
+ /* % is the precursor to another set of commands */
+ case '%':
+ buf++;
+ if (strncasecmp(buf, "BAND", 3) == 0) {
+ if (!gn_atem_parse_option(buf + 4,
+ &gn_atem_op_band, data.band))
+ break;
+ }
+ gn_atem_modem_result(MR_ERROR);
+ return;
+
default:
gn_atem_modem_result(MR_ERROR);
return;
@@ -1011,6 +1276,105 @@
return (false);
}
+ /* AT+CSCS is character set selection */
+ if (strncasecmp(*buf, "SCS", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cscs, data.cscs);
+ }
+
+ /* AT+CIMI is international mobile subscriber identity */
+ if (strcasecmp(*buf, "IMI") == 0) {
+ gn_atem_string_out("QEMU_IMSI\r\n");
+ return (false);
+ }
+
+ /* AT+CMUX is multiplexing mode */
+ if (strncasecmp(*buf, "MUX", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cmux, data.cmux);
+ }
+
+ /* AT+CSTA is address type selection */
+ if (strncasecmp(*buf, "STA", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_csta, data.csta);
+ }
+
+ /* AT+CMOD is call mode */
+ if (strncasecmp(*buf, "MOD", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cmod, data.cmod);
+ }
+
+ /* AT+CBST is bearer service type */
+ if (strncasecmp(*buf, "BST", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cbst, data.cbst);
+ }
+
+ /* AT+CRLP is radio link protocol */
+ if (strncasecmp(*buf, "RLP", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_crlp, data.crlp);
+ }
+
+ /* AT+CR is reporting control */
+ if (strncasecmp(*buf, "R", 1) == 0) {
+ return gn_atem_parse_option(buf[0] + 1,
+ &gn_atem_op_cr, data.cr);
+ }
+
+ /* AT+CEER is extended error report */
+ if (strncasecmp(*buf, "EER", 3) == 0) {
+ gn_atem_string_out("+CEER: 0,0,5,16,normal call clearing\r\n");
+ return (false);
+ }
+
+ /* AT+CRC is cellular result codes */
+ if (strncasecmp(*buf, "RC", 2) == 0) {
+ return gn_atem_parse_option(buf[0] + 2,
+ &gn_atem_op_crc, data.crc);
+ }
+
+ /* AT+CSNS is single numbering scheme */
+ if (strncasecmp(*buf, "SNS", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_csns, data.csns);
+ }
+
+ /* AT+CREG is network registration */
+ if (strncasecmp(*buf, "REG", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_creg, data.creg);
+ }
+
+ /* AT+COPS is PLMN selection */
+ if (strncasecmp(*buf, "OPS", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cops, data.cops);
+ }
+
+ /* AT+CPAS is phone activity status */
+ if (strncasecmp(*buf, "PAS", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cpas, data.cpas);
+ }
+
+ /* AT+CFUN is phone functionality */
+ if (strncasecmp(*buf, "FUN", 3) == 0) {
+ return gn_atem_parse_option(buf[0] + 3,
+ &gn_atem_op_cfun, data.cfun);
+ }
+
+ if (strncasecmp(*buf, "BC", 2) == 0) {
+ return gn_atem_parse_option(buf[0] + 2,
+ &gn_atem_op_cbc, data.cbc);
+ }
+ if (strncasecmp(*buf, "CSSN", 2) == 0) {
+ return gn_atem_parse_option(buf[0] + 2,
+ &gn_atem_op_cssn, data.cssn);
+ }
+
return (true);
}
Modified: trunk/src/host/qemu-neo1973/gnokiigsm/data.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/data.h 2007-05-18 20:48:49 UTC (rev 2025)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/data.h 2007-05-18 20:52:47 UTC (rev 2026)
@@ -45,7 +45,7 @@
} gn_phone_model;
/* For all 'AT+XXXX=?' commands */
-typedef char gn_choice[10];
+typedef char gn_choice[256];
/* This is a generic holder for high level information - eg a gn_bmp */
typedef struct {
@@ -115,6 +115,8 @@
gn_choice cbst;
gn_choice crlp;
gn_choice cr;
+ gn_choice crc;
+ gn_choice cmod;
gn_choice csns;
gn_choice creg;
gn_choice cpas;
More information about the commitlog
mailing list