gnokii-users
[Top][All Lists]
Advanced

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

Fixing sms sending


From: Pavel Machek
Subject: Fixing sms sending
Date: Sun, 19 May 2002 22:29:59 +0200
User-agent: Mutt/1.3.28i

Hi!

This reintroduces layout (in separate file, and marked "obsolete"),
and fixes SMS sending for "fake" driver. Make test now actually works.

I should fix atgen within half hour.
                                                                Pavel

I'm commiting it.

Index: common/Makefile
===================================================================
RCS file: /cvsroot/gnokii/gnokii/common/Makefile,v
retrieving revision 1.39
diff -u -u -r1.39 Makefile
--- common/Makefile     14 Apr 2002 16:57:38 -0000      1.39
+++ common/Makefile     19 May 2002 20:21:07 -0000
@@ -25,6 +25,7 @@
        vcal.o \
        misc.o \
        gsm-sms.o \
+       sms-layout.o \
        gsm-bitmaps.o \
        gsm-common.o \
        gsm-encoding.o \
Index: common/gsm-sms.c
===================================================================
RCS file: /cvsroot/gnokii/gnokii/common/gsm-sms.c,v
retrieving revision 1.60
diff -u -u -r1.60 gsm-sms.c
--- common/gsm-sms.c    19 May 2002 11:27:49 -0000      1.60
+++ common/gsm-sms.c    19 May 2002 20:21:20 -0000
@@ -23,11 +23,14 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   Copyright (C) 2001-2002 PaweĊ‚ Kot <address@hidden>
+  Copyright (C) 2001-2002 Pavel Machek <address@hidden>
 
   Library for parsing and creating Short Messages (SMS).
 
 */
 
+#define DEBUG
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -958,10 +961,251 @@
        return GE_NONE;
 }
 
-/* Fake functions. To let gnokii compile */
+/***
+ *** ENCODING SMS
+ ***/
+
+/**
+ * EncodeData - encodes the date from the SMS structure to the phone frame
+ *
+ * @SMS: SMS structure to be encoded
+ * @dcs: Data Coding Scheme field in the frame to be set
+ * @message: phone frame to be filled in
+ * @multipart: do we send one message or more?
+ * @clen: coded data length
+ *
+ * This function does the phone frame encoding basing on the given SMS
+ * structure. This function is capable to create only one frame at a time.
+ */
+GSM_Error EncodeData(GSM_API_SMS *sms, GSM_SMSMessage *rawsms, bool multipart)
+{
+       SMS_AlphabetType al;
+       unsigned int i, length, size = 0, offset = 0;
+       int text_index = -1, bitmap_index = -1, ringtone_index = -1;
+       char *message = rawsms->UserData;
+       int *clen = &rawsms->UserDataLength;
+
+       /* Version: Smart Messaging Specification 3.0.0 */
+       message[0] = 0x30;
+       for (i = 0; i < 3; i++) {
+               switch (sms->UserData[i].Type) {
+               case SMS_PlainText:
+                       text_index     = i; break;
+               case SMS_BitmapData:
+                       bitmap_index   = i; break;
+               case SMS_RingtoneData:
+                       ringtone_index = i; break;
+               default:
+                       break;
+               }
+       }
+
+       length = strlen(sms->UserData[0].u.Text);
+
+       /* Additional Headers */
+       switch (sms->DCS.Type) {
+       case SMS_GeneralDataCoding:
+               switch (sms->DCS.u.General.Class) {
+               case 1: rawsms->DCS |= 0xf0; break; /* Class 0 */
+               case 2: rawsms->DCS |= 0xf1; break; /* Class 1 */
+               case 3: rawsms->DCS |= 0xf2; break; /* Class 2 */
+               case 4: rawsms->DCS |= 0xf3; break; /* Class 3 */
+               default: break;
+               }
+               if (sms->DCS.u.General.Compressed) {
+                       /* Compression not supported yet */
+                       /* dcs[0] |= 0x20; */
+               }
+               al = sms->DCS.u.General.Alphabet;
+               break;
+       case SMS_MessageWaiting:
+               al = sms->DCS.u.MessageWaiting.Alphabet;
+               if (sms->DCS.u.MessageWaiting.Discard) rawsms->DCS |= 0xc0;
+               else if (sms->DCS.u.MessageWaiting.Alphabet == SMS_UCS2) 
rawsms->DCS |= 0xe0;
+               else rawsms->DCS |= 0xd0;
+
+               if (sms->DCS.u.MessageWaiting.Active) rawsms->DCS |= 0x08;
+               rawsms->DCS |= (sms->DCS.u.MessageWaiting.Type & 0x03);
+
+               break;
+       default:
+               return GE_SMSWRONGFORMAT;
+       }
+
+       if ((al == SMS_8bit) && multipart) al = SMS_DefaultAlphabet;
+       rawsms->Length = *clen = 0;
+
+       /* Text Coding */
+       if (text_index != -1) {
+               switch (al) {
+               case SMS_DefaultAlphabet:
+                       if (multipart) {
+                               offset = 4;
+                               memcpy(message + 1, "\x00\x00\x00", 3);
+                               rawsms->DCS |= 0xf4;
+                       }
+#define UDH_Length 0
+                       size = Pack7BitCharacters((7 - (UDH_Length % 7)) % 7, 
sms->UserData[text_index].u.Text, message + offset);
+                       // sms->Length = 8 * 0 + (7 - (0 % 7)) % 7 + length + 
offset;
+                       rawsms->Length = 
strlen(sms->UserData[text_index].u.Text);
+                       *clen = size + offset;
+                       if (multipart) {
+                               message[2] = (size & 0xff00) >> 8;
+                               message[3] = (size & 0x00ff);
+                       }
+                       break;
+               case SMS_8bit:
+                       rawsms->DCS |= 0xf4;
+                       memcpy(message, sms->UserData[text_index].u.Text + 1, 
sms->UserData[text_index].u.Text[0]);
+                       *clen = rawsms->Length = 
sms->UserData[text_index].u.Text[0];
+                       break;
+               case SMS_UCS2:
+                       if (multipart) {
+                               offset = 4;
+                               memcpy(message + 1, "\x02\x00\x00", 3);
+                       }
+                       rawsms->DCS |= 0x08;
+                       EncodeUnicode(message + offset, 
sms->UserData[text_index].u.Text, length);
+                       length *= 2;
+                       *clen = rawsms->Length = length + offset;
+                       if (multipart) {
+                               message[2] = (length & 0xff00) >> 8;
+                               message[3] = (length & 0x00ff);
+                       }
+                       break;
+               default:
+                       return GE_SMSWRONGFORMAT;
+               }
+       }
+
+       /* Bitmap coding */
+       if (bitmap_index != -1) {
+#ifdef BITMAP_SUPPORT
+               size = 
GSM_EncodeSMSBitmap(&(sms->UserData[bitmap_index].u.Bitmap), message + 
rawsms->Length);
+               rawsms->Length += size;
+               *clen += size;
+#else
+               return GE_NOTSUPPORTED;
+#endif
+       }
+
+       /* Ringtone coding */
+       if (ringtone_index != -1) {
+#ifdef RINGTONE_SUPPORT
+               size = GSM_EncodeSMSRingtone(message + rawsms->Length, 
&sms->UserData[ringtone_index].u.Ringtone);
+               rawsms->Length += size;
+               *clen += size;
+#else
+               return GE_NOTSUPPORTED;
+#endif
+       }
+       return GE_NONE;
+}
+
+/**
+ * EncodeUDH - encodes User Data Header
+ * @UDHi: User Data Header information
+ * @SMS: SMS structure with the data source
+ * @UDH: phone frame where to save User Data Header
+ *
+ * This function encodes the UserDataHeader as described in:
+ *  o GSM 03.40 version 6.1.0 Release 1997, section 9.2.3.24
+ *  o Smart Messaging Specification, Revision 1.0.0, September 15, 1997
+ *  o Smart Messaging Specification, Revision 3.0.0
+ */
+static GSM_Error EncodeUDH(SMS_UDHInfo UDHi, GSM_SMSMessage *SMS, char *UDH)
+{
+       unsigned char pos;
+
+       pos = UDH[0];
+       switch (UDHi.Type) {
+       case SMS_NoUDH:
+               break;
+       case SMS_VoiceMessage:
+       case SMS_FaxMessage:
+       case SMS_EmailMessage:
+               UDH[pos+4] = UDHi.u.SpecialSMSMessageIndication.MessageCount;
+               if (UDHi.u.SpecialSMSMessageIndication.Store) UDH[pos+3] |= 
0x80;
+       case SMS_ConcatenatedMessages:
+               printf("Adding ConcatMsg header\n");
+       case SMS_OpLogo:
+               printf("Adding OpLogo header\n");
+       case SMS_CallerIDLogo:
+       case SMS_Ringtone:
+       case SMS_MultipartMessage:
+               UDH[0] += headers[UDHi.Type].length;
+               memcpy(UDH+pos+1, headers[UDHi.Type].header, 
headers[UDHi.Type].length);
+               break;
+       default:
+               dprintf("Not supported User Data Header type\n");
+               break;
+       }
+       return GE_NONE;
+}
+
+GSM_Error PrepareSMS(GSM_Data *data, int i)
+{
+       GSM_API_SMS *SMS = data->SMS;
+       GSM_SMSMessage *rawsms = data->RawSMS;
+
+       switch (rawsms->Type = SMS->Type) {
+       case SMS_Submit:
+       case SMS_Deliver:
+               break;
+       case SMS_Picture:
+       case SMS_Delivery_Report:
+       default:
+               dprintf("Not supported message type: %d\n", rawsms->Type);
+               return GE_NOTSUPPORTED;
+       }
+
+       EncodeData(SMS, rawsms, 0);
+
+       return GE_NONE;
+}
+
+/**
+ * SendSMS - The main function for the SMS sending
+ * @data:
+ * @state:
+ */
 API GSM_Error SendSMS(GSM_Data *data, GSM_Statemachine *state)
 {
-       return GE_NOTIMPLEMENTED;
+       GSM_Error error = GE_NONE;
+       GSM_RawData rawdata;
+       int i, count;
+
+       count = 1;
+#if 0
+       /* AT does not need smsc */
+       if (data->SMS->MessageCenter.No) {
+               data->MessageCenter = &data->SMS->MessageCenter;
+               error = SM_Functions(GOP_GetSMSCenter, data, state);
+               if (error != GE_NONE) return error;
+       }
+#endif
+
+       if (count < 1) return GE_SMSWRONGFORMAT;
+
+       memset(&rawdata, 0, sizeof(rawdata));
+       data->RawData = &rawdata;
+       data->RawSMS = malloc(sizeof(*data->RawSMS));
+       memset(data->RawSMS, 0, sizeof(*data->RawSMS));
+
+       for (i = 0; i < count; i++) {
+               data->RawData->Data = calloc(256, 1);
+
+               error = PrepareSMS(data, i);
+               if (error != GE_NONE) break;
+
+               error = SM_Functions(GOP_SendSMS, data, state);
+
+               // dprintf("%d\n", data->RawSMS->Length);
+               free(data->RawData->Data);
+               if (error != GE_NONE) break;
+       }
+       data->RawData = NULL;
+       return error;
 }
 
 API GSM_Error SaveSMS(GSM_Data *data, GSM_Statemachine *state)
Index: common/phones/fake.c
===================================================================
RCS file: /cvsroot/gnokii/gnokii/common/phones/fake.c,v
retrieving revision 1.7
diff -u -u -r1.7 fake.c
--- common/phones/fake.c        19 May 2002 19:52:23 -0000      1.7
+++ common/phones/fake.c        19 May 2002 20:21:37 -0000
@@ -101,6 +101,7 @@
        unsigned char req[10240];
        int length, i;
 
+       EncodeByLayout(data, &at_submit, 0);
        if (!data->RawData) return GE_INTERNALERROR;
 
        length = data->RawData->Length;
Index: include/gsm-sms.h
===================================================================
RCS file: /cvsroot/gnokii/gnokii/include/gsm-sms.h,v
retrieving revision 1.33
diff -u -u -r1.33 gsm-sms.h
--- include/gsm-sms.h   17 May 2002 00:22:10 -0000      1.33
+++ include/gsm-sms.h   19 May 2002 20:21:42 -0000
@@ -364,6 +364,55 @@
        SMS_DateTime Time;               /* Delivery timestamp. Only for 
reading. */
 } GSM_API_SMS;
 
+/* Define the layout of the SMS message header */
+/* Misc notes:
+ *   - value -1 indicates in the location field means that the field is not
+ *     supported,
+ *   - when SMSC/Remote numbers have variable width all other fields should
+ *     contain values as its value was 1 ('0x00' as the length) -- if field X
+ *     follows SMSCNumber, X's locations would be SMSC's location + 1,
+ *   - see the examples in common/phones/7110.c, commmon/phones/6100.c,
+ *     common/phones/atgen.c.
+
+ *     DO NOT USE THIS. OBSOLETE INTERFACE TO BE KILLED.
+ */
+typedef struct {
+       bool IsSupported;               /* Indicates if SMS is supported */
+
+       short MessageCenter;            /* Location of the MessageCenter */
+       bool IsMessageCenterCoded;      /* Indicates if the MessageCenter 
address is BCD coded */
+       bool HasMessageCenterFixedLen;  /* Indicates if the MessageCenter field 
has always the fixed length */
+
+       short MoreMessages;             /* Location of the MoreMessages bit */
+       short ReplyViaSameSMSC;         /* Location of the ReplyPath bit */
+       short RejectDuplicates;         /* Location of the RejectDuplicates bit 
*/
+       short Report;                   /* Location of the Report bit */
+       short Number;                   /* Location of the MessageReference 
number */
+       short Reference;                /* Location of the Reference bit */
+       short PID;                      /* Location of the ProtocolIdentifier 
bit */
+       short ReportStatus;             /* Location of the ReportStatus bit */
+       short Length;                   /* Location of the UserDataLength field 
*/
+       short DataCodingScheme;         /* Location of the DataCodingScheme 
field */
+       short UserDataHeader;           /* Location of the UserDataHeader 
indicator bit */
+
+       short ValidityIndicator;        /* Location of the ValidityType 
Indicator field */
+       short Validity;                 /* Location of the Validity field */
+       short ValidityLen;              /* Length ot the Validity field. -1 if 
the length is variable (as with GSM SPEC) */
+
+       short RemoteNumber;             /* Location of the RemoteNumber */
+       bool IsRemoteNumberCoded;       /* Indicates if the RemoteNumber 
address is BCD coded */
+       bool HasRemoteNumberFixedLen;   /* Indicates if the MessageCenter field 
has always the fixed length */
+
+       short SMSCTime;                 /* Location of the SMSC Response time */
+       short Time;                     /* Location of the Delivery time */
+
+       short MemoryType;               /* Location of the Memory Type field */
+       short Status;                   /* Location of the Status field */
+       short UserData;                 /* Location of the UserData field */
+       bool IsUserDataCoded;           /* Indicates if the UserData should be 
PDU coded */
+} SMSMessage_Layout;
+
+
 /* Define datatype for SMS messages, describes precisely GSM Spec 03.40 */
 typedef struct {
        unsigned int Type;                             /* Message Type 
Indicator - 2 bits (9.2.3.1) */
@@ -386,6 +435,7 @@
        unsigned int Length;                           /* User Data Length 
(9.2.3.16), Command Data Length (9.2.3.20) */
        bool UDHIndicator;
        unsigned char UserData[SMS_USER_DATA_LEN];     /* User Data (9.2.3.24), 
Command Data (9.2.3.21), extened to Nokia Multipart Messages from Smart 
Messaging Specification 3.0.0 */
+       int UserDataLength;                             /* Length of just 
previous field */
 
        bool ValidityIndicator;
        unsigned char Validity[MAX_VALIDITY_LENGTH];   /* Validity Period 
Format & Validity Period (9.2.3.3 & 9.2.3.12) - `Message validity' in the phone 
*/

-- 
(about SSSCA) "I don't say this lightly.  However, I really think that the U.S.
no longer is classifiable as a democracy, but rather as a plutocracy." --hpa



reply via email to

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