From 66ddffab0a8fe2f517d83859ffb20467acd0cbe6 Mon Sep 17 00:00:00 2001 From: laforge Date: Thu, 16 Aug 2007 04:18:54 +0000 Subject: From 294d27e78680d497da22e3a8ad679f50d1ba29e5 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Wed, 11 Jul 2007 16:11:10 +0200 Subject: [PATCH] SMS support in gsmd and in libgsmd. This adds the proper support for sms related calls in libgsmd and their implementation in gsmd. I assumed that conversion between data coding schemes is to be done on the client side because the {packing,unpacking}* calls were exported. TEXT mode support is non-functional, but the code only has to be filled in the right places to make it work, if it is ever needed. I had been lucky to be able to test with the different kinds of messages with exotic formats because I just got a bunch of network messages today (urging to top-up the credit). I tried to not modify the libgsmd api, although I would prefer to have a totally different api, possibly with synchronous calls that just return the result of an operation, for a exmaple a whole list of messages, rather than the client waiting for an unknown number of events each with one message. git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@2710 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/Makefile.am | 3 +- src/gsmd/sms_cb.c | 17 +++- src/gsmd/sms_pdu.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/gsmd/usock.c | 260 +++++++++++++++++++++++++++++++++++---------------- 4 files changed, 455 insertions(+), 84 deletions(-) create mode 100644 src/gsmd/sms_pdu.c (limited to 'src/gsmd') diff --git a/src/gsmd/Makefile.am b/src/gsmd/Makefile.am index 49d96e3..6b25812 100644 --- a/src/gsmd/Makefile.am +++ b/src/gsmd/Makefile.am @@ -6,7 +6,8 @@ sbin_PROGRAMS = gsmd gsmd_CFLAGS = -D PLUGINDIR=\"$(plugindir)\" gsmd_SOURCES = gsmd.c atcmd.c select.c machine.c vendor.c unsolicited.c log.c \ - usock.c talloc.c timer.c operator_cache.c ext_response.c + usock.c talloc.c timer.c operator_cache.c ext_response.c \ + sms_pdu.c gsmd_LDADD = -ldl gsmd_LDFLAGS = -Wl,--export-dynamic diff --git a/src/gsmd/sms_cb.c b/src/gsmd/sms_cb.c index 330317c..22bf613 100644 --- a/src/gsmd/sms_cb.c +++ b/src/gsmd/sms_cb.c @@ -184,18 +184,29 @@ static const struct gsmd_unsolocit gsm0705_unsolicit[] = { { "+CDS", &cds_parse }, /* SMS Status Index (stored in ME/TA) */ }; - int sms_cb_init(struct gsmd *gsmd) { struct gsmd_atcmd *atcmd; + char buffer[10]; atcmd = atcmd_fill("AT+CSMS=0", NULL, gu, 0); if (!atcmd) return -ENOMEM; atcmd_submit(gsmd, atcmd); - /* Switch into "text mode" (Section 3.2.3) */ - atcdm = atcmd_fill("AT+CMGF=1", 9, &sms_cb_init_cb, gu, 0); + /* If text mode, set the encoding */ + if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { + atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13, NULL, gu, 0); + if (!atcmd) + return -ENOMEM; + atcmd_submit(gsmd, atcmd); + } + + /* Switch into desired mode (Section 3.2.3) */ + snprintf(buffer, sizeof(buffer), "AT+CMGF=%i", + (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) ? + GSMD_SMS_FMT_TEXT : GSMD_SMS_FMT_PDU); + atcmd = atcmd_fill(buffer, strlen(buffer) + 1, NULL, gu, 0); if (!atcmd) return -ENOMEM; diff --git a/src/gsmd/sms_pdu.c b/src/gsmd/sms_pdu.c new file mode 100644 index 0000000..1ec3202 --- /dev/null +++ b/src/gsmd/sms_pdu.c @@ -0,0 +1,259 @@ +/* Convert raw PDUs to and from gsmd format. + * + * Copyright (C) 2007 OpenMoko, Inc. + * Written by Andrzej Zaborowski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#include "gsmd.h" + +#include +#include + +static int sms_number_bytelen(u_int8_t type, u_int8_t len) +{ + switch (type & __GSMD_TOA_TON_MASK) { + case GSMD_TOA_TON_ALPHANUMERIC: + return (len + 1) >> 1; + default: + return (len + 1) >> 1; + } +} + +static int sms_data_bytelen(u_int8_t data_coding_scheme, u_int8_t len) +{ + switch (data_coding_scheme) { /* Get length in bytes */ + case ALPHABET_DEFAULT: + return (len * 7 + 7) >> 3; + case ALPHABET_8BIT: + return len; + case ALPHABET_UCS2: + return len * 2; + } + return 0; +} + +static int sms_address2ascii(struct gsmd_addr *dst, u_int8_t *src) +{ + int i; + + if (src[0] > GSMD_ADDR_MAXLEN) + return 1; + + /* The Type-of-address field */ + dst->type = src[1]; + + switch (dst->type & __GSMD_TOA_TON_MASK) { + case GSMD_TOA_TON_ALPHANUMERIC: + for (i = 0; ((i * 7 + 3) >> 2) < src[0]; i ++) + dst->number[i] = + ((src[2 + ((i * 7 + 7) >> 3)] << + (7 - ((i * 7 + 7) & 7))) | + (src[2 + ((i * 7) >> 3)] >> + ((i * 7) & 7))) & 0x7f; + break; + default: + for (i = 0; i < src[0]; i ++) + dst->number[i] = '0' + + ((src[2 + (i >> 1)] >> ((i << 2) & 4)) & 0xf); + } + dst->number[i] = 0; + + return 0; +} + +int sms_pdu_to_msg(struct gsmd_sms_list *dst, + u_int8_t *src, int pdulen, int len) +{ + int i, vpf; + if (len < 1 || len < 1 + src[0] + pdulen || pdulen < 1) + return 1; + + /* Skip SMSC number and its Type-of-address */ + len -= 1 + src[0]; + src += 1 + src[0]; + + /* TP-UDHI */ + dst->payload.has_header = !!(src[0] & GSMD_SMS_TP_UDHI_WITH_HEADER); + + /* TP-VPF */ + vpf = (src[0] >> 3) & 3; + + /* TP-MTI */ + switch (src[0] & 3) { + case GSMD_SMS_TP_MTI_DELIVER: + if (len < 3) + return 1; + i = sms_number_bytelen(src[2], src[1]); + if (len < 13 + i) + return 1; + + if (sms_address2ascii(&dst->addr, src + 1)) + return 1; + + len -= 3 + i; + src += 3 + i; + + /* TP-DCS */ + switch (src[1] >> 4) { + case 0x0 ... 3: /* General Data Coding indication */ + case 0xc: /* Message Waiting indication: Discard */ + /* FIXME: support compressed data */ + dst->payload.coding_scheme = src[1] & 0xc; + break; + case 0xd: /* Message Waiting indication: Store */ + dst->payload.coding_scheme = ALPHABET_DEFAULT; + break; + case 0xe: /* Message Waiting indication: Store */ + dst->payload.coding_scheme = ALPHABET_UCS2; + break; + case 0xf: /* Data coding/message class */ + dst->payload.coding_scheme = (src[1] & 4) ? + ALPHABET_8BIT : ALPHABET_DEFAULT; + break; + default: + return 1; + } + + /* TP-SCTS */ + memcpy(dst->time_stamp, src + 2, 7); + + /* Skip TP-PID */ + len -= 9; + src += 9; + break; + case GSMD_SMS_TP_MTI_SUBMIT: + if (len < 4) + return 1; + i = sms_number_bytelen(src[3], src[2]); + if (len < 8 + i) + return 1; + + if (sms_address2ascii(&dst->addr, src + 2)) + return 1; + + len -= 4 + i; + src += 4 + i; + + /* TP-DCS */ + switch (src[1] >> 4) { + case 0x0 ... 3: /* General Data Coding indication */ + case 0xc: /* Message Waiting indication: Discard */ + /* FIXME: compressed data */ + dst->payload.coding_scheme = src[1] & 0xc; + break; + case 0xd: /* Message Waiting indication: Store */ + dst->payload.coding_scheme = ALPHABET_DEFAULT; + break; + case 0xe: /* Message Waiting indication: Store */ + dst->payload.coding_scheme = ALPHABET_UCS2; + break; + case 0xf: /* Data coding/message class */ + dst->payload.coding_scheme = (src[1] & 4) ? + ALPHABET_8BIT : ALPHABET_DEFAULT; + break; + default: + return 1; + } + + /* Skip TP-PID and TP-Validity-Period */ + len -= vpf ? 3 : 2; + src += vpf ? 3 : 2; + + memset(dst->time_stamp, 0, 7); + break; + default: + /* Unknown PDU type */ + return 1; + } + + /* TP-UDL */ + dst->payload.length = src[0]; + i = sms_data_bytelen(dst->payload.coding_scheme, src[0]); + + /* TP-UD */ + if (len < 1 + i || i > GSMD_SMS_DATA_MAXLEN) + return 1; + memcpy(dst->payload.data, src + 1, i); + dst->payload.data[i] = 0; + + return 0; +} + +/* Refer to GSM 03.40 subclause 9.2.3.3, for SMS-SUBMIT */ +int sms_pdu_make_smssubmit(char *dest, struct gsmd_sms_submit *src) +{ + /* FIXME: ALPHANUMERIC encoded addresses can be longer than 13B */ + u_int8_t header[15 + GSMD_ADDR_MAXLEN]; + int pos = 0, i, len; + + /* SMSC Length octet. If omitted or zero, use SMSC stored in the + * phone. One some phones this can/has to be omitted. */ + header[pos ++] = 0x00; + + header[pos ++] = + GSMD_SMS_TP_MTI_SUBMIT | + (0 << 2) | /* Reject Duplicates: 0 */ + GSMD_SMS_TP_VPF_NOT_PRESENT | + GSMD_SMS_TP_SRR_NOT_REQUEST | + (src->payload.has_header ? GSMD_SMS_TP_UDHI_WITH_HEADER : + GSMD_SMS_TP_UDHI_NO_HEADER) | + GSMD_SMS_TP_RP_NOT_SET; + + /* TP-Message-Reference - 00 lets the phone set the number itself */ + header[pos ++] = 0x00; + + header[pos ++] = strlen(src->addr.number); + header[pos ++] = src->addr.type; + for (i = 0; src->addr.number[i]; i ++) { + header[pos] = src->addr.number[i ++] - '0'; + if (src->addr.number[i]) + header[pos ++] |= (src->addr.number[i] - '0') << 4; + else { + header[pos ++] |= 0xf0; + break; + } + } + + /* TP-Protocol-Identifier - 00 means implicit */ + header[pos ++] = 0x00; + + /* TP-Data-Coding-Scheme */ + header[pos ++] = src->payload.coding_scheme; + + /* TP-Validity-Period, if present, would go here */ + + header[pos ++] = src->payload.length; + len = sms_data_bytelen(src->payload.coding_scheme, + src->payload.length); + + if (dest) { + for (i = 0; i < pos; i ++) { + sprintf(dest, "%02X", header[i]); + dest += 2; + } + for (i = 0; i < len; i ++) { + sprintf(dest, "%02X", src->payload.data[i]); + dest += 2; + } + } + + return pos + len; +} diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index db073a4..be8aee8 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -434,17 +434,46 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + struct gsmd_sms_list msg; + int i, idx, stat, len, cr; + u_int8_t pdu[180]; + + if (cmd->ret && cmd->ret != -255) + return 0; - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, - GSMD_SMS_LIST, 0); + /* FIXME: TEXT mode */ + if ( + sscanf(resp, "+CMGL: %i,%i,,%i\n%n", + &idx, &stat, &len, &cr) < 3 && + sscanf(resp, "+CMGL: %i,%i,%*i,%i\n%n", + &idx, &stat, &len, &cr) < 3) + return -EINVAL; + if (len > 164) + return -EINVAL; + + msg.index = idx; + msg.stat = stat; + msg.is_last = (cmd->ret == 0); + for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' && i < 180; i ++) { + if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) { + gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); + return -EINVAL; + } + cr += 2; + } + if (sms_pdu_to_msg(&msg, pdu, len, i)) { + gsmd_log(GSMD_DEBUG, "malformed PDU\n"); + return -EINVAL; + } + + ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, + GSMD_SMS_LIST, cmd->id); if (!ucmd) return -ENOMEM; + memcpy(ucmd->buf, &msg, sizeof(msg)); - /* FIXME: implementation */ - strcpy(ucmd->buf, resp); - usock_cmd_enqueue(ucmd, gu); return 0; @@ -452,17 +481,45 @@ static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + struct gsmd_sms_list msg; + int i, stat, len, cr; + u_int8_t pdu[180]; - /* FIXME: implementation */ + if (cmd->ret) + return 0; + + /* FIXME: TEXT mode */ + if ( + sscanf(resp, "+CMGR: %i,,%i\n%n", + &stat, &len, &cr) < 2 && + sscanf(resp, "+CMGR: %i,%*i,%i\n%n", + &stat, &len, &cr) < 2) + return -EINVAL; + if (len > 164) + return -EINVAL; + + msg.index = 0; + msg.stat = stat; + msg.is_last = 1; + for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' && i < 180; i ++) { + if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) { + gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); + return -EINVAL; + } + cr += 2; + } + if (sms_pdu_to_msg(&msg, pdu, len, i)) { + gsmd_log(GSMD_DEBUG, "malformed PDU\n"); + return -EINVAL; + } - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, - GSMD_SMS_READ, 0); + ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, + GSMD_SMS_READ, cmd->id); if (!ucmd) return -ENOMEM; - - strcpy(ucmd->buf, resp); + memcpy(ucmd->buf, &msg, sizeof(msg)); usock_cmd_enqueue(ucmd, gu); @@ -471,15 +528,21 @@ static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; - - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, - GSMD_SMS_SEND, 0); + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + int msgref; + + if (cmd->ret == 0) { + if (sscanf(resp, "+CMGS: %i", &msgref) < 1) + return -EINVAL; + } else + msgref = -cmd->ret; + + ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, + GSMD_SMS_SEND, cmd->id); if (!ucmd) return -ENOMEM; - - strcpy(ucmd->buf, resp); + *(int *) ucmd->buf = msgref; usock_cmd_enqueue(ucmd, gu); @@ -488,15 +551,21 @@ static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; - - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, - GSMD_SMS_WRITE, 0); - if (!ucmd) - return -ENOMEM; + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + int result; - strcpy(ucmd->buf, resp); + if (cmd->ret == 0) { + if (sscanf(resp, "+CMGW: %i", &result) < 1) + return -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); @@ -505,113 +574,144 @@ static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + int *result; - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, - GSMD_SMS_DELETE, 0); + ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, + GSMD_SMS_DELETE, cmd->id); if (!ucmd) return -ENOMEM; - strcpy(ucmd->buf, resp); + result = (int *) ucmd->buf; + *result = cmd->ret; usock_cmd_enqueue(ucmd, gu); return 0; } +static const char *gsmd_cmgl_stat[] = { + "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL", +}; + static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) { /* FIXME: TEXT mode support!! */ struct gsmd_atcmd *cmd = NULL; struct gsmd_sms_delete *gsd; - struct gsmd_sms *gs; + struct gsmd_sms_submit *gss; struct gsmd_sms_write *gsw; int *stat, *index; int atcmd_len; char buf[1024]; - + switch (gph->msg_subtype) { case GSMD_SMS_LIST: - /* FIXME: only support PDU mode!! */ if(len < sizeof(*gph) + sizeof(int)) return -EINVAL; - stat = (int *) ((void *)gph + sizeof(*gph)); + stat = (int *) ((void *)gph + sizeof(*gph)); + if (*stat < 0 || *stat > 4) + return -EINVAL; - sprintf(buf, "%d", *stat); - - atcmd_len = 1 + strlen("AT+CMGL=") + strlen(buf); - cmd = atcmd_fill("AT+CMGL=", atcmd_len, - &sms_list_cb, gu, gph->id); + /* FIXME: should we set to "SM"/"ME" before that? */ + if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) + atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"", + gsmd_cmgl_stat[*stat]); + else + atcmd_len = sprintf(buf, "AT+CMGL=%i", *stat); + + cmd = atcmd_fill(buf, atcmd_len + 1, + &sms_list_cb, gu, gph->id); if (!cmd) return -ENOMEM; - sprintf(cmd->buf, "AT+CMGL=%s", buf); break; + case GSMD_SMS_READ: - /* FIXME: only support PDU mode!! */ if(len < sizeof(*gph) + sizeof(int)) return -EINVAL; index = (int *) ((void *)gph + sizeof(*gph)); - sprintf(buf, "%d", *index); - - atcmd_len = 1 + strlen("AT+CMGR=") + strlen(buf); - cmd = atcmd_fill("AT+CMGR=", atcmd_len, + /* FIXME: should we set to "SM"/"ME" before that? */ + atcmd_len = sprintf(buf, "AT+CMGR=%i", *index); + + cmd = atcmd_fill(buf, atcmd_len + 1, &sms_read_cb, gu, gph->id); if (!cmd) return -ENOMEM; - sprintf(cmd->buf, "AT+CMGR=%s", buf); break; -#if 0 + case GSMD_SMS_SEND: - /* FIXME: only support PDU mode!! */ - if(len < sizeof(*gph) + sizeof(*gs)) + if (len < sizeof(*gph) + sizeof(*gss)) return -EINVAL; - gs = (struct gsmd_sms *) ((void *)gph + sizeof(*gph)); + gss = (struct gsmd_sms_submit *) ((void *) gph + sizeof(*gph)); + + if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { + atcmd_len = sprintf(buf, "AT+CMGS=\"%s\"\n%.*s", + gss->addr.number, + gss->payload.length, + gss->payload.data); /* FIXME */ + } else { + atcmd_len = sprintf(buf, "AT+CMGS=%i\n", + sms_pdu_make_smssubmit(NULL, gss) - 1); + atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len, + gss) * 2; + } + buf[atcmd_len ++] = 26; /* ^Z ends the message */ + buf[atcmd_len ++] = 0; - sprintf(buf, "%d", *index); - - atcmd_len = 1 + strlen("AT+CMGR=") + 1; - cmd = atcmd_fill("AT+CMGR=", atcmd_len, - &sms_send_cb, gu, gph->id); - if (!cmd)GSMD_SMS_WRITE + cmd = atcmd_fill(buf, atcmd_len, &sms_send_cb, gu, gph->id); + if (!cmd) return -ENOMEM; - sprintf(cmd->buf, "AT+CMGR=%d", index); break; + case GSMD_SMS_WRITE: - /* FIXME: only support PDU mode!! */ - if(len < sizeof(*gph) + sizeof(*gsw)) + if (len < sizeof(*gph) + sizeof(*gsw)) return -EINVAL; - &index = (int *) ((void *)gph + sizeof(*gph)); - - atcmd_len = 1 + strlen("AT+CMGR=") + 1; - cmd = atcmd_fill("AT+CMGR=", atcmd_len, - &sms_write_cb, gu, gph->id); + gsw = (struct gsmd_sms_write *) ((void *) gph + sizeof(*gph)); + if (gsw->stat > 4) + return -EINVAL; + + /* FIXME: should we set to "SM"/"ME" before that? */ + if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { + atcmd_len = sprintf(buf, "AT+CMGW=\"%s\"\n%.*s", + gsw->sms.addr.number, + gsw->sms.payload.length, + gsw->sms.payload.data); /* FIXME */ + } else { + atcmd_len = sprintf(buf, "AT+CMGW=%i,%i\n", + sms_pdu_make_smssubmit(NULL, + &gsw->sms) - 1, gsw->stat); + atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len, + &gsw->sms) * 2; + } + buf[atcmd_len ++] = 26; /* ^Z ends the message */ + buf[atcmd_len ++] = 0; + + cmd = atcmd_fill(buf, atcmd_len, &sms_write_cb, gu, gph->id); if (!cmd) return -ENOMEM; - sprintf(cmd->buf, "AT+CMGR=%d", index); break; -#endif - case GSMD_SMS_DELETE: + + case GSMD_SMS_DELETE: if(len < sizeof(*gph) + sizeof(*gsd)) return -EINVAL; gsd = (struct gsmd_sms_delete *) ((void *)gph + sizeof(*gph)); - - sprintf(buf, "%d,%d", gsd->index, gsd->delflg); - - atcmd_len = 1 + strlen("AT+CMGR=") + strlen(buf); - cmd = atcmd_fill("AT+CMGD=", atcmd_len, + + atcmd_len = sprintf(buf, "AT+CMGD=%d,%d", + gsd->index, gsd->delflg); + + cmd = atcmd_fill(buf, atcmd_len + 1, &sms_delete_cb, gu, gph->id); if (!cmd) return -ENOMEM; - sprintf(cmd->buf, "AT+CMGD=%s", buf); break; default: return -EINVAL; } - - gsmd_log(GSMD_DEBUG, "%s\n", cmd->buf); + + gsmd_log(GSMD_DEBUG, "%s\n", cmd ? cmd->buf : 0); if (cmd) return atcmd_submit(gu->gsmd, cmd); else @@ -867,7 +967,7 @@ static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = { [GSMD_MSG_PIN] = &usock_rcv_pin, [GSMD_MSG_PHONE] = &usock_rcv_phone, [GSMD_MSG_NETWORK] = &usock_rcv_network, - [GSMD_MSG_SMS] = &usock_rcv_sms, + [GSMD_MSG_SMS] = &usock_rcv_sms, //[GSMD_MSG_PHONEBOOK] = &usock_rcv_phonebook, }; -- cgit v1.2.3