summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/event.h8
-rw-r--r--include/gsmd/sms.h1
-rw-r--r--src/gsmd/atcmd.c26
-rw-r--r--src/gsmd/sms_cb.c73
-rw-r--r--src/gsmd/unsolicited.c8
-rw-r--r--src/gsmd/usock.c21
-rw-r--r--src/util/event.c10
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;
}
personal git repositories of Harald Welte. Your mileage may vary