[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Picture SMS-es and long sms support
From: |
Pavel Machek |
Subject: |
Picture SMS-es and long sms support |
Date: |
Thu, 30 May 2002 01:10:16 +0200 |
User-agent: |
Mutt/1.3.28i |
Hi!
This is long sms-es and picture support. [Picture image support is not
quite complete and quite working, but with small hacks it can be made
to work.]
Long sms-es is handled in slightly funny way, but I found it cleaner:
it is now permitted to attempt to send SMS with up to 10K of user
data. Code detects it and splits message accordingly.
Commited to CVS.
Pavel
Index: common/gsm-bitmaps.c
===================================================================
RCS file: /cvsroot/gnokii/gnokii/common/gsm-bitmaps.c,v
retrieving revision 1.23
diff -u -u -r1.23 gsm-bitmaps.c
--- common/gsm-bitmaps.c 25 May 2002 23:42:13 -0000 1.23
+++ common/gsm-bitmaps.c 29 May 2002 23:05:23 -0000
@@ -25,10 +25,14 @@
Copyright (C) 1999, 2000 Hugh Blemings & Pavel JanÃk ml.
Copyright (C) 2002 Pavel Machek <address@hidden>
+ Based on work from mygnokii, thanks go to Marcin Wiacek.
+
Functions for common bitmap operations.
*/
+//#define DEBUG
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -215,6 +219,7 @@
int GSM_EncodeSMSBitmap(GSM_Bitmap *bitmap, char *message)
{
unsigned short size, current = 0;
+ int i;
switch (bitmap->type) {
case GSM_OperatorLogo:
@@ -226,13 +231,40 @@
break;
case GSM_PictureMessage:
dprintf("Picture Image\n");
- /* Type of multipart message - picture image */
- message[current++] = 0x02;
- /* Size of the message */
- size = bitmap->size + 4; /* for bitmap the header */
- message[current++] = (size & 0xff00) >> 8;
- message[current++] = size & 0x00ff;
- break;
+
+ strcpy(bitmap->text, "");
+
+ message[current++]=0x30; /* SM version. Here 3.0 */
+ message[current++]=0x06; /* ID for bitmap, 0x06 is id for
screensaver */
+ message[current++]=0x01; /* Length for picture part, hi */
+ message[current++]=0x00; /* length lo */
+
+ /* Set the logo size */
+ message[current++] = 0x00;
+ message[current++] = bitmap->width;
+ message[current++] = bitmap->height;
+ message[current++] = 0x01;
+
+ memcpy(message+current,bitmap->bitmap,bitmap->size);
+ current=current+bitmap->size;
+
+ if (strlen(bitmap->text)!=0) {
+ /* FIXME: unicode length is not as simple as strlen */
+ int uni = 0, len; /* 0 ..
ISO-8859-1, 1 .. Unicode */
+
+ message[current++]=uni;
+
+ /* Length for text part */
+ len = strlen(bitmap->text)*(uni + 1);
+ message[current++]=0x00;
+ message[current++]=len;
+ if (uni)
+ EncodeUnicode
(message+current,bitmap->text,strlen(bitmap->text));
+ else
+
memcpy(message+current,bitmap->text,strlen(bitmap->text));
+ current += len;
+ }
+ return current;
case GSM_EMSPicture:
dprintf("EMS picture\n");
if (bitmap->width % 8) {
Index: common/gsm-sms.c
===================================================================
RCS file: /cvsroot/gnokii/gnokii/common/gsm-sms.c,v
retrieving revision 1.80
diff -u -u -r1.80 gsm-sms.c
--- common/gsm-sms.c 27 May 2002 22:56:50 -0000 1.80
+++ common/gsm-sms.c 29 May 2002 23:05:35 -0000
@@ -58,11 +58,11 @@
{ 0x06, "\x05\x04\x15\x81\x00\x00" }, /* Ringtones */
{ 0x06, "\x05\x04\x15\x82\x00\x00" }, /* Operator logos */
{ 0x06, "\x05\x04\x15\x83\x00\x00" }, /* Caller logos */
- { 0x06, "\x05\x04\x15\x8a\x00\x00" }, /* Multipart Message */
+ { 0x0B, "\x05\x04\x15\x8a\x00\x00\x00\x03\xce\x03\x01" }, /* Multipart
Message */
{ 0x06, "\x05\x04\x23\xf4\x00\x00" }, /* WAP vCard */
- { 0x06, "\x05\0x4\x23\xf5\x00\x00" }, /* WAP vCalendar */
+ { 0x06, "\x05\x04\x23\xf5\x00\x00" }, /* WAP vCalendar */
{ 0x06, "\x05\x04\x23\xf6\x00\x00" }, /* WAP vCardSecure */
- { 0x06, "\x05\0x4\x23\xf7\x00\x00" }, /* WAP vCalendarSecure */
+ { 0x06, "\x05\x04\x23\xf7\x00\x00" }, /* WAP vCalendarSecure */
{ 0x04, "\x03\x01\x00\x00" }, /* Voice Messages */
{ 0x04, "\x03\x01\x01\x00" }, /* Fax Messages */
{ 0x04, "\x03\x01\x02\x00" }, /* Email Messages */
@@ -1019,15 +1019,10 @@
{
SMS_AlphabetType al;
unsigned int i, length, size = 0, offset = 0;
- int text_index = -1, bitmap_index = -1, ringtone_index = -1,
imelody_index = -1;
+ int text_index = -1, bitmap_index = -1, ringtone_index = -1,
imelody_index = -1, multi_index = -1;
char *message = rawsms->UserData;
GSM_Error error;
-#if 0
- /* Version: Smart Messaging Specification 3.0.0 */
- if (multipart)
- message[0] = 0x30;
-#endif
for (i = 0; i < 3; i++) {
switch (sms->UserData[i].Type) {
case SMS_PlainText:
@@ -1038,6 +1033,8 @@
ringtone_index = i; break;
case SMS_iMelodyText:
imelody_index = i; break;
+ case SMS_MultiData:
+ multi_index = i; break;
case SMS_NoData:
break;
default:
@@ -1135,12 +1132,27 @@
rawsms->UDHIndicator = 1;
}
+ /* MultiData coding */
+ if (multi_index != -1) {
+ size = 128;
+ error = EncodeUDH(rawsms, 0x05, message);
+ rawsms->UserData[10] = sms->UserData[multi_index].u.Multi.total;
+ rawsms->UserData[11] = sms->UserData[multi_index].u.Multi.this;
+ if (error != GE_NONE) return error;
+ memcpy(message + rawsms->UserDataLength,
sms->UserData[multi_index].u.Multi.Binary, 128);
+ rawsms->Length += size;
+ rawsms->UserDataLength += size;
+ rawsms->DCS = 0xf5;
+ rawsms->UDHIndicator = 1;
+ }
+
/* Bitmap coding */
if (bitmap_index != -1) {
error = GE_NONE;
switch (sms->UserData[0].u.Bitmap.type) {
case GSM_OperatorLogo: error = EncodeUDH(rawsms, SMS_OpLogo,
message); break;
case GSM_EMSPicture:
+ case GSM_PictureMessage:
case GSM_EMSAnimation: break; /* We'll construct headers in
EncodeSMSBitmap */
}
if (error != GE_NONE) return error;
@@ -1208,6 +1220,32 @@
printf("UserData: %s\n", buf);
}
+API GSM_Error SendLongSMS(GSM_Data *data, GSM_Statemachine *state)
+{
+ int i, count;
+ GSM_SMSMessage LongSMS, *rawsms = &LongSMS; /* We need local copy
for our dirty tricks */
+ GSM_API_SMS sms;
+ GSM_Error error = GE_NONE;
+
+ LongSMS = *data->RawSMS;
+ sms = *data->SMS;
+
+ DumpRawSMS(rawsms);
+ count = (rawsms->UserDataLength + 127) / 128;
+ printf("Will need %d sms-es\n", count);
+ for (i=0; i<count; i++) {
+ printf("Sending sms #%d\n", i);
+ sms.UserData[0].Type = SMS_MultiData;
+ memcpy(sms.UserData[0].u.Multi.Binary, rawsms->UserData +
i*128, 128);
+ sms.UserData[0].u.Multi.this = i+1;
+ sms.UserData[0].u.Multi.total = count;
+ data->SMS = &sms;
+ error = SendSMS(data, state);
+ if (error != GE_NONE) return error;
+ }
+ return GE_NONE;
+}
+
/**
* SendSMS - The main function for the SMS sending
* @data:
@@ -1217,9 +1255,8 @@
{
GSM_Error error = GE_NONE;
GSM_RawData rawdata;
- int i, count;
+ int i;
- count = 1;
#if 0
/* AT does not need smsc */
if (data->SMS->MessageCenter.No) {
@@ -1229,25 +1266,25 @@
}
#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;
+ data->RawData->Data = calloc(10240, 1);
-// DumpRawSMS(data->RawSMS); Usefull for debugging...
- error = SM_Functions(GOP_SendSMS, data, state);
+ error = PrepareSMS(data, 0);
+ if (error != GE_NONE) return error;
- free(data->RawData->Data);
- if (error != GE_NONE) break;
+ if (data->RawSMS->Length > 171) {
+ printf("SMS is too long? %d\n", data->RawSMS->Length);
+ return SendLongSMS(data, state);
}
+
+ error = SM_Functions(GOP_SendSMS, data, state);
+
+ free(data->RawData->Data);
+
data->RawData = NULL;
return error;
}
Index: include/gsm-sms.h
===================================================================
RCS file: /cvsroot/gnokii/gnokii/include/gsm-sms.h,v
retrieving revision 1.38
diff -u -u -r1.38 gsm-sms.h
--- include/gsm-sms.h 26 May 2002 15:09:57 -0000 1.38
+++ include/gsm-sms.h 29 May 2002 23:06:14 -0000
@@ -303,7 +303,8 @@
SMS_BitmapData = 0x02,
SMS_RingtoneData = 0x03,
SMS_iMelodyText = 0x04,
- SMS_OtherData = 0x05
+ SMS_MultiData = 0x05,
+ SMS_OtherData = 0x06
} SMS_DataType;
/*** FOLDER INFO ***/
@@ -332,10 +333,16 @@
} SMS_FolderStats;
typedef struct {
+ unsigned char Binary[GSM_MAX_SMS_LENGTH];
+ int this, total; /* Number of this part, total number of parts */
+} GSM_Multi;
+
+typedef struct {
SMS_DataType Type;
unsigned int Length;
union {
unsigned char Text[GSM_MAX_SMS_LENGTH];
+ GSM_Multi Multi;
GSM_Bitmap Bitmap;
GSM_Ringtone Ringtone;
} u;
@@ -435,7 +442,7 @@
unsigned int DCS; /* Data Coding Scheme
(9.2.3.10) */
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 */
+ unsigned char UserData[10240]; /* 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;
--
(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
- Picture SMS-es and long sms support,
Pavel Machek <=