diff options
Diffstat (limited to 'src/gsmd')
-rw-r--r-- | src/gsmd/gsmd.h | 2 | ||||
-rw-r--r-- | src/gsmd/unsolicited.c | 13 | ||||
-rw-r--r-- | src/gsmd/usock.c | 54 |
3 files changed, 53 insertions, 16 deletions
diff --git a/src/gsmd/gsmd.h b/src/gsmd/gsmd.h index 9c3a484..c67e15e 100644 --- a/src/gsmd/gsmd.h +++ b/src/gsmd/gsmd.h @@ -76,7 +76,7 @@ extern int gsmdlog_init(const char *path); /* write a message to the daemons' logfile */ void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...); /* macro for logging including filename and line number */ -#define gsmd_log(level, format, args...) \ +#define gsmd_log(level, format, args ...) \ __gsmd_log(level, __FILE__, __LINE__, __FUNCTION__, format, ## args) #define DEBUGP(x, args ...) gsmd_log(GSMD_DEBUG, x, ## args) diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index 5242042..e97f478 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -217,6 +217,7 @@ static int clip_parse(char *buf, int len, const char *param, if (!comma) return -EINVAL; + if (comma - param > GSMD_ADDR_MAXLEN) return -EINVAL; @@ -308,7 +309,7 @@ static const struct gsmd_unsolicit gsm0707_unsolicit[] = { /* called by midlevel parser if a response seems unsolicited */ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) { - int i; + int i, rc; for (i = 0; i < ARRAY_SIZE(gsm0707_unsolicit); i++) { const char *colon; @@ -316,14 +317,20 @@ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) strlen(gsm0707_unsolicit[i].prefix))) continue; - colon = strchr(buf, ':') + 1; + colon = strchr(buf, ':') + 2; if (colon > buf+len) colon = NULL; - return gsm0707_unsolicit[i].parse(buf, len, colon, g); + rc = gsm0707_unsolicit[i].parse(buf, len, colon, g); + if (rc < 0) + gsmd_log(GSMD_ERROR, "error %d during parse of " + "unsolicied response `%s'\n", rc, buf); + return rc; } /* FIXME: call vendor-specific unsolicited code parser */ + gsmd_log(GSMD_NOTICE, "no parser for unsolicited response `%s'\n", buf); + return -ENOENT; } diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index b774f74..93e9751 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -30,13 +30,15 @@ void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu) static int usock_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd = malloc(sizeof(*ucmd)+cmd->buflen); + int rlen = strlen(resp)+1; + struct gsmd_ucmd *ucmd = malloc(sizeof(*ucmd)+rlen); DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu); if (!ucmd) return -ENOMEM; + /* FIXME: pass error values back somehow */ ucmd->hdr.version = GSMD_PROTO_VERSION; ucmd->hdr.msg_type = GSMD_MSG_PASSTHROUGH; ucmd->hdr.msg_subtype = GSMD_PASSTHROUGH_RESP; @@ -70,49 +72,77 @@ static int usock_rcv_event(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int l if (len < sizeof(*gph) + sizeof(u_int32_t)) return -EINVAL; - if (gph->msg_subtype != GSMD_EVENT_SUBSCRIPTIONS) + if (gph->msg_subtype != GSMD_EVT_SUBSCRIPTIONS) return -EINVAL; gu->subscriptions = *evtmask; } -static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) +static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, + int len) { - struct gsmd_atcmd *cmd; + struct gsmd_atcmd *cmd = NULL; + struct gsmd_addr *ga; switch (gph->msg_subtype) { case GSMD_VOICECALL_DIAL: - /* FIXME */ + if (len < sizeof(*gph) + sizeof(*ga)) + return -EINVAL; + ga = (struct gsmd_addr *) (void *)gph + sizeof(*gph); + ga->number[GSMD_ADDR_MAXLEN] = '\0'; + cmd = atcmd_fill("ATD", 5 + strlen(ga->number), + &usock_cmd_cb, gu, gph->id); + sprintf(cmd->buf, "ATD%s;", ga->number); + /* FIXME: number type! */ break; case GSMD_VOICECALL_HANGUP: cmd = atcmd_fill("ATH0", 5, &usock_cmd_cb, gu, gph->id); break; + case GSMD_VOICECALL_ANSWER: + cmd = atcmd_fill("ATA", 4, &usock_cmd_cb, gu, gph->id); + break; default: return -EINVAL; } - return 0; + if (cmd) + return atcmd_submit(gu->gsmd, cmd); + else + return 0; } -#define GSMD_PIN_MAXLEN 16 +static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + gsmd_log(GSMD_DEBUG, "null cmd cb\n"); + return 0; +} -static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) +static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, + int len) { u_int8_t *pin = (u_int8_t *)gph + sizeof(*gph); int pin_len = len - sizeof(*gph); - char pinbuf[GSMD_PIN_MAXLEN + 11]; /* `AT+CPIN=""\0' */ - - snprintf(pinbuf, sizeof(pinbuf), "AT+CPIN=\"%s\"", pin); + struct gsmd_atcmd *cmd; switch (gph->msg_subtype) { case GSMD_PIN_INPUT: /* FIXME */ break; default: + gsmd_log(GSMD_ERROR, "unknown pin type %u\n", + gph->msg_subtype); return -EINVAL; } - return 0; + cmd = atcmd_fill("AT+CPIN=\"", 9+1+1+strlen(pin), + &null_cmd_cb, gu, 0); + if (!cmd) + return -ENOMEM; + + strcat(cmd->buf, pin); + strcat(cmd->buf, "\""); + + return atcmd_submit(gu->gsmd, cmd); } static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = { |