diff options
| -rw-r--r-- | include/gsmd/usock.h | 4 | ||||
| -rw-r--r-- | include/libgsmd/libgsmd.h | 2 | ||||
| -rw-r--r-- | src/gsmd/sms_cb.c | 112 | ||||
| -rw-r--r-- | src/gsmd/usock.c | 422 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd.c | 2 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd_event.c | 5 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd_passthrough.c | 17 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd_pin.c | 4 | ||||
| -rw-r--r-- | src/util/atcmd.c | 1 | 
9 files changed, 181 insertions, 388 deletions
| diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h index 370553e..a4e5e41 100644 --- a/include/gsmd/usock.h +++ b/include/gsmd/usock.h @@ -620,8 +620,8 @@ extern int usock_init(struct gsmd *g);  extern void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu);  extern struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int16_t len);  extern int usock_evt_send(struct gsmd *gsmd, struct gsmd_ucmd *ucmd, u_int32_t evt); -extern struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type, -		u_int8_t msg_subtype, u_int16_t id); +extern int gsmd_ucmd_submit(struct gsmd_user *gu, u_int8_t msg_type, +		u_int8_t msg_subtype, u_int16_t id, int len, const void *data);  #endif /* __GSMD__ */ diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h index fc56890..f260ae2 100644 --- a/include/libgsmd/libgsmd.h +++ b/include/libgsmd/libgsmd.h @@ -66,5 +66,7 @@ extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions);  extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);  extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);  extern int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len); +extern int lgsm_blocking_wait_packet(struct lgsm_handle *lh, u_int16_t id, +		struct gsmd_msg_hdr *gmh, int rlen);  #endif diff --git a/src/gsmd/sms_cb.c b/src/gsmd/sms_cb.c index d640596..ea622fc 100644 --- a/src/gsmd/sms_cb.c +++ b/src/gsmd/sms_cb.c @@ -64,13 +64,12 @@ static inline int parse_memtype(char *memtype)  static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	struct gsmd_sms_list msg;  	int i, idx, stat, len, cr;  	u_int8_t pdu[SMS_MAX_PDU_SIZE];  	if (cmd->ret && cmd->ret != -255) -		return 0; +		return 0;	/* TODO: Send a response */  	/* FIXME: TEXT mode */  	if ( @@ -78,9 +77,9 @@ static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  				&idx, &stat, &len, &cr) < 3 &&  			sscanf(resp, "+CMGL: %i,%i,\"%*[^\"]\",%i\n%n",  				&idx, &stat, &len, &cr) < 3) -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	if (len > 164) -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	msg.index = idx;  	msg.stat = stat; @@ -89,37 +88,29 @@ static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  			i < SMS_MAX_PDU_SIZE; i ++) {  		if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {  			gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); -			return -EINVAL; +			return -EINVAL;	/* TODO: Send a response */  		}  		cr += 2;  	}  	if (sms_pdu_to_msg(&msg, pdu, len, i)) {  		gsmd_log(GSMD_DEBUG, "malformed PDU\n"); -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	} -	ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, -			GSMD_SMS_LIST, cmd->id); -	if (!ucmd) -		return -ENOMEM; -	memcpy(ucmd->buf, &msg, sizeof(msg)); - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_SMS, GSMD_SMS_LIST, +			cmd->id, sizeof(msg), &msg);  }  static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	struct gsmd_sms_list msg;  	int i, stat, len, cr;  	u_int8_t pdu[SMS_MAX_PDU_SIZE];  	const char *colon;  	if (cmd->ret) -		return 0; +		return 0;	/* TODO: Send a response */  	/* FIXME: TEXT mode */  	if ( @@ -127,9 +118,9 @@ static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  				&stat, &len, &cr) < 2 &&                          sscanf(resp, "+CMGR: %i,\"%*[^\"]\",%i\n%n",  				&stat, &len, &cr) < 2) -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	if (len > 164) -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	msg.index = 0;  	colon = strchr(cmd->buf, '='); @@ -143,7 +134,7 @@ static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  			i < SMS_MAX_PDU_SIZE; i ++) {  		if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {  			gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); -			return -EINVAL; +			return -EINVAL;	/* TODO: Send a response */  		}  		cr += 2;  	} @@ -152,80 +143,44 @@ static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  		return -EINVAL;  	} -	ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, -			GSMD_SMS_READ, cmd->id); -	if (!ucmd) -		return -ENOMEM; -	memcpy(ucmd->buf, &msg, sizeof(msg)); - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_SMS, GSMD_SMS_READ, +			cmd->id, sizeof(msg), &msg);  }  static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	int msgref;  	if (cmd->ret == 0 || cmd->ret == -255) {  		if (sscanf(resp, "+CMGS: %i", &msgref) < 1) -			return -EINVAL; +			msgref = -EINVAL;  	} else  		msgref = -cmd->ret; -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, -			GSMD_SMS_SEND, cmd->id); -	if (!ucmd) -		return -ENOMEM; -	*(int *) ucmd->buf = msgref; - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_SEND, +			cmd->id, sizeof(msgref), &msgref);  }  static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	int result;  	if (cmd->ret == 0) {  		if (sscanf(resp, "+CMGW: %i", &result) < 1) -			return -EINVAL; +			result = -EINVAL;  	} else  		result = -cmd->ret; -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, -			GSMD_SMS_WRITE, cmd->id); -	if (!ucmd) -		return -ENOMEM; -	*(int *) ucmd->buf = result; - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_WRITE, +			cmd->id, sizeof(result), &result);  }  static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -	int *result; +	int result = cmd->ret; -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, -			GSMD_SMS_DELETE, cmd->id); -	if (!ucmd) -		return -ENOMEM; - -	result = (int *) ucmd->buf; -	*result = cmd->ret; - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_DELETE, +			cmd->id, sizeof(result), &result);  }  static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) @@ -253,7 +208,7 @@ static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  				buf[2], &gss->mem[2].used, &gss->mem[2].total)  			< 9) {  		talloc_free(ucmd); -		return -EINVAL; +		return -EINVAL;	/* TODO: Send a response */  	}  	gss->mem[0].memtype = parse_memtype(buf[0]); @@ -267,24 +222,15 @@ static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  static int usock_get_smsc_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -	struct gsmd_addr *ga; +	struct gsmd_addr ga; -	ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_addr), GSMD_MSG_SMS, -			GSMD_SMS_GET_SERVICE_CENTRE, cmd->id); -	if (!ucmd) -		return -ENOMEM; - -	ga = (struct gsmd_addr *) ucmd->buf;  	if (sscanf(resp, "+CSCA: \"%31[^\"]\",%hhi", -				ga->number, &ga->type) < 2) { -		talloc_free(ucmd); -		return -EINVAL; -	} +				ga.number, &ga.type) < 2) +		return -EINVAL;	/* TODO: Send a response */ -	usock_cmd_enqueue(ucmd, gu); -	return 0; +	return gsmd_ucmd_submit(ctx, +			GSMD_MSG_SMS, GSMD_SMS_GET_SERVICE_CENTRE, +			cmd->id, sizeof(ga), &ga);  }  static const char *gsmd_cmgl_stat[] = { diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 73bb3c3..5c5ec13 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -20,6 +20,7 @@   *   */  +#define _GNU_SOURCE  #include <stdlib.h>  #include <stdio.h>  #include <unistd.h> @@ -186,18 +187,13 @@ static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  static int pin_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PIN, -			GSMD_PIN_INPUT, 0); - -	if (!ucmd) -		return -ENOMEM; +	int ret = cmd->ret;  	/* Pass a GSM07.07 CME code directly, don't issue a new PIN  	 * request because the client waits for a response to her  	 * PIN submission rather than an event.  */ -	((int *) ucmd->buf)[0] = cmd->ret; -	usock_cmd_enqueue(ucmd, gu); -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_PIN, GSMD_PIN_INPUT, +			cmd->id, sizeof(ret), &ret);  }  static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  @@ -227,13 +223,13 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  	if (!cmd)  		return -ENOMEM; -	strcat(cmd->buf, gp->pin); +	strncat(cmd->buf, gp->pin, sizeof(gp->pin));  	switch (gp->type) {  	case GSMD_PIN_SIM_PUK:  	case GSMD_PIN_SIM_PUK2:  		strcat(cmd->buf, "\",\""); -		strcat(cmd->buf, gp->newpin); +		strncat(cmd->buf, gp->newpin, sizeof(gp->newpin));  		break;  	default:  		break; @@ -247,10 +243,10 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  static int phone_powerup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; +	int ret = cmd->ret;  	/* We need to verify if there is some error */ -	switch (cmd->ret) { +	switch (ret) {  	case 0:  		gsmd_log(GSMD_DEBUG, "Radio powered-up\n");  		gu->gsmd->dev_state.on = 1; @@ -261,47 +257,23 @@ static int phone_powerup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  		break;  	} -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONE, -			GSMD_PHONE_POWERUP, 0); -	if (ucmd) { -		((int *) ucmd->buf)[0] = cmd->ret; -		usock_cmd_enqueue(ucmd, gu); -		return 0; -	} -	return -ENOMEM; +	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_POWERUP, +			cmd->id, sizeof(ret), &ret);  }  static int phone_powerdown_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONE, -			GSMD_PHONE_POWERDOWN, 0); - -	if (ucmd) { -		((int *) ucmd->buf)[0] = cmd->ret; -		usock_cmd_enqueue(ucmd, gu); -		return 0; -	} -	return -ENOMEM; +	int ret = cmd->ret; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_POWERDOWN, +			cmd->id, sizeof(ret), &ret);  }  static int get_imsi_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -  	DEBUGP("resp: %s\n", resp); -	ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONE, -				  GSMD_PHONE_GET_IMSI, 0); -	if (!ucmd) -		return -ENOMEM; - -	strcpy(ucmd->buf, resp); - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_GET_IMSI, +			cmd->id, strlen(resp) + 1, resp);  }  static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  @@ -400,56 +372,46 @@ out_free_einval:  	return -EINVAL;  } -struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type, -		u_int8_t msg_subtype, u_int16_t id) +int gsmd_ucmd_submit(struct gsmd_user *gu, u_int8_t msg_type, +		u_int8_t msg_subtype, u_int16_t id, int len, const void *data)  { -	struct gsmd_ucmd *ucmd; +	struct gsmd_ucmd *ucmd = ucmd_alloc(len); -	ucmd = ucmd_alloc(len);  	if (!ucmd) -		return NULL; +		return -ENOMEM;  	ucmd->hdr.version = GSMD_PROTO_VERSION;  	ucmd->hdr.msg_type = msg_type;  	ucmd->hdr.msg_subtype = msg_subtype;  	ucmd->hdr.len = len;  	ucmd->hdr.id = id; +	memcpy(ucmd->buf, data, len); -	return ucmd; +	usock_cmd_enqueue(ucmd, gu); +	return 0;  }  static int network_sigq_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_signal_quality *gsq; -	struct gsmd_ucmd *ucmd; +	struct gsmd_signal_quality gsq;  	char *comma; -	 -	ucmd = gsmd_ucmd_fill(sizeof(*gsq), GSMD_MSG_NETWORK, -			      GSMD_NETWORK_SIGQ_GET, 0); -	if (!ucmd) -		return -ENOMEM; -	 -	gsq = (struct gsmd_signal_quality *) ucmd->buf; -	gsq->rssi = atoi(resp + 6); + +	gsq.rssi = atoi(resp + 6);  	comma = strchr(resp, ','); -	if (!comma) { -		talloc_free(ucmd); +	if (!comma ++)  		return -EIO; -	} -	gsq->ber = atoi(comma+1); +	gsq.ber = atoi(comma); -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET, +			cmd->id, sizeof(gsq), &gsq);  }  static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	const char *end, *opname; -	int format, s; +	int format, s, ret; +	char *buf;  	/* Format: <mode>[,<format>,<oper>] */  	/* In case we're not registered, return an empty string.  */ @@ -470,17 +432,11 @@ static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  			return -EINVAL;  	} -	ucmd = gsmd_ucmd_fill(end - opname + 1, GSMD_MSG_NETWORK, -			GSMD_NETWORK_OPER_GET, 0); -	if (!ucmd) -		return -ENOMEM; - -	memcpy(ucmd->buf, opname, end - opname); -	ucmd->buf[end - opname] = '\0'; - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	buf = strndup(opname, end - opname); +	ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET, +			cmd->id, end - opname + 1, buf); +	free(buf); +	return ret;  }  static int network_opers_parse(const char *str, struct gsmd_msg_oper out[]) @@ -538,102 +494,77 @@ final:  static int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -	int len; +	struct gsmd_msg_oper *buf; +	int len, ret;  	len = network_opers_parse(resp, 0); - -	ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_msg_oper) * (len + 1), -			GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST, 0); -	if (!ucmd) +	buf = talloc_size(__gu_ctx, sizeof(struct gsmd_msg_oper) * (len + 1)); +	if (!buf)  		return -ENOMEM; +	network_opers_parse(resp, buf); -	network_opers_parse(resp, (struct gsmd_msg_oper *) ucmd->buf); -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST, +			cmd->id, sizeof(*buf) * (len + 1), buf); +	talloc_free(buf); +	return ret;  }  static int network_pref_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = (struct gsmd_user *) ctx; -	struct gsmd_ucmd *ucmd; -	struct gsmd_msg_prefoper *entry; +	struct gsmd_msg_prefoper entry;  	int index;  	char opname[17];  	if (cmd->ret && cmd->ret != -255) -		return 0; +		return 0;	/* TODO: Send a response */  	if (sscanf(resp, "+CPOL: %i,0,\"%16[^\"]\"", &index, opname) < 2) -		return -EINVAL; - -	ucmd = gsmd_ucmd_fill(sizeof(*entry), GSMD_MSG_NETWORK, -			GSMD_NETWORK_PREF_LIST, cmd->id); -	if (!ucmd) -		return -ENOMEM; - -	entry = (struct gsmd_msg_prefoper *) ucmd->buf; -	entry->index = index; -	entry->is_last = (cmd->ret == 0); -	memcpy(entry->opname_longalpha, opname, -			sizeof(entry->opname_longalpha)); +		return -EINVAL;	/* TODO: Send a response */ -	usock_cmd_enqueue(ucmd, gu); +	entry.index = index; +	entry.is_last = (cmd->ret == 0); +	memcpy(entry.opname_longalpha, opname, sizeof(entry.opname_longalpha)); -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_LIST, +			cmd->id, sizeof(entry), &entry);  }  static int network_pref_num_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = (struct gsmd_user *) ctx; -	struct gsmd_ucmd *ucmd;  	int min_index, max_index, size;  	if (cmd->ret) -		return 0; +		return 0;	/* TODO: Send a response */  	/* This is not a full general case, theoretically the range string  	 * can include commas and more dashes, but we have no full parser for  	 * ranges yet.  */  	if (sscanf(resp, "+CPOL: (%i-%i)", &min_index, &max_index) < 2) -		return -EINVAL; - -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_NETWORK, -			GSMD_NETWORK_PREF_SPACE, cmd->id); -	if (!ucmd) -		return -ENOMEM; - +		return -EINVAL;	/* TODO: Send a response */  	size = max_index - min_index + 1; -	memcpy(ucmd->buf, &size, sizeof(int)); - -	usock_cmd_enqueue(ucmd, gu); -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_SPACE, +			cmd->id, sizeof(size), &size);  }  static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = (struct gsmd_user *) ctx; -	struct gsmd_ucmd *ucmd;  	struct gsmd_own_number *num;  	int len, ret, type;  	char dummy;  	if (cmd->ret && cmd->ret != -255) -		return 0; +		return 0;	/* TODO: Send a response */  	if (sscanf(resp, "+CNUM: \"%*[^\"]\"%c%n", &dummy, &len) > 0)  		len -= strlen("+CNUM: \"\",");  	else  		len = 0; -	ucmd = gsmd_ucmd_fill(sizeof(*num) + len + 1, -			GSMD_MSG_NETWORK, GSMD_NETWORK_GET_NUMBER, cmd->id); -	if (!ucmd) -		return -ENOMEM; - -	num = (struct gsmd_own_number *) ucmd->buf; +	num = talloc_size(__gu_ctx, sizeof(*num) + len + 1);  	if (len)  		ret = sscanf(resp, "+CNUM: \"%[^\"]\",\"%32[^\"]\",%i,%*i,%i,",  				num->name, num->addr.number, @@ -643,8 +574,8 @@ static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  				num->addr.number,  				&type, &num->service);  	if (ret < 2) { -		talloc_free(ucmd); -		return -EINVAL; +		talloc_free(num); +		return -EINVAL;	/* TODO: Send a response */  	}  	if (ret < 3)  		num->service = GSMD_SERVICE_UNKNOWN; @@ -652,9 +583,10 @@ static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  	num->addr.type = type;  	num->is_last = (cmd->ret == 0); -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_GET_NUMBER, +			cmd->id, sizeof(*num) + len + 1, num); +	talloc_free(num); +	return ret;  }  static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  @@ -732,10 +664,9 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,  static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	struct gsmd_phonebooks *gps;  	char *fcomma, *lcomma, *ptr1, *ptr2 = NULL; -	int *num; +	int num;  	DEBUGP("resp: %s\n", resp); @@ -743,15 +674,7 @@ static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  	 * [+CPBF: <index1>,<number>,<type>,<text>[[...]  	 * <CR><LF>+CPBF: <index2>,<unmber>,<type>,<text>]]  	 */ -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_FIND, 0); -	if (!ucmd) -		return -ENOMEM;	 - -	num = (int*) ucmd->buf; - -	*num = 0; - +	num = 0;  	ptr1 = strtok(resp, "\n");  	while (ptr1) { @@ -774,68 +697,55 @@ static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  		llist_add_tail(&gps->list, &gu->pb_find_list); -		(*num)++; +		num++;  		ptr1 = strtok(NULL, "\n");  	} -	usock_cmd_enqueue(ucmd, gu);  	talloc_free(__pb_ctx); -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_FIND, +			cmd->id, sizeof(num), &num);  }  static int phonebook_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_phonebook *gp; -	struct gsmd_ucmd *ucmd; +	struct gsmd_phonebook gp;  	char *fcomma, *lcomma;  	char *ptr;  	DEBUGP("resp: %s\n", resp); -	ucmd = gsmd_ucmd_fill(sizeof(*gp), GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_READ, 0);	 - -	if (!ucmd) -		return -ENOMEM; - -	gp = (struct gsmd_phonebook *) ucmd->buf; -	 -	  	/* check the record is empty or not */  	if (!strncmp(resp, "+CPBR", 5)) {  		ptr = strchr(resp, ' '); -		gp->index = atoi(ptr + 1); +		gp.index = atoi(ptr + 1);  		fcomma = strchr(resp, '"');  		lcomma = strchr(fcomma + 1, '"'); -		strncpy(gp->numb, fcomma + 1, (lcomma - fcomma - 1)); -		gp->numb[(lcomma-fcomma) - 1] = '\0'; -		 -		gp->type = atoi(lcomma + 2); +		strncpy(gp.numb, fcomma + 1, (lcomma - fcomma - 1)); +		gp.numb[(lcomma-fcomma) - 1] = '\0'; + +		gp.type = atoi(lcomma + 2);  		ptr = strrchr(resp, ',');  		fcomma = ptr + 1;  		lcomma = strchr(fcomma + 1, '"'); -		strncpy(gp->text, fcomma + 1, (lcomma-fcomma - 1)); -		gp->text[(lcomma - fcomma) - 1] = '\0'; -	} -	else -		gp->index = 0; - -	usock_cmd_enqueue(ucmd, gu); +		strncpy(gp.text, fcomma + 1, (lcomma-fcomma - 1)); +		gp.text[(lcomma - fcomma) - 1] = '\0'; +	} else +		gp.index = 0; -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_READ, +			cmd->id, sizeof(gp), &gp);  }  static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  {  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd;  	struct gsmd_phonebooks *gps;  	char *fcomma, *lcomma, *ptr1, *ptr2 = NULL; -	int *num; +	int num;  	DEBUGP("resp: %s\n", resp); @@ -843,15 +753,7 @@ static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  	 * [+CPBR: <index1>,<number>,<type>,<text>[[...]  	 * <CR><LF>+CPBR: <index2>,<unmber>,<type>,<text>]]  	 */ -	ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_READRG, 0); -	if (!ucmd) -		return -ENOMEM;	 - -	num = (int*) ucmd->buf; - -	*num = 0; - +	num = 0;  	ptr1 = strtok(resp, "\n");  	while (ptr1) { @@ -874,52 +776,30 @@ static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  		llist_add_tail(&gps->list, &gu->pb_readrg_list); -		(*num)++; +		num++;  		ptr1 = strtok(NULL, "\n");  	} -	usock_cmd_enqueue(ucmd, gu);  	talloc_free(__pb_ctx); -	return 0; +	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_READRG, +			cmd->id, sizeof(num), &num);  }  static int phonebook_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -  	DEBUGP("resp: %s\n", resp); -	ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_WRITE, 0); -	if (!ucmd) -		return -ENOMEM; - -	strcpy(ucmd->buf, resp); - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_WRITE, +			cmd->id, strlen(resp) + 1, resp);  }  static int phonebook_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)  { -	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -  	DEBUGP("resp: %s\n", resp); -	ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_DELETE, 0); -	if (!ucmd) -		return -ENOMEM;	 - -	strcpy(ucmd->buf, resp); - -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_DELETE, +			cmd->id, strlen(resp) + 1, resp);  }  static int phonebook_get_support_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) @@ -927,43 +807,30 @@ static int phonebook_get_support_cb(struct gsmd_atcmd *cmd, void *ctx, char *res  	/* TODO: Need to handle command error */  	/* +CPBR: (1-100),44,16 */  	struct gsmd_user *gu = ctx; -	struct gsmd_phonebook_support *gps; -	struct gsmd_ucmd *ucmd; +	struct gsmd_phonebook_support gps;  	char *fcomma, *lcomma;  	char *dash;  	DEBUGP("resp: %s\n", resp); -	 -	ucmd = gsmd_ucmd_fill(sizeof(*gps), GSMD_MSG_PHONEBOOK, -			      GSMD_PHONEBOOK_GET_SUPPORT, 0); -	if (!ucmd) -		return -ENOMEM; -	gps = (struct gsmd_phonebook_support *) ucmd->buf; -		  	dash = strchr(resp, '-'); -	if (!dash) { -		talloc_free(ucmd); -		return -EIO; -	}	 -	gps->index = atoi(dash + 1); +	if (!dash) +		return -EIO;	/* TODO: Send a response */ +	gps.index = atoi(dash + 1);  	fcomma = strchr(resp, ','); -	if (!fcomma) { -		talloc_free(ucmd); -		return -EIO; -	} -	gps->nlength = atoi(fcomma+1); -	 +	if (!fcomma) +		return -EIO;	/* TODO: Send a response */ +	gps.nlength = atoi(fcomma+1); +  	lcomma = strrchr(resp, ','); -	if (!lcomma) { -		talloc_free(ucmd); -		return -EIO; -	}	 -	gps->tlength = atoi(lcomma+1);	 +	if (!lcomma) +		return -EIO;	/* TODO: Send a response */ +	gps.tlength = atoi(lcomma+1); -	usock_cmd_enqueue(ucmd, gu); -	return 0; +	return gsmd_ucmd_submit(gu, +			GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_GET_SUPPORT, +			cmd->id, sizeof(gps), &gps);  }  static int phonebook_list_storage_cb(struct gsmd_atcmd *cmd, @@ -971,8 +838,7 @@ static int phonebook_list_storage_cb(struct gsmd_atcmd *cmd,  {  	/* TODO; using link list ; need to handle command error */  	struct gsmd_user *gu = ctx; -	struct gsmd_ucmd *ucmd; -	struct gsmd_phonebook_storage *gps; +	struct gsmd_phonebook_storage gps;  	char *ptr;  	DEBUGP("resp: %s\n", resp); @@ -980,31 +846,22 @@ static int phonebook_list_storage_cb(struct gsmd_atcmd *cmd,  	/*  	 * +CPBS: (<storage>s)  	 */ - -	ucmd = gsmd_ucmd_fill(sizeof(*gps), -			GSMD_MSG_PHONEBOOK, -			GSMD_PHONEBOOK_LIST_STORAGE, 0); - -        if (!ucmd) -		return -ENOMEM; - -	gps = (struct gsmd_phonebook_storage *) ucmd->buf; -	gps->num = 0; +	gps.num = 0;  	if (!strncmp(resp, "+CPBS", 5)) {  		char* delim = "(,";  		ptr = strpbrk(resp, delim); -		while ( ptr ) { -			strncpy(gps->mem[gps->num].type, ptr+2, 2); -			gps->mem[gps->num].type[2] = '\0'; -			ptr = strpbrk(ptr+2, delim); -			gps->num++; +		while (ptr) { +			strncpy(gps.mem[gps.num].type, ptr + 2, 2); +			gps.mem[gps.num].type[2] = '\0'; +			ptr = strpbrk(ptr + 2, delim); +			gps.num++;  		}  	} -	usock_cmd_enqueue(ucmd, gu); - -	return 0; +	return gsmd_ucmd_submit(gu, +			GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_LIST_STORAGE, +			cmd->id, sizeof(gps), &gps);  } @@ -1012,13 +869,12 @@ static int usock_rcv_phonebook(struct gsmd_user *gu,  		struct gsmd_msg_hdr *gph,int len)  {	  	struct gsmd_atcmd *cmd = NULL; -	struct gsmd_ucmd *ucmd = NULL;  	struct gsmd_phonebook_readrg *gpr;  	struct gsmd_phonebook *gp;  	struct gsmd_phonebook_find *gpf;  	struct gsmd_phonebooks *cur, *cur2;  	int *index, *num; -	int atcmd_len, i; +	int atcmd_len, i, ret;  	char *storage;  	char buf[1024]; @@ -1127,17 +983,8 @@ static int usock_rcv_phonebook(struct gsmd_user *gu,  			return -EINVAL;  		num = (int *) ((void *)gph + sizeof(*gph)); - -		ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_phonebook)*(*num), -				GSMD_MSG_PHONEBOOK, -				GSMD_PHONEBOOK_RETRIEVE_READRG, 0); -		if (!ucmd) -			return -ENOMEM; - -		gp = (struct gsmd_phonebook*) ucmd->buf; - -		if (!llist_empty(&gu->pb_readrg_list)) { - +		gp = talloc_size(__pb_ctx, sizeof(*gp) * (*num)); +		if (!llist_empty(&gu->pb_readrg_list))  			llist_for_each_entry_safe(cur, cur2,  					&gu->pb_readrg_list, list) {  				gp->index = cur->pb.index; @@ -1149,26 +996,21 @@ static int usock_rcv_phonebook(struct gsmd_user *gu,  				llist_del(&cur->list);  				free(cur);  			} -		} -		usock_cmd_enqueue(ucmd, gu); - -		break; +		ret = gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, +				GSMD_PHONEBOOK_RETRIEVE_READRG, gph->id, +				sizeof(*gp) * (*num), gp); +		talloc_free(gp); +		return ret;  	case GSMD_PHONEBOOK_RETRIEVE_FIND:  		if (len < sizeof(*gph) + sizeof(int))  			return -EINVAL;  		num = (int *) ((void *)gph + sizeof(*gph)); - -		ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_phonebook)*(*num), GSMD_MSG_PHONEBOOK, -				      GSMD_PHONEBOOK_RETRIEVE_FIND, 0); -		if (!ucmd) -			return -ENOMEM; - -		gp = (struct gsmd_phonebook*) ucmd->buf; - -		if (!llist_empty(&gu->pb_find_list)) { -			llist_for_each_entry_safe(cur, cur2, &gu->pb_find_list, list) { +		gp = talloc_size(__pb_ctx, sizeof(*gp) * (*num)); +		if (!llist_empty(&gu->pb_find_list)) +			llist_for_each_entry_safe(cur, cur2, +					&gu->pb_find_list, list) {  				gp->index = cur->pb.index;  				strcpy(gp->numb, cur->pb.numb);  				gp->type = cur->pb.type; @@ -1178,12 +1020,12 @@ static int usock_rcv_phonebook(struct gsmd_user *gu,  				llist_del(&cur->list);  				free(cur);  			} -		} - -		usock_cmd_enqueue(ucmd, gu); -		break; -         +		ret = gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, +				GSMD_PHONEBOOK_RETRIEVE_FIND, gph->id, +				sizeof(*gp) * (*num), gp); +		talloc_free(gp); +		return ret;  	default:  		return -EINVAL;  	}	 diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c index b5d163f..b9db59a 100644 --- a/src/libgsmd/libgsmd.c +++ b/src/libgsmd/libgsmd.c @@ -133,7 +133,7 @@ void lgsm_unregister_handler(struct lgsm_handle *lh, int type)  }  /* blocking read and processing of packets until packet matching 'id' is found */ -int lgsm_blocking_wait_packet(struct lgsm_handle *lh, u_int16_t id,  +int lgsm_blocking_wait_packet(struct lgsm_handle *lh, u_int16_t id,  			      struct gsmd_msg_hdr *gmh, int rlen)  {  	int rc; diff --git a/src/libgsmd/libgsmd_event.c b/src/libgsmd/libgsmd_event.c index 777edd8..b01a8b2 100644 --- a/src/libgsmd/libgsmd_event.c +++ b/src/libgsmd/libgsmd_event.c @@ -52,9 +52,10 @@ void lgsm_evt_handler_unregister(struct lgsm_handle *lh, int evt_type)  } -static int evt_demux_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) +static int evt_demux_msghandler(struct lgsm_handle *lh, +		struct gsmd_msg_hdr *gmh)  { -	struct gsmd_evt_auxdata *aux = gmh->data; +	struct gsmd_evt_auxdata *aux = (struct gsmd_evt_auxdata *) gmh->data;  	if (gmh->len < sizeof(*aux))  		return -EIO; diff --git a/src/libgsmd/libgsmd_passthrough.c b/src/libgsmd/libgsmd_passthrough.c index b6b32fc..1849688 100644 --- a/src/libgsmd/libgsmd_passthrough.c +++ b/src/libgsmd/libgsmd_passthrough.c @@ -59,7 +59,8 @@ int lgsm_passthrough_send(struct lgsm_handle *lh, const char *tx)  	return gmh->id;  } -int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len) +int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, +		char *rx, unsigned int *rx_len)  {  	struct gsmd_msg_hdr *rgmh = (struct gsmd_msg_hdr *)passthrough_rbuf;  	char *rx_buf = (char *)rgmh + sizeof(*rgmh); @@ -72,8 +73,7 @@ int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned  	/* since we synchronously want to wait for a response, we need to  	 * _internally_ loop over incoming packets and call the callbacks for  	 * intermediate messages (if applicable) */ -	rc = lgsm_blocking_wait_packet(lh, rc, passthrough_rbuf,  -					sizeof(passthrough_rbuf)); +	rc = lgsm_blocking_wait_packet(lh, rc, rgmh, sizeof(passthrough_rbuf));  	if (rc <= 0)  		return rc; @@ -82,10 +82,11 @@ int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned  	if (rc < sizeof(*rgmh) + rgmh->len)  		return -EINVAL; -	 -	/* FIXME: make sure rx_buf is zero-terminated */ -	strcpy(rx, rx_buf); -	*rx_len = rgmh->len; -	return rx_len; +	rx[*--rx_len] = 0; +	if (rgmh->len < *rx_len) +		*rx_len = rgmh->len; +	memcpy(rx, rx_buf, *rx_len); + +	return *rx_len;  } diff --git a/src/libgsmd/libgsmd_pin.c b/src/libgsmd/libgsmd_pin.c index f99084a..204f655 100644 --- a/src/libgsmd/libgsmd_pin.c +++ b/src/libgsmd/libgsmd_pin.c @@ -75,7 +75,7 @@ int lgsm_pin(struct lgsm_handle *lh, unsigned int type,  		return -ENOMEM;  	gm->gp.type = type; -	strcpy(gm->gp.pin, pin); +	strncpy(gm->gp.pin, pin, sizeof(gm->gp.pin));  	switch (type) {  	case GSMD_PIN_SIM_PUK: @@ -87,7 +87,7 @@ int lgsm_pin(struct lgsm_handle *lh, unsigned int type,  			free(gm);  			return -EINVAL;  		} -		strcpy(gm->gp.newpin, newpin); +		strncpy(gm->gp.newpin, newpin, sizeof(gm->gp.newpin));  		break;  	default:  		break; diff --git a/src/util/atcmd.c b/src/util/atcmd.c index e31f81f..36984b5 100644 --- a/src/util/atcmd.c +++ b/src/util/atcmd.c @@ -92,6 +92,7 @@ int atcmd_main(struct lgsm_handle *lgsmh)  			/* this is a synchronous call for a passthrough  			 * command */ +			rlen = STDIN_BUF_SIZE + 1;  			lgsm_passthrough(lgsmh, buf, rbuf, &rlen);  			printf("RSTR=`%s'\n", rbuf); | 
