summaryrefslogtreecommitdiff
path: root/src/libgsmd
diff options
context:
space:
mode:
authorlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-08-16 04:18:54 +0000
committerlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-08-16 04:18:54 +0000
commit66ddffab0a8fe2f517d83859ffb20467acd0cbe6 (patch)
treef207a43dddc8205763309e8b9b3bb5043f96647e /src/libgsmd
parent00361c2946aef3975e302d5a5957ae239da21de8 (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.c123
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 */
personal git repositories of Harald Welte. Your mileage may vary