diff options
author | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-08-16 04:18:54 +0000 |
---|---|---|
committer | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-08-16 04:18:54 +0000 |
commit | 66ddffab0a8fe2f517d83859ffb20467acd0cbe6 (patch) | |
tree | f207a43dddc8205763309e8b9b3bb5043f96647e /src/libgsmd | |
parent | 00361c2946aef3975e302d5a5957ae239da21de8 (diff) |
From 294d27e78680d497da22e3a8ad679f50d1ba29e5 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <balrog@zabor.org>
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
Diffstat (limited to 'src/libgsmd')
-rw-r--r-- | src/libgsmd/libgsmd_sms.c | 123 |
1 files changed, 79 insertions, 44 deletions
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<strlen(src); i++ ) { ch1 = src[i] & 0x7F; ch1 = ch1 >> 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<strlen(src); i+=2 ) { - sprintf(buf, "%c%c", src[i], src[i+1]); - ch1 = strtol(buf, NULL, 16); - - j = strlen(dest); - dest[j++] = ((ch1 & (0x7F >> 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 */ |