-rw-r--r-- | gammu/emb/common/service/backup/backgen.h | 4 | ||||
-rw-r--r-- | gammu/emb/common/service/backup/backtext.c | 221 | ||||
-rw-r--r-- | gammu/emb/common/service/backup/gsmback.c | 36 | ||||
-rw-r--r-- | gammu/emb/common/service/backup/gsmback.h | 2 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmcal.h | 2 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmdata.c | 120 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmdata.h | 2 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmlogo.c | 47 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmlogo.h | 28 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmmisc.h | 7 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmring.c | 45 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmring.h | 8 | ||||
-rw-r--r-- | gammu/emb/common/service/sms/gsmmulti.c | 5 | ||||
-rw-r--r-- | gammu/emb/common/service/sms/gsmmulti.h | 11 | ||||
-rw-r--r-- | gammu/emb/common/service/sms/gsmsms.c | 5 | ||||
-rw-r--r-- | gammu/emb/common/service/sms/gsmsms.h | 5 |
16 files changed, 491 insertions, 57 deletions
diff --git a/gammu/emb/common/service/backup/backgen.h b/gammu/emb/common/service/backup/backgen.h index 9d7d973..9a930fc 100644 --- a/gammu/emb/common/service/backup/backgen.h +++ b/gammu/emb/common/service/backup/backgen.h @@ -1,69 +1,73 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_backgen_h #define __gsm_backgen_h #include "../../config.h" #include "../../misc/misc.h" #include "../gsmpbk.h" #include "../gsmcal.h" #include "../gsmlogo.h" #include "../gsmring.h" #include "../gsmdata.h" #include "../gsmprof.h" #include "../gsmmisc.h" #include "../sms/gsmsms.h" #define GSM_BACKUP_MAX_PHONEPHONEBOOK 501 #define GSM_BACKUP_MAX_SIMPHONEBOOK 251 #define GSM_BACKUP_MAX_CALLER 6 #define GSM_BACKUP_MAX_SMSC 10 #define GSM_BACKUP_MAX_WAPBOOKMARK 40 #define GSM_BACKUP_MAX_WAPSETTINGS 30 #define GSM_BACKUP_MAX_MMSSETTINGS 30 +#define GSM_BACKUP_MAX_SYNCMLSETTINGS 10 +#define GSM_BACKUP_MAX_CHATSETTINGS 10 #define GSM_BACKUP_MAX_RINGTONES 30 #define GSM_BACKUP_MAX_PROFILES 10 #define GSM_BACKUP_MAX_FMSTATIONS 20 #define GSM_BACKUP_MAX_GPRSPOINT 10 #define GSM_BACKUP_MAX_NOTE 10 /* FIXME */ typedef struct { char IMEI [MAX_IMEI_LENGTH]; char Model [MAX_MODEL_LENGTH+MAX_VERSION_LENGTH]; char Creator [80]; GSM_DateTime DateTime; bool DateTimeAvailable; char MD5Original [100]; char MD5Calculated [100]; GSM_MemoryEntry *PhonePhonebook [GSM_BACKUP_MAX_PHONEPHONEBOOK + 1]; GSM_MemoryEntry *SIMPhonebook [GSM_BACKUP_MAX_SIMPHONEBOOK + 1]; GSM_CalendarEntry *Calendar [GSM_MAXCALENDARTODONOTES + 1]; GSM_Bitmap *CallerLogos [GSM_BACKUP_MAX_CALLER + 1]; GSM_SMSC *SMSC [GSM_BACKUP_MAX_SMSC + 1]; GSM_WAPBookmark *WAPBookmark [GSM_BACKUP_MAX_WAPBOOKMARK + 1]; GSM_MultiWAPSettings *WAPSettings [GSM_BACKUP_MAX_WAPSETTINGS + 1]; GSM_MultiWAPSettings *MMSSettings [GSM_BACKUP_MAX_MMSSETTINGS + 1]; + GSM_SyncMLSettings *SyncMLSettings [GSM_BACKUP_MAX_SYNCMLSETTINGS + 1]; + GSM_ChatSettings *ChatSettings [GSM_BACKUP_MAX_CHATSETTINGS + 1]; GSM_Ringtone *Ringtone [GSM_BACKUP_MAX_RINGTONES + 1]; GSM_ToDoEntry *ToDo [GSM_MAXCALENDARTODONOTES + 1]; GSM_Profile *Profiles [GSM_BACKUP_MAX_PROFILES + 1]; GSM_FMStation *FMStation [GSM_BACKUP_MAX_FMSTATIONS +1]; GSM_GPRSAccessPoint *GPRSPoint [GSM_BACKUP_MAX_GPRSPOINT + 1]; GSM_NoteEntry *Note [GSM_BACKUP_MAX_NOTE + 1]; GSM_Bitmap *StartupLogo; GSM_Bitmap *OperatorLogo; } GSM_Backup; #define GSM_BACKUP_MAX_SMS 500 typedef struct { GSM_SMSMessage *SMS[GSM_BACKUP_MAX_SMS]; } GSM_SMS_Backup; extern GSM_Error GSM_ReadSMSBackupFile(char *FileName, GSM_SMS_Backup *backup); extern GSM_Error GSM_SaveSMSBackupFile(char *FileName, GSM_SMS_Backup *backup); #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/backup/backtext.c b/gammu/emb/common/service/backup/backtext.c index fee0f73..4cb1bb7 100644 --- a/gammu/emb/common/service/backup/backtext.c +++ b/gammu/emb/common/service/backup/backtext.c @@ -106,143 +106,144 @@ static void SaveLinkedBackupText(FILE *file, char *myname, char *myvalue, bool U current = 0; } if (UseUnicode) { sprintf(buffer3,"%s%02i = %s%c%c",myname,w,buffer2,13,10); EncodeUnicode(buffer2,buffer3,strlen(buffer3)); fwrite(buffer2,1,strlen(buffer3)*2,file); } else { fprintf(file,"%s%02i = %s%c%c",myname,w,buffer2,13,10); } if (current == 0) break; w++; } } static void ReadLinkedBackupText(INI_Section *file_info, char *section, char *myname, char *myvalue, bool UseUnicode) { unsigned char buffer2[300]; char *readvalue; int i; i=0; myvalue[0] = 0; while (true) { sprintf(buffer2,"%s%02i",myname,i); readvalue = ReadCFGText(file_info, section, buffer2, UseUnicode); if (readvalue!=NULL) { myvalue[strlen(myvalue)+strlen(readvalue)]=0; memcpy(myvalue+strlen(myvalue),readvalue,strlen(readvalue)); } else break; i++; } } static void SaveBackupText(FILE *file, char *myname, char *myvalue, bool UseUnicode) { unsigned char buffer[10000], buffer2[10000]; if (myname[0] == 0x00) { if (UseUnicode) { EncodeUnicode(buffer,myvalue,strlen(myvalue)); fwrite(buffer,1,strlen(myvalue)*2,file); } else fprintf(file,"%s",myvalue); } else { if (UseUnicode) { sprintf(buffer,"%s = \"",myname); EncodeUnicode(buffer2,buffer,strlen(buffer)); fwrite(buffer2,1,strlen(buffer)*2,file); - fwrite(myvalue,1,UnicodeLength(myvalue)*2,file); + fwrite(EncodeUnicodeSpecialChars(myvalue),1,UnicodeLength(EncodeUnicodeSpecialChars(myvalue))*2,file); sprintf(buffer,"\"%c%c",13,10); EncodeUnicode(buffer2,buffer,strlen(buffer)); fwrite(buffer2,1,strlen(buffer)*2,file); } else { - sprintf(buffer,"%s = \"%s\"%c%c",myname,DecodeUnicodeString(myvalue),13,10); + sprintf(buffer,"%s = \"%s\"%c%c",myname,EncodeSpecialChars(DecodeUnicodeString(myvalue)),13,10); fprintf(file,"%s",buffer); EncodeHexBin(buffer,myvalue,UnicodeLength(myvalue)*2); fprintf(file,"%sUnicode = %s%c%c",myname,buffer,13,10); } } } static bool ReadBackupText(INI_Section *file_info, char *section, char *myname, char *myvalue, bool UseUnicode) { unsigned char paramname[10000],*readvalue; if (UseUnicode) { EncodeUnicode(paramname,myname,strlen(myname)); readvalue = INI_GetValue(file_info, section, paramname, UseUnicode); if (readvalue!=NULL) { - CopyUnicodeString(myvalue,readvalue+2); - myvalue[UnicodeLength(readvalue)*2-4]=0; - myvalue[UnicodeLength(readvalue)*2-3]=0; + CopyUnicodeString(myvalue,DecodeUnicodeSpecialChars(readvalue+2)); + myvalue[UnicodeLength(myvalue)*2-2]=0; + myvalue[UnicodeLength(myvalue)*2-1]=0; + dbgprintf("%s\n",DecodeUnicodeString(readvalue)); } else { myvalue[0]=0; myvalue[1]=0; return false; } } else { strcpy(paramname,myname); strcat(paramname,"Unicode"); readvalue = ReadCFGText(file_info, section, paramname, UseUnicode); if (readvalue!=NULL) { dbgprintf("%s %i\n",readvalue,strlen(readvalue)); DecodeHexBin (myvalue, readvalue, strlen(readvalue)); myvalue[strlen(readvalue)/2]=0; myvalue[strlen(readvalue)/2+1]=0; dbgprintf("%s\n",DecodeUnicodeString(myvalue)); } else { strcpy(paramname,myname); readvalue = ReadCFGText(file_info, section, paramname, UseUnicode); if (readvalue!=NULL) { - EncodeUnicode(myvalue,readvalue+1,strlen(readvalue)-2); + EncodeUnicode(myvalue,DecodeSpecialChars(readvalue+1),strlen(DecodeSpecialChars(readvalue+1))-1); } else { myvalue[0]=0; myvalue[1]=0; return false; } } } return true; } static void SaveVCalDateTime(FILE *file, GSM_DateTime *dt, bool UseUnicode) { unsigned char buffer[100]; int Length = 3; sprintf(buffer, " = "); SaveVCALDateTime(buffer, &Length, dt, NULL); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveVCalDate(FILE *file, GSM_DateTime *dt, bool UseUnicode) { unsigned char buffer[100]; sprintf(buffer, " = %04d%02d%02d%c%c", dt->Year, dt->Month, dt->Day,13,10); SaveBackupText(file, "", buffer, UseUnicode); } /* ---------------------- backup files ------------------------------------- */ static void SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, bool UseUnicode) { bool text; char buffer[1000]; int j, i; sprintf(buffer,"Location = %03i%c%c",Pbk->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); for (j=0;j<Pbk->EntriesNum;j++) { text = true; switch (Pbk->Entries[j].EntryType) { case PBK_Number_General: sprintf(buffer,"Entry%02iType = NumberGeneral%c%c",j,13,10); SaveBackupText(file, "", buffer, UseUnicode); break; case PBK_Number_Mobile: sprintf(buffer,"Entry%02iType = NumberMobile%c%c",j,13,10); SaveBackupText(file, "", buffer, UseUnicode); @@ -373,96 +374,107 @@ static void SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, bool UseUnicode) case PBK_Text_Custom2: sprintf(buffer,"Entry%02iType = Custom2%c%c",j,13,10); SaveBackupText(file, "", buffer, UseUnicode); break; case PBK_Text_Custom3: sprintf(buffer,"Entry%02iType = Custom3%c%c",j,13,10); SaveBackupText(file, "", buffer, UseUnicode); break; case PBK_Text_Custom4: sprintf(buffer,"Entry%02iType = Custom4%c%c",j,13,10); SaveBackupText(file, "", buffer, UseUnicode); break; case PBK_SMSListID: case PBK_RingtoneFileSystemID: case PBK_Date: break; } if (text) { sprintf(buffer,"Entry%02iText",j); SaveBackupText(file,buffer,Pbk->Entries[j].Text, UseUnicode); } switch (Pbk->Entries[j].EntryType) { case PBK_Number_General: case PBK_Number_Mobile: case PBK_Number_Work: case PBK_Number_Fax: case PBK_Number_Home: case PBK_Number_Other: case PBK_Number_Pager: if (Pbk->Entries[j].VoiceTag!=0) { sprintf(buffer,"Entry%02iVoiceTag = %i%c%c",j,Pbk->Entries[j].VoiceTag,13,10); SaveBackupText(file, "", buffer, UseUnicode); } i = 0; while (Pbk->Entries[j].SMSList[i]!=0) { sprintf(buffer,"Entry%02iSMSList%02i = %i%c%c",j,i,Pbk->Entries[j].SMSList[i],13,10); SaveBackupText(file, "", buffer, UseUnicode); i++; } break; default: break; } } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } +static void SaveNoteEntry(FILE *file, GSM_NoteEntry *Note, bool UseUnicode) +{ + char buffer[1000]; + + sprintf(buffer,"Location = %d%c%c", Note->Location,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveBackupText(file, "Text", Note->Text, UseUnicode); + sprintf(buffer, "%c%c",13,10); + SaveBackupText(file, "", buffer, UseUnicode); +} + static void SaveCalendarEntry(FILE *file, GSM_CalendarEntry *Note, bool UseUnicode) { int i; char buffer[1000]; sprintf(buffer,"Location = %d%c%c", Note->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBackupText(file, "", "Type = ", UseUnicode); switch (Note->Type) { case GSM_CAL_REMINDER : sprintf(buffer,"Reminder%c%c", 13,10); break; case GSM_CAL_CALL : sprintf(buffer,"Call%c%c", 13,10); break; case GSM_CAL_MEETING : sprintf(buffer,"Meeting%c%c", 13,10); break; case GSM_CAL_BIRTHDAY : sprintf(buffer,"Birthday%c%c", 13,10); break; case GSM_CAL_TRAVEL : sprintf(buffer,"Travel%c%c", 13,10); break; case GSM_CAL_VACATION : sprintf(buffer,"Vacation%c%c", 13,10); break; case GSM_CAL_MEMO : sprintf(buffer,"Memo%c%c", 13,10); break; case GSM_CAL_ALARM : sprintf(buffer,"Alarm%c%c", 13,10); break; case GSM_CAL_DAILY_ALARM : sprintf(buffer,"DailyAlarm%c%c", 13,10); break; case GSM_CAL_T_ATHL : sprintf(buffer,"Training/Athletism%c%c", 13,10); break; case GSM_CAL_T_BALL : sprintf(buffer,"Training/BallGames%c%c", 13,10); break; case GSM_CAL_T_CYCL : sprintf(buffer,"Training/Cycling%c%c", 13,10); break; case GSM_CAL_T_BUDO : sprintf(buffer,"Training/Budo%c%c", 13,10); break; case GSM_CAL_T_DANC : sprintf(buffer,"Training/Dance%c%c", 13,10); break; case GSM_CAL_T_EXTR : sprintf(buffer,"Training/ExtremeSports%c%c", 13,10); break; case GSM_CAL_T_FOOT : sprintf(buffer,"Training/Football%c%c", 13,10); break; case GSM_CAL_T_GOLF : sprintf(buffer,"Training/Golf%c%c", 13,10); break; case GSM_CAL_T_GYM : sprintf(buffer,"Training/Gym%c%c", 13,10); break; case GSM_CAL_T_HORS : sprintf(buffer,"Training/HorseRaces%c%c", 13,10); break; case GSM_CAL_T_HOCK : sprintf(buffer,"Training/Hockey%c%c", 13,10); break; case GSM_CAL_T_RACE : sprintf(buffer,"Training/Races%c%c", 13,10); break; case GSM_CAL_T_RUGB : sprintf(buffer,"Training/Rugby%c%c", 13,10); break; case GSM_CAL_T_SAIL : sprintf(buffer,"Training/Sailing%c%c", 13,10); break; case GSM_CAL_T_STRE : sprintf(buffer,"Training/StreetGames%c%c", 13,10); break; case GSM_CAL_T_SWIM : sprintf(buffer,"Training/Swimming%c%c", 13,10); break; case GSM_CAL_T_TENN : sprintf(buffer,"Training/Tennis%c%c", 13,10); break; case GSM_CAL_T_TRAV : sprintf(buffer,"Training/Travels%c%c", 13,10); break; case GSM_CAL_T_WINT : sprintf(buffer,"Training/WinterGames%c%c", 13,10); break; } SaveBackupText(file, "", buffer, UseUnicode); for (i=0;i<Note->EntriesNum;i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: SaveBackupText(file, "", "StartTime", UseUnicode); SaveVCalDateTime(file, &Note->Entries[i].Date, UseUnicode); break; case CAL_END_DATETIME: SaveBackupText(file, "", "StopTime", UseUnicode); SaveVCalDateTime(file, &Note->Entries[i].Date, UseUnicode); @@ -612,96 +624,138 @@ static void SaveWAPSettingsEntry(FILE *file, GSM_MultiWAPSettings *settings, boo SaveBackupText(file, buffer, settings->Settings[i].DialUp, UseUnicode); if (settings->Settings[i].ManualLogin) { sprintf(buffer,"Login%02i = Manual%c%c",i,13,10); } else { sprintf(buffer,"Login%02i = Automatic%c%c",i,13,10); } SaveBackupText(file, "", buffer, UseUnicode); if (settings->Settings[i].IsNormalAuthentication) { sprintf(buffer,"Authentication%02i = Normal%c%c",i,13,10); } else { sprintf(buffer,"Authentication%02i = Secure%c%c",i,13,10); } SaveBackupText(file, "", buffer, UseUnicode); switch (settings->Settings[i].Speed) { case WAPSETTINGS_SPEED_9600 : sprintf(buffer,"CallSpeed%02i = 9600%c%c" ,i,13,10); break; case WAPSETTINGS_SPEED_14400: sprintf(buffer,"CallSpeed%02i = 14400%c%c",i,13,10); break; case WAPSETTINGS_SPEED_AUTO : sprintf(buffer,"CallSpeed%02i = auto%c%c" ,i,13,10); break; } switch (settings->Settings[i].Speed) { case WAPSETTINGS_SPEED_9600 : case WAPSETTINGS_SPEED_14400: case WAPSETTINGS_SPEED_AUTO : SaveBackupText(file, "", buffer, UseUnicode); default: break; } sprintf(buffer,"User%02i",i); SaveBackupText(file, buffer, settings->Settings[i].User, UseUnicode); sprintf(buffer,"Password%02i",i); SaveBackupText(file, buffer, settings->Settings[i].Password, UseUnicode); break; case WAPSETTINGS_BEARER_USSD: sprintf(buffer,"Bearer%02i = USSD%c%c",i,13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"ServiceCode%02i",i); SaveBackupText(file, buffer, settings->Settings[i].Code, UseUnicode); if (settings->Settings[i].IsIP) { sprintf(buffer,"IP%02i",i); } else { sprintf(buffer,"Number%02i",i); } SaveBackupText(file, buffer, settings->Settings[i].Service, UseUnicode); } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } } +static void SaveChatSettingsEntry(FILE *file, GSM_ChatSettings *settings, bool UseUnicode) +{ + char buffer[10000]; + + sprintf(buffer,"HomePage"); + SaveBackupText(file, buffer, settings->HomePage, UseUnicode); + sprintf(buffer,"User"); + SaveBackupText(file, buffer, settings->User, UseUnicode); + sprintf(buffer,"Password"); + SaveBackupText(file, buffer, settings->Password, UseUnicode); + SaveWAPSettingsEntry(file, &settings->Connection, UseUnicode); +} + +static void SaveSyncMLSettingsEntry(FILE *file, GSM_SyncMLSettings *settings, bool UseUnicode) +{ + char buffer[10000]; + + sprintf(buffer,"User"); + SaveBackupText(file, buffer, settings->User, UseUnicode); + sprintf(buffer,"Password"); + SaveBackupText(file, buffer, settings->Password, UseUnicode); + sprintf(buffer,"PhonebookDB"); + SaveBackupText(file, buffer, settings->PhonebookDataBase, UseUnicode); + sprintf(buffer,"CalendarDB"); + SaveBackupText(file, buffer, settings->CalendarDataBase, UseUnicode); + sprintf(buffer,"Server"); + SaveBackupText(file, buffer, settings->Server, UseUnicode); + if (settings->SyncPhonebook) { + sprintf(buffer,"SyncPhonebook = True%c%c",13,10); + } else { + sprintf(buffer,"SyncPhonebook = False%c%c",13,10); + } + SaveBackupText(file, "", buffer, UseUnicode); + if (settings->SyncCalendar) { + sprintf(buffer,"SyncCalendar = True%c%c",13,10); + } else { + sprintf(buffer,"SyncCalendar = False%c%c",13,10); + } + SaveBackupText(file, "", buffer, UseUnicode); + SaveWAPSettingsEntry(file, &settings->Connection, UseUnicode); +} + static void SaveBitmapEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000],buffer2[10000]; int x,y; sprintf(buffer,"Width = %i%c%c",bitmap->BitmapWidth,13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"Height = %i%c%c",bitmap->BitmapHeight,13,10); SaveBackupText(file, "", buffer, UseUnicode); for (y=0;y<bitmap->BitmapHeight;y++) { for (x=0;x<bitmap->BitmapWidth;x++) { buffer[x] = ' '; if (GSM_IsPointBitmap(bitmap,x,y)) buffer[x]='#'; } buffer[bitmap->BitmapWidth] = 0; sprintf(buffer2,"Bitmap%02i = \"%s\"%c%c",y,buffer,13,10); SaveBackupText(file, "", buffer2, UseUnicode); } } static void SaveCallerEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[1000]; sprintf(buffer,"Location = %03i%c%c",bitmap->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); if (!bitmap->DefaultName) SaveBackupText(file, "Name", bitmap->Text, UseUnicode); if (!bitmap->DefaultRingtone) { if (bitmap->FileSystemRingtone) { sprintf(buffer,"FileRingtone = %02x%c%c",bitmap->RingtoneID,13,10); } else { sprintf(buffer,"Ringtone = %02x%c%c",bitmap->RingtoneID,13,10); } SaveBackupText(file, "", buffer, UseUnicode); } if (bitmap->BitmapEnabled) { sprintf(buffer,"Enabled = True%c%c",13,10); } else { sprintf(buffer,"Enabled = False%c%c",13,10); } SaveBackupText(file, "", buffer, UseUnicode); if (!bitmap->DefaultBitmap) SaveBitmapEntry(file, bitmap, UseUnicode); sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveWAPBookmarkEntry(FILE *file, GSM_WAPBookmark *bookmark, bool UseUnicode) { @@ -720,112 +774,113 @@ static void SaveStartupEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) sprintf(buffer,"[Startup]%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); if (bitmap->Type == GSM_WelcomeNote_Text) { SaveBackupText(file, "Text", bitmap->Text, UseUnicode); } if (bitmap->Type == GSM_StartupLogo) { SaveBitmapEntry(file, bitmap, UseUnicode); } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveSMSCEntry(FILE *file, GSM_SMSC *SMSC, bool UseUnicode) { unsigned char buffer[1000]; sprintf(buffer,"Location = %03i%c%c",SMSC->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBackupText(file, "Name", SMSC->Name, UseUnicode); SaveBackupText(file, "Number", SMSC->Number, UseUnicode); SaveBackupText(file, "DefaultNumber", SMSC->DefaultNumber, UseUnicode); SaveBackupText(file, "", "Format = ", UseUnicode); switch (SMSC->Format) { case SMS_FORMAT_Text : sprintf(buffer,"Text"); break; case SMS_FORMAT_Fax : sprintf(buffer,"Fax"); break; case SMS_FORMAT_Email : sprintf(buffer,"Email"); break; case SMS_FORMAT_Pager : sprintf(buffer,"Pager"); break; } SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"%c%cValidity = ",13,10); SaveBackupText(file, "", buffer, UseUnicode); switch (SMSC->Validity.Relative) { case SMS_VALID_1_Hour : sprintf(buffer, "1hour" ); break; case SMS_VALID_6_Hours : sprintf(buffer, "6hours" ); break; case SMS_VALID_1_Day : sprintf(buffer, "24hours" ); break; case SMS_VALID_3_Days : sprintf(buffer, "72hours" ); break; case SMS_VALID_1_Week : sprintf(buffer, "1week" ); break; case SMS_VALID_Max_Time : default : sprintf(buffer,"MaximumTime" ); break; } SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"%c%c%c%c",13,10,13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveRingtoneEntry(FILE *file, GSM_Ringtone *ringtone, bool UseUnicode) { unsigned char buffer[45000]; - int i,j; sprintf(buffer,"Location = %i%c%c",ringtone->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBackupText(file, "Name", ringtone->Name, UseUnicode); switch (ringtone->Format) { case RING_NOKIABINARY: - j = 0; i = 0; EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); SaveLinkedBackupText(file, "NokiaBinary", buffer, UseUnicode); break; case RING_MIDI: - j = 0; i = 0; EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); SaveLinkedBackupText(file, "Pure Midi", buffer, UseUnicode); break; + case RING_MMF: + EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); + SaveLinkedBackupText(file, "SMAF", buffer, UseUnicode); + break; case RING_NOTETONE: break; } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveOperatorEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[1000]; sprintf(buffer,"[Operator]%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"Network = \"%s\"%c%c", bitmap->NetworkCode,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBitmapEntry(file, bitmap, UseUnicode); sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveToDoEntry(FILE *file, GSM_ToDoEntry *ToDo, bool UseUnicode) { unsigned char buffer[1000]; int j; sprintf(buffer,"Location = %i%c%c",ToDo->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); switch (ToDo->Priority) { case GSM_Priority_High: sprintf(buffer,"Priority = High%c%c",13,10); break; case GSM_Priority_Medium: sprintf(buffer,"Priority = Medium%c%c",13,10); break; case GSM_Priority_Low: sprintf(buffer,"Priority = Low%c%c",13,10); break; } SaveBackupText(file, "", buffer, UseUnicode); for (j=0;j<ToDo->EntriesNum;j++) { switch (ToDo->Entries[j].EntryType) { case TODO_END_DATETIME: SaveBackupText(file, "", "DueTime", UseUnicode); SaveVCalDateTime(file, &ToDo->Entries[j].Date, UseUnicode); break; case TODO_COMPLETED: sprintf(buffer,"Completed = %s%c%c",ToDo->Entries[j].Number == 1 ? "yes" : "no" ,13,10); @@ -1030,131 +1085,152 @@ GSM_Error SaveBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) if (UseUnicode) { sprintf(buffer,"%c%c", 0xFE, 0xFF); SaveBackupText(file, "", buffer, false); } sprintf(buffer,"# Format of this file was designed for Gammu (see www.mwiacek.com)%c%c%c%c",13,10,13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"[Backup]%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"IMEI = \"%s\"%c%c",backup->IMEI,13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"Phone = \"%s\"%c%c",backup->Model,13,10); SaveBackupText(file, "", buffer, UseUnicode); if (backup->Creator[0] != 0) { sprintf(buffer,"Creator = \"%s\"%c%c",backup->Creator,13,10); SaveBackupText(file, "", buffer, UseUnicode); } if (backup->DateTimeAvailable) { SaveBackupText(file, "", "DateTime", UseUnicode); SaveVCalDateTime(file, &backup->DateTime, UseUnicode); } sprintf(buffer,"Format = 1.03%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); i=0; while (backup->PhonePhonebook[i]!=NULL) { sprintf(buffer,"[PhonePBK%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SavePbkEntry(file, backup->PhonePhonebook[i], UseUnicode); i++; } i=0; while (backup->SIMPhonebook[i]!=NULL) { sprintf(buffer,"[SIMPBK%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SavePbkEntry(file, backup->SIMPhonebook[i], UseUnicode); i++; } i=0; while (backup->Calendar[i]!=NULL) { sprintf(buffer,"[Calendar%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveCalendarEntry(file, backup->Calendar[i], UseUnicode); i++; } i=0; + while (backup->Note[i]!=NULL) { + sprintf(buffer,"[Note%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveNoteEntry(file, backup->Note[i], UseUnicode); + i++; + } + i=0; while (backup->CallerLogos[i]!=NULL) { sprintf(buffer,"[Caller%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveCallerEntry(file, backup->CallerLogos[i], UseUnicode); i++; } i=0; while (backup->SMSC[i]!=NULL) { sprintf(buffer,"[SMSC%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveSMSCEntry(file, backup->SMSC[i], UseUnicode); i++; } i=0; while (backup->WAPBookmark[i]!=NULL) { sprintf(buffer,"[WAPBookmark%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveWAPBookmarkEntry(file, backup->WAPBookmark[i], UseUnicode); i++; } i=0; while (backup->WAPSettings[i]!=NULL) { sprintf(buffer,"[WAPSettings%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveWAPSettingsEntry(file, backup->WAPSettings[i], UseUnicode); i++; } i=0; while (backup->MMSSettings[i]!=NULL) { sprintf(buffer,"[MMSSettings%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveWAPSettingsEntry(file, backup->MMSSettings[i], UseUnicode); i++; } i=0; + while (backup->SyncMLSettings[i]!=NULL) { + sprintf(buffer,"[SyncMLSettings%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveSyncMLSettingsEntry(file, backup->SyncMLSettings[i], UseUnicode); + i++; + } + i=0; + while (backup->ChatSettings[i]!=NULL) { + sprintf(buffer,"[ChatSettings%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveChatSettingsEntry(file, backup->ChatSettings[i], UseUnicode); + i++; + } + i=0; while (backup->Ringtone[i]!=NULL) { sprintf(buffer,"[Ringtone%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveRingtoneEntry(file, backup->Ringtone[i], UseUnicode); i++; } i=0; while (backup->ToDo[i]!=NULL) { sprintf(buffer,"[TODO%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveToDoEntry(file, backup->ToDo[i], UseUnicode); i++; } i=0; while (backup->Profiles[i]!=NULL) { sprintf(buffer,"[Profile%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveProfileEntry(file, backup->Profiles[i], UseUnicode); i++; } i=0; while (backup->FMStation[i]!=NULL) { sprintf(buffer,"[FMStation%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveFMStationEntry(file, backup->FMStation[i], UseUnicode); i++; } i=0; while (backup->GPRSPoint[i]!=NULL) { sprintf(buffer,"[GPRSPoint%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveGPRSPointEntry(file, backup->GPRSPoint[i], UseUnicode); i++; } if (backup->StartupLogo!=NULL) { SaveStartupEntry(file, backup->StartupLogo, UseUnicode); } if (backup->OperatorLogo!=NULL) { SaveOperatorEntry(file, backup->OperatorLogo, UseUnicode); } fclose(file); FindBackupChecksum(FileName, UseUnicode, checksum); file = fopen(FileName, "ab"); if (file == NULL) return ERR_CANTOPENFILE; @@ -2611,97 +2687,222 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) EncodeUnicode(buffer,"GPRSPoint",9); if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_GPRSPOINT) { backup->GPRSPoint[num] = malloc(sizeof(GSM_GPRSAccessPoint)); if (backup->GPRSPoint[num] == NULL) return ERR_MOREMEMORY; backup->GPRSPoint[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_GPRSPOINT\n"); return ERR_MOREMEMORY; } backup->GPRSPoint[num]->Location = num + 1; ReadGPRSPointEntry(file_info, h->SectionName, backup->GPRSPoint[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Note",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("Note", h->SectionName, 4)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Text", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_NOTE) { backup->Note[num] = malloc(sizeof(GSM_NoteEntry)); if (backup->Note[num] == NULL) return ERR_MOREMEMORY; backup->Note[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_NOTE\n"); return ERR_MOREMEMORY; } ReadNoteEntry(file_info, h->SectionName, backup->Note[num],UseUnicode); num++; } } if (backup->MD5Original[0]!=0) { FindBackupChecksum(FileName, UseUnicode, backup->MD5Calculated); } - + for (h = file_info; h != NULL; h = h->Next) { + found = false; + if (UseUnicode) { + EncodeUnicode(buffer,"Backup",4); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("Backup", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Checksum",4); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Checksum", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Profile",7); + if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; + } else { + if (mystrncasecmp("Profile", h->SectionName, 7)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"PhonePBK",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("PhonePBK", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"SIMPBK",6); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("SIMPBK", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Calendar",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Calendar", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Caller",6); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("Caller", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"SMSC",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("SMSC", h->SectionName, 4)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"WAPBookmark",11); + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; + if (!found) { + EncodeUnicode(buffer,"Bookmark",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } + } else { + if (mystrncasecmp("WAPBookmark", h->SectionName, 11)) found = true; + if (!found) { + if (mystrncasecmp("Bookmark", h->SectionName, 8)) found = true; + } + } + if (UseUnicode) { + EncodeUnicode(buffer,"WAPSettings",11); + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; + if (!found) { + EncodeUnicode(buffer,"Settings",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } + } else { + if (mystrncasecmp("WAPSettings", h->SectionName, 11)) found = true; + if (!found) { + if (mystrncasecmp("Settings", h->SectionName, 8)) found = true; + } + } + if (UseUnicode) { + EncodeUnicode(buffer,"MMSSettings",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("MMSSettings", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Ringtone",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Ringtone", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"TODO",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("TODO", h->SectionName, 4)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Startup",7); + if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; + } else { + if (mystrncasecmp("Startup", h->SectionName, 7)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Operator",7); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Operator", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"FMStation",9); + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; + } else { + if (mystrncasecmp("FMStation", h->SectionName, 9)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"GPRSPoint",9); + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; + } else { + if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Note",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("Note", h->SectionName, 4)) found = true; + } + if (!found) return ERR_NOTIMPLEMENTED; + } return ERR_NONE; } /* ---------------------- backup files for SMS ----------------------------- */ static void ReadSMSBackupEntry(INI_Section *file_info, char *section, GSM_SMSMessage *SMS) { unsigned char buffer[10000], *readvalue; GSM_SetDefaultSMSData(SMS); SMS->PDU = SMS_Submit; SMS->SMSC.Location = 0; sprintf(buffer,"SMSC"); ReadBackupText(file_info, section, buffer, SMS->SMSC.Number, false); sprintf(buffer,"ReplySMSC"); SMS->ReplyViaSameSMSC = false; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"True",0)) SMS->ReplyViaSameSMSC = true; } sprintf(buffer,"Class"); SMS->Class = -1; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->Class = atoi(readvalue); sprintf(buffer,"Sent"); readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &SMS->DateTime); SMS->PDU = SMS_Deliver; } sprintf(buffer,"RejectDuplicates"); SMS->RejectDuplicates = false; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"True",0)) SMS->RejectDuplicates = true; } sprintf(buffer,"ReplaceMessage"); SMS->ReplaceMessage = 0; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->ReplaceMessage = atoi(readvalue); sprintf(buffer,"MessageReference"); SMS->MessageReference = 0; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->MessageReference = atoi(readvalue); sprintf(buffer,"State"); SMS->State = SMS_UnRead; readvalue = ReadCFGText(file_info, section, buffer, false); diff --git a/gammu/emb/common/service/backup/gsmback.c b/gammu/emb/common/service/backup/gsmback.c index 91ac745..c94a4d2 100644 --- a/gammu/emb/common/service/backup/gsmback.c +++ b/gammu/emb/common/service/backup/gsmback.c @@ -28,253 +28,271 @@ void GSM_FreeBackup(GSM_Backup *backup) while (backup->PhonePhonebook[i]!=NULL) { free(backup->PhonePhonebook[i]); backup->PhonePhonebook[i] = NULL; i++; } i=0; while (backup->SIMPhonebook[i]!=NULL) { free(backup->SIMPhonebook[i]); backup->SIMPhonebook[i] = NULL; i++; } i=0; while (backup->Calendar[i]!=NULL) { free(backup->Calendar[i]); backup->Calendar[i] = NULL; i++; } i=0; while (backup->CallerLogos[i]!=NULL) { free(backup->CallerLogos[i]); backup->CallerLogos[i] = NULL; i++; } i=0; while (backup->SMSC[i]!=NULL) { free(backup->SMSC[i]); backup->SMSC[i] = NULL; i++; } i=0; while (backup->WAPBookmark[i]!=NULL) { free(backup->WAPBookmark[i]); backup->WAPBookmark[i] = NULL; i++; } i=0; while (backup->WAPSettings[i]!=NULL) { free(backup->WAPSettings[i]); backup->WAPSettings[i] = NULL; i++; } i=0; while (backup->MMSSettings[i]!=NULL) { free(backup->MMSSettings[i]); backup->MMSSettings[i] = NULL; i++; } i=0; + while (backup->SyncMLSettings[i]!=NULL) { + free(backup->SyncMLSettings[i]); + backup->SyncMLSettings[i] = NULL; + i++; + } + i=0; + while (backup->ChatSettings[i]!=NULL) { + free(backup->ChatSettings[i]); + backup->ChatSettings[i] = NULL; + i++; + } + i=0; while (backup->Ringtone[i]!=NULL) { free(backup->Ringtone[i]); backup->Ringtone[i] = NULL; i++; } i=0; while (backup->ToDo[i]!=NULL) { free(backup->ToDo[i]); backup->ToDo[i] = NULL; i++; } i=0; while (backup->Profiles[i]!=NULL) { free(backup->Profiles[i]); backup->Profiles[i] = NULL; i++; } i=0; while (backup->FMStation[i]!=NULL) { free(backup->FMStation[i]); backup->FMStation[i] = NULL; i++; } if (backup->StartupLogo!=NULL) { free(backup->StartupLogo); backup->StartupLogo = NULL; } if (backup->OperatorLogo!=NULL) { free(backup->OperatorLogo); backup->OperatorLogo = NULL; } i=0; while (backup->GPRSPoint[i]!=NULL) { free(backup->GPRSPoint[i]); backup->GPRSPoint[i] = NULL; i++; } i=0; while (backup->Note[i]!=NULL) { free(backup->Note[i]); backup->Note[i] = NULL; i++; } } GSM_Error GSM_SaveBackupFile(char *FileName, GSM_Backup *backup, bool UseUnicode) { - if (strstr(FileName,".lmb")) { + if (mystrcasestr(FileName,".lmb")) { return SaveLMB(FileName,backup); - } else if (strstr(FileName,".vcs")) { + } else if (mystrcasestr(FileName,".vcs")) { return SaveVCalendar(FileName,backup); - } else if (strstr(FileName,".vcf")) { + } else if (mystrcasestr(FileName,".vcf")) { return SaveVCard(FileName,backup); - } else if (strstr(FileName,".ldif")) { + } else if (mystrcasestr(FileName,".ldif")) { return SaveLDIF(FileName,backup); - } else if (strstr(FileName,".ics")) { + } else if (mystrcasestr(FileName,".ics")) { return SaveICS(FileName,backup); } else { return SaveBackup(FileName,backup, UseUnicode); } } GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup) { FILE *file; unsigned char buffer[300]; file = fopen(FileName, "rb"); if (file == NULL) return ERR_CANTOPENFILE; fread(buffer, 1, 9, file); /* Read the header of the file. */ fclose(file); GSM_ClearBackup(backup); /* Attempt to identify filetype */ - if (strstr(FileName,".vcs")) { + if (mystrcasestr(FileName,".vcs")) { return LoadVCalendar(FileName,backup); - } else if (strstr(FileName,".vcf")) { + } else if (mystrcasestr(FileName,".vcf")) { return LoadVCard(FileName,backup); - } else if (strstr(FileName,".ldif")) { + } else if (mystrcasestr(FileName,".ldif")) { return LoadLDIF(FileName,backup); - } else if (strstr(FileName,".ics")) { + } else if (mystrcasestr(FileName,".ics")) { return LoadICS(FileName,backup); } else if (memcmp(buffer, "LMB ",4)==0) { return LoadLMB(FileName,backup); } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) { return LoadBackup(FileName,backup,true); } else if (buffer[0] == 0xFF && buffer[1] == 0xFE) { return LoadBackup(FileName,backup,true); } else { return LoadBackup(FileName,backup,false); } } void GSM_ClearBackup(GSM_Backup *backup) { backup->PhonePhonebook [0] = NULL; backup->SIMPhonebook [0] = NULL; backup->Calendar [0] = NULL; backup->CallerLogos [0] = NULL; backup->SMSC [0] = NULL; backup->WAPBookmark [0] = NULL; backup->WAPSettings [0] = NULL; backup->MMSSettings [0] = NULL; + backup->SyncMLSettings [0] = NULL; + backup->ChatSettings [0] = NULL; backup->Ringtone [0] = NULL; backup->Profiles [0] = NULL; backup->ToDo [0] = NULL; backup->GPRSPoint [0] = NULL; backup->FMStation [0] = NULL; backup->Note [0] = NULL; backup->StartupLogo = NULL; backup->OperatorLogo = NULL; backup->Creator [0] = 0; backup->IMEI [0] = 0; backup->Model [0] = 0; backup->DateTimeAvailable = false; backup->MD5Original [0] = 0; backup->MD5Calculated [0] = 0; } void GSM_GetBackupFormatFeatures(char *FileName, GSM_Backup_Info *info) { info->UseUnicode = false; info->IMEI = false; info->Model = false; info->DateTime = false; info->PhonePhonebook = false; info->SIMPhonebook = false; info->ToDo = false; info->Calendar = false; info->CallerLogos = false; info->SMSC = false; info->WAPBookmark = false; info->WAPSettings = false; info->MMSSettings = false; + info->SyncMLSettings = false; + info->ChatSettings = false; info->Ringtone = false; info->StartupLogo = false; info->OperatorLogo = false; info->Profiles = false; info->FMStation = false; info->GPRSPoint = false; info->Note = false; if (strstr(FileName,".lmb")) { info->PhonePhonebook = true; info->SIMPhonebook = true; info->CallerLogos = true; info->StartupLogo = true; } else if (strstr(FileName,".vcs")) { info->ToDo = true; info->Calendar = true; } else if (strstr(FileName,".vcf")) { info->PhonePhonebook = true; } else if (strstr(FileName,".ics")) { info->ToDo = true; info->Calendar = true; } else if (strstr(FileName,".ldif")) { info->PhonePhonebook = true; } else { info->UseUnicode = true; info->IMEI = true; info->Model = true; info->DateTime = true; info->PhonePhonebook = true; info->SIMPhonebook = true; info->ToDo = true; info->Calendar = true; info->CallerLogos = true; info->SMSC = true; info->WAPBookmark = true; info->WAPSettings = true; info->MMSSettings = true; + info->SyncMLSettings = true; + info->ChatSettings = true; info->Ringtone = true; info->StartupLogo = true; info->OperatorLogo = true; info->Profiles = true; info->FMStation = true; info->GPRSPoint = true; info->Note = true; } } void GSM_GetBackupFileFeatures(char *FileName, GSM_Backup_Info *info, GSM_Backup *backup) { GSM_GetBackupFormatFeatures(FileName, info); if (info->PhonePhonebook && backup->PhonePhonebook[0] == NULL) info->PhonePhonebook = false; if (info->SIMPhonebook && backup->SIMPhonebook[0] == NULL) info->SIMPhonebook = false; if (info->Calendar && backup->Calendar[0] == NULL) info->Calendar = false; if (info->ToDo && backup->ToDo[0] == NULL) info->ToDo = false; if (info->WAPBookmark && backup->WAPBookmark[0] == NULL) info->WAPBookmark = false; if (info->WAPSettings && backup->WAPSettings[0] == NULL) info->WAPSettings = false; if (info->MMSSettings && backup->MMSSettings[0] == NULL) info->MMSSettings = false; if (info->FMStation && backup->FMStation[0] == NULL) info->FMStation = false; if (info->GPRSPoint && backup->GPRSPoint[0] == NULL) info->GPRSPoint = false; if (info->Profiles && backup->Profiles[0] == NULL) info->Profiles = false; /* .... */ } #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/backup/gsmback.h b/gammu/emb/common/service/backup/gsmback.h index 1fd99b0..791e81d 100644 --- a/gammu/emb/common/service/backup/gsmback.h +++ b/gammu/emb/common/service/backup/gsmback.h @@ -1,48 +1,50 @@ /* (c) 2003-2004 by Marcin Wiacek */ #ifndef __gsm_back_h #define __gsm_back_h #include "backgen.h" #ifdef GSM_ENABLE_BACKUP GSM_Error GSM_SaveBackupFile(char *FileName, GSM_Backup *backup, bool UseUnicode); GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup); void GSM_ClearBackup (GSM_Backup *backup); void GSM_FreeBackup (GSM_Backup *backup); typedef struct { bool UseUnicode; bool IMEI; bool Model; bool DateTime; bool ToDo; bool PhonePhonebook; bool SIMPhonebook; bool Calendar; bool CallerLogos; bool SMSC; bool WAPBookmark; bool Profiles; bool WAPSettings; bool MMSSettings; + bool SyncMLSettings; + bool ChatSettings; bool Ringtone; bool StartupLogo; bool OperatorLogo; bool FMStation; bool GPRSPoint; bool Note; } GSM_Backup_Info; void GSM_GetBackupFormatFeatures(char *FileName, GSM_Backup_Info *info); void GSM_GetBackupFileFeatures (char *FileName, GSM_Backup_Info *info, GSM_Backup *backup); #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/gsmcal.h b/gammu/emb/common/service/gsmcal.h index 067a4a4..0a41b7b 100644 --- a/gammu/emb/common/service/gsmcal.h +++ b/gammu/emb/common/service/gsmcal.h @@ -360,86 +360,86 @@ typedef struct { unsigned int Number; } GSM_SubToDoEntry; /** * To do entry. */ typedef struct { /** * Priority of entry. */ GSM_ToDo_Priority Priority; /** * Location in memory. */ int Location; /** * Number of entries. */ int EntriesNum; /** * Values of current entry. */ GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]; } GSM_ToDoEntry; void GSM_ToDoFindDefaultTextTimeAlarmCompleted(GSM_ToDoEntry *entry, int *Text, int *Alarm, int *Completed, int *EndTime, int *Phone); typedef enum { Nokia_VToDo = 1, SonyEricsson_VToDo } GSM_VToDoVersion; GSM_Error GSM_EncodeVTODO(char *Buffer, int *Length, GSM_ToDoEntry *note, bool header, GSM_VToDoVersion Version); /** * Status of to do entries. */ typedef struct { /** * Number of used positions. */ int Used; } GSM_ToDoStatus; /* --------------------------- note ---------------------------------------- */ typedef struct { int Location; - char Text[100]; + char Text[3000*2]; } GSM_NoteEntry; GSM_Error GSM_EncodeVNTFile(unsigned char *Buffer, int *Length, GSM_NoteEntry *Note); /* --------------------------- alarm --------------------------------------- */ /** * Alarm values. */ typedef struct { /** * Location where it is stored. */ int Location; /** * Date and time of alarm. */ GSM_DateTime DateTime; /** * Whether it repeats each day. */ bool Repeating; /** * Text that is shown on display. */ char Text[(MAX_CALENDAR_TEXT_LENGTH + 1) * 2]; } GSM_Alarm; /* --------------------------- calendar & todo ----------------------------- */ GSM_Error GSM_DecodeVCALENDAR_VTODO(unsigned char *Buffer, int *Pos, GSM_CalendarEntry *Calendar, GSM_ToDoEntry *ToDo, GSM_VCalendarVersion CalVer, GSM_VToDoVersion ToDoVer); #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/gsmdata.c b/gammu/emb/common/service/gsmdata.c index 94e9b7b..9303b57 100644 --- a/gammu/emb/common/service/gsmdata.c +++ b/gammu/emb/common/service/gsmdata.c @@ -201,143 +201,221 @@ void NOKIA_EncodeWAPMMSSettingsSMSText(unsigned char *Buffer, int *Length, GSM_W } /* PORT */ if (settings->IsSecurity) { if (settings->IsContinuous) { /* Port = 9203. Continuous */ AddWAPSMSParameterInt(Buffer, Length, 0x14, 0x63); } else { /* Port = 9202. Temporary */ AddWAPSMSParameterInt(Buffer, Length, 0x14, 0x62); } } else { if (settings->IsContinuous) { /* Port = 9201. Continuous */ AddWAPSMSParameterInt(Buffer, Length, 0x14, 0x61); } else { /* Port = 9200. Temporary */ AddWAPSMSParameterInt(Buffer, Length, 0x14, 0x60); } } Buffer[(*Length)++] = 0x01; //END PARMeter /* URL */ Buffer[(*Length)++] = 0x86; //CHARACTERISTIC-LIST with attributes if (MMS) { Buffer[(*Length)++] = 0x7C; //TYPE = MMSURL } else { Buffer[(*Length)++] = 0x07; //TYPE = URL } Buffer[(*Length)++] = 0x11; //VALUE Buffer[(*Length)++] = 0x03; //Inline string sprintf(buffer,"%s",DecodeUnicodeString(settings->HomePage)); for (i=0;i<(int)strlen(buffer);i++) { Buffer[(*Length)++] = buffer[i];//Text } Buffer[(*Length)++] = 0x00; //END Inline string Buffer[(*Length)++] = 0x01; //END PARMeter /* ISP_NAME (name) */ Buffer[(*Length)++] = 0xC6; //CHARACTERISTIC with content and attributes Buffer[(*Length)++] = 0x08; //TYPE=NAME Buffer[(*Length)++] = 0x01; //END PARMeter /* Settings name */ AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(settings->Title), UnicodeLength(settings->Title)); Buffer[(*Length)++] = 0x01; //END PARMeter Buffer[(*Length)++] = 0x01; //END PARMeter } /* http://forum.nokia.com: OTA Settings 7.0 */ +/* first it used default/ISO coding */ +/* Joergen Thomsen changed to UTF8 */ void NOKIA_EncodeWAPBookmarkSMSText(unsigned char *Buffer, int *Length, GSM_WAPBookmark *bookmark) { unsigned char buffer[100]; - bool UnicodeCoding = false; - EncodeUTF8QuotedPrintable(buffer,bookmark->Title); - if (UnicodeLength(bookmark->Title)!=strlen(buffer)) UnicodeCoding = true; +// bool UnicodeCoding = false; +// EncodeUTF8QuotedPrintable(buffer,bookmark->Title); +// if (UnicodeLength(bookmark->Title)!=strlen(buffer)) UnicodeCoding = true; Buffer[(*Length)++] = 0x01; //Push ID Buffer[(*Length)++] = 0x06; //PDU Type (push) Buffer[(*Length)++] = 0x2D; //Headers length (content type + headers) strcpy(Buffer+(*Length),"\x1F\x2B"); (*Length)=(*Length)+2; //Value length strcpy(Buffer+(*Length),"application/x-wap-prov.browser-bookmarks"); (*Length)=(*Length)+40; //MIME-Type Buffer[(*Length)++] = 0x00; //end inline string strcpy(Buffer+(*Length),"\x81\xEA"); (*Length)=(*Length)+2; //charset UTF-8 short int. + /* removed by Joergen Thomsen */ /* Block from sniffs. UNKNOWN */ - if (!UnicodeCoding) { - Buffer[(*Length)++] = 0x00; - Buffer[(*Length)++] = 0x01; - } else { - strcpy(Buffer+(*Length),"\x01\x01\x87\x68"); - (*Length)=(*Length)+4; - } - Buffer[(*Length)++] = 0x00; +// if (!UnicodeCoding) { +// Buffer[(*Length)++] = 0x00; +// Buffer[(*Length)++] = 0x01; +// } else { +// strcpy(Buffer+(*Length),"\x01\x01\x87\x68"); +// (*Length)=(*Length)+4; +// } +// Buffer[(*Length)++] = 0x00; + + /* added by Joergen Thomsen */ + Buffer[(*Length)++] = 0x01; // Version WBXML 1.1 + Buffer[(*Length)++] = 0x01; // Unknown public identifier + Buffer[(*Length)++] = 0x6A; // charset UTF-8 + Buffer[(*Length)++] = 0x00; // string table length Buffer[(*Length)++] = 0x45; //CHARACTERISTIC-LIST with content /* URL */ Buffer[(*Length)++] = 0xC6; //CHARACTERISTIC with content and attributes Buffer[(*Length)++] = 0x7F; //TYPE = BOOKMARK Buffer[(*Length)++] = 0x01; //END PARMeter - if (!UnicodeCoding) { - /* TITLE */ - AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(bookmark->Title), UnicodeLength(bookmark->Title)); - /* URL */ - AddWAPSMSParameterText(Buffer, Length, 0x17, DecodeUnicodeString(bookmark->Address), UnicodeLength(bookmark->Address)); - } else { + + /* removed by Joergen Thomsen */ +// if (!UnicodeCoding) { +// /* TITLE */ +// AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(bookmark->Title), UnicodeLength(bookmark->Title)); +// /* URL */ +// AddWAPSMSParameterText(Buffer, Length, 0x17, DecodeUnicodeString(bookmark->Address), UnicodeLength(bookmark->Address)); +// } else { +// /* TITLE */ +// AddWAPSMSParameterText(Buffer, Length, 0x15, bookmark->Title, UnicodeLength(bookmark->Title)*2+1); +// /* URL */ +// AddWAPSMSParameterText(Buffer, Length, 0x17, bookmark->Address, UnicodeLength(bookmark->Address)*2+1); +// } + + /* added by Joergen Thomsen */ /* TITLE */ - AddWAPSMSParameterText(Buffer, Length, 0x15, bookmark->Title, UnicodeLength(bookmark->Title)*2+1); + EncodeUTF8(buffer, bookmark->Title); + AddWAPSMSParameterText(Buffer, Length, 0x15, buffer, strlen(buffer)); /* URL */ - AddWAPSMSParameterText(Buffer, Length, 0x17, bookmark->Address, UnicodeLength(bookmark->Address)*2+1); + EncodeUTF8(buffer, bookmark->Address); + AddWAPSMSParameterText(Buffer, Length, 0x17, buffer, strlen(buffer)); + + Buffer[(*Length)++] = 0x01; //END (CHARACTERISTIC) + Buffer[(*Length)++] = 0x01; //END (CHARACTERISTIC-LIST) } - Buffer[(*Length)++] = 0x01; //END PARMeter - Buffer[(*Length)++] = 0x01; //END PARMeter + +void GSM_EncodeWAPIndicatorSMSText(unsigned char *Buffer, int *Length, char *Text, char *URL) +{ + int i; + + Buffer[(*Length)++] = 0x01; //Push ID + Buffer[(*Length)++] = 0x06; //PDU Type (push) + Buffer[(*Length)++] = 28; //Headers length (content type + headers) + strcpy(Buffer+(*Length),"\x1F\x23"); + (*Length)=(*Length)+2; //Value length + strcpy(Buffer+(*Length),"application/vnd.wap.sic"); + (*Length)=(*Length)+23; //MIME-Type + Buffer[(*Length)++] = 0x00; //end inline string + strcpy(Buffer+(*Length),"\x81\xEA"); + (*Length)=(*Length)+2; //charset UTF-8 short int. + + Buffer[(*Length)++] = 0x02; // WBXML 1.2 + Buffer[(*Length)++] = 0x05; // SI 1.0 Public Identifier + Buffer[(*Length)++] = 0x6A; // charset UTF-8 + Buffer[(*Length)++] = 0x00; // string table length + Buffer[(*Length)++] = 0x45; // SI with content + Buffer[(*Length)++] = 0xC6; // indication with content and attributes + Buffer[(*Length)++] = 0x0B; // address + Buffer[(*Length)++] = 0x03; // Inline string + for (i=0;i<(int)strlen(URL);i++) { + Buffer[(*Length)++] = URL[i];//Text + } + Buffer[(*Length)++] = 0x00; // END Inline string + +#ifdef XXX + Buffer[(*Length)++] = 0x0A; // created... + Buffer[(*Length)++] = 0xC3; // OPAQUE + Buffer[(*Length)++] = 0x07; // length + Buffer[(*Length)++] = 0x19; // year + Buffer[(*Length)++] = 0x80; // year + Buffer[(*Length)++] = 0x21; // month + Buffer[(*Length)++] = 0x12; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x10; // expires + Buffer[(*Length)++] = 0xC3; // OPAQUE + Buffer[(*Length)++] = 0x04; // length + Buffer[(*Length)++] = 0x20; // year + Buffer[(*Length)++] = 0x10; // year + Buffer[(*Length)++] = 0x06; // month + Buffer[(*Length)++] = 0x25; // day +#endif + + Buffer[(*Length)++] = 0x01; // END (indication) + Buffer[(*Length)++] = 0x03; // Inline string + for (i=0;i<(int)strlen(Text);i++) { + Buffer[(*Length)++] = Text[i]; //Text + } + Buffer[(*Length)++] = 0x00; // END Inline string + Buffer[(*Length)++] = 0x01; // END (indication) + Buffer[(*Length)++] = 0x01; // END (SI) } void GSM_EncodeMMSFile(GSM_EncodeMultiPartMMSInfo *Info, unsigned char *Buffer, int *Length) { int i; strcpy(Buffer+(*Length),"\x8C\x80\x98\x4F"); (*Length)=(*Length)+4; /* Unique MMS ID ? */ strcpy(Buffer+(*Length),"123456789"); (*Length)=(*Length)+9; Buffer[(*Length)++] = 0x00; strcpy(Buffer+(*Length),"\x8D\x90\x89"); (*Length)=(*Length)+3; strcpy(Buffer+(*Length),"\x01\x81\x86\x81\x96"); (*Length)=(*Length)+5; if (UnicodeLength(Info->Subject) != 0) { sprintf(Buffer+(*Length),"%s",DecodeUnicodeString(Info->Subject)); (*Length)=(*Length)+UnicodeLength(Info->Subject); Buffer[(*Length)++] = 0x00; } for (i=0;i<Info->EntriesNum;i++) { switch(Info->Entries[i].ID) { case MMS_Text: strcpy(Buffer+(*Length),"\x84\xA3\x01\x04\x04\x03\x83\x81\xEA"); (*Length)=(*Length)+9; sprintf(Buffer+(*Length),"%s",DecodeUnicodeString(Info->Entries[i].Buffer)); (*Length)=(*Length)+UnicodeLength(Info->Entries[i].Buffer); break; default: break; } } } void GSM_ClearMultiPartMMSInfo(GSM_EncodeMultiPartMMSInfo *Info) { Info->EntriesNum = 0; Info->Subject[0] = 0x00; Info->Subject[1] = 0x00; Info->Source[0] = 0x00; Info->Source[1] = 0x00; diff --git a/gammu/emb/common/service/gsmdata.h b/gammu/emb/common/service/gsmdata.h index f5f8e07..e81589f 100644 --- a/gammu/emb/common/service/gsmdata.h +++ b/gammu/emb/common/service/gsmdata.h @@ -43,96 +43,98 @@ typedef struct { char Code [(10+1)*2]; /* for data or gprs */ char IPAddress [(20+1)*2]; bool ManualLogin; char DialUp [(20+1)*2]; char User [(50+1)*2]; /*is length OK ?*/ char Password [(50+1)*2]; /*is length OK ?*/ WAPSettings_Speed Speed; } GSM_WAPSettings; typedef struct { int Location; unsigned char Number; GSM_WAPSettings Settings[4]; bool Active; bool ReadOnly; char Proxy [(100+1)*2]; int ProxyPort; char Proxy2 [(100+1)*2]; int Proxy2Port; WAPSettings_Bearer ActiveBearer; } GSM_MultiWAPSettings; void NOKIA_EncodeWAPMMSSettingsSMSText(unsigned char *Buffer, int *Length, GSM_WAPSettings *settings, bool MMS); /* -------------------------------- WAP Bookmark --------------------------- */ typedef struct { char Address [(255+1)*2]; char Title [(50+1)*2]; int Location; } GSM_WAPBookmark; void NOKIA_EncodeWAPBookmarkSMSText (unsigned char *Buffer, int *Length, GSM_WAPBookmark *bookmark); GSM_Error GSM_EncodeURLFile (unsigned char *Buffer, int *Length, GSM_WAPBookmark *bookmark); /* ------------------------------ MMS Indicator ---------------------------- */ typedef struct { unsigned char Address[500]; unsigned char Title[200]; unsigned char Sender[200]; } GSM_MMSIndicator; void GSM_EncodeMMSIndicatorSMSText(unsigned char *Buffer, int *Length, GSM_MMSIndicator Indicator); +void GSM_EncodeWAPIndicatorSMSText(unsigned char *Buffer, int *Length, char *Text, char *URL); + /* ------------------------------ MMS file --------------------------------- */ #define MAX_MULTI_MMS 20 typedef enum { MMS_Text = 1, MMS_Bitmap_JPG } EncodeMultiPartMMSID; typedef struct { EncodeMultiPartMMSID ID; GSM_File File; unsigned char *Buffer; } EncodeMultiPartMMSEntry; typedef struct { /* Input values */ EncodeMultiPartMMSEntry Entries[MAX_MULTI_MMS]; int EntriesNum; unsigned char Source[200]; unsigned char Destination[200]; unsigned char Subject[200]; } GSM_EncodeMultiPartMMSInfo; void GSM_EncodeMMSFile (GSM_EncodeMultiPartMMSInfo *Info, unsigned char *Buffer, int *Length); void GSM_ClearMultiPartMMSInfo (GSM_EncodeMultiPartMMSInfo *Info); /* ------------------------------------------------------------------------ */ typedef struct { int Location; bool Active; bool SyncPhonebook; bool SyncCalendar; char Name[(20+1)*2]; char PhonebookDataBase[(50+1)*2]; char CalendarDataBase[(50+1)*2]; char User[(30+1)*2]; char Password[(20+1)*2]; char Server[(128+1)*2]; GSM_MultiWAPSettings Connection; } GSM_SyncMLSettings; /* ------------------------------------------------------------------------ */ typedef struct { diff --git a/gammu/emb/common/service/gsmlogo.c b/gammu/emb/common/service/gsmlogo.c index c992915..7c19967 100644 --- a/gammu/emb/common/service/gsmlogo.c +++ b/gammu/emb/common/service/gsmlogo.c @@ -1,52 +1,53 @@ /* (c) 2001-2004 by Marcin Wiacek */ #include <string.h> #include <stdlib.h> +#include <sys/stat.h> #include "../misc/misc.h" #include "../misc/coding/coding.h" #include "gsmlogo.h" #include "gsmnet.h" void PHONE_GetBitmapWidthHeight(GSM_Phone_Bitmap_Types Type, int *width, int *height) { *width = 0; *height = 0; switch (Type) { case GSM_EMSSmallPicture : *width=8; *height=8; break; case GSM_EMSMediumPicture : *width=16; *height=16; break; case GSM_EMSBigPicture : *width=32; *height=32; break; case GSM_NokiaOperatorLogo : case GSM_NokiaCallerLogo : *width=72; *height=14; break; case GSM_NokiaPictureImage : *width=72; *height=28; break; case GSM_Nokia7110OperatorLogo : case GSM_Nokia6510OperatorLogo : *width=78; *height=21; break; case GSM_NokiaStartupLogo : *width=84; *height=48; break; case GSM_Nokia6210StartupLogo : *width=96; *height=60; break; case GSM_Nokia7110StartupLogo : *width=96; *height=65; break; case GSM_EMSVariablePicture : break; case GSM_AlcatelBMMIPicture : break; } } int PHONE_GetBitmapSize(GSM_Phone_Bitmap_Types Type, int Width, int Height) { int width, height, x; PHONE_GetBitmapWidthHeight(Type, &width, &height); if (width == 0 && height == 0) { width = Width; height = Height; } switch (Type) { case GSM_Nokia6510OperatorLogo: x = width * height; return x/8 + (x%8 > 0); case GSM_Nokia7110OperatorLogo: return (width*height + 7)/8; case GSM_NokiaStartupLogo: case GSM_NokiaOperatorLogo: case GSM_NokiaCallerLogo: case GSM_NokiaPictureImage: case GSM_EMSSmallPicture: case GSM_EMSMediumPicture: @@ -116,96 +117,97 @@ static void PHONE_SetPointBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int case GSM_NokiaPictureImage: buffer[9*y + x/8] |= 1 << (7-(x%8)); break; case GSM_AlcatelBMMIPicture: pixel = height / 8; if ((height % 8) != 0) pixel++; buffer[pixel*x + y/8] |= 1 << (7 - (y%8)); break; } } void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap) { int width, height, x,y; PHONE_GetBitmapWidthHeight(Type, &width, &height); if (Type != GSM_Nokia6510OperatorLogo && Type != GSM_Nokia7110OperatorLogo && Type != GSM_EMSVariablePicture) { Bitmap->BitmapHeight = height; Bitmap->BitmapWidth = width; } switch (Type) { case GSM_NokiaOperatorLogo : case GSM_Nokia7110OperatorLogo : case GSM_Nokia6510OperatorLogo : Bitmap->Type=GSM_OperatorLogo; break; case GSM_NokiaCallerLogo : Bitmap->Type=GSM_CallerGroupLogo; break; case GSM_AlcatelBMMIPicture : case GSM_NokiaStartupLogo : case GSM_Nokia7110StartupLogo : case GSM_Nokia6210StartupLogo : Bitmap->Type=GSM_StartupLogo; break; case GSM_NokiaPictureImage : case GSM_EMSVariablePicture : case GSM_EMSSmallPicture : case GSM_EMSMediumPicture : case GSM_EMSBigPicture : Bitmap->Type=GSM_PictureImage; break; } Bitmap->Location = 0; Bitmap->Text[0] = 0; Bitmap->Text[1] = 0; Bitmap->BitmapEnabled = false; Bitmap->DefaultName = false; Bitmap->DefaultBitmap = false; Bitmap->DefaultRingtone = false; Bitmap->RingtoneID = 0; Bitmap->NetworkCode[0] = 0; Bitmap->Sender[0] = 0; Bitmap->Sender[1] = 0; Bitmap->ID = 0; + Bitmap->Name = NULL; GSM_ClearBitmap(Bitmap); for (x=0;x<Bitmap->BitmapWidth;x++) { for (y=0;y<Bitmap->BitmapHeight;y++) { if (PHONE_IsPointBitmap(Type, buffer, x, y, Bitmap->BitmapWidth, Bitmap->BitmapHeight)) { GSM_SetPointBitmap(Bitmap,x,y); } } } } void PHONE_ClearBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int width, int height) { memset(buffer,0,PHONE_GetBitmapSize(Type,width,height)); } void PHONE_EncodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap) { int width, height, x, y; GSM_Bitmap dest; PHONE_GetBitmapWidthHeight(Type, &width, &height); if (width == 0 && height == 0) { width = Bitmap->BitmapWidth; height = Bitmap->BitmapHeight; } GSM_ResizeBitmap(&dest, Bitmap, width, height); PHONE_ClearBitmap(Type, buffer, width, height); for (x=0;x<width;x++) { for (y=0;y<height;y++) { if (GSM_IsPointBitmap(&dest,x,y)) PHONE_SetPointBitmap(Type, buffer, x, y, width, height); } } } void GSM_GetMaxBitmapWidthHeight(GSM_Bitmap_Types Type, unsigned char *width, unsigned char *height) { switch (Type) { case GSM_CallerGroupLogo: *width=72; *height=14; break; case GSM_OperatorLogo : *width=101;*height=21; break; case GSM_StartupLogo : *width=96; *height=65; break; case GSM_PictureImage : *width=72; *height=28; break; default : break; } } void GSM_SetPointBitmap(GSM_Bitmap *bmp, int x, int y) @@ -581,107 +583,107 @@ static GSM_Error savexpm(FILE *file, GSM_MultiBitmap *bitmap) if (y==bitmap->Bitmap[0].BitmapHeight-1) { fprintf(file,"};\n"); } else { fprintf(file,",\n"); } } return ERR_NONE; } static GSM_Error savensl(FILE *file, GSM_MultiBitmap *bitmap) { char buffer[GSM_BITMAP_SIZE]; unsigned char header[]={ 'F','O','R','M', 0x01,0xFE, /* File ID block, size 1*256+0xFE=510*/ 'N','S','L','D', 0x01,0xF8}; /* Startup Logo block, size 1*256+0xF8=504*/ fwrite(header,1,sizeof(header),file); PHONE_EncodeBitmap(GSM_NokiaStartupLogo, buffer, &bitmap->Bitmap[0]); fwrite(buffer,1,PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0),file); return ERR_NONE; } static GSM_Error savewbmp(FILE *file, GSM_MultiBitmap *bitmap) { unsigned char buffer[4]; buffer[0] = 0x00; buffer[1] = 0x00; buffer[2] = bitmap->Bitmap[0].BitmapWidth; buffer[3] = bitmap->Bitmap[0].BitmapHeight; fwrite(buffer,1,4,file); PrivSaveNLMWBMP(file, &bitmap->Bitmap[0]); return ERR_NONE; } GSM_Error GSM_SaveBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) { FILE *file; GSM_Error error=ERR_NONE; file = fopen(FileName, "wb"); if (file == NULL) return ERR_CANTOPENFILE; /* Attempt to identify filetype */ - if (strstr(FileName,".nlm")) { + if (mystrcasestr(FileName,".nlm")) { error=savenlm(file,bitmap); - } else if (strstr(FileName,".ngg")) { + } else if (mystrcasestr(FileName,".ngg")) { error=savengg(file,bitmap); - } else if (strstr(FileName,".nol")) { + } else if (mystrcasestr(FileName,".nol")) { error=savenol(file,bitmap); - } else if (strstr(FileName,".xpm")) { + } else if (mystrcasestr(FileName,".xpm")) { error=savexpm(file,bitmap); - } else if (strstr(FileName,".nsl")) { + } else if (mystrcasestr(FileName,".nsl")) { error=savensl(file,bitmap); - } else if (strstr(FileName,".wbmp")) { + } else if (mystrcasestr(FileName,".wbmp")) { error=savewbmp(file,bitmap); } else { error=savebmp(file,bitmap); } fclose(file); return error; } GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) { bool first_white,isfile=false; unsigned char buff[34]; int w,h,pos,y,x,i,buffpos=0; #ifdef DEBUG int sizeimage=0; #endif if (bitmap->Type == GSM_None) bitmap->Type = GSM_StartupLogo; if (file!=NULL) isfile=true; if (isfile) { fread(buff, 1, 34, file); } else { memcpy(buff,buffer,34); } /* height and width of image in the file */ h=buff[22]+256*buff[21]; w=buff[18]+256*buff[17]; dbgprintf("Image Size in BMP file: %dx%d\n",w,h); GSM_GetMaxBitmapWidthHeight(bitmap->Type, &bitmap->BitmapWidth, &bitmap->BitmapHeight); if (h<bitmap->BitmapHeight) bitmap->BitmapHeight=h; if (w<bitmap->BitmapWidth) bitmap->BitmapWidth=w; dbgprintf("Height %i %i, width %i %i\n",h,bitmap->BitmapHeight,w,bitmap->BitmapWidth); GSM_ClearBitmap(bitmap); #ifdef DEBUG dbgprintf("Number of colors in BMP file: "); switch (buff[28]) { case 1 : dbgprintf("2 (supported)\n"); break; case 4 : dbgprintf("16 (NOT SUPPORTED)\n"); break; case 8 : dbgprintf("256 (NOT SUPPORTED)\n"); break; case 24 : dbgprintf("True Color (NOT SUPPORTED)\n"); break; default : dbgprintf("unknown\n"); break; } #endif @@ -910,94 +912,127 @@ static GSM_Error loadnsl(FILE *file, GSM_MultiBitmap *bitmap) while (fread(block,1,6,file)==6) { block_size = block[4]*256 + block[5]; dbgprintf("Block %c%c%c%c, size %i\n",block[0],block[1],block[2],block[3],block_size); if (!strncmp(block, "FORM", 4)) { dbgprintf("File ID\n"); } else { if (block_size>504) return ERR_UNKNOWN; if (block_size!=0) { fread(buffer,1,block_size,file); /* if it's string, we end it with 0 */ buffer[block_size]=0; #ifdef DEBUG if (!strncmp(block, "VERS", 4)) dbgprintf("File saved by: %s\n",buffer); if (!strncmp(block, "MODL", 4)) dbgprintf("Logo saved from: %s\n",buffer); if (!strncmp(block, "COMM", 4)) dbgprintf("Phone was connected to COM port: %s\n",buffer); #endif if (!strncmp(block, "NSLD", 4)) { bitmap->Bitmap[0].BitmapHeight = 48; bitmap->Bitmap[0].BitmapWidth = 84; OldType = bitmap->Bitmap[0].Type; PHONE_DecodeBitmap(GSM_NokiaStartupLogo, buffer, &bitmap->Bitmap[0]); if (OldType != GSM_None) bitmap->Bitmap[0].Type = OldType; dbgprintf("Startup logo (size %i)\n",block_size); } } } } bitmap->Number = 1; return(ERR_NONE); } static GSM_Error loadwbmp(FILE *file, GSM_MultiBitmap *bitmap) { unsigned char buffer[10000]; fread(buffer,1,4,file); bitmap->Bitmap[0].BitmapWidth = buffer[2]; bitmap->Bitmap[0].BitmapHeight = buffer[3]; bitmap->Number = 1; fread(buffer,1,10000,file); PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo, buffer, &bitmap->Bitmap[0]); GSM_ReverseBitmap(&bitmap->Bitmap[0]); return ERR_NONE; } +static GSM_Error loadgif(FILE *file, GSM_MultiBitmap *bitmap) +{ + GSM_Bitmap *bmap = &bitmap->Bitmap[0]; + char *buffer; + struct stat st; + int length; + + dbgprintf("loading gif file\n"); + fstat(fileno(file), &st); + bmap->BinaryPic.Length = length = st.st_size; + bmap->BinaryPic.Buffer = buffer = malloc(length); + if (bmap->BinaryPic.Buffer == NULL) + return ERR_MOREMEMORY; + + fread(buffer, 1, length, file); + dbgprintf("Length %i name \"%s\"\n", length, + DecodeUnicodeString(bmap->Name)); + + bmap->Type = GSM_PictureBinary; + bmap->BinaryPic.Type = PICTURE_GIF; + bmap->BitmapWidth = 256 * buffer[7] + buffer[6]; + bmap->BitmapHeight = 256 * buffer[9] + buffer[8]; + bitmap->Number = 1; + + return ERR_NONE; +} + GSM_Error GSM_ReadBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) { FILE *file; unsigned char buffer[300]; file = fopen(FileName, "rb"); if (file == NULL) return ERR_CANTOPENFILE; + bitmap->Bitmap[0].Name = malloc((strlen(FileName) + 1) * 2); + if (bitmap->Bitmap[0].Name == NULL) return ERR_MOREMEMORY; + EncodeUnicode(bitmap->Bitmap[0].Name, FileName, strlen(FileName)); + fread(buffer, 1, 9, file); /* Read the header of the file. */ rewind(file); bitmap->Bitmap[0].DefaultBitmap = false; /* Attempt to identify filetype */ if (memcmp(buffer, "BM",2)==0) { return loadbmp(file,bitmap); } else if (buffer[0] == 0x00 && buffer[1] == 0x00) { return loadwbmp(file,bitmap); } else if (memcmp(buffer, "NLM",3)==0) { return loadnlm(file,bitmap); } else if (memcmp(buffer, "NOL",3)==0) { return loadnolngg(file,bitmap,true); } else if (memcmp(buffer, "NGG",3)==0) { return loadnolngg(file,bitmap,false); } else if (memcmp(buffer, "FORM",4)==0) { return loadnsl(file,bitmap); + } else if (memcmp(buffer, "GIF",3)==0) { + return loadgif(file,bitmap); } return ERR_UNKNOWN; } void NOKIA_CopyBitmap(GSM_Phone_Bitmap_Types Type, GSM_Bitmap *Bitmap, char *Buffer, int *Length) { int Width, Height; Buffer[(*Length)++] = 0x00; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); Buffer[(*Length)++] = Width; Buffer[(*Length)++] = Height; Buffer[(*Length)++] = 0x01; PHONE_EncodeBitmap(Type, Buffer + (*Length), Bitmap); (*Length) = (*Length) + PHONE_GetBitmapSize(Type,0,0); } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/gsmlogo.h b/gammu/emb/common/service/gsmlogo.h index b1b579d..6c6e2d8 100644 --- a/gammu/emb/common/service/gsmlogo.h +++ b/gammu/emb/common/service/gsmlogo.h @@ -1,165 +1,191 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_bitmaps_h #define __gsm_bitmaps_h #include "../gsmcomon.h" +typedef enum { + PICTURE_BMP = 1, + PICTURE_GIF, + PICTURE_JPG, + PICTURE_ICN, + PICTURE_PNG +} GSM_BinaryPicture_Types; + +typedef struct { + GSM_BinaryPicture_Types Type; + unsigned char *Buffer; + int Length; +} GSM_BinaryPicture; + /** * Enum to handle all possible bitmaps, which are not saved in various filesystems. */ typedef enum { GSM_None = 1, /** * ID of static file in filesystem displayed during startup */ GSM_ColourStartupLogo_ID, /** * Static mono bitmap/ID of animated mono bitmap displayed during startup */ GSM_StartupLogo, /** * ID of static file in filesystem displayed instead of operator name */ GSM_ColourOperatorLogo_ID, /** * Mono bitmap displayed instead of operator name */ GSM_OperatorLogo, /** * ID of static file in filesystem displayed as wallpaper */ GSM_ColourWallPaper_ID, /** * Mono bitmap assigned to caller group */ GSM_CallerGroupLogo, /** * Text displayed during startup, which can't be removed from phone menu */ GSM_DealerNote_Text, /** * Text displayed during startup */ GSM_WelcomeNote_Text, /** * Image defined in Smart Messaging specification */ - GSM_PictureImage + GSM_PictureImage, + /** + * Binary picture (BMP, GIF, etc.) + */ + GSM_PictureBinary } GSM_Bitmap_Types; #define GSM_BITMAP_SIZE (65+7)/8*96 #define GSM_BITMAP_TEXT_LENGTH 128 /** * Structure for all possible bitmaps, which are not saved in various filesystems */ typedef struct { /** * For all: bitmap type */ GSM_Bitmap_Types Type; /** * For caller group logos: number of group * For startup logos: number of animated bitmap */ unsigned char Location; /** * For dealer/welcome note text: text * For caller group logo: name of group * For picture images: text assigned to it */ unsigned char Text[2 * (GSM_BITMAP_TEXT_LENGTH + 1)]; /** * For caller group logo: true, when logo is enabled in group */ bool BitmapEnabled; /** * For caller group logo: true, when group has default name */ bool DefaultName; /** * For caller group logo: true, when group has default bitmap */ bool DefaultBitmap; /** * For caller group logo: true, when group has default ringtone */ bool DefaultRingtone; /** * For caller group logo: ringtone ID. Phone model specific */ unsigned char RingtoneID; bool FileSystemRingtone; /** * For mono bitmaps: body of bitmap */ unsigned char BitmapPoints[GSM_BITMAP_SIZE]; /** * For mono bitmaps: height specified in pixels */ unsigned char BitmapHeight; /** * For mono bitmaps: width specified in pixels */ unsigned char BitmapWidth; /** * For operator logos: Network operator code */ char NetworkCode[7]; /** * For picture images: number of sender */ unsigned char Sender[2 * (GSM_MAX_NUMBER_LENGTH + 1)]; /** * For colour bitmaps: ID */ unsigned char ID; + /** + * For binary pictures (GIF, BMP, etc.): frame and length + */ + GSM_BinaryPicture BinaryPic; + /** + * Bitmap name + */ + char *Name; } GSM_Bitmap; #define MAX_MULTI_BITMAP 6 /** * Structure to handle more than one bitmap */ typedef struct { /** * Number of bitmaps */ unsigned char Number; /** * All bitmaps */ GSM_Bitmap Bitmap[MAX_MULTI_BITMAP]; } GSM_MultiBitmap; typedef enum { GSM_NokiaStartupLogo = 1, /*size 84*48*/ GSM_NokiaOperatorLogo, /*size 72*14*/ GSM_Nokia7110OperatorLogo, /*size 78*21*/ GSM_Nokia6510OperatorLogo, /*size 78*21*/ GSM_NokiaCallerLogo, /*size 72*14*/ GSM_NokiaPictureImage, /*size 72*28*/ GSM_Nokia7110StartupLogo, /*size 96*65*/ GSM_Nokia6210StartupLogo, /*size 96*60*/ GSM_AlcatelBMMIPicture, GSM_EMSSmallPicture, /*size 8* 8*/ GSM_EMSMediumPicture, /*size 16*16*/ GSM_EMSBigPicture, /*size 32*32*/ GSM_EMSVariablePicture } GSM_Phone_Bitmap_Types; bool GSM_IsPointBitmap (GSM_Bitmap *bmp, int x, int y); void GSM_SetPointBitmap (GSM_Bitmap *bmp, int x, int y); void GSM_ClearPointBitmap (GSM_Bitmap *bmp, int x, int y); void GSM_ClearBitmap (GSM_Bitmap *bmp); void GSM_ResizeBitmap (GSM_Bitmap *dest, GSM_Bitmap *src, int width, int height); void GSM_ReverseBitmap (GSM_Bitmap *Bitmap); void GSM_GetMaxBitmapWidthHeight(GSM_Bitmap_Types Type, unsigned char *width, unsigned char *height); int GSM_GetBitmapSize (GSM_Bitmap *bmp); void GSM_PrintBitmap (FILE *file, GSM_Bitmap *bitmap); GSM_Error GSM_SaveBitmapFile (char *FileName, GSM_MultiBitmap *bitmap); GSM_Error GSM_ReadBitmapFile (char *FileName, GSM_MultiBitmap *bitmap); GSM_Error BMP2Bitmap (unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap); diff --git a/gammu/emb/common/service/gsmmisc.h b/gammu/emb/common/service/gsmmisc.h index 37501ad..793d3d1 100644 --- a/gammu/emb/common/service/gsmmisc.h +++ b/gammu/emb/common/service/gsmmisc.h @@ -247,70 +247,75 @@ typedef enum { #endif GSM_File_Other } GSM_FileType; typedef struct { int Used; /* how many bytes used */ unsigned char Name[300]; /* Name */ bool Folder; /* true, when folder */ int Level; GSM_FileType Type; unsigned char ID_FullName[400]; unsigned char *Buffer; GSM_DateTime Modified; bool ModifiedEmpty; /* File attributes */ bool Protected; bool ReadOnly; bool Hidden; bool System; } GSM_File; GSM_Error GSM_ReadFile(char *FileName, GSM_File *File); GSM_Error GSM_JADFindData(GSM_File File, char *Vendor, char *Name, char *JAR, char *Version, int *Size); void GSM_IdentifyFileFormat(GSM_File *File); typedef struct { int Free; int Used; } GSM_FileSystemStatus; /* ----------------------------- GPRS access points ----------------------- */ typedef struct { int Location; unsigned char Name[300]; unsigned char URL[500]; bool Active; } GSM_GPRSAccessPoint; /* ------------------------------------------------------------------------ */ typedef enum { GSM_Date_DDMMYYYY = 1, GSM_Date_MMDDYYYY, - GSM_Date_YYYYMMDD + GSM_Date_YYYYMMDD, + GSM_Date_DDMMMYY, + GSM_Date_MMDDYY, + GSM_Date_DDMMYY, + GSM_Date_YYMMDD, + GSM_Date_OFF } GSM_DateFormat; typedef struct { unsigned char DateSeparator; GSM_DateFormat DateFormat; bool AMPMTime; } GSM_Locale; /* ------------------------------------------------------------------------ */ void ReadVCALDateTime(char *Buffer, GSM_DateTime *dt); void SaveVCALDateTime(char *Buffer, int *Length, GSM_DateTime *Date, char *Start); void SaveVCALText(char *Buffer, int *Length, char *Text, char *Start); bool ReadVCALText(char *Buffer, char *Start, char *Value); #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/gsmring.c b/gammu/emb/common/service/gsmring.c index 7df46f1..dab028c 100644 --- a/gammu/emb/common/service/gsmring.c +++ b/gammu/emb/common/service/gsmring.c @@ -1,57 +1,60 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* Based on some work from Ralf Thelen (7110 ringtones), - * Gnokii (RTTL and SM) and others +/* Based on some work from Ralf Thelen (7110 ringtones) and others */ +/* Based on some work (RTTL and SM) from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later */ #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> +#include <sys/stat.h> #ifdef WIN32 # include <windows.h> #endif #include "../gsmcomon.h" #include "../misc/coding/coding.h" #include "../gsmstate.h" #include "gsmring.h" #include "sms/gsmsms.h" int GSM_RingNoteGetFrequency(GSM_RingNote Note) { double freq=0; /* Values according to the software from http://iki.fi/too/sw/xring/ * generated with: * perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)' */ switch (Note.Note) { case Note_C : freq = 523.3; break; case Note_Cis: freq = 554.4; break; case Note_D : freq = 587.3; break; case Note_Dis: freq = 622.3; break; case Note_E : freq = 659.3; break; case Note_F : freq = 698.5; break; case Note_Fis: freq = 740; break; case Note_G : freq = 784; break; case Note_Gis: freq = 830.6; break; case Note_A : freq = 880; break; case Note_Ais: freq = 932.3; break; case Note_H : freq = 987.8; break; case Note_Pause: break; } switch (Note.Scale) { case Scale_440 : freq = freq / 2; break; case Scale_880 : break; case Scale_1760: freq = freq * 2; break; case Scale_3520: freq = freq * 4; break; default : break; } return (int)freq; } int GSM_RingNoteGetFullDuration(GSM_RingNote Note) { int duration = 1; switch (Note.Duration) { @@ -111,96 +114,102 @@ GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone) DATA_Buffer[j] = ((int)(0.5*50000)); #endif phase = phase + phase_step; length++; } fwrite(&DATA_Buffer,sizeof(short),j,file); } } wavfilesize = sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header) + length*2; WAV_Header[4] = ((unsigned char)wavfilesize % 256); WAV_Header[5] = ((unsigned char)wavfilesize / 256); WAV_Header[6] = ((unsigned char)wavfilesize / (256*256)); WAV_Header[7] = ((unsigned char)wavfilesize / (256*256*256)); wavfilesize = wavfilesize - 54; DATA_Header[4] = ((unsigned char)wavfilesize % 256); DATA_Header[5] = ((unsigned char)wavfilesize / 256); DATA_Header[6] = ((unsigned char)wavfilesize / (256*256)); DATA_Header[7] = ((unsigned char)wavfilesize / (256*256*256)); fseek( file, 0, SEEK_SET); fwrite(&WAV_Header, 1, sizeof(WAV_Header), file); fwrite(&FMT_Header, 1, sizeof(FMT_Header), file); fwrite(&DATA_Header, 1, sizeof(DATA_Header), file); return ERR_NONE; } static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone) { char nullchar=0x00; fwrite(&nullchar,1,1,file); fwrite(&nullchar,1,1,file); fprintf(file,"\x0C\x01\x2C"); fprintf(file,"%s",DecodeUnicodeString(ringtone->Name)); fwrite(&nullchar,1,1,file); fwrite(&nullchar,1,1,file); fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); return ERR_NONE; } static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) { fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); return ERR_NONE; } +static GSM_Error savemmf(FILE *file, GSM_Ringtone *ringtone) +{ + fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); + return ERR_NONE; +} + GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) { GSM_RingNoteScale DefNoteScale; GSM_RingNoteDuration DefNoteDuration; GSM_RingNoteStyle DefNoteStyle=0; int DefNoteTempo=0; bool started = false, firstcomma = true; GSM_RingNote *Note; unsigned char buffer[15]; int i,j,k=0; /* Saves ringtone name */ fprintf(file,"%s:",DecodeUnicodeString(ringtone->Name)); /* Find the most frequently used duration */ for (i=0;i<6;i++) buffer[i]=0; for (i=0;i<ringtone->NoteTone.NrCommands;i++) { if (ringtone->NoteTone.Commands[i].Type == RING_Note) { Note = &ringtone->NoteTone.Commands[i].Note; /* some durations need 2 bytes in file, some 1 */ if (Note->Duration >= Duration_Full && Note->Duration <= Duration_1_8) { buffer[Note->Duration/32]++; } if (Note->Duration >= Duration_1_16 && Note->Duration <= Duration_1_32) { buffer[Note->Duration/32]+=2; } } } /* Now find the most frequently used */ j=0; for (i=0;i<6;i++) { if (buffer[i]>j) { k=i; j=buffer[i]; } } /* Finally convert the default duration */ DefNoteDuration = k * 32; dbgprintf("DefNoteDuration=%d\n", DefNoteDuration); switch (DefNoteDuration) { case Duration_Full:fprintf(file,"d=1"); break; case Duration_1_2 :fprintf(file,"d=2"); break; case Duration_1_4 :fprintf(file,"d=4"); break; case Duration_1_8 :fprintf(file,"d=8"); break; case Duration_1_16:fprintf(file,"d=16");break; @@ -440,96 +449,99 @@ void savemid(FILE* file, GSM_Ringtone *ringtone) fwrite(midifile,1,current,file); } #endif void saveott(FILE *file, GSM_Ringtone *ringtone) { char Buffer[2000]; int i=2000; GSM_EncodeNokiaRTTLRingtone(*ringtone, Buffer, &i); fwrite(Buffer, 1, i, file); } GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone) { FILE *file; file = fopen(FileName, "wb"); if (file == NULL) return ERR_CANTOPENFILE; switch (ringtone->Format) { case RING_NOTETONE: if (strstr(FileName,".ott")) { saveott(file,ringtone); #ifndef ENABLE_LGPL } else if (strstr(FileName,".mid")) { savemid(file,ringtone); #endif } else if (strstr(FileName,".rng")) { saveott(file,ringtone); } else if (strstr(FileName,".imy")) { saveimelody(file,ringtone); } else if (strstr(FileName,".ime")) { saveimelody(file,ringtone); } else if (strstr(FileName,".wav")) { savewav(file,ringtone); } else { saverttl(file, ringtone); } break; case RING_NOKIABINARY: savebin(file, ringtone); break; case RING_MIDI: savepuremidi(file, ringtone); break; + case RING_MMF: + savemmf(file, ringtone); + break; } fclose(file); return ERR_NONE; } static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) { GSM_RingNoteScale DefNoteScale = Scale_880; GSM_RingNoteDuration DefNoteDuration = Duration_1_4; GSM_RingNoteStyle DefNoteStyle = NaturalStyle; int DefNoteTempo = 63, i=0; unsigned char buffer[2000],Name[100]; GSM_RingNote *Note; fread(buffer, 2000, 1, file); ringtone->NoteTone.NrCommands = 0; /* -------------- name ---------------- */ while (buffer[i] != ':') { if (buffer[i] == 0x00) return ERR_NONE; i++; } if (i == 0) { /* This is for RTTL ringtones without name. */ EncodeUnicode(ringtone->Name,"Gammu",5); } else { memcpy(Name,buffer,i); Name[i] = 0x00; EncodeUnicode(ringtone->Name,Name,strlen(Name)); } i++; /* --------- section with default ringtone settings ----------- */ while(1) { switch (buffer[i]) { case ':': break; case 0x00: return ERR_NONE; case 'd': case 'D': switch (atoi(buffer+i+2)) { case 1: DefNoteDuration = Duration_Full; break; case 2: DefNoteDuration = Duration_1_2 ; break; case 4: DefNoteDuration = Duration_1_4 ; break; @@ -724,169 +736,198 @@ static GSM_Error loadcommunicator(FILE *file, GSM_Ringtone *ringtone) char Buffer[4000]; int i,j; i=fread(Buffer, 1, 4000, file); i=0;j=0; while (true) { if (Buffer[j] ==0x00 && Buffer[j+1]==0x02 && Buffer[j+2]==0x4a && Buffer[j+3]==0x3a) break; if (j==i-4) return ERR_UNKNOWN; j++; } j++; return GSM_DecodeNokiaRTTLRingtone(ringtone, Buffer+j, i-j); } static GSM_Error loadbin(FILE *file, GSM_Ringtone *ringtone) { int i; unsigned char buffer[2000]; dbgprintf("loading binary\n"); ringtone->NokiaBinary.Length=fread(buffer, 1, 500, file); i=5; while (buffer[i]!=0x00) i++; EncodeUnicode(ringtone->Name,buffer+5,i-5); while (buffer[i]!=0x02 && buffer[i+1]!=0xFC && buffer[i+2]!=0x09) { i++; } ringtone->NokiaBinary.Length=ringtone->NokiaBinary.Length-i; memcpy(ringtone->NokiaBinary.Frame,buffer+i,ringtone->NokiaBinary.Length); dbgprintf("Length %i name \"%s\"\n",ringtone->NokiaBinary.Length,DecodeUnicodeString(ringtone->Name)); return ERR_NONE; } static GSM_Error loadpuremidi(FILE *file, GSM_Ringtone *ringtone) { unsigned char buffer[30000]; dbgprintf("loading midi\n"); EncodeUnicode(ringtone->Name,"MIDI",4); ringtone->NokiaBinary.Length=fread(buffer, 1, 30000, file); memcpy(ringtone->NokiaBinary.Frame,buffer,ringtone->NokiaBinary.Length); dbgprintf("Length %i name \"%s\"\n",ringtone->NokiaBinary.Length,DecodeUnicodeString(ringtone->Name)); return ERR_NONE; } +static GSM_Error loadmmf(FILE *file, GSM_Ringtone *ringtone) +{ + struct stat st; + char *buffer; + int length; + + dbgprintf("loading smaf file\n"); + fstat(fileno(file), &st); + ringtone->BinaryTone.Length = length = st.st_size; + ringtone->BinaryTone.Buffer = buffer = malloc(length); + if (buffer == NULL) + return ERR_MOREMEMORY; + fread(buffer, 1, length, file); + + dbgprintf("Length %i name \"%s\"\n", length, + DecodeUnicodeString(ringtone->Name)); + + return ERR_NONE; +} + static GSM_Error loadre(FILE *file, GSM_Ringtone *ringtone) { unsigned char buffer[2000]; ringtone->NokiaBinary.Length=fread(buffer, 1, 500, file); if (buffer[18]==0x00 && buffer[21]!=0x02) { /* DCT3, Unicode subformat, 62xx & 7110 */ CopyUnicodeString(ringtone->Name,buffer+18); ringtone->NokiaBinary.Length = ringtone->NokiaBinary.Length - (21+UnicodeLength(ringtone->Name)*2); memcpy(ringtone->NokiaBinary.Frame,buffer+21+UnicodeLength(ringtone->Name)*2,ringtone->NokiaBinary.Length); } else { /* DCT3, normal subformat, 32xx/33xx/51xx/5210/5510/61xx/8xxx */ EncodeUnicode(ringtone->Name,buffer+17,buffer[16]); ringtone->NokiaBinary.Length = ringtone->NokiaBinary.Length - (19+UnicodeLength(ringtone->Name)); memcpy(ringtone->NokiaBinary.Frame,buffer+19+UnicodeLength(ringtone->Name),ringtone->NokiaBinary.Length); } dbgprintf("Name \"%s\"\n",DecodeUnicodeString(ringtone->Name)); return ERR_NONE; } GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone) { FILE *file; unsigned char buffer[300]; GSM_Error error = ERR_UNKNOWN; dbgprintf("Loading ringtone %s\n",FileName); file = fopen(FileName, "rb"); if (file == NULL) return ERR_CANTOPENFILE; /* Read the header of the file. */ fread(buffer, 1, 4, file); if (ringtone->Format == 0x00) { ringtone->Format = RING_NOTETONE; if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x0C && buffer[3]==0x01) { ringtone->Format = RING_NOKIABINARY; } if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x00) { ringtone->Format = RING_NOKIABINARY; } if (buffer[0]==0x4D && buffer[1]==0x54 && buffer[2]==0x68 && buffer[3]==0x64) { ringtone->Format = RING_MIDI; } + if (buffer[0]==0x4D && buffer[1]==0x4D && + buffer[2]==0x4D && buffer[3]==0x44) { + ringtone->Format = RING_MMF; + } } rewind(file); switch (ringtone->Format) { case RING_NOTETONE: if (buffer[0]==0x02 && buffer[1]==0x4A) { error=loadott(file,ringtone); } else if (buffer[0]==0xC7 && buffer[1]==0x45) { error=loadcommunicator(file,ringtone); } else { error=loadrttl(file,ringtone); } ringtone->NoteTone.AllNotesScale=false; break; case RING_NOKIABINARY: if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x0C && buffer[3]==0x01) { error=loadbin(file,ringtone); } if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x00) { error=loadre(file,ringtone); } break; case RING_MIDI: EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); error = loadpuremidi(file,ringtone); + break; + case RING_MMF: + EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); + error = loadmmf(file,ringtone); + break; } fclose(file); return(error); } /* -------------------------- required with Nokia & RTTL ------------------- */ /* Beats per Minute like written in Smart Messaging */ static int SM_BeatsPerMinute[] = { 25, 28, 31, 35, 40, 45, 50, 56, 63, 70, 80, 90, 100, 112, 125, 140, 160, 180, 200, 225, 250, 285, 320, 355, 400, 450, 500, 565, 635, 715, 800, 900 }; int GSM_RTTLGetTempo(int Beats) { int i=0; while (Beats > SM_BeatsPerMinute[i] && SM_BeatsPerMinute[i] != 900) i++; return i<<3; } /* This function packs the ringtone from the structure "ringtone" to "package", where maxlength means length of package. Function returns number of packed notes and change maxlength to number of used chars in "package" */ unsigned char GSM_EncodeNokiaRTTLRingtone(GSM_Ringtone ringtone, unsigned char *package, int *maxlength) { unsigned char CommandLength = 0x02; unsigned char Loop = 0x15; /* Infinite */ unsigned char Buffer[200]; int StartBit=0, OldStartBit; int StartBitHowManyCommands; int HowManyCommands = 0; /* How many instructions packed */ int HowManyNotes = 0; int i,j; bool started; GSM_RingNote *Note; GSM_RingNoteScale DefScale = 255; GSM_RingNoteStyle DefStyle = 255; int DefTempo = 255; AddBufferByte(package, &StartBit, CommandLength, 8); AddBufferByte(package, &StartBit, SM_Command_RingingToneProgramming, 7); diff --git a/gammu/emb/common/service/gsmring.h b/gammu/emb/common/service/gsmring.h index 207cf31..2d2dd7a 100644 --- a/gammu/emb/common/service/gsmring.h +++ b/gammu/emb/common/service/gsmring.h @@ -75,111 +75,113 @@ typedef enum { DoubleDottedNote = 0x02<<6, Length_2_3 = 0x03<<6 } GSM_RingNoteDurationSpec; typedef enum { Scale_55 = 1, /* 55 Hz for note A */ Scale_110, /* 110 Hz for note A */ Scale_220, Scale_440, /* first scale for Nokia */ Scale_880, Scale_1760, Scale_3520, /* last scale for Nokia */ Scale_7040, Scale_14080 } GSM_RingNoteScale; typedef struct { GSM_RingNoteDuration Duration; GSM_RingNoteDurationSpec DurationSpec; GSM_RingNoteNote Note; GSM_RingNoteStyle Style; GSM_RingNoteScale Scale; int Tempo; } GSM_RingNote; typedef enum { RING_Note = 1, RING_EnableVibra, RING_DisableVibra, RING_EnableLight, RING_DisableLight, RING_EnableLED, RING_DisableLED, RING_Repeat } GSM_RingCommandType; typedef struct { GSM_RingCommandType Type; GSM_RingNote Note; unsigned char Value; } GSM_RingCommand; typedef struct { int NrCommands; GSM_RingCommand Commands[MAX_RINGTONE_NOTES]; bool AllNotesScale; } GSM_NoteRingtone; +/* FIXME: should use BinaryTone instead? */ /* Structure to hold Nokia binary ringtones. */ typedef struct { - unsigned char Frame[30000]; + unsigned char Frame[50000]; int Length; } GSM_NokiaBinaryRingtone; typedef struct { - unsigned char *Frame; + unsigned char *Buffer; int Length; } GSM_BinaryTone; typedef enum { RING_NOTETONE = 1, RING_NOKIABINARY, - RING_MIDI + RING_MIDI, + RING_MMF } GSM_RingtoneFormat; /** * Structure for saving various ringtones formats */ typedef struct { /** * Ringtone saved in one of three formats */ GSM_NokiaBinaryRingtone NokiaBinary; GSM_BinaryTone BinaryTone; GSM_NoteRingtone NoteTone; /** * Ringtone format */ GSM_RingtoneFormat Format; /** * Ringtone name */ char Name[20*2]; /** * Ringtone location */ int Location; } GSM_Ringtone; typedef struct { int Group; //Nokia specific int ID; char Name[30*2]; } GSM_RingtoneInfo; typedef struct { int Number; GSM_RingtoneInfo Ringtone[100]; } GSM_AllRingtonesInfo; GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone); GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone); void saveott(FILE *file, GSM_Ringtone *ringtone); void savemid(FILE *file, GSM_Ringtone *ringtone); void saverng(FILE *file, GSM_Ringtone *ringtone); void saveimelody(FILE *file, GSM_Ringtone *ringtone); GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone); GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone); unsigned char GSM_EncodeNokiaRTTLRingtone (GSM_Ringtone ringtone, unsigned char *package, int *maxlength); diff --git a/gammu/emb/common/service/sms/gsmmulti.c b/gammu/emb/common/service/sms/gsmmulti.c index 6c1cdcd..bdb5ee9 100644 --- a/gammu/emb/common/service/sms/gsmmulti.c +++ b/gammu/emb/common/service/sms/gsmmulti.c @@ -442,96 +442,101 @@ GSM_Error GSM_EncodeMultiPartSMS(GSM_MultiPartSMSInfo *Info, return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages); } } return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages16bit); } return error; } if (Info->EntriesNum != 1) return ERR_UNKNOWN; switch (Info->Entries[0].ID) { case SMS_AlcatelMonoBitmapLong: Buffer[0] = Info->Entries[0].Bitmap->Bitmap[0].BitmapWidth; Buffer[1] = Info->Entries[0].Bitmap->Bitmap[0].BitmapHeight; PHONE_EncodeBitmap(GSM_AlcatelBMMIPicture, Buffer+2, &Info->Entries[0].Bitmap->Bitmap[0]); Length = PHONE_GetBitmapSize(GSM_AlcatelBMMIPicture,Info->Entries[0].Bitmap->Bitmap[0].BitmapWidth,Info->Entries[0].Bitmap->Bitmap[0].BitmapHeight)+2; return GSM_EncodeAlcatelMultiPartSMS(SMS,Buffer,Length,Info->Entries[0].Bitmap->Bitmap[0].Text,ALCATELTDD_PICTURE); case SMS_AlcatelMonoAnimationLong: /* Number of sequence words */ Buffer[0] = (Info->Entries[0].Bitmap->Number+1) % 256; Buffer[1] = (Info->Entries[0].Bitmap->Number+1) / 256; /* Picture display time 1 second (1 = 100ms) */ Buffer[2] = 10 % 256; Buffer[3] = 10 / 256 + 0xF0; Length = 4; j = 0; /* Offsets to bitmaps */ for (i=0;i<Info->Entries[0].Bitmap->Number;i++) { Buffer[Length++] = (4+j+Info->Entries[0].Bitmap->Number*2) % 256; Buffer[Length++] = (4+j+Info->Entries[0].Bitmap->Number*2) / 256; j += PHONE_GetBitmapSize(GSM_AlcatelBMMIPicture,Info->Entries[0].Bitmap->Bitmap[i].BitmapWidth,Info->Entries[0].Bitmap->Bitmap[i].BitmapHeight)+2; } /* Bitmaps */ for (i=0;i<Info->Entries[0].Bitmap->Number;i++) { Buffer[Length++] = Info->Entries[0].Bitmap->Bitmap[i].BitmapWidth; Buffer[Length++] = Info->Entries[0].Bitmap->Bitmap[i].BitmapHeight; PHONE_EncodeBitmap(GSM_AlcatelBMMIPicture, Buffer+Length, &Info->Entries[0].Bitmap->Bitmap[i]); Length += PHONE_GetBitmapSize(GSM_AlcatelBMMIPicture,Info->Entries[0].Bitmap->Bitmap[i].BitmapWidth,Info->Entries[0].Bitmap->Bitmap[i].BitmapHeight); } return GSM_EncodeAlcatelMultiPartSMS(SMS,Buffer,Length,Info->Entries[0].Bitmap->Bitmap[0].Text,ALCATELTDD_ANIMATION); case SMS_MMSIndicatorLong: Class = 1; UDH = UDH_MMSIndicatorLong; GSM_EncodeMMSIndicatorSMSText(Buffer,&Length,*Info->Entries[0].MMSIndicator); break; + case SMS_WAPIndicatorLong: + Class = 1; + UDH = UDH_MMSIndicatorLong; + GSM_EncodeWAPIndicatorSMSText(Buffer,&Length,Info->Entries[0].MMSIndicator->Title,Info->Entries[0].MMSIndicator->Address); + break; case SMS_NokiaRingtoneLong: case SMS_NokiaRingtone: UDH = UDH_NokiaRingtone; Class = 1; /* 7 = length of UDH_NokiaRingtone UDH header */ Length = GSM_MAX_8BIT_SMS_LENGTH-7; Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); if (Info->Entries[0].ID == SMS_NokiaRingtone) break; if (Info->Entries[0].RingtoneNotes != Info->Entries[0].Ringtone->NoteTone.NrCommands) { UDH = UDH_NokiaRingtoneLong; Length = (GSM_MAX_8BIT_SMS_LENGTH-12)*3; Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); } break; case SMS_NokiaOperatorLogoLong: if (Info->Entries[0].Bitmap->Bitmap[0].BitmapWidth > 72 || Info->Entries[0].Bitmap->Bitmap[0].BitmapHeight > 14) { UDH = UDH_NokiaOperatorLogoLong; Class = 1; NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); Length = Length + 3; NOKIA_CopyBitmap(GSM_Nokia7110OperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); break; } case SMS_NokiaOperatorLogo: UDH = UDH_NokiaOperatorLogo; Class = 1; NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); Length = Length + 3; NOKIA_CopyBitmap(GSM_NokiaOperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); break; case SMS_NokiaCallerLogo: UDH = UDH_NokiaCallerLogo; Class = 1; NOKIA_CopyBitmap(GSM_NokiaCallerLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); break; case SMS_NokiaProfileLong: case SMS_NokiaPictureImageLong: case SMS_NokiaScreenSaverLong: Class = 1; UDH = UDH_NokiaProfileLong; GSM_EncodeSMS30MultiPartSMS(Info,Buffer,&Length); break; case SMS_NokiaWAPBookmarkLong: Class = 1; NOKIA_EncodeWAPBookmarkSMSText(Buffer,&Length,Info->Entries[0].Bookmark); /* 7 = length of UDH_NokiaWAP UDH header */ if (Length>(GSM_MAX_8BIT_SMS_LENGTH-7)) { UDH=UDH_NokiaWAPLong; diff --git a/gammu/emb/common/service/sms/gsmmulti.h b/gammu/emb/common/service/sms/gsmmulti.h index c672261..3f70d81 100644 --- a/gammu/emb/common/service/sms/gsmmulti.h +++ b/gammu/emb/common/service/sms/gsmmulti.h @@ -1,53 +1,57 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_multi_h #define __gsm_multi_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include "../../gsmcomon.h" #include "../gsmlogo.h" #include "../gsmcal.h" #include "../gsmpbk.h" #include "../gsmdata.h" #include "../gsmring.h" #include "gsmsms.h" /* ---------------------- multi SMS --------------------------------------- */ /* Identifiers for Smart Messaging 3.0 multipart SMS */ #define SM30_ISOTEXT 0 /* ISO 8859-1 text */ #define SM30_UNICODETEXT 1 #define SM30_OTA 2 #define SM30_RINGTONE 3 #define SM30_PROFILENAME 4 /* ... */ #define SM30_SCREENSAVER 6 /* Identifiers for Alcatel Terminal Data Download */ #define ALCATELTDD_PICTURE 4 #define ALCATELTDD_ANIMATION 5 #define ALCATELTDD_SMSTEMPLATE 6 void GSM_SMSCounter(int MessageLength, unsigned char *MessageBuffer, GSM_UDH UDHType, GSM_Coding_Type Coding, int *SMSNum, int *CharsLeft); #define MAX_MULTI_SMS 10 /** * Multiple SMS messages, used for Smart Messaging 3.0/EMS. */ typedef struct { /** * Sender or recipient number. */ unsigned char Number; /** * Array of SMSes. */ GSM_SMSMessage SMS[MAX_MULTI_SMS]; } GSM_MultiSMSMessage; @@ -127,145 +131,150 @@ typedef enum { */ SMS_NokiaWAPBookmarkLong, /** * Nokia WAP settings in 2 SMS */ SMS_NokiaWAPSettingsLong, /** * Nokia MMS settings in 2 SMS */ SMS_NokiaMMSSettingsLong, /** * Nokia VCARD 1.0 - only name and default number */ SMS_NokiaVCARD10Long, /** * Nokia VCARD 2.1 - all numbers + text */ SMS_NokiaVCARD21Long, /** * Nokia VCALENDAR 1.0 - can be in few sms */ SMS_NokiaVCALENDAR10Long, SMS_NokiaVTODOLong, SMS_VCARD10Long, SMS_VCARD21Long, SMS_DisableVoice, SMS_DisableFax, SMS_DisableEmail, SMS_EnableVoice, SMS_EnableFax, SMS_EnableEmail, SMS_VoidSMS, /** * IMelody 1.0 */ SMS_EMSSound10, /** * IMelody 1.2 */ SMS_EMSSound12, /** * IMelody without header - SonyEricsson extension */ SMS_EMSSonyEricssonSound, /** * IMelody 1.0 with UPI. */ SMS_EMSSound10Long, - /*** + /** * IMelody 1.2 with UPI. */ SMS_EMSSound12Long, /** * IMelody without header with UPI. */ SMS_EMSSonyEricssonSoundLong, SMS_EMSPredefinedSound, SMS_EMSPredefinedAnimation, SMS_EMSAnimation, /** * Fixed bitmap of size 16x16 or 32x32. */ SMS_EMSFixedBitmap, SMS_EMSVariableBitmap, SMS_EMSVariableBitmapLong, SMS_MMSIndicatorLong, + SMS_WAPIndicatorLong, /** * Variable bitmap with black and white colors */ SMS_AlcatelMonoBitmapLong, /** * Variable animation with black and white colors */ SMS_AlcatelMonoAnimationLong, SMS_AlcatelSMSTemplateName } EncodeMultiPartSMSID; typedef struct { EncodeMultiPartSMSID ID; int Number; GSM_Ringtone *Ringtone; GSM_MultiBitmap *Bitmap; GSM_WAPBookmark *Bookmark; GSM_WAPSettings *Settings; GSM_MMSIndicator *MMSIndicator; GSM_MemoryEntry *Phonebook; GSM_CalendarEntry *Calendar; GSM_ToDoEntry *ToDo; bool Protected; unsigned char *Buffer; bool Left; bool Right; bool Center; bool Large; bool Small; bool Bold; bool Italic; bool Underlined; bool Strikethrough; /* Return values */ int RingtoneNotes; } MultiPartSMSEntry; typedef struct { MultiPartSMSEntry Entries[MAX_MULTI_SMS]; int EntriesNum; bool UnicodeCoding; int Class; unsigned char ReplaceMessage; bool Unknown; } GSM_MultiPartSMSInfo; /** * Encodes multi part SMS from "readable" format. */ GSM_Error GSM_EncodeMultiPartSMS (GSM_MultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS); /** * Decodes multi part SMS to "readable" format. */ bool GSM_DecodeMultiPartSMS (GSM_MultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS, bool ems); /** * Clears @ref GSM_MultiPartSMSInfo to default values. */ void GSM_ClearMultiPartSMSInfo (GSM_MultiPartSMSInfo *Info); /** * Frees any allocated structures inside @ref GSM_MultiPartSMSInfo. */ void GSM_FreeMultiPartSMSInfo (GSM_MultiPartSMSInfo *Info); /** * Links SMS messages according to IDs. */ GSM_Error GSM_LinkSMS(GSM_MultiSMSMessage **INPUT, GSM_MultiSMSMessage **OUTPUT, bool ems); +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/sms/gsmsms.c b/gammu/emb/common/service/sms/gsmsms.c index 9920835..feceba4 100644 --- a/gammu/emb/common/service/sms/gsmsms.c +++ b/gammu/emb/common/service/sms/gsmsms.c @@ -1,50 +1,53 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Pawel Kot, others and Gnokii */ +/* Based on some Pawel Kot and others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <ctype.h> #include <string.h> #include <time.h> #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" /* User data headers */ static GSM_UDHHeader UDHHeaders[] = { /* See GSM 03.40 section 9.2.3.24.1 * 1 byte 0x00 * 1 byte 0x03 * 1 byte 0x01: unique ID for message series * 1 byte 0x00: how many SMS in sequence * 1 byte 0x00: number of current SMS in sequence */ { UDH_ConcatenatedMessages, 0x05, "\x00\x03\x01\x00\x00",2,-1,4,3}, /* See GSM 03.40 section 9.2.3.24.2 for voice, fax and email messages */ { UDH_DisableVoice, 0x04, "\x01\x02\x00\x00",-1,-1,-1,-1}, { UDH_DisableFax, 0x04, "\x01\x02\x01\x00",-1,-1,-1,-1}, { UDH_DisableEmail, 0x04, "\x01\x02\x02\x00",-1,-1,-1,-1}, { UDH_EnableVoice, 0x04, "\x01\x02\x00\x01",-1,-1,-1,-1}, { UDH_EnableFax, 0x04, "\x01\x02\x01\x01",-1,-1,-1,-1}, { UDH_EnableEmail, 0x04, "\x01\x02\x02\x01",-1,-1,-1,-1}, /* When send such SMS to some phones, they don't display anything, * only beep and enable vibra/light */ { UDH_VoidSMS, 0x08, "\x01\x02\x02\x01\x01\x02\x02\x00",-1,-1,-1,-1}, /* Nokia Smart Messaging (short version) UDH * General format : * 1 byte 0x05 : IEI application port addressing scheme, 16 bit address * 1 byte 0x04 : IEI length * 2 bytes : destination address : high & low byte * 2 bytes 0x00 0x00 : originator address : high & low byte */ { UDH_NokiaRingtone, 0x06, "\x05\x04\x15\x81\x00\x00",-1,-1,-1,-1}, { UDH_NokiaOperatorLogo, 0x06, "\x05\x04\x15\x82\x00\x00",-1,-1,-1,-1}, { UDH_NokiaCallerLogo, 0x06, "\x05\x04\x15\x83\x00\x00",-1,-1,-1,-1}, { UDH_NokiaWAP, 0x06, "\x05\x04\xc3\x4f\x00\x00",-1,-1,-1,-1}, diff --git a/gammu/emb/common/service/sms/gsmsms.h b/gammu/emb/common/service/sms/gsmsms.h index d87ff60..0b950d3 100644 --- a/gammu/emb/common/service/sms/gsmsms.h +++ b/gammu/emb/common/service/sms/gsmsms.h @@ -1,50 +1,53 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Pawel Kot, others and Gnokii */ +/* Based on some Pawel Kot and others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #ifndef __gsm_sms_h #define __gsm_sms_h #include "../../gsmcomon.h" #include "../gsmlogo.h" #include "../gsmcal.h" #include "../gsmpbk.h" #include "../gsmdata.h" #include "../gsmring.h" /* --------------------- Some general definitions ------------------------- */ #define GSM_MAX_UDH_LENGTH 140 #define GSM_MAX_SMS_LENGTH 160 #define GSM_MAX_8BIT_SMS_LENGTH 140 /* -------------------- Cell Broadcast ------------------------------------ */ /** * Structure for Cell Broadcast messages. */ typedef struct { /** * Message text. */ char Text[300]; /** * Channel number. */ int Channel; } GSM_CBMessage; /* ------------------------ SMS status ------------------------------------ */ /** * Status of SMS memory. */ typedef struct { /** * Number of unread messages on SIM. */ int SIMUnRead; /** * Number of all saved messages (including unread) on SIM. */ int SIMUsed; /** |