diff options
Diffstat (limited to 'src/gsmd')
-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 |
4 files changed, 90 insertions, 38 deletions
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: |