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); |