Send commitlog mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        [EMAIL PROTECTED]

You can reach the person managing the list at
        [EMAIL PROTECTED]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r2710 - in trunk/src/target/gsm: include/gsmd include/libgsmd
      src/gsmd src/libgsmd src/util ([EMAIL PROTECTED])
--- Begin Message ---
Author: laforge
Date: 2007-08-16 06:18:54 +0200 (Thu, 16 Aug 2007)
New Revision: 2710

Added:
   trunk/src/target/gsm/include/gsmd/sms.h
   trunk/src/target/gsm/src/gsmd/sms_pdu.c
Modified:
   trunk/src/target/gsm/include/gsmd/gsmd.h
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/include/libgsmd/sms.h
   trunk/src/target/gsm/src/gsmd/Makefile.am
   trunk/src/target/gsm/src/gsmd/sms_cb.c
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c
   trunk/src/target/gsm/src/util/shell.c
Log:
>From 294d27e78680d497da22e3a8ad679f50d1ba29e5 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
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.


Modified: trunk/src/target/gsm/include/gsmd/gsmd.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/gsmd.h    2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/include/gsmd/gsmd.h    2007-08-16 04:18:54 UTC (rev 
2710)
@@ -63,6 +63,7 @@
 struct gsmd;
 
 #define GSMD_FLAG_V0           0x0001  /* V0 responses to be expected from TA 
*/
+#define GSMD_FLAG_SMS_FMT_TEXT 0x0002  /* TODO Use TEXT rather than PDU mode */
 
 struct gsmd {
        unsigned int flags;

Added: trunk/src/target/gsm/include/gsmd/sms.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/sms.h     2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/include/gsmd/sms.h     2007-08-16 04:18:54 UTC (rev 
2710)
@@ -0,0 +1,14 @@
+#ifndef __GSMD_SMS_H
+#define __GSMD_SMS_H
+
+#ifdef __GSMD__
+
+#include <gsmd/gsmd.h>
+
+int sms_pdu_make_smssubmit(char *dest, const struct gsmd_sms_submit *src);
+int sms_pdu_to_msg(struct gsmd_sms_list *dst, const u_int8_t *src,
+               int pdulen, int len);
+
+#endif /* __GSMD__ */
+
+#endif

Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 04:18:54 UTC (rev 
2710)
@@ -87,6 +87,23 @@
        GSMD_SMS_FMT_TEXT       = 1,
 };
 
+/* Data Coding Scheme, refer to GSM 03.38 Clause 4 */
+#define B5_COMPRESSED  (1<<5)
+#define B4_CLASSMEANING        (1<<4)
+enum {
+       MESSAGE_CLASS_CLASS0            = 0x00,
+       MESSAGE_CLASS_CLASS1            = 0x01,
+       MESSAGE_CLASS_CLASS2            = 0x10,
+       MESSAGE_CLASS_CLASS3            = 0x11,
+};
+
+enum gsmd_sms_alphabet {
+       ALPHABET_DEFAULT                = (0x00<<2),
+       ALPHABET_8BIT                   = (0x01<<2),
+       ALPHABET_UCS2                   = (0x10<<2),
+       ALPHABET_RESERVED               = (0x11<<2),
+};
+
 /* Refer to GSM 03.40 subclause 9.2.3.1 */
 enum gsmd_sms_tp_mti {
        GSMD_SMS_TP_MTI_DELIVER         = 0,
@@ -139,7 +156,7 @@
 /* for SMS-SUBMIT, SMS-DELIVER */
 enum gsmd_sms_tp_udhi {
        GSMD_SMS_TP_UDHI_NO_HEADER      = (0<<6),
-       GSMD_SMS_TP_UDHI_WTIH_HEADER    = (1<<6),
+       GSMD_SMS_TP_UDHI_WITH_HEADER    = (1<<6),
 };
 
 /* SMS delflg from 3GPP TS 07.05, Clause 3.5.4 */
@@ -160,6 +177,35 @@
        GSMD_PHONEBOOK_GET_SUPPORT      = 6,
 };
 
+/* Type-of-Address, Numbering-Plan-Identification field, GSM 03.40, 9.1.2.5 */
+enum gsmd_toa_npi {
+       GSMD_TOA_NPI_UNKNOWN            = 0x0,
+       GSMD_TOA_NPI_ISDN               = 0x1,
+       GSMD_TOA_NPI_DATA               = 0x3,
+       GSMD_TOA_NPI_TELEX              = 0x4,
+       GSMD_TOA_NPI_NATIONAL           = 0x8,
+       GSMD_TOA_NPI_PRIVATE            = 0x9,
+       GSMD_TOA_NPI_ERMES              = 0xa,
+       GSMD_TOA_NPI_RESERVED           = 0xf,
+};
+
+/* Type-of-Address, Type-of-Number field, GSM 03.40, Subclause 9.1.2.5 */
+enum gsmd_toa_ton {
+       GSMD_TOA_TON_UNKNOWN            = (0<<4),
+       GSMD_TOA_TON_INTERNATIONAL      = (1<<4),
+       GSMD_TOA_TON_NATIONAL           = (2<<4),
+       GSMD_TOA_TON_NETWORK            = (3<<4),
+       GSMD_TOA_TON_SUBSCRIBER         = (4<<4),
+       GSMD_TOA_TON_ALPHANUMERIC       = (5<<4),
+       GSMD_TOA_TON_ABBREVIATED        = (6<<4),
+       __GSMD_TOA_TON_MASK             = (7<<4),
+};
+
+/* Type-of-Address, bit 7 always 1 */
+enum gsmd_toa_reserved {
+       GSMD_TOA_RESERVED               = (1<<7),
+};
+
 /* Length from 3GPP TS 04.08, Clause 10.5.4.7 */
 
 #define GSMD_ADDR_MAXLEN       32
@@ -244,30 +290,33 @@
 #define GSMD_SMS_DATA_MAXLEN   164 
 struct gsmd_sms {
        u_int8_t length;        
+       u_int8_t coding_scheme;
+       int has_header;
        char data[GSMD_SMS_DATA_MAXLEN+1];      
 } __attribute__ ((packed));
 
+/* Refer to GSM 03.40 subclause 9.2.2.2 */
+struct gsmd_sms_submit {
+       struct gsmd_addr addr;
+       struct gsmd_sms payload;
+};
+
 /* Refer to GSM 07.05 subclause 4.4 */
 struct gsmd_sms_write {
        u_int8_t stat;
-       struct gsmd_sms sms;
+       struct gsmd_sms_submit sms;
 } __attribute__ ((packed));
 
-/* Refer to GSM 03.40 subclause 9.2.2.2 */
-struct gsmd_sms_submit {
-       u_int8_t length;        
-       char data[GSMD_SMS_DATA_MAXLEN+1];      
-} __attribute__ ((packed));
-
 /* Refer to GSM 03.40 subclause 9.2.2.1 */
-struct gsmd_sms_deliver {
-       u_int8_t length;        
-       char origl_addr[12];
-       u_int8_t proto_ident;
-       u_int8_t coding_scheme;
+struct gsmd_sms_list {
+       /* FIXME Defined as in range of location numbers supported by memory */
+       u_int8_t index;
+       enum gsmd_msg_sms_type stat;
        char time_stamp[7];     
-       char user_data[140];
-} __attribute__ ((packed));
+       struct gsmd_addr addr;
+       struct gsmd_sms payload;
+       int is_last;
+};
 
 /* Refer to GSM 07.07 subclause 8.12 */
 struct gsmd_phonebook_readrg {

Modified: trunk/src/target/gsm/include/libgsmd/sms.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/sms.h  2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/include/libgsmd/sms.h  2007-08-16 04:18:54 UTC (rev 
2710)
@@ -5,23 +5,6 @@
 
 /* Short Message Service */
 
-/* Data Coding Scheme, refer to GSM 03.38 Clause 4 */
-#define B5_COMPRESSED  (1<<5)
-#define B4_CLASSMEANING        (1<<4)
-enum {
-       MESSAGE_CLASS_CLASS0            = 0x00,
-       MESSAGE_CLASS_CLASS1            = 0x01,
-       MESSAGE_CLASS_CLASS2            = 0x10,
-       MESSAGE_CLASS_CLASS3            = 0x11,
-};
-
-enum {
-       ALPHABET_DEFAULT                = (0x00<<2),
-       ALPHABET_8BIT                   = (0x01<<2),
-       ALPHABET_UCS2                   = (0x10<<2),
-       ALPHABET_RESERVED               = (0x11<<2),
-};
-
 /* Coding of Alpha fields in the SIM for UCS2, (3GPP TS 11.11 Annex B) */
 //enum {       
                
@@ -57,15 +40,17 @@
 #define LGSM_SMS_ADDR_MAXLEN   12
 #define LGSM_SMS_DATA_MAXLEN   140
 struct lgsm_sms {
-       /* FIXME: max length of data, 
-        * 7 bit coding - 160(140*8/7); ucs2 coding - 70(140/2) */
        char addr[LGSM_SMS_ADDR_MAXLEN+1];
-       char data[LGSM_SMS_DATA_MAXLEN+1];
+       /* FIXME: max length of data,
+        * 7 bit coding - 160(140*8/7); ucs2 coding - 70(140/2) */
+       enum gsmd_sms_alphabet alpha;
+       u_int8_t data[LGSM_SMS_DATA_MAXLEN+1];
+       int length;
 };
 
 /* GSM 03.40 subclause 9.2.2.2 and GSM 07.05 subclause 4.4 and subclause 3.1 */
 struct lgsm_sms_write {
-       enum lgsm_msg_sms_stat stat;                    
+       enum lgsm_msg_sms_stat stat;
        struct lgsm_sms sms;
 };
 
@@ -87,10 +72,10 @@
                const struct lgsm_sms_write *sms_write);
 
 /* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */
-extern int packing_7bit_character(char *src, char *dest);
+extern int packing_7bit_character(const char *src, struct lgsm_sms *dest);
 
 /* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */
-extern int unpacking_7bit_character(char *src, char *dest);
+extern int unpacking_7bit_character(const struct gsmd_sms *src, char *dest);
 
 /* Refer to 3GPP TS 11.11 Annex B */
 extern int packing_UCS2_80(char *src, char *dest);

Modified: trunk/src/target/gsm/src/gsmd/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/gsmd/Makefile.am   2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/src/gsmd/Makefile.am   2007-08-16 04:18:54 UTC (rev 
2710)
@@ -6,7 +6,8 @@
 
 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
 

Modified: trunk/src/target/gsm/src/gsmd/sms_cb.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:18:54 UTC (rev 
2710)
@@ -184,18 +184,29 @@
        { "+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;
 

Added: trunk/src/target/gsm/src/gsmd/sms_pdu.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_pdu.c     2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/src/gsmd/sms_pdu.c     2007-08-16 04:18:54 UTC (rev 
2710)
@@ -0,0 +1,259 @@
+/* Convert raw PDUs to and from gsmd format.
+ *
+ * Copyright (C) 2007 OpenMoko, Inc.
+ * Written by Andrzej Zaborowski <[EMAIL PROTECTED]>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+
+#include "gsmd.h"
+
+#include <gsmd/gsmd.h>
+#include <gsmd/usock.h>
+
+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;
+}

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 04:18:54 UTC (rev 
2710)
@@ -434,17 +434,46 @@
 
 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];
 
-       ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS,
-                             GSMD_SMS_LIST, 0);
+       if (cmd->ret && cmd->ret != -255)
+               return 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,18 +481,46 @@
 
 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;
 
-       ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS,
-                             GSMD_SMS_READ, 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(sizeof(msg), GSMD_MSG_SMS,
+                             GSMD_SMS_READ, cmd->id);
        if (!ucmd)
                return -ENOMEM;
+       memcpy(ucmd->buf, &msg, sizeof(msg));
 
-       strcpy(ucmd->buf, resp);        
-
        usock_cmd_enqueue(ucmd, gu);
 
        return 0;
@@ -471,15 +528,21 @@
 
 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,16 +551,22 @@
 
 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);
+       struct gsmd_user *gu = ctx;
+       struct gsmd_ucmd *ucmd;
+       int result;
+
+       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; 
+               return -ENOMEM;
+       *(int *) ucmd->buf = result;
 
-       strcpy(ucmd->buf, resp);
-
        usock_cmd_enqueue(ucmd, gu);
 
        return 0;
@@ -505,113 +574,144 @@
 
 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 <mem1> 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 <mem1> 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));
 
-               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
+               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;
+
+               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 <mem2> 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 @@
        [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,
 };
 

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c      2007-08-16 04:16:26 UTC 
(rev 2709)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c      2007-08-16 04:18:54 UTC 
(rev 2710)
@@ -83,20 +83,54 @@
        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)) {
                lgsm_gmh_free(gmh);
@@ -108,7 +142,7 @@
        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 @@
                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 @@
        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;
+       int i = 0;
 
-        *dest = '\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';
 
-        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++;
-        }
-
-        return 0;
+       return i;
 }
 
 /* Refer to 3GPP TS 11.11 Annex B */

Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c       2007-08-16 04:16:26 UTC (rev 
2709)
+++ trunk/src/target/gsm/src/util/shell.c       2007-08-16 04:18:54 UTC (rev 
2710)
@@ -32,6 +32,7 @@
 #include <libgsmd/phonebook.h>
 #include <libgsmd/sms.h>
 #include <gsmd/usock.h>
+#include <gsmd/ts0705.h>
 
 #define STDIN_BUF_SIZE 1024
 
@@ -76,22 +77,98 @@
 
 /* this is the handler for receiving sms responses */
 static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
-{      
-       char *payload;
+{
+       char payload[GSMD_SMS_DATA_MAXLEN];
+       int *result;
+       struct gsmd_sms_list *sms;
+       static const char *type[] = { "Unread", "Received", "Unsent", "Sent" };
 
        switch (gmh->msg_subtype) {
        case GSMD_SMS_LIST:
-               break;  
-       case GSMD_SMS_READ:             
-       case GSMD_SMS_SEND:             
-       case GSMD_SMS_WRITE:                    
+       case GSMD_SMS_READ:
+               sms = (struct gsmd_sms_list *) ((void *) gmh + sizeof(*gmh));
+               printf("%s message %i from/to %s%s, at %i%i-%i%i-%i%i "
+                               "%i%i:%i%i:%i%i, GMT%c%i\n", type[sms->stat],
+                               sms->index,
+                               ((sms->addr.type & __GSMD_TOA_TON_MASK) ==
+                                GSMD_TOA_TON_INTERNATIONAL) ? "+" : "",
+                               sms->addr.number,
+                               sms->time_stamp[0] & 0xf,
+                               sms->time_stamp[0] >> 4,
+                               sms->time_stamp[1] & 0xf,
+                               sms->time_stamp[1] >> 4,
+                               sms->time_stamp[2] & 0xf,
+                               sms->time_stamp[2] >> 4,
+                               sms->time_stamp[3] & 0xf,
+                               sms->time_stamp[3] >> 4,
+                               sms->time_stamp[4] & 0xf,
+                               sms->time_stamp[4] >> 4,
+                               sms->time_stamp[5] & 0xf,
+                               sms->time_stamp[5] >> 4,
+                               (sms->time_stamp[6] & 8) ? '-' : '+',
+                               (((sms->time_stamp[6] << 4) |
+                                 (sms->time_stamp[6] >> 4)) & 0x3f) >> 2);
+               if (sms->payload.coding_scheme == ALPHABET_DEFAULT) {
+                       unpacking_7bit_character(&sms->payload, payload);
+                       printf("\"%s\"\n", payload);
+               } else if (sms->payload.coding_scheme == ALPHABET_8BIT)
+                       printf("8-bit encoded data\n");
+               else if (sms->payload.coding_scheme == ALPHABET_UCS2)
+                       printf("Unicode-16 encoded text\n");
+               break;
+       case GSMD_SMS_SEND:
+               result = (int *) ((void *) gmh + sizeof(*gmh));
+               if (*result >= 0) {
+                       printf("Send: message sent as ref %i\n", *result);
+                       break;
+               }
+
+               switch (-*result) {
+               case 42:
+                       printf("Store: congestion\n");
+                       break;
+               default:
+                       printf("Store: error %i\n", *result);
+                       break;
+               }
+               break;
+       case GSMD_SMS_WRITE:
+               result = (int *) ((void *) gmh + sizeof(*gmh));
+               if (*result >= 0) {
+                       printf("Store: message stored with index %i\n",
+                                       *result);
+                       break;
+               }
+
+               switch (-*result) {
+               case GSM0705_CMS_SIM_NOT_INSERTED:
+                       printf("Store: SIM not inserted\n");
+                       break;
+               default:
+                       printf("Store: error %i\n", *result);
+                       break;
+               }
+               break;
        case GSMD_SMS_DELETE:
-               payload = (char *)gmh + sizeof(*gmh);
-               printf("%s\n", payload);                
-               break;  
+               result = (int *) ((void *) gmh + sizeof(*gmh));
+               switch (*result) {
+               case 0:
+                       printf("Delete: success\n");
+                       break;
+               case GSM0705_CMS_SIM_NOT_INSERTED:
+                       printf("Delete: SIM not inserted\n");
+                       break;
+               case GSM0705_CMS_INVALID_MEMORY_INDEX:
+                       printf("Delete: invalid memory index\n");
+                       break;
+               default:
+                       printf("Delete: error %i\n", *result);
+                       break;
+               }
+               break;
        default:
                return -EINVAL;
-       }       
+       }
 }
 
 static int shell_help(void)
@@ -101,7 +178,8 @@
                "\tH\tHangup call\n"
                "\tO\tPower On\n"
                "\to\tPower Off\n"
-               "\tR\tRegister Netowrk\n"
+               "\tR\tRegister Network\n"
+               "\tU\tUnregister from netowrk\n"
                "\tT\tSend DTMF Tone\n"
                "\tpd\tPB Delete (pb=index)\n"
                "\tpr\tPB Read (pr=index)\n"
@@ -197,6 +275,9 @@
                        } else if (!strcmp(buf, "R")) {
                                printf("Register\n");
                                lgsm_netreg_register(lgsmh, 0);
+                       } else if (!strcmp(buf, "U")) {
+                               printf("Unregister\n");
+                               lgsm_netreg_register(lgsmh, 2);
                        } else if (!strcmp(buf, "q")) {
                                exit(0);
                        } else if (buf[0] == 'T') {
@@ -239,7 +320,7 @@
                                pb.index = atoi(ptr+1);
 
                                fcomma = strchr(buf, ',');
-                               lcomma = strrchr(buf, ',');
+                               lcomma = strchr(fcomma+1, ',');
                                strncpy(pb.numb, fcomma+1, (lcomma-fcomma-1));
                                pb.numb[(lcomma-fcomma-1)] = '\0';              
                
                                if ( '+' == pb.numb[0] )
@@ -279,25 +360,25 @@
 
                                ptr = strchr(buf, '=');
                                fcomma = strchr(buf, ',');
-                               strncpy(sms.addr, ptr+1, (fcomma-ptr-1));
+                               strncpy(sms.addr, ptr+1, fcomma-ptr-1);
                                sms.addr[fcomma-ptr-1] = '\0';
-                               strncpy(sms.data, fcomma+1, strlen(fcomma+1));
-                               sms.data[strlen(fcomma+1)] = '\0';
-                                               
-                               lgsmd_sms_send(lgsmh, &sms);                    
+                               packing_7bit_character(fcomma+1, &sms);
+
+                               lgsmd_sms_send(lgsmh, &sms);
                        } else if ( !strncmp(buf, "sw", 2)) {   
                                printf("Write SMS\n");                          
                                struct lgsm_sms_write sms_write;
 
                                ptr = strchr(buf, '=');
-                               sms_write.stat = atoi(ptr+1);                   
        
+                               sms_write.stat = atoi(ptr+1);
                                fcomma = strchr(buf, ',');
-                               lcomma = strrchr(buf, ',');
-                               strncpy(sms_write.sms.addr, fcomma+1, 
(lcomma-fcomma-1));
+                               lcomma = strchr(fcomma+1, ',');
+                               strncpy(sms_write.sms.addr,
+                                               fcomma+1, lcomma-fcomma-1);
                                sms_write.sms.addr[lcomma-fcomma-1] = '\0';
-                               strncpy(sms_write.sms.data, lcomma+1, 
strlen(lcomma+1));
-                               sms_write.sms.data[strlen(lcomma+1)] = '\0';    
-                               
+                               packing_7bit_character(
+                                               lcomma+1, &sms_write.sms);
+
                                lgsmd_sms_write(lgsmh, &sms_write);
                        } else {
                                printf("Unknown command `%s'\n", buf);




--- End Message ---
_______________________________________________
commitlog mailing list
[email protected]
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to