/* (c) 2002-2004 by Marcin Wiacek */ #include #include #include #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../gsmcal.h" #include "../gsmpbk.h" #include "../gsmlogo.h" #include "../gsmring.h" #include "../gsmdata.h" #include "../gsmnet.h" #include "gsmsms.h" #include "gsmmulti.h" /* EMS Developers' Guidelines from www.sonyericsson.com * docs from Alcatel */ GSM_Error GSM_EncodeEMSMultiPartSMS(GSM_MultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS, GSM_UDH UDHType) { unsigned char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; int i,UsedText,j,Length,Width,Height,z,x,y; unsigned int Len; int Used,FreeText,FreeBytes,Width2,CopiedText,CopiedSMSText; unsigned char UDHID; GSM_Bitmap Bitmap,Bitmap2; GSM_Ringtone Ring; GSM_Coding_Type Coding = SMS_Coding_Default; GSM_Phone_Bitmap_Types BitmapType; MultiPartSMSEntry *Entry; bool start; GSM_DateTime Date; #ifdef DEBUG if (UDHType != UDH_NoUDH) dbgprintf("linked EMS\n"); #endif if (Info->UnicodeCoding) Coding = SMS_Coding_Unicode; /* Cleaning on the start */ for (i=0;iSMS[i]); SMS->SMS[i].UDH.Type = UDHType; GSM_EncodeUDHHeader(&SMS->SMS[i].UDH); SMS->SMS[i].Coding = Coding; } /* Packing */ for (i=0;iEntriesNum;i++) { Entry = &Info->Entries[i]; switch (Entry->ID) { case SMS_ConcatenatedTextLong: case SMS_ConcatenatedTextLong16bit: Len = 0; while(1) { if (Entry->Left || Entry->Right || Entry->Center || Entry->Large || Entry->Small || Entry->Bold || Entry->Italic || Entry->Underlined || Entry->Strikethrough) { Buffer[0] = 0x0A; /* ID for text format */ Buffer[1] = 0x03; /* length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ Buffer[3] = 0x00; /* how many chars */ Buffer[4] = 0x00; /* formatting bits */ if (Entry->Left) { } else if (Entry->Right) { Buffer[4] |= 1; } else if (Entry->Center) { Buffer[4] |= 2; } else Buffer[4] |= 3; if (Entry->Large) { Buffer[4] |= 4; } else if (Entry->Small) { Buffer[4] |= 8;} if (Entry->Bold) Buffer[4] |= 16; if (Entry->Italic) Buffer[4] |= 32; if (Entry->Underlined) Buffer[4] |= 64; if (Entry->Strikethrough) Buffer[4] |= 128; GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5,true,&UsedText,&CopiedText,&CopiedSMSText); GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); if (FreeText == 0) continue; } GSM_AddSMS_Text_UDH(SMS,Coding,Entry->Buffer+Len*2,UnicodeLength(Entry->Buffer) - Len,false,&UsedText,&CopiedText,&CopiedSMSText); if (Entry->Left || Entry->Right || Entry->Center || Entry->Large || Entry->Small || Entry->Bold || Entry->Italic || Entry->Underlined || Entry->Strikethrough) { SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3] = UsedText; SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = CopiedSMSText; } Len += CopiedText; if (Len == UnicodeLength(Entry->Buffer)) break; dbgprintf("%i %i\n",Len,UnicodeLength(Entry->Buffer)); } break; case SMS_EMSPredefinedSound: case SMS_EMSPredefinedAnimation: if (Entry->ID == SMS_EMSPredefinedSound) { Buffer[0] = 0x0B; /* ID for def.sound */ } else { Buffer[0] = 0x0D; /* ID for def.animation */ } Buffer[1] = 0x02; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ Buffer[3] = Entry->Number; /* Number of anim. */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = UsedText; break; case SMS_EMSSonyEricssonSound: case SMS_EMSSound10: case SMS_EMSSound12: if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } Length = 128; /* 128 bytes is maximal length from specs */ switch (Entry->ID) { case SMS_EMSSound10: Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.0, true); break; case SMS_EMSSound12: Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.2, true); break; case SMS_EMSSonyEricssonSound: Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 0, true); break; default: break; } Buffer[0] = 0x0C; /* ID for EMS sound */ Buffer[1] = Length+1; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; break; case SMS_EMSSonyEricssonSoundLong: case SMS_EMSSound10Long: case SMS_EMSSound12Long: Ring = *Entry->Ringtone; /* First check if we can use classic format */ Length = 128; /* 128 bytes is maximal length from specs */ switch (Entry->ID) { case SMS_EMSSound10Long: Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, true); break; case SMS_EMSSound12Long: Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, true); break; case SMS_EMSSonyEricssonSoundLong: Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, true); break; default: break; } if (Entry->RingtoneNotes == Ring.NoteTone.NrCommands) { if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } Buffer[0] = 0x0C; /* ID for EMS sound */ Buffer[1] = Length+1; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; break; } /* Find free place in first SMS */ GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); Length = FreeBytes - 3; if (Entry->Protected) Length = Length - 4; if (Length < 0) Length = 128; if (Length > 128) Length = 128; Ring = *Entry->Ringtone; /* Checking number of SMS */ Used = 0; FreeBytes = 0; start = true; while (1) { if (FreeBytes != 0) { z = 0; for (j=FreeBytes;jID) { case SMS_EMSSound10Long: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); break; case SMS_EMSSound12Long: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); break; case SMS_EMSSonyEricssonSoundLong: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); break; default: break; } start = false; Used++; } dbgprintf("Used SMS: %i\n",Used); if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = Used+1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } /* Save UPI UDH */ Buffer[0] = 0x13; /* ID for UPI */ Buffer[1] = 1; /* Length of rest */ Buffer[2] = Used; /* Number of used parts */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); /* Find free place in first SMS */ GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); Length = FreeBytes - 3; if (Length < 0) Length = 128; if (Length > 128) Length = 128; Ring = *Entry->Ringtone; /* Saving */ FreeBytes = 0; start = true; while (1) { if (FreeBytes != 0) { z = 0; for (j=FreeBytes;jID) { case SMS_EMSSound10Long: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); break; case SMS_EMSSound12Long: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); break; case SMS_EMSSonyEricssonSoundLong: FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); break; default: break; } Buffer[0] = 0x0C; /* ID for EMS sound */ Buffer[1] = Length+1; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; start = false; } Entry->RingtoneNotes = Entry->Ringtone->NoteTone.NrCommands; break; case SMS_EMSAnimation: if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } if (Entry->Bitmap->Bitmap[0].BitmapWidth > 8 || Entry->Bitmap->Bitmap[0].BitmapHeight > 8) { BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ Buffer[0] = 0x0E; /* ID for 16x16 animation */ } else { BitmapType = GSM_EMSSmallPicture; /* Bitmap 8x8 */ Buffer[0] = 0x0F; /* ID for 8x8 animation */ } Length = PHONE_GetBitmapSize(BitmapType,0,0); Buffer[1] = Length*Entry->Bitmap->Number + 1; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ for (j=0;jBitmap->Number;j++) { PHONE_EncodeBitmap(BitmapType, Buffer+3+j*Length, &Entry->Bitmap->Bitmap[j]); } GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length*Entry->Bitmap->Number,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length*Entry->Bitmap->Number] = UsedText; break; case SMS_EMSFixedBitmap: if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } if (Entry->Bitmap->Bitmap[0].BitmapWidth > 16 || Entry->Bitmap->Bitmap[0].BitmapHeight > 16) { BitmapType = GSM_EMSBigPicture; /* Bitmap 32x32 */ Buffer[0] = 0x10; /* ID for EMS bitmap */ } else { BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ Buffer[0] = 0x11; /* ID for EMS bitmap */ } Length = PHONE_GetBitmapSize(BitmapType,0,0); PHONE_GetBitmapWidthHeight(BitmapType, &Width, &Height); Buffer[1] = Length + 1; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ PHONE_EncodeBitmap(BitmapType,Buffer+3, &Entry->Bitmap->Bitmap[0]); GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length] = UsedText; break; case SMS_EMSVariableBitmapLong: BitmapType = GSM_EMSVariablePicture; Width = Entry->Bitmap->Bitmap[0].BitmapWidth; Height = Entry->Bitmap->Bitmap[0].BitmapHeight; Bitmap = Entry->Bitmap->Bitmap[0]; /* First check if we can use classical format */ while (1) { /* Width should be multiply of 8 */ while (Width % 8 != 0) Width--; /* specs */ if (Width <= 96 && Height <= 128) break; Height--; } Length = PHONE_GetBitmapSize(BitmapType,Width,Height); if (Length <= 128) { if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } Buffer[0] = 0x12; /* ID for EMS bitmap */ Buffer[1] = Length + 3; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ Buffer[3] = Width/8; /* Bitmap width/8 */ Buffer[4] = Height; /* Bitmap height */ GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); #endif PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; break; } /* Find free place in first SMS */ GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); Used = 0; Length = FreeBytes - 3; if (Entry->Protected) Length = Length - 4; if (Length < 0) Length = 128; if (Length > 128) Length = 128; /* Checking number of SMS */ FreeBytes = 0; while (FreeBytes != Width) { Width2 = 8; while (FreeBytes + Width2 != Width) { if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; Width2 = Width2 + 8; } FreeBytes = FreeBytes + Width2; Length = 128; Used ++; } dbgprintf("Used SMS: %i\n",Used); if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = Used+1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } /* Save UPI UDH */ Buffer[0] = 0x13; /* ID for UPI */ Buffer[1] = 1; /* Length of rest */ Buffer[2] = Used; /* Number of used parts */ /* Find free place in first SMS */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); Length = FreeBytes - 3; if (Length < 0) Length = 128; if (Length > 128) Length = 128; #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); #endif /* Saving SMS */ FreeBytes = 0; while (FreeBytes != Width) { Width2 = 8; while (FreeBytes + Width2 != Width) { if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; Width2 = Width2 + 8; } /* Copying part of bitmap to new structure */ Bitmap2.BitmapWidth = Width2; Bitmap2.BitmapHeight = Height; GSM_ClearBitmap(&Bitmap2); for (x=0;xSMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; FreeBytes = FreeBytes + Width2; Length = 128; } break; case SMS_EMSVariableBitmap: if (Entry->Protected) { Buffer[0] = 0x17; /* ID for ODI */ Buffer[1] = 2; /* Length of rest */ Buffer[2] = 1; /* Number of protected objects */ Buffer[3] = 1; /* 1=Protected,0=Not protected */ GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); } BitmapType = GSM_EMSVariablePicture; Width = Entry->Bitmap->Bitmap[0].BitmapWidth; Height = Entry->Bitmap->Bitmap[0].BitmapHeight; while (1) { /* Width should be multiply of 8 */ while (Width % 8 != 0) Width--; /* specs */ if (PHONE_GetBitmapSize(BitmapType,Width,Height) <= 128) break; Height--; } Length = PHONE_GetBitmapSize(BitmapType,Width,Height); Buffer[0] = 0x12; /* ID for EMS bitmap */ Buffer[1] = Length + 3; /* Length of rest */ Buffer[2] = 0x00; /* Position in EMS msg */ Buffer[3] = Width/8; /* Bitmap width/8 */ Buffer[4] = Height; /* Bitmap height */ GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); #endif PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; break; default: break; } } SMS->Number++; if (UDHType == UDH_ConcatenatedMessages) { UDHID = GSM_MakeSMSIDFromTime(); for (i=0;iNumber;i++) { SMS->SMS[i].UDH.Text[2+1] = UDHID; SMS->SMS[i].UDH.Text[3+1] = SMS->Number; SMS->SMS[i].UDH.Text[4+1] = i+1; } } if (UDHType == UDH_ConcatenatedMessages16bit) { UDHID = GSM_MakeSMSIDFromTime(); GSM_GetCurrentDateTime (&Date); for (i=0;iNumber;i++) { SMS->SMS[i].UDH.Text[2+1] = Date.Hour; SMS->SMS[i].UDH.Text[3+1] = UDHID; SMS->SMS[i].UDH.Text[4+1] = SMS->Number; SMS->SMS[i].UDH.Text[5+1] = i+1; } } #ifdef DEBUG dbgprintf("SMS number is %i\n",SMS->Number); for (i=0;iNumber;i++) { dbgprintf("UDH length %i\n",SMS->SMS[i].UDH.Length); DumpMessage(di.df, di.dl, SMS->SMS[i].UDH.Text, SMS->SMS[i].UDH.Length); dbgprintf("SMS length %i\n",UnicodeLength(SMS->SMS[i].Text)*2); DumpMessage(di.df, di.dl, SMS->SMS[i].Text, UnicodeLength(SMS->SMS[i].Text)*2); } #endif return ERR_NONE; } static bool AddEMSText(GSM_SMSMessage *SMS, GSM_MultiPartSMSInfo *Info, int *Pos, int Len) { int BufferLen; if (Len==0) return true; if (Info->Entries[Info->EntriesNum].ID!=SMS_ConcatenatedTextLong && Info->Entries[Info->EntriesNum].ID!=0) { (Info->EntriesNum)++; } BufferLen = UnicodeLength(Info->Entries[Info->EntriesNum].Buffer)*2; switch (SMS->Coding) { case SMS_Coding_8bit: // memcpy(Info->Entries[Info->EntriesNum].Buffer+BufferLen,SMS->Text+(*Pos),Len); // BufferLen+=Len; // (*Pos)+=Len; break; case SMS_Coding_Unicode: case SMS_Coding_Default: Info->Entries[Info->EntriesNum].Buffer = realloc(Info->Entries[Info->EntriesNum].Buffer, BufferLen + (Len * 2) + 2); if (Info->Entries[Info->EntriesNum].Buffer == NULL) return false; memcpy(Info->Entries[Info->EntriesNum].Buffer + BufferLen, SMS->Text + (*Pos) *2, Len * 2); BufferLen += Len * 2; break; } (*Pos)+=Len; Info->Entries[Info->EntriesNum].Buffer[BufferLen] = 0; Info->Entries[Info->EntriesNum].Buffer[BufferLen+1] = 0; Info->Entries[Info->EntriesNum].ID = SMS_ConcatenatedTextLong; return true; } bool GSM_DecodeEMSMultiPartSMS(GSM_MultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS) { int i, w, Pos, z, UPI = 1, width, height; bool RetVal = false, NewPicture = true; GSM_Phone_Bitmap_Types BitmapType; GSM_Bitmap Bitmap,Bitmap2; for (i=0;iEntries[i].ID = 0; } for (i=0;iNumber;i++) { Pos = 0; w = 1; while (w < SMS->SMS[i].UDH.Length) { if (Info->EntriesNum + 1 == MAX_MULTI_SMS) { dbgprintf("Couldn't parse SMS, contains too many EMS parts!\n"); return false; } switch(SMS->SMS[i].UDH.Text[w]) { case 0x00: dbgprintf("UDH part - linked SMS with 8 bit ID\n"); break; case 0x08: dbgprintf("UDH part - linked SMS with 16 bit ID\n"); break; // case 0x0A: // dbgprintf("UDH part - EMS text formatting\n"); // break; case 0x0B: dbgprintf("UDH part - default EMS sound\n"); if (SMS->SMS[i].UDH.Text[w+2] > Pos) { z = Pos; if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z)) return false; } if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; Info->Entries[Info->EntriesNum].Number = SMS->SMS[i].UDH.Text[w+3]; Info->Entries[Info->EntriesNum].ID = SMS_EMSPredefinedSound; RetVal = true; break; // case 0x0C: // dbgprintf("UDH part - EMS sound\n"); // break; case 0x0D: dbgprintf("UDH part - default EMS animation\n"); if (SMS->SMS[i].UDH.Text[w+2] > Pos) { z = Pos; if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z)) return false; } if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; Info->Entries[Info->EntriesNum].Number = SMS->SMS[i].UDH.Text[w+3]; Info->Entries[Info->EntriesNum].ID = SMS_EMSPredefinedAnimation; RetVal = true; break; case 0x0E: case 0x0F: if (SMS->SMS[i].UDH.Text[w] == 0x0E) { dbgprintf("UDH part - EMS 16x16 animation\n"); BitmapType = GSM_EMSMediumPicture; } else { dbgprintf("UDH part - EMS 8x8 animation\n"); BitmapType = GSM_EMSSmallPicture; } dbgprintf("Position - %i\n",SMS->SMS[i].UDH.Text[w+2]); if (SMS->SMS[i].UDH.Text[w+2] > Pos) { z = Pos; if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z)) return false; } (Info->EntriesNum)++; Info->Entries[Info->EntriesNum].ID = SMS_EMSAnimation; Info->Entries[Info->EntriesNum].Bitmap = (GSM_MultiBitmap *)malloc(sizeof(GSM_MultiBitmap)); if (Info->Entries[Info->EntriesNum].Bitmap == NULL) return false; Info->Entries[Info->EntriesNum].Bitmap->Number = 0; for (z=0;z<((SMS->SMS[i].UDH.Text[w+1]-1)/PHONE_GetBitmapSize(BitmapType,0,0));z++) { Info->Entries[Info->EntriesNum].Bitmap->Bitmap[z].Type = GSM_PictureImage; PHONE_DecodeBitmap(BitmapType, SMS->SMS[i].UDH.Text + w + 3 + PHONE_GetBitmapSize(BitmapType,0,0) * z, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[z]); Info->Entries[Info->EntriesNum].Bitmap->Number++; } RetVal = true; break; case 0x10: case 0x11: if (SMS->SMS[i].UDH.Text[w] == 0x10) { dbgprintf("UDH part - EMS 32x32 picture\n"); BitmapType = GSM_EMSBigPicture; } else { dbgprintf("UDH part - EMS 16x16 picture\n"); BitmapType = GSM_EMSMediumPicture; } dbgprintf("Position - %i\n",SMS->SMS[i].UDH.Text[w+2]); if (SMS->SMS[i].UDH.Text[w+2] > Pos) { z = Pos; if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z)) return false; } if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; Info->Entries[Info->EntriesNum].Bitmap = (GSM_MultiBitmap *)malloc(sizeof(GSM_MultiBitmap)); if (Info->Entries[Info->EntriesNum].Bitmap == NULL) return false; PHONE_DecodeBitmap(BitmapType, SMS->SMS[i].UDH.Text + w + 3, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0]); Info->Entries[Info->EntriesNum].Bitmap->Number = 1; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[0] = 0; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[1] = 0; Info->Entries[Info->EntriesNum].ID = SMS_EMSFixedBitmap; RetVal = true; break; case 0x12: dbgprintf("UDH part - EMS variable width bitmap\n"); if (SMS->SMS[i].UDH.Text[w+2] > Pos) { z = Pos; if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z)) return false; } if (NewPicture) { (Info->EntriesNum)++; Info->Entries[Info->EntriesNum].Bitmap->Number = 0; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapWidth = 0; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapHeight = 0; } Bitmap.BitmapWidth = SMS->SMS[i].UDH.Text[w+3]*8; Bitmap.BitmapHeight = SMS->SMS[i].UDH.Text[w+4]; Info->Entries[Info->EntriesNum].Bitmap = (GSM_MultiBitmap *)malloc(sizeof(GSM_MultiBitmap)); if (Info->Entries[Info->EntriesNum].Bitmap == NULL) return false; if (NewPicture) { Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapWidth = Bitmap.BitmapWidth; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapHeight = Bitmap.BitmapHeight; PHONE_DecodeBitmap(GSM_EMSVariablePicture, SMS->SMS[i].UDH.Text + w + 5, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0]); } else { PHONE_DecodeBitmap(GSM_EMSVariablePicture, SMS->SMS[i].UDH.Text + w + 5, &Bitmap); Bitmap2 = Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0]; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapWidth = Bitmap.BitmapWidth+Bitmap2.BitmapWidth; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].BitmapHeight = Bitmap2.BitmapHeight; for (width=0;widthEntries[Info->EntriesNum].Bitmap->Bitmap[0],width,height); } else { GSM_ClearPointBitmap(&Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0],width,height); } } } for (width=0;widthEntries[Info->EntriesNum].Bitmap->Bitmap[0],width+Bitmap2.BitmapWidth,height); } else { GSM_ClearPointBitmap(&Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0],width+Bitmap2.BitmapWidth,height); } } } } if (UPI == 1) { Info->Entries[Info->EntriesNum].Bitmap->Number = 1; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[0] = 0; Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[1] = 0; Info->Entries[Info->EntriesNum].ID = SMS_EMSVariableBitmap; RetVal = true; NewPicture = true; dbgprintf("New variable picture\n"); } else { NewPicture = false; UPI--; } break; case 0x13: dbgprintf("UDH part - UPI\n"); dbgprintf("Value %i\n",SMS->SMS[i].UDH.Text[w+2]); UPI = SMS->SMS[i].UDH.Text[w+2]; break; case 0x17: dbgprintf("UDH part - Object Distribution Indicator (Media Rights Protecting) ignored now\n"); break; default: dbgprintf("UDH part - block %02x\n",SMS->SMS[i].UDH.Text[w]); Info->Unknown = true; } /* switch */ w=w+SMS->SMS[i].UDH.Text[w+1]+2; } /* while */ if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].Length-Pos)) return false; RetVal = true; } if (RetVal) (Info->EntriesNum)++; return RetVal; } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */