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] = {  | 
