gnokii-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

3110 SMS data encoding [patch]


From: Osma Suominen
Subject: 3110 SMS data encoding [patch]
Date: Fri, 30 May 2003 15:28:22 +0300 (EEST)

Hello,

continuing my 3110 work, here's a patch that fixes SMS data encoding.
The current code is a huge hack both ways (send & receive). This code
translates between PDU format in the raw_sms data structure and the
ASCII (or Latin-1) that the phone expects. It makes for a lot of
encoding/decoding back and forth but the result works and is clean
wrt code structure (which the current code isn't).

So with this patch text, Unicode and 8bit SMS's work properly (only text
used to work). There are also a couple of related bugfixes: elimination
of an unused variable (int count) and there is no longer garbage in the
debug outbut when reading a saved SMS from the 3110 phone.

Hope you like it. More to come...

-Osma

--- common/phones/nk3110.c.orig 2003-05-28 20:52:04.000000000 +0300
+++ common/phones/nk3110.c      2003-05-29 21:06:14.000000000 +0300
@@ -85,6 +85,8 @@
 static gn_error P3110_IncomingPhoneInfo(int messagetype, unsigned char 
*buffer, int length, gn_data *data, struct gn_statemachine *state);

 static int sms_header_encode(gn_data *data, struct gn_statemachine *state, 
unsigned char *req, int ulength, bool save_sms);
+static int sms_data_encode(int in_length, int out_length, unsigned char 
*input, unsigned char *output, unsigned int dcs);
+static int sms_data_decode(int in_length, unsigned char *input, unsigned char 
*output, unsigned int dcs);
 static int get_memory_type(gn_memory_type memory_type);

 static gn_incoming_function_type incoming_functions[] = {
@@ -347,6 +349,11 @@
                if (error != GN_ERR_NONE) return error;
        } while (DRVINSTANCE(state)->user_data_count < data->raw_sms->length);

+       sms_data_decode(DRVINSTANCE(state)->user_data_count,
+                       DRVINSTANCE(state)->user_data,
+                       data->raw_sms->user_data,
+                       data->raw_sms->dcs);
+
        return GN_ERR_NONE;
 }

@@ -386,26 +393,11 @@

        msgtype = save_sms ? 0x24 : 0x23;

-       /* FIXME Dirty hacks ahead:
-        * The message data can either be unpacked from the raw_sms
-        * structure - which is stupid - or it can be read directly from
-        * the data->sms structure - which is ugly and breaks the code
-        * structure. But the latter seems to work a bit better with
-        * special characters, not sure why, but anyway this is not the
-        * way things should be done, but it should be fixed elsewhere. */
-
-#if 0
-       /* The phone expects ASCII data instead of 7bit packed data, which
-        * is the format used in raw_sms. So the data has to be unpacked
-        * again. */
-
-       ulength = char_7bit_unpack(0, data->raw_sms->user_data_length,
-                                       sizeof(udata),
-                                       data->raw_sms->user_data, udata);
-#else
-       ulength = strlen(data->sms->user_data[0].u.text);
-       memcpy(udata, data->sms->user_data[0].u.text, ulength);
-#endif
+       ulength = sms_data_encode(data->raw_sms->user_data_length,
+                                 sizeof(udata),
+                                 data->raw_sms->user_data,
+                                 udata,
+                                 data->raw_sms->dcs);

        hsize = sms_header_encode(data, state, hreq, ulength, save_sms);

@@ -606,8 +598,6 @@

 static gn_error P3110_IncomingSMSUserData(int messagetype, unsigned char 
*message, int length, gn_data *data, struct gn_statemachine *state)
 {
-       int count;
-
        /* First see if it was an acknowledgement to one of our messages,
           if so then nothing to do */
        if (length == 0x02) return GN_ERR_NONE;
@@ -618,16 +608,16 @@
        }

        /* This function may be called several times; it accumulates the
-        * SMS content in data->raw_sms->user_data.
+        * SMS content in DRVINSTANCE(state)->user_data
         * DRVINSTANCE(state)->user_data_count is used as a counter. */

        /* If this is the first block, reset accumulated message length. */
        if (message[2] == 1)
                DRVINSTANCE(state)->user_data_count = 0;

-       count = DRVINSTANCE(state)->user_data_count + length - 3;
-
-       memcpy(data->raw_sms->user_data + DRVINSTANCE(state)->user_data_count, 
message + 3, length - 3);
+       memcpy(DRVINSTANCE(state)->user_data +
+              DRVINSTANCE(state)->user_data_count, message + 3,
+              length - 3);

        DRVINSTANCE(state)->user_data_count += length - 3;

@@ -724,12 +714,7 @@
        else
                data->raw_sms->udh_indicator = 0;

-
        data->raw_sms->dcs = message[7];
-       /* FIXME the DCS is set to indicate an 8-bit message in order
-        * to avoid the conversion from 7bit in gsm-sms.c
-        * This really should be done some other way... */
-       data->raw_sms->dcs = 0xf4;

        /* Set message length */
        data->raw_sms->length = message[15];
@@ -769,6 +754,9 @@
                remote[remote_length] = '\0';
                l = char_semi_octet_pack(remote, data->raw_sms->remote_number + 
1, remote_number_type);
                data->raw_sms->remote_number[0] = l;
+       } else {
+               remote[0] = '\0';
+               smsc[0] = '\0';
        }

        dprintf("PID:%02x DCS:%02x Timezone:%02x Stat1:%02x Stat2:%02x\n",
@@ -1119,6 +1107,61 @@
        return pos;     /* length of encoded header is returned */
 }

+/* Encode and decode messages, ASCII format to/from 7bit packed format.
+ * The 3110 does this encoding itself and wants ASCII but the data->raw_sms
+ * structure uses 7bit packed data, so conversion is required both ways.
+ * An alternative would be for gsm-sms.c to recognize the possibility that
+ * not all phones want 7bit packed (PDU) data and deal with those phones
+ * (only the 3110 series AFAIK) separately, avoiding conversions entirely.
+ * Note that for 8bit and Unicode messages there is no need to do conversion
+ * as these are passed right through by the phone. */
+
+static int sms_data_encode(int in_length, int out_length,
+                          unsigned char *input, unsigned char *output,
+                          unsigned int dcs)
+{
+       int ulength;
+
+       if (   (dcs & 0x08) == 0x08     /* Unicode */
+           || (dcs & 0xf4) == 0xf4 ) { /* 8bit */
+
+               ulength = in_length;
+               memcpy(output, input, in_length);
+
+       } else {        /* 7bit default alphabet */
+               /* The phone expects ASCII data instead of 7bit packed data,
+                * which is the format used in raw_sms. So the data has to
+                * be unpacked again. */
+
+               ulength = char_7bit_unpack(0, in_length, out_length,
+                                          input, output);
+               char_ascii_decode(output, output, ulength);
+               ulength = strlen(output);
+       }
+       return ulength;
+}
+
+static int sms_data_decode(int in_length, unsigned char *input,
+                          unsigned char *output, unsigned int dcs)
+{
+
+       if (   (dcs & 0x08) == 0x08     /* Unicode */
+           || (dcs & 0xf4) == 0xf4 ) { /* 8bit */
+
+               memcpy(output, input, in_length);
+
+       } else {        /* 7bit default alphabet */
+               /* The phone sends ASCII data instead of 7bit packed data,
+                * which is the format used in raw_sms. So the data has to
+                * be packed - to be later unpacked again! */
+
+               in_length = 0;
+               char_7bit_pack(0, input, output, &in_length);
+       }
+       return in_length;
+}
+
+
 static int get_memory_type(gn_memory_type memory_type)
 {
        int result;
--- include/phones/nk3110.h.orig        2003-05-29 21:11:49.000000000 +0300
+++ include/phones/nk3110.h     2003-05-29 20:47:36.000000000 +0300
@@ -45,6 +45,7 @@

 typedef struct {
        bool sim_available;
+       unsigned char user_data[GN_SMS_MAX_LENGTH];
        int user_data_count;
 } nk3110_driver_instance;


-- 
*** Osma Suominen *** address@hidden *** http://www.iki.fi/ozone/ ***




reply via email to

[Prev in Thread] Current Thread [Next in Thread]