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/libgsmd/libgsmd_sms.c | 123 +++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 44 deletions(-) (limited to 'src/libgsmd') diff --git a/src/libgsmd/libgsmd_sms.c b/src/libgsmd/libgsmd_sms.c index 261dca3..9ac9bf2 100644 --- a/src/libgsmd/libgsmd_sms.c +++ b/src/libgsmd/libgsmd_sms.c @@ -83,19 +83,53 @@ int lgsmd_sms_delete(struct lgsm_handle *lh, return 0; } -int lgsmd_sms_send(struct lgsm_handle *lh, - const struct lgsm_sms *sms) +int lgsmd_number2addr(struct gsmd_addr *dst, const char *src) +{ + char *ch; + + if (strlen(src) + 1 > sizeof(dst->number)) + return 1; + if (src[0] == '+') { + dst->type = + GSMD_TOA_NPI_ISDN | + GSMD_TOA_TON_INTERNATIONAL | + GSMD_TOA_RESERVED; + strcpy(dst->number, src + 1); + } else { + dst->type = + GSMD_TOA_NPI_ISDN | + GSMD_TOA_TON_UNKNOWN | + GSMD_TOA_RESERVED; + strcpy(dst->number, src); + } + + for (ch = dst->number; *ch; ch ++) + if (*ch < '0' || *ch > '9') + return 1; + return 0; +} + +int lgsmd_sms_send(struct lgsm_handle *lh, + const struct lgsm_sms *sms) { /* FIXME: only support PDU mode */ struct gsmd_msg_hdr *gmh; - struct gsmd_sms *gs; - int rc; + struct gsmd_sms_submit *gss; + int i, rc; gmh = lgsm_gmh_fill(GSMD_MSG_SMS, - GSMD_SMS_SEND, sizeof(*gs)); + GSMD_SMS_SEND, sizeof(*gss)); if (!gmh) return -ENOMEM; - gs = (struct gsmd_sms *) gmh->data; + gss = (struct gsmd_sms_submit *) gmh->data; + + if (lgsmd_number2addr(&gss->addr, sms->addr)) + return -EINVAL; + + gss->payload.has_header = 0; + gss->payload.length = sms->length; + gss->payload.coding_scheme = sms->alpha; + memcpy(gss->payload.data, sms->data, LGSM_SMS_DATA_MAXLEN); rc = lgsm_send(lh, gmh); if (rc < gmh->len + sizeof(*gmh)) { @@ -108,7 +142,7 @@ int lgsmd_sms_send(struct lgsm_handle *lh, return 0; } -int lgsmd_sms_write(struct lgsm_handle *lh, +int lgsmd_sms_write(struct lgsm_handle *lh, const struct lgsm_sms_write *sms_write) { /* FIXME: only support PDU mode */ @@ -122,6 +156,17 @@ int lgsmd_sms_write(struct lgsm_handle *lh, return -ENOMEM; gsw = (struct gsmd_sms_write *) gmh->data; + gsw->stat = sms_write->stat; + + if (lgsmd_number2addr(&gsw->sms.addr, sms_write->sms.addr)) + return -EINVAL; + + gsw->sms.payload.has_header = 0; + gsw->sms.payload.length = sms_write->sms.length; + gsw->sms.payload.coding_scheme = sms_write->sms.alpha; + memcpy(gsw->sms.payload.data, sms_write->sms.data, + LGSM_SMS_DATA_MAXLEN); + rc = lgsm_send(lh, gmh); if (rc < gmh->len + sizeof(*gmh)) { lgsm_gmh_free(gmh); @@ -133,65 +178,55 @@ int lgsmd_sms_write(struct lgsm_handle *lh, return 0; } -int packing_7bit_character(char *src, char *dest) +int packing_7bit_character(const char *src, struct lgsm_sms *dest) { int i,j = 0; unsigned char ch1, ch2; char tmp[2]; int shift = 0; - - *dest = '\0'; + + dest->alpha = ALPHABET_DEFAULT; for ( i=0; i> shift; ch2 = src[(i+1)] & 0x7F; - ch2 = ch2 << (7-shift); + ch2 = ch2 << (7-shift); ch1 = ch1 | ch2; - - j = strlen(dest); - sprintf(tmp, "%x", (ch1 >> 4)); - dest[j++] = tmp[0]; - sprintf(tmp, "%x", (ch1 & 0x0F)); - dest[j++] = tmp[0]; - dest[j++] = '\0'; - + + if (j > sizeof(dest->data)) + break; + dest->data[j++] = ch1; + shift++; - + if ( 7 == shift ) { shift = 0; i++; } - } - - return 0; + } + + dest->length = i; + return j; } -int unpacking_7bit_character(char *src, char *dest) +int unpacking_7bit_character(const struct gsmd_sms *src, char *dest) { - unsigned char ch1, ch2 = '\0'; - int i, j; - char buf[8]; - int shift = 0; - - *dest = '\0'; - - for ( i=0; i> shift)) << shift) | ch2; - dest[j++] = '\0'; - - ch2 = ch1 >> (7-shift); - - shift++; - } + int i = 0; + + if (src->has_header) + i += ((src->data[0] << 3) + 14) / 7; + for (; i < src->length; i ++) + *(dest ++) = + ((src->data[(i * 7 + 7) >> 3] << + (7 - ((i * 7 + 7) & 7))) | + (src->data[(i * 7) >> 3] >> + ((i * 7) & 7))) & 0x7f; + *dest = '\0'; - return 0; + return i; } /* Refer to 3GPP TS 11.11 Annex B */ -- cgit v1.2.3