summaryrefslogtreecommitdiff
path: root/src/gsmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsmd')
-rw-r--r--src/gsmd/gsmd.h2
-rw-r--r--src/gsmd/unsolicited.c13
-rw-r--r--src/gsmd/usock.c54
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] = {
personal git repositories of Harald Welte. Your mileage may vary