diff options
-rw-r--r-- | include/gsmd/event.h | 8 | ||||
-rw-r--r-- | include/gsmd/sms.h | 1 | ||||
-rw-r--r-- | src/gsmd/atcmd.c | 26 | ||||
-rw-r--r-- | src/gsmd/sms_cb.c | 73 | ||||
-rw-r--r-- | src/gsmd/unsolicited.c | 8 | ||||
-rw-r--r-- | src/gsmd/usock.c | 21 | ||||
-rw-r--r-- | src/util/event.c | 10 |
7 files changed, 103 insertions, 44 deletions
diff --git a/include/gsmd/event.h b/include/gsmd/event.h index 395c488..829b0fa 100644 --- a/include/gsmd/event.h +++ b/include/gsmd/event.h @@ -53,8 +53,14 @@ enum gsmd_call_type { __NUM_GSMD_CALL }; +/* Chapter 7.2 */ enum gsmd_netreg_state { - GSMD_NETREG_NONE = 0, + GSMD_NETREG_UNREG = 0, + GSMD_NETREG_REG_HOME, + GSMD_NETREG_UNREG_BUSY, + GSMD_NETREG_DENIED, + GSMD_NETREG_UNKNOWN, + GSMD_NETREG_REG_ROAMING, __NUM_GSMD_NETREG }; diff --git a/include/gsmd/sms.h b/include/gsmd/sms.h index f4def25..b48ce5d 100644 --- a/include/gsmd/sms.h +++ b/include/gsmd/sms.h @@ -6,6 +6,7 @@ #include <gsmd/gsmd.h> int sms_cb_init(struct gsmd *gsmd); +int sms_cb_network_init(struct gsmd *gsmd); #define MAX_PDU_SIZE 180 int sms_pdu_make_smssubmit(char *dest, const struct gsmd_sms_submit *src); diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index 506f7b8..9d45588 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -197,6 +197,7 @@ static int ml_parse(const char *buf, int len, void *ctx) static char mlbuf[MLPARSE_BUF_SIZE]; int rc = 0; static int mlbuf_len; + static int mlunsolicited = 0; int cme_error = 0; DEBUGP("buf=`%s'(%d)\n", buf, len); @@ -272,6 +273,16 @@ static int ml_parse(const char *buf, int len, void *ctx) if (colon > buf+len) colon = NULL; rc = unsolicited_parse(g, buf, len, colon); + if (rc == -EAGAIN) { + /* The parser wants one more line of + * input. Wait for the next line, concatenate + * and resumbit to unsolicited_parse(). */ + DEBUGP("Multiline unsolicited code\n"); + mlbuf_len = len; + memcpy(mlbuf, buf, len); + mlunsolicited = 1; + return 0; + } /* if unsolicited parser didn't handle this 'reply', then we * need to continue and try harder and see what it is */ if (rc != -ENOENT) { @@ -356,6 +367,21 @@ static int ml_parse(const char *buf, int len, void *ctx) len = sizeof(mlbuf) - mlbuf_len; memcpy(mlbuf + mlbuf_len, buf, len); mlbuf_len += len; + + if (mlunsolicited) { + rc = unsolicited_parse(g, mlbuf, mlbuf_len, + strchr(mlbuf, ':') + 1); + if (rc == -EAGAIN) { + /* The parser wants one more line of + * input. Wait for the next line, concatenate + * and resumbit to unsolicited_parse(). */ + DEBUGP("Multiline unsolicited code\n"); + return 0; + } + mlunsolicited = 0; + mlbuf_len = 0; + return rc; + } return 0; final_cb: diff --git a/src/gsmd/sms_cb.c b/src/gsmd/sms_cb.c index 9aed070..1ae337e 100644 --- a/src/gsmd/sms_cb.c +++ b/src/gsmd/sms_cb.c @@ -498,7 +498,7 @@ static int cmt_parse(char *buf, int len, const char *param, struct gsmd *gsmd) len = strtoul(comma + 1, &cr, 10); if (cr[0] != '\n') { talloc_free(ucmd); - return -EINVAL; + return -EAGAIN; } cr ++; @@ -567,8 +567,10 @@ static int cbm_parse(char *buf, int len, const char *param, struct gsmd *gsmd) msg = (struct gsmd_sms_list *) aux->data; len = strtoul(param, &cr, 10); - if (cr[0] != '\n') - return -EINVAL; + if (cr[0] != '\n') { + talloc_free(ucmd); + return -EAGAIN; + } cr ++; for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) { @@ -631,8 +633,10 @@ static int cds_parse(char *buf, int len, const char *param, struct gsmd *gsmd) msg = (struct gsmd_sms_list *) aux->data; len = strtoul(param, &cr, 10); - if (cr[0] != '\n') - return -EINVAL; + if (cr[0] != '\n') { + talloc_free(ucmd); + return -EAGAIN; + } cr ++; for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) { @@ -671,37 +675,6 @@ int sms_cb_init(struct gsmd *gsmd) unsolicited_register_array(gsm0705_unsolicit, ARRAY_SIZE(gsm0705_unsolicit)); - atcmd = atcmd_fill("AT+CSMS=0", 9 + 1, NULL, gsmd, 0); - if (!atcmd) - return -ENOMEM; - atcmd_submit(gsmd, atcmd); - - /* - * Set the New Message Indications properties to values that are - * likely supported. We will get a: - * +CMTI on a new incoming SMS, - * +CBM on a new incoming CB, - * +CDS on an SMS status report. - * - * FIXME: ask for supported +CNMI values first. - */ - atcmd = atcmd_fill("AT+CNMI=2,1,2,1,0", 17 + 1, NULL, gsmd, 0); - if (!atcmd) - return -ENOMEM; - atcmd_submit(gsmd, atcmd); - - /* Store into ME/TA and notify */ - atcmd = atcmd_fill("AT+CSBS=1", 9 + 1, NULL, gsmd, 0); - if (!atcmd) - return -ENOMEM; - atcmd_submit(gsmd, atcmd); - - /* Store into ME/TA and notify */ - atcmd = atcmd_fill("AT+CSDS=2", 9 + 1, NULL, gsmd, 0); - if (!atcmd) - return -ENOMEM; - atcmd_submit(gsmd, atcmd); - /* If text mode, set the encoding */ if (gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13 + 1, NULL, gsmd, 0); @@ -721,3 +694,31 @@ int sms_cb_init(struct gsmd *gsmd) return atcmd_submit(gsmd, atcmd); } + +/* Called everytime the phone registers to the network and we want to start + * receiving messages. */ +int sms_cb_network_init(struct gsmd *gsmd) +{ + int ret = 0; + + ret |= gsmd_simplecmd(gsmd, "AT+CSMS=0"); + + /* + * Set the New Message Indications properties to values that are + * likely supported. We will get a: + * +CMTI on a new incoming SMS, + * +CBM on a new incoming CB, + * +CDS on an SMS status report. + * + * FIXME: ask for supported +CNMI values first. + */ + ret |= gsmd_simplecmd(gsmd, "AT+CNMI=2,1,2,1,0"); + + /* Store into ME/TA and notify */ + ret |= gsmd_simplecmd(gsmd, "AT+CSBS=1"); + + /* Store into ME/TA and notify */ + ret |= gsmd_simplecmd(gsmd, "AT+CSDS=2"); + + return ret; +} diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index 82a4f17..0cef5ca 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -163,6 +163,12 @@ static int creg_parse(char *buf, int len, const char *param, } else aux->u.netreg.lac = aux->u.netreg.ci = 0; + /* Intialise things that depend on network registration */ + if (aux->u.netreg.state == GSMD_NETREG_REG_HOME || + aux->u.netreg.state == GSMD_NETREG_REG_ROAMING) { + sms_cb_network_init(gsmd); + } + return usock_evt_send(gsmd, ucmd, GSMD_EVT_NETREG); } @@ -378,6 +384,8 @@ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) colon = NULL; rc = i->parse(buf, len, colon, g); + if (rc == -EAGAIN) + return rc; if (rc < 0) gsmd_log(GSMD_ERROR, "error %d during parsing of " "an unsolicied response `%s'\n", diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 08563cf..5224f92 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -239,6 +239,24 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, return atcmd_submit(gu->gsmd, cmd); } +static int phone_powerup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + + /* We need to verify if there is some error */ + switch (cmd->ret) { + case 0: + gsmd_log(GSMD_DEBUG, "Radio powered-up\n"); + gu->gsmd->dev_state.on = 1; + break; + default: + /* something went wrong */ + gsmd_log(GSMD_DEBUG, "Radio power-up failed\n"); + break; + } + return 0; +} + static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) { @@ -247,8 +265,7 @@ static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, switch (gph->msg_subtype) { case GSMD_PHONE_POWERUP: cmd = atcmd_fill("AT+CFUN=1", 9+1, - &null_cmd_cb, gu, 0); - gu->gsmd->dev_state.on = 1; + &phone_powerup_cb, gu, 0); break; case GSMD_PHONE_POWERDOWN: diff --git a/src/util/event.c b/src/util/event.c index 209d34b..f98c7da 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -60,19 +60,19 @@ static int netreg_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxda printf("EVENT: Netreg "); switch (aux->u.netreg.state) { - case 0: + case GSMD_NETREG_UNREG: printf("not searching for network "); break; - case 1: + case GSMD_NETREG_REG_HOME: printf("registered (home network) "); break; - case 2: + case GSMD_NETREG_UNREG_BUSY: printf("searching for network "); break; - case 3: + case GSMD_NETREG_DENIED: printf("registration denied "); break; - case 5: + case GSMD_NETREG_REG_ROAMING: printf("registered (roaming) "); break; } |