summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/usock.h4
-rw-r--r--include/libgsmd/libgsmd.h2
-rw-r--r--src/gsmd/sms_cb.c112
-rw-r--r--src/gsmd/usock.c422
-rw-r--r--src/libgsmd/libgsmd.c2
-rw-r--r--src/libgsmd/libgsmd_event.c5
-rw-r--r--src/libgsmd/libgsmd_passthrough.c17
-rw-r--r--src/libgsmd/libgsmd_pin.c4
-rw-r--r--src/util/atcmd.c1
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);
personal git repositories of Harald Welte. Your mileage may vary