-rw-r--r-- | bin/kdepim/WhatsNew.txt | 5 | ||||
-rw-r--r-- | gammu/emb/common/phone/alcatel/alcatel.c | 2 | ||||
-rw-r--r-- | gammu/emb/gammu/depend/nokia/dct3.c | 2 | ||||
-rw-r--r-- | gammu/emb/gammu/depend/nokia/dct3trac/wmx.c | 2 | ||||
-rw-r--r-- | gammu/emb/gammu/depend/nokia/dct4.c | 2 | ||||
-rw-r--r-- | gammu/emb/gammu/depend/siemens/dsiemens.c | 2 | ||||
-rw-r--r-- | kaddressbook/addresseeeditorwidget.h | 1 | ||||
-rw-r--r-- | pwmanager/libcrypt/cipher/serpent.c | 4 | ||||
-rw-r--r-- | pwmanager/pwmanager/binentrygen.cpp | 5 | ||||
-rw-r--r-- | pwmanager/pwmanager/binentrygen.h | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/blowfish.cpp | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/blowfish.h | 4 | ||||
-rw-r--r-- | pwmanager/pwmanager/genpasswd.cpp | 1 | ||||
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.h | 4 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmexception.h | 3 | ||||
-rw-r--r-- | pwmanager/pwmanager/randomizer.h | 1 |
16 files changed, 28 insertions, 14 deletions
diff --git a/bin/kdepim/WhatsNew.txt b/bin/kdepim/WhatsNew.txt index cd37aac..9879ef0 100644 --- a/bin/kdepim/WhatsNew.txt +++ b/bin/kdepim/WhatsNew.txt @@ -1,128 +1,133 @@ Info about the changes in new versions of KDE-Pim/Pi ********** VERSION 2.2.8 ************ I forgot what I fixed... Some minor fixes in KA/Pi and KO/Pi. KA/Pi uses popup menu now for quick category selection in contact edit dialog. In the Pi-syc mode of KO/Pi it is now possible to define specific resources which can be synced with the remote pi-sync server. This feature must be considered as unstable - it still needs some more testing. +On Wintendo now KA/Pi can sync with Outlook. The configuration of the sync needs some moer tweking. +Fixed some gcc 4.xx compilation probs. +Fixed an annoying cursor focus reset problem when editing and (auto-)saving journal enries in KO/Pi. + + ********** VERSION 2.2.7 ************ Added for Desktop Versions (Windows + Linux) the possibility to specify an email client to call if the user clicks on an emailaddress. (Menu: Config->Global Settings->Extern.Applications: E-mail). Added as default (and example) Mozilla Thunderbird settings. If the path to the binary in this Mozilla Thunderbird example is not matching your environment you can take these settings as an template and configure "User defined email client". ********** VERSION 2.2.6 ************ KO/Pi: Made navigation in datepicker more userfriendly when using keyboard for scrolling. KO/Pi Alarm applet: Made font size for the two popup menus with larger font configurable: Change size with menu: Play Beeps->Font Size Save settings such that it will be restored after next reboot with menu: Play Beeps->Config->Save. KA/Pi: Big change! Needed for the upcoming Outlook sync: (Outlook sync available appr. end of 2005) Telephone number types are now fixed in KA/Pi (but still compatible with the vCard standard, of cource) and they are compatible with the types used by the evil empire. That makes syncing with OL possible and make it possible to sync better with mobile devices. NOTE: All your telephone types will be converted automatically at loading/importing! Such that it may be a good idea to make a backup of the data before starting KA/Pi. But the editing of phone numbers and types has changed completely such that it is now much faster to edit/change types and numbers. HINT: To see whether there was some number for some contact not converted senseful, choose Menu: View->Modify view and add "Other Phone" ( in German "Sonst. Telefon") to the view. If a type was not converted senseful to some of the 18 new, fixed types, it will get the "Other" type. ********** VERSION 2.2.5 ************ Bugfixes in KO/Pi, KA/Pi and OM/Pi. Added possibility to disable auto saving in KO/Pi. How to disable it? Good question! Next question, please? Added info about count of events/todos/journals to calendar info. ********** VERSION 2.2.4 ************ KO/Pi alarm applet: Made font smaller and added a dealy before starting KO/Pi to avoid problems accessing data storage when an alarm did wake up the Z. Added 3 sec notification about a started timer. KO/Pi: Added export option for all data to File->Export menu. Better management if a save error occours. Added 15 sec delay in automatic saving when Z wake up from suspend and the automatic save timer did expire - to avoid problems accessing data storage directly after wake up. Fix for displaying month names of an utf8 translated language (like Russian). I hope a Russian version of KO/Pi will be available soon. Added duration info about multiday events. Changed behaviour of "Set complete" in Todo viewer: Now Todo viewer closes not automatically. KA/Pi: Added for vCard import the option to import contact data in Latin1 format. ********** VERSION 2.2.3 ************ KO/Pi: Fixed a problem with (non empty) exception dates in the exception date edit dialog of recurring events for newly created events. Fixed usability problem in KA/Pi: Now searching works for "all phone numbers and all addresses" if "all fields" is selected as search option. Changed some behaviour in OM/Pi mail management to make it more usable. ********** VERSION 2.2.2 ************ KO/Pi: Fixed a problem with the sort order of last modified date in list view. KA/Pi: Fixed a resource config read problem on windows. ********** VERSION 2.2.1 ************ KO/Pi: Fixed a problem displaying very long allday events in agenda view in single day mode. Fixed a problem with the default settings for new todos. Added an error message dialog if saving of calendar files is not possible. Made it impossible to close KO/Pi if saving fails. Fixed a problem adding calendars on windows such that these calendars can be used on the memory stick. Added config options for conflict detection. KA/Pi: Added a config option to turn on asking before a contact is deleted. Fixed a problem with the default view and view selection at startup. Formatted name is now set on import, if formatted name is empty. Fixed a problem of displaying images in the contact details view: Now the wid/hei ratio is not changed. I a picture is larger than 128 pixels in wid or hei it is downscaled to max 128 pixels wid/hei. ********** VERSION 2.2.0 ************ New stable release! Fixed some minor usability problems. Added writing of next alarm to a file for usage on pdaXrom. ************************************* You can find the complete changelog from version 1.7.7 to 2.2.0 in the source package or on http://www.pi-sync.net/html/changelog.html diff --git a/gammu/emb/common/phone/alcatel/alcatel.c b/gammu/emb/common/phone/alcatel/alcatel.c index b75077f..718d91e 100644 --- a/gammu/emb/common/phone/alcatel/alcatel.c +++ b/gammu/emb/common/phone/alcatel/alcatel.c @@ -1,4009 +1,4009 @@ /* (c) 2002-2004 by Michal Cihar */ /* * High level functions for communication with Alcatel One Touch 501 and * compatible mobile phone. * * This code implements functions to communicate with Alcatel phones, * currently seem to work: * - BE5 series (501/701) * - BF5 series (715) * - BH4 series (535/735) * For some functions it uses normal AT mode (not implemented here, look at * ../at/atgen.[ch]) for others it switches into binary mode and initialises * underlaying protocol (see ../../protocol/alcatel/alcabus.[ch]) and * communicates over it. Don't ask me why Alcatel uses such silly thing... * * Notes for future features: * - max phone number length is 61 (BE5) * - max name length is 50 (BE5) */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ALCATEL #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../misc/misc.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "alcatel.h" /* Timeout for GSM_WaitFor calls. */ #define ALCATEL_TIMEOUT 64 /* Some magic numbers for protocol follow */ /* synchronisation types (for everything except begin transfer): */ #define ALCATEL_SYNC_TYPE_CALENDAR 0x64 #define ALCATEL_SYNC_TYPE_TODO 0x68 #define ALCATEL_SYNC_TYPE_CONTACTS 0x6C /* synchronisation types (for begin transfer): */ #define ALCATEL_BEGIN_SYNC_CALENDAR 0x00 #define ALCATEL_BEGIN_SYNC_TODO 0x02 #define ALCATEL_BEGIN_SYNC_CONTACTS 0x01 /* category types */ #define ALCATEL_LIST_TODO_CAT 0x9B #define ALCATEL_LIST_CONTACTS_CAT 0x96 /* We need lot of ATGEN functions, because Alcatel is an AT device. */ -extern GSM_Reply_Function ALCATELReplyFunctions[]; +static GSM_Reply_Function ALCATELReplyFunctions[]; extern GSM_Reply_Function ATGENReplyFunctions[]; extern GSM_Error ATGEN_Initialise (GSM_StateMachine *s); extern GSM_Error ATGEN_Terminate (GSM_StateMachine *s); extern GSM_Error ATGEN_GetIMEI (GSM_StateMachine *s); extern GSM_Error ATGEN_GetFirmware (GSM_StateMachine *s); extern GSM_Error ATGEN_GetModel (GSM_StateMachine *s); extern GSM_Error ATGEN_GetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time); extern GSM_Error ATGEN_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry); extern GSM_Error ATGEN_GetNextMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start); extern GSM_Error ATGEN_SetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry); extern GSM_Error ATGEN_AddMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry); extern GSM_Error ATGEN_DeleteMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry); extern GSM_Error ATGEN_GetMemoryStatus (GSM_StateMachine *s, GSM_MemoryStatus *Status); extern GSM_Error ATGEN_GetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc); extern GSM_Error ATGEN_SetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc); extern GSM_Error ATGEN_GetSMSFolders (GSM_StateMachine *s, GSM_SMSFolders *folders); extern GSM_Error ATGEN_GetSMSStatus (GSM_StateMachine *s, GSM_SMSMemoryStatus *status); extern GSM_Error ATGEN_GetSMS (GSM_StateMachine *s, GSM_MultiSMSMessage *sms); extern GSM_Error ATGEN_GetNextSMS (GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start); extern GSM_Error ATGEN_SendSavedSMS (GSM_StateMachine *s, int Folder, int Location); extern GSM_Error ATGEN_SendSMS (GSM_StateMachine *s, GSM_SMSMessage *sms); extern GSM_Error ATGEN_DeleteSMS (GSM_StateMachine *s, GSM_SMSMessage *sms); extern GSM_Error ATGEN_AddSMS (GSM_StateMachine *s, GSM_SMSMessage *sms); extern GSM_Error ATGEN_GetBatteryCharge (GSM_StateMachine *s, GSM_BatteryCharge *bat); extern GSM_Error ATGEN_GetSignalQuality (GSM_StateMachine *s, GSM_SignalQuality *sig); extern GSM_Error ATGEN_DialVoice (GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber); extern GSM_Error ATGEN_AnswerCall (GSM_StateMachine *s, int ID, bool all); extern GSM_Error ATGEN_CancelCall (GSM_StateMachine *s, int ID, bool all); extern GSM_Error ATGEN_SetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time); extern GSM_Error ATGEN_EnterSecurityCode (GSM_StateMachine *s, GSM_SecurityCode Code); extern GSM_Error ATGEN_GetSecurityStatus (GSM_StateMachine *s, GSM_SecurityCodeType *Status); extern GSM_Error ATGEN_ResetPhoneSettings (GSM_StateMachine *s, GSM_ResetSettingsType Type); extern GSM_Error ATGEN_SendDTMF (GSM_StateMachine *s, char *sequence); extern GSM_Error ATGEN_GetSIMIMSI (GSM_StateMachine *s, char *IMSI); extern GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *s); extern GSM_Error ATGEN_GetNetworkInfo (GSM_StateMachine *s, GSM_NetworkInfo *netinfo); extern GSM_Error ATGEN_Reset (GSM_StateMachine *s, bool hard); extern GSM_Error ATGEN_PressKey (GSM_StateMachine *s, GSM_KeyCode Key, bool Press); extern GSM_Error ATGEN_GetDisplayStatus (GSM_StateMachine *s, GSM_DisplayFeatures *features); extern GSM_Error ATGEN_SetAutoNetworkLogin (GSM_StateMachine *s); extern GSM_Error ATGEN_DeleteAllMemory (GSM_StateMachine *s, GSM_MemoryType type); extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s); extern GSM_Error ATGEN_SetFastSMSSending (GSM_StateMachine *s, bool enable); extern GSM_Error ATGEN_SetIncomingCB (GSM_StateMachine *s, bool enable); extern GSM_Error ATGEN_SetIncomingSMS (GSM_StateMachine *s, bool enable); /** * Alcatel uses some 8-bit characters in contacts, calendar etc.. This table * attempts to decode it, it is probably not complete, here are just chars * that I found... */ unsigned char GSM_AlcatelAlphabet[] = { /* in phone unicode description */ 0x80, 0x00,0x20, /* empty */ 0x81, 0x00,0x20, /* empty */ 0x82, 0x00,0x20, /* empty */ 0x83, 0x00,0x20, /* empty */ 0x84, 0x00,0xe7, /* c cedilla */ 0x85, 0x20,0x26, /* ... */ 0x86, 0x03,0xc0, /* pi */ 0x87, 0x01,0x3e, /* l caron */ 0x88, 0x00,0xc0, /* A grave */ 0x89, 0x00,0xc1, /* A acute */ 0x8a, 0x00,0xc2, /* A circumflex */ 0x8b, 0x00,0xc3, /* A tilde */ 0x8c, 0x00,0xc8, /* E grave */ 0x8d, 0x00,0xca, /* E circumflex */ 0x8e, 0x00,0xcb, /* E diaresis */ 0x8f, 0x00,0xcc, /* I grave */ 0x90, 0x00,0xcd, /* I acute */ 0x91, 0x00,0xd0, /* ETH */ 0x92, 0x00,0xd2, /* O grave */ 0x93, 0x00,0xd3, /* O acute */ 0x94, 0x00,0xd4, /* O circumflex */ 0x95, 0x00,0xd5, /* O tilde */ 0x96, 0x00,0xd9, /* U grave */ 0x97, 0x00,0xda, /* U acute */ 0x98, 0x00,0xe1, /* a acute */ 0x99, 0x00,0xe2, /* a circumflex */ 0x9a, 0x00,0xe3, /* a tilde */ 0x9b, 0x00,0xea, /* e circumflex */ 0x9c, 0x00,0xeb, /* e diaresis */ 0x9d, 0x00,0xed, /* i acute */ 0x9e, 0x00,0xee, /* i circumflex */ 0x9f, 0x00,0xef, /* i diaresis */ 0xa0, 0x00,0xf3, /* o acute */ 0xa1, 0x00,0xf4, /* o circumflex */ 0xa2, 0x00,0xf5, /* o tilde */ 0xa3, 0x00,0xfa, /* u acute */ 0xa4, 0x00,0xa2, /* cent */ 0xa5, 0x00,0x5b, /* [ */ 0xa6, 0x01,0x59, /* r caron */ 0xa7, 0x01,0x0d, /* c caron */ 0xa8, 0x01,0x61, /* s caron */ 0xa9, 0x01,0x1b, /* e caron */ 0xaa, 0x01,0x6f, /* u ring */ 0xab, 0x00,0xfd, /* y acute */ 0xac, 0x00,0xf0, /* eth */ 0xad, 0x01,0x07, /* c acute */ 0xae, 0x01,0x19, /* e ogonek */ 0xaf, 0x01,0x05, /* a ogonek */ 0xb0, 0x01,0x7c, /* z dot */ 0xb1, 0x01,0x7a, /* z acute */ 0xb2, 0x01,0x5b, /* s acute */ 0xb3, 0x01,0x44, /* n acute */ 0xb4, 0x01,0x42, /* l stroke */ 0xb5, 0x00,0x20, /* empty */ 0xb6, 0x01,0x48, /* n caron */ 0xb7, 0x01,0x65, /* t caron */ 0xb8, 0x00,0x20, /* empty */ 0xb9, 0x01,0x7e, /* z caron */ 0xba, 0x01,0xe7, /* g caron */ 0xbb, 0x00,0x20, /* empty */ 0xbc, 0x00,0x20, /* empty */ 0xbd, 0x1e,0x20, /* G macron */ 0xbe, 0x1e,0x21, /* g macron */ 0xbf, 0x01,0x5e, /* S cedilla */ 0xc0, 0x01,0x5f, /* s cedilla */ 0xc1, 0x01,0x2f, /* i ogonek */ /* FIXME: not sure with this, it look like normal i */ 0xc2, 0x01,0x31, /* i dotless */ 0xc3, 0x01,0x68, /* U tilde */ 0xc4, 0x01,0x50, /* O dbl acute */ 0xc5, 0x01,0x69, /* u tilde */ 0xc6, 0x01,0x51, /* o dbl acute */ 0xc7, 0x27,0xa9, /* => */ 0xc8, 0x27,0xa8, /* filled => */ 0xc9, 0x00,0xd7, /* x */ 0xca, 0x00,0x5d, /* ] */ 0xcb, 0x26,0x0f, /* phone */ 0xcc, 0x01,0x0f, /* d caron */ 0xcd, 0x00,0x20, /* empty */ 0xce, 0x00,0x7e, /* ~ */ 0xcf, 0x00,0x5c, /* \ */ 0xd0, 0x00,0x5e, /* ^ */ 0xd1, 0x00,0x20, /* empty */ 0xd2, 0x00,0x7b, /* { */ 0xd3, 0x00,0x7c, /* | */ 0xd4, 0x00,0x7d, /* } */ 0xd5, 0x00,0x20, /* empty */ 0xd6, 0x01,0x63, /* t cedilla */ 0xd7, 0x00,0x20, /* empty */ 0xd8, 0x00,0x20, /* empty */ 0xd9, 0x00,0x20, /* empty */ 0xda, 0x00,0x20, /* empty */ 0xdb, 0x00,0x20, /* empty */ 0xdc, 0x00,0x20, /* empty */ 0xdd, 0x00,0x20, /* empty */ 0xde, 0x00,0x20, /* empty */ 0xdf, 0x00,0x20, /* empty */ 0xe0, 0x00,0x20, /* empty */ 0xe1, 0x00,0x20, /* two candles */ /* FIXME */ 0xe2, 0x00,0x20, /* empty */ 0xe3, 0x00,0x20, /* empty */ 0xe4, 0x00,0x20, /* empty */ 0xe5, 0x01,0xce, /* a caron */ 0xe6, 0x01,0x01, /* a macron */ 0xe7, 0x01,0x13, /* e macron */ 0xe8, 0x01,0x2b, /* i macron */ 0xe9, 0x01,0x4d, /* o macron */ 0xea, 0x01,0x6b, /* u macron */ 0xeb, 0x00,0x41, /* A */ 0xec, 0x00,0x40, /* @ */ 0xed, 0x00,0x20, /* some strange char :-) */ /* FIXME */ 0xee, 0x00,0x20, /* big key stroken */ /* FIXME */ 0xef, 0x00,0x20, /* big key */ /* FIXME */ 0xf0, 0x00,0x20, /* empty */ 0xf1, 0x00,0x31, /* 1 */ 0xf2, 0x00,0x21, /* bold ! */ 0xf3, 0x26,0x0e, /* black phone */ 0xf4, 0x00,0x26, /* & */ 0xf5, 0x23,0x7e, /* bell */ 0xf6, 0x26,0x6a, /* note */ 0xf7, 0x27,0x13, /* okay inv */ /* FIXME */ 0xf8, 0x27,0x13, /* okay */ 0xf9, 0x00,0x20, /* empty */ 0xfa, 0x00,0x20, /* key */ /* FIXME */ 0xfb, 0x00,0x20, /* empty */ 0xfc, 0x20,0xac, /* Euro */ 0xfd, 0x21,0x97, /* NE arrow */ 0xfe, 0x21,0x98, /* SE arrow */ 0xff, 0x00,0x20, /* empty */ 0x00, 0x00,0x00 }; /* This is being called from atgen */ GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s) { char *str, *str2; /* * Reply received here looks like: * 1 "AT+CPROT=?" * 2 "+CPROT: 0,"V1.0",1" * 3 "+CPROT: 16,"V1.1",16" * 4 "OK" */ switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: str = strstr(msg.Buffer, "\"V"); if (str == NULL) return ERR_UNKNOWNRESPONSE; str += 2; while((str2 = strstr(str, "\"V")) != NULL) str = str2 + 2; if (strncmp(str, "1.0", 3) == 0) { s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_0; } else if (strncmp(str, "1.1", 3) == 0) { s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_1; } else { smprintf(s, "Unknown protocol version. Please send debug log and phone info to author.\n"); return ERR_NOTIMPLEMENTED; } return ERR_NONE; case AT_Reply_Error: case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: return ERR_UNKNOWNRESPONSE; } } static GSM_Error ALCATEL_SetBinaryMode(GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; if (Priv->Mode == ModeBinary) return ERR_NONE; dbgprintf ("Changing to binary mode\n"); error=GSM_WaitFor (s, "AT+IFC=2,2\r", 11, 0x02, 4, ID_SetFlowControl); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, "AT+CPROT=?\r", 11, 0x02, 4, ID_AlcatelProtocol); if (error != ERR_NONE) return error; if (Priv->ProtocolVersion == V_1_0) { error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.0\",16\r", 22, 0x00, 4, ID_AlcatelConnect); } else { error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.1\",16\r", 22, 0x00, 4, ID_AlcatelConnect); } if (error == ERR_TIMEOUT && s->Speed != 19200) { smprintf(s, "HINT: Try changing speed to 19200, it is sometimes needed for Alcatel binary mode.\n"); } if (error != ERR_NONE) return error; dbgprintf ("Changing protocol to Alcabus\n"); s->Protocol.Functions = &ALCABUSProtocol; error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) { s->Protocol.Functions = &ATProtocol; return error; } s->Phone.Functions->ReplyFunctions = ALCATELReplyFunctions; Priv->Mode = ModeBinary; Priv->BinaryItem = 0; Priv->BinaryType = 0; Priv->BinaryState = StateAttached; return ERR_NONE; } static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_BinaryState state, GSM_Alcatel_BinaryType type, int item) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char attach_buffer[] = {0x00, 0x00, 0x7C ,0x20}; unsigned char detach_buffer[] = {0x00, 0x01, 0x7C ,0x00}; unsigned char start_buffer[] = {0x00, 0x04, 0x7C, 0x80, /* 4 byte database id follows */ 0x12, 0x34, 0x56, 0x78}; unsigned char end_buffer[] = {0x00, 0x04, 0x7C, 0x82, 0x00, /* type */ 0x00, 0x00, 0x00, 0x00}; /* TimeStamp */ unsigned char close_buffer[] = {0x00, 0x04, 0x00, /*type */ 0x23, 0x01}; unsigned char select1_buffer[] = {0x00, 0x00, 0x00, /*type */ 0x20}; unsigned char select2_buffer[] = {0x00, 0x04, 0x00, /*type */ 0x22, 0x01, 0x00}; unsigned char begin_buffer[] = {0x00, 0x04, 0x7C, 0x81, 0x00, /*type */ 0x00, 0x85, 0x00}; unsigned char commit_buffer[] = {0x00, 0x04, 0x00, /*type */ 0x20, 0x01}; smprintf(s, "Alcatel state switcher: %d -> %d, %d -> %d, %d -> %d\n", Priv->BinaryState, state, Priv->BinaryType, type, Priv->BinaryItem, item); error = ALCATEL_SetBinaryMode(s); if (error != ERR_NONE) return error; /* Do we need to do anything? */ if ((state == Priv->BinaryState) && (type == Priv->BinaryType) && (item == Priv->BinaryItem)) return ERR_NONE; /* We're editing, but the next state is not the same. so commit editing */ if (Priv->BinaryState == StateEdit) { /* Something has changed, we will have to reread fields! */ Priv->CurrentFieldsItem = -1; switch (Priv->BinaryType) { case TypeCalendar: commit_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: commit_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: commit_buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } dbgprintf ("Commiting edited record\n"); error=GSM_WaitFor (s, commit_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelCommit); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelCommit2); if (error != ERR_NONE) return error; Priv->BinaryState = StateSession; Priv->BinaryItem = 0; } /* Do we want to edit something of same type? */ if ((state == StateEdit) && (type == Priv->BinaryType)) { /* Edit state doesn't need any switching, it is needed only for * indication that e have to commit record before we switch to other * mode. */ Priv->BinaryState = StateEdit; Priv->BinaryItem = item; return ERR_NONE; } /* Now we can be only in Attached or Session state, so if states and types matches, just keep them as they are */ if ((state == Priv->BinaryState) && (type == Priv->BinaryType)) { return ERR_NONE; } /* Do we need to close session? */ if (Priv->BinaryState == StateSession) { dbgprintf ("Ending session\n"); switch (Priv->BinaryType) { case TypeCalendar: end_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR; break; case TypeContacts: end_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS; break; case TypeToDo: end_buffer[4] = ALCATEL_BEGIN_SYNC_TODO; break; } error=GSM_WaitFor (s, end_buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelEnd); if (error != ERR_NONE) return error; switch (Priv->BinaryType) { case TypeCalendar: close_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: close_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: close_buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } dbgprintf ("Closing session\n"); error=GSM_WaitFor (s, close_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelClose); if (error != ERR_NONE) return error; dbgprintf ("Detaching binary mode\n"); GSM_WaitFor (s, detach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDetach); Priv->BinaryState = StateAttached; Priv->BinaryType = 0; } /* Do we need to open session? */ if (state == StateSession || state == StateEdit) { dbgprintf ("Starting session for %s\n", (type == TypeCalendar ? "Calendar" : (type == TypeToDo ? "Todo" : (type == TypeContacts ? "Contacts" : "Unknown!")))); /* Fill up buffers */ switch (type) { case TypeCalendar: select1_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; select2_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; begin_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR; break; case TypeContacts: select1_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; select2_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; begin_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS; break; case TypeToDo: select1_buffer[2] = ALCATEL_SYNC_TYPE_TODO; select2_buffer[2] = ALCATEL_SYNC_TYPE_TODO; begin_buffer[4] = ALCATEL_BEGIN_SYNC_TODO; break; } dbgprintf ("Attaching in binary mode\n"); /* Communicate */ error=GSM_WaitFor (s, attach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelAttach); if (error != ERR_NONE) return error; smprintf(s,"Start session\n"); error=GSM_WaitFor (s, start_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelStart); if (error != ERR_NONE) return error; smprintf(s,"Select type\n"); error=GSM_WaitFor (s, select1_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, select2_buffer, 6, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect2); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelSelect3); if (error != ERR_NONE) return error; smprintf(s,"Begin transfer\n"); error=GSM_WaitFor (s, begin_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelBegin1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelBegin2); if (error != ERR_NONE) return error; Priv->BinaryState = StateSession; Priv->BinaryType = type; /* Do we want to edit something of same type? */ if ((state == StateEdit) && (type == Priv->BinaryType)) { Priv->BinaryState = StateEdit; Priv->BinaryItem = item; return ERR_NONE; } } return ERR_NONE; } static GSM_Error ALCATEL_SetATMode(GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; if (Priv->Mode == ModeAT) return ERR_NONE; error = ALCATEL_GoToBinaryState(s, StateAttached, 0, 0); if (error != ERR_NONE) return error; error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; dbgprintf ("Changing protocol to AT\n"); s->Protocol.Functions = &ATProtocol; s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions; Priv->Mode = ModeAT; s->Phone.Data.Priv.ATGEN.PBKCharset = 0; s->Phone.Data.Priv.ATGEN.PBKMemory = 0; my_sleep(100); /* In case we don't send AT command short after closing binary mode, * phone takes VERY long to react next time. The error code in * intetionally ignored. */ GSM_WaitFor (s, "AT\r", 3, 0x00, 0, ID_IncomingFrame); return ERR_NONE; } static GSM_Error ALCATEL_Initialise(GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; Priv->Mode = ModeAT; Priv->CalendarItems = NULL; Priv->ContactsItems = NULL; Priv->ToDoItems = NULL; Priv->CalendarItemsCount = 0; Priv->ToDoItemsCount = 0; Priv->ContactsItemsCount = 0; Priv->CurrentFields[0] = 0; Priv->CurrentFieldsCount = 0; Priv->CurrentFieldsItem = 0; Priv->CurrentFieldsType = 0; Priv->ProtocolVersion = V_1_0; Priv->CurrentFieldsItem = -1; Priv->CurrentCategoriesCount = 0; Priv->CurrentCategoriesType = 0; s->Protocol.Functions = &ATProtocol; s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions; if (ATGEN_Initialise(s) != ERR_NONE || GSM_WaitFor (s, "AT\r", 3, 0x00, 2, ID_IncomingFrame) != ERR_NONE) { smprintf(s,"AT initialisation failed, trying to stop binary mode...\n"); s->Protocol.Functions = &ALCABUSProtocol; error = s->Protocol.Functions->Terminate(s); s->Protocol.Functions = &ATProtocol; error = ATGEN_Initialise(s); if (error != ERR_NONE) return error; } return ERR_NONE; } static GSM_Error ALCATEL_Terminate(GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; free(Priv->CalendarItems); free(Priv->ContactsItems); free(Priv->ToDoItems); error = ALCATEL_SetATMode(s); return ATGEN_Terminate(s); } /* finds whether id is set in the phone */ static GSM_Error ALCATEL_IsIdAvailable(GSM_StateMachine *s, int id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if (id > ALCATEL_MAX_LOCATION) return ERR_INVALIDLOCATION; switch (Priv->BinaryType) { case TypeCalendar: Priv->CurrentList = &(Priv->CalendarItems); Priv->CurrentCount = &(Priv->CalendarItemsCount); break; case TypeContacts: Priv->CurrentList = &(Priv->ContactsItems); Priv->CurrentCount = &(Priv->ContactsItemsCount); break; case TypeToDo: Priv->CurrentList = &(Priv->ToDoItems); Priv->CurrentCount = &(Priv->ToDoItemsCount); break; } for (i=0; i<*Priv->CurrentCount; i++) { if ((*Priv->CurrentList)[i] == id) return ERR_NONE; } return ERR_EMPTY; } /* finds next id that is available in the phone */ static GSM_Error ALCATEL_GetNextId(GSM_StateMachine *s, int *id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i = 0; int next = ALCATEL_MAX_LOCATION; switch (Priv->BinaryType) { case TypeCalendar: Priv->CurrentList = &(Priv->CalendarItems); Priv->CurrentCount = &(Priv->CalendarItemsCount); break; case TypeContacts: Priv->CurrentList = &(Priv->ContactsItems); Priv->CurrentCount = &(Priv->ContactsItemsCount); break; case TypeToDo: Priv->CurrentList = &(Priv->ToDoItems); Priv->CurrentCount = &(Priv->ToDoItemsCount); break; } for (i=0; i<*Priv->CurrentCount; i++) { if (((*Priv->CurrentList)[i] > *id) && ((*Priv->CurrentList)[i] < next )) { next = (*Priv->CurrentList)[i]; } } if (next == ALCATEL_MAX_LOCATION) { return ERR_EMPTY; } else { *id = next; return ERR_NONE; } } static GSM_Error ALCATEL_ReplyGetIds(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int count,i,pos; count = msg.Buffer[10]; *Priv->CurrentCount += count; *Priv->CurrentList = (int *)realloc(*Priv->CurrentList, (*Priv->CurrentCount + 1)* sizeof(int)); if (*Priv->CurrentList == NULL) return ERR_MOREMEMORY; for (i = 0; i < count; i++) { pos = 11 + (4 * i); (*Priv->CurrentList)[*Priv->CurrentCount - count + i] = msg.Buffer[pos + 3] + (msg.Buffer[pos + 2] << 8) + (msg.Buffer[pos + 1] << 16) + (msg.Buffer[pos] << 24); } (*Priv->CurrentList)[*Priv->CurrentCount] = 0; /* If last byte is 0, then we transmitted all items */ Priv->TransferCompleted = msg.Buffer[4 + msg.Buffer[4]] == 0; return ERR_NONE; } static GSM_Error ALCATEL_GetAvailableIds(GSM_StateMachine *s, bool refresh) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; int i; unsigned char buffer[] = {0x00, 0x04, 0x00, /*type */ 0x2F, 0x01}; if (Priv->BinaryState != StateSession) return ERR_UNKNOWN; switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; Priv->CurrentList = &(Priv->CalendarItems); Priv->CurrentCount = &(Priv->CalendarItemsCount); break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; Priv->CurrentList = &(Priv->ContactsItems); Priv->CurrentCount = &(Priv->ContactsItemsCount); break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; Priv->CurrentList = &(Priv->ToDoItems); Priv->CurrentCount = &(Priv->ToDoItemsCount); break; } if (*Priv->CurrentList != NULL) { if (!refresh) return ERR_NONE; free(*Priv->CurrentList); *Priv->CurrentList = NULL; } smprintf(s,"Reading items list\n"); *Priv->CurrentCount = 0; Priv->TransferCompleted = false; error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetIds1); if (error != ERR_NONE) return error; while (!Priv->TransferCompleted) { error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetIds2); if (error != ERR_NONE) return error; } i = 0; smprintf(s,"Received %d ids: ", *Priv->CurrentCount); for (i=0; i < *Priv->CurrentCount; i++) { smprintf(s,"%x ", (*Priv->CurrentList)[i]); } smprintf(s,"\n"); return ERR_NONE; } static GSM_Error ALCATEL_ReplyGetFields(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if (msg.Buffer[14] > GSM_PHONEBOOK_ENTRIES) { smprintf(s, "WARNING: Field list truncated, you should increase GSM_PHONEBOOK_ENTRIES to at least %d\n", msg.Buffer[14]); Priv->CurrentFieldsCount = GSM_PHONEBOOK_ENTRIES; } else { Priv->CurrentFieldsCount = msg.Buffer[14]; } Priv->CurrentFields[Priv->CurrentFieldsCount] = 0; for (i = 0; i < Priv->CurrentFieldsCount; i++) { Priv->CurrentFields[i] = msg.Buffer[15 + i]; } return ERR_NONE; } static GSM_Error ALCATEL_GetFields(GSM_StateMachine *s, int id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; int i; unsigned char buffer[] = {0x00, 0x04, 0x00, /* type */ 0x30, 0x01, 0x00, 0x00, 0x00, 0x00}; /* item */ if (Priv->BinaryState != StateSession) return ERR_UNKNOWN; if ((Priv->CurrentFieldsItem == id) && (Priv->CurrentFieldsType == Priv->BinaryType)) return ERR_NONE; smprintf(s,"Reading item fields (%d)\n", id); buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } Priv->CurrentFieldsItem = id; Priv->CurrentFieldsType = Priv->BinaryType; error=GSM_WaitFor (s, buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFields1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFields2); if (error != ERR_NONE) return error; i = 0; smprintf(s,"Received %d fields: ", Priv->CurrentFieldsCount); for (i=0; i < Priv->CurrentFieldsCount; i++) { smprintf(s,"%x ", Priv->CurrentFields[i]); } smprintf(s,"\n"); return ERR_NONE; } static GSM_Error ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; unsigned char *buffer = &(msg.Buffer[16]); if (buffer[1] == 0x05 && buffer[2] == 0x67) { /* date */ Priv->ReturnType = Alcatel_date; Priv->ReturnDateTime.Day = buffer[4]; Priv->ReturnDateTime.Month = buffer[5]; Priv->ReturnDateTime.Year = buffer[7] + (buffer[6] << 8); Priv->ReturnDateTime.Timezone = 0; /* FIXME: how to acquire this? */ Priv->ReturnDateTime.Hour = 0; Priv->ReturnDateTime.Minute = 0; Priv->ReturnDateTime.Second = 0; } else if (buffer[1] == 0x06 && buffer[2] == 0x68) { /* time */ Priv->ReturnType = Alcatel_time; Priv->ReturnDateTime.Hour = buffer[4]; Priv->ReturnDateTime.Minute = buffer[5]; Priv->ReturnDateTime.Second = buffer[6]; Priv->ReturnDateTime.Day = 0; Priv->ReturnDateTime.Month = 0; Priv->ReturnDateTime.Year = 0; Priv->ReturnDateTime.Timezone = 0; } else if (buffer[1] == 0x08 && buffer[2] == 0x3C) { /* string */ Priv->ReturnType = Alcatel_string; if (GSM_PHONEBOOK_TEXT_LENGTH < buffer[3]) smprintf(s, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer[3] + 1); if (Priv->ProtocolVersion == V_1_0) { DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet); } else if(Priv->ProtocolVersion == V_1_1 && (buffer[4] & 0x80)) { memcpy(Priv->ReturnString, buffer + 5, buffer[3]); Priv->ReturnString[buffer[3] + 1] = 0; Priv->ReturnString[buffer[3] + 2] = 0; ReverseUnicodeString(Priv->ReturnString); } else { DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet); } } else if (buffer[1] == 0x07 && buffer[2] == 0x3C) { /* phone */ Priv->ReturnType = Alcatel_phone; if (GSM_PHONEBOOK_TEXT_LENGTH < buffer[3]) smprintf(s, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer[3] + 1); if (Priv->ProtocolVersion == V_1_0) { DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet); } else if(Priv->ProtocolVersion == V_1_1 && (buffer[4] & 0x80)) { memcpy(Priv->ReturnString, buffer + 5, buffer[3]); Priv->ReturnString[buffer[3] + 1] = 0; Priv->ReturnString[buffer[3] + 2] = 0; ReverseUnicodeString(Priv->ReturnString); } else { DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet); } } else if (buffer[1] == 0x03 && buffer[2] == 0x3B) { /* boolean */ Priv->ReturnType = Alcatel_bool; Priv->ReturnInt = buffer[3]; } else if (buffer[1] == 0x02 && buffer[2] == 0x3A) { /* integer */ Priv->ReturnType = Alcatel_int; Priv->ReturnInt = buffer[6] + (buffer[5] << 8) + (buffer[4] << 16) + (buffer[3] << 24); } else if (buffer[1] == 0x04 && buffer[2] == 0x38) { /* enumeration */ Priv->ReturnType = Alcatel_enum; Priv->ReturnInt = buffer[3]; } else if (buffer[1] == 0x00 && buffer[2] == 0x38) { /* byte */ Priv->ReturnType = Alcatel_byte; Priv->ReturnInt = buffer[3]; } else { smprintf(s, "WARNING: Uknown data type received (%02X,%02X)\n", buffer[1], buffer[2]); return ERR_UNKNOWNRESPONSE; } return ERR_NONE; } static GSM_Error ALCATEL_GetFieldValue(GSM_StateMachine *s, int id, int field) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[] = {0x00, 0x04, 0x00, /* type */ 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */ 0x00}; /* field */ smprintf(s,"Reading item value (%08x.%02x)\n", id, field); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); buffer[9] = (field & 0xff); error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue2); if (error != ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_ReplyGetCategories(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; /* Did we get any category? */ if (msg.Buffer[4] == 6) { Priv->CurrentCategoriesCount = 0; return ERR_NONE; } if (msg.Buffer[12] > ALCATEL_MAX_CATEGORIES) { smprintf(s, "WARNING: Field list truncated, you should increase ALCATEL_MAX_CATEGORIES to at least %d\n", msg.Buffer[12]); Priv->CurrentCategoriesCount = ALCATEL_MAX_CATEGORIES; } else { Priv->CurrentCategoriesCount = msg.Buffer[12]; } for (i = 0; i < Priv->CurrentCategoriesCount; i++) { Priv->CurrentCategories[i] = msg.Buffer[13 + i]; Priv->CurrentCategoriesCache[i][0] = '\000'; Priv->CurrentCategoriesCache[i][1] = '\000'; } return ERR_NONE; } static GSM_Error ALCATEL_GetAvailableCategoryIds(GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; int i; unsigned char buffer[] = {0x00, 0x04, 0x00 /*type */, 0x0b, 0x00 /* list */}; if (Priv->BinaryState != StateSession) return ERR_UNKNOWN; if (Priv->CurrentCategoriesType == Priv->BinaryType) return ERR_NONE; switch (Priv->BinaryType) { case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; buffer[4] = ALCATEL_LIST_CONTACTS_CAT; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; buffer[4] = ALCATEL_LIST_TODO_CAT; break; default: return ERR_NOTSUPPORTED; } Priv->CurrentCategoriesType = Priv->BinaryType; smprintf(s,"Reading category list\n"); error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategories1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategories2); if (error != ERR_NONE) return error; i = 0; smprintf(s,"Received %d ids: ", Priv->CurrentCategoriesCount); for (i=0; i < Priv->CurrentCategoriesCount; i++) { smprintf(s,"%i ", Priv->CurrentCategories[i]); } smprintf(s,"\n"); return ERR_NONE; } static GSM_Error ALCATEL_IsCategoryIdAvailable(GSM_StateMachine *s, int id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i = 0; if (Priv->CurrentCategoriesType != Priv->BinaryType) return ERR_UNKNOWN; for (i = 0; i< Priv->CurrentCategoriesCount; i++) { if (Priv->CurrentCategories[i] == id) return ERR_NONE; } return ERR_EMPTY; } static GSM_Error ALCATEL_ReplyAddCategoryText(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; Priv->ReturnInt = msg.Buffer[12]; return ERR_NONE; } static GSM_Error ALCATEL_AddCategoryText(GSM_StateMachine *s, const unsigned char *str) { unsigned char buffer[200] = {0x00, 0x04, 0x00 /*type*/, 0x0d, 0x00 /*list*/, 0x0b }; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; int len; smprintf(s,"Creating category\n"); len = UnicodeLength(str); EncodeDefault(buffer + 8, str, &len, true, GSM_AlcatelAlphabet); buffer[6] = len + 1; buffer[7] = len; switch (Priv->BinaryType) { case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; buffer[4] = ALCATEL_LIST_CONTACTS_CAT; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; buffer[4] = ALCATEL_LIST_TODO_CAT; break; default: return ERR_NOTSUPPORTED; } error=GSM_WaitFor (s, buffer, 8 + len, 0x02, ALCATEL_TIMEOUT, ID_AlcatelAddCategoryText1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelAddCategoryText2); if (error != ERR_NONE) return error; /* Refresh list */ Priv->CurrentCategoriesType = 0; return ALCATEL_GetAvailableCategoryIds(s); } static GSM_Error ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int len; len = msg.Buffer[14]; if (len > GSM_MAX_CATEGORY_NAME_LENGTH) { smprintf(s, "WARNING: Category name truncated, you should increase GSM_MAX_CATEGORY_NAME_LENGTH to at least %d\n", len); } if (Priv->ProtocolVersion == V_1_0) { DecodeDefault( Priv->ReturnString, msg.Buffer + 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH, len), false, GSM_AlcatelAlphabet); } else if(Priv->ProtocolVersion == V_1_1 && (msg.Buffer[15] & 0x80)) { memcpy(Priv->ReturnString, msg.Buffer + 16, len); Priv->ReturnString[len + 1] = 0; Priv->ReturnString[len + 2] = 0; ReverseUnicodeString(Priv->ReturnString); } else { DecodeDefault( Priv->ReturnString, msg.Buffer + 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH, len), false, GSM_AlcatelAlphabet); } return ERR_NONE; } static GSM_Error ALCATEL_GetCategoryText(GSM_StateMachine *s, int id) { unsigned char buffer[] = {0x00, 0x04, 0x00 /*type*/, 0x0c, 0x00 /*list*/, 0x0A, 0x01, 0x00 /*item*/ }; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; if (Priv->CurrentCategoriesCache[id][0] != '\000' || Priv->CurrentCategoriesCache[id][1] != '\000') { CopyUnicodeString(Priv->ReturnString, Priv->CurrentCategoriesCache[id]); return ERR_NONE; } smprintf(s,"Reading category %d\n", id); switch (Priv->BinaryType) { case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; buffer[4] = ALCATEL_LIST_CONTACTS_CAT; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; buffer[4] = ALCATEL_LIST_TODO_CAT; break; default: return ERR_NOTSUPPORTED; } buffer[7] = (id & 0xff); error=GSM_WaitFor (s, buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText2); if (error != ERR_NONE) return error; CopyUnicodeString(Priv->CurrentCategoriesCache[id], Priv->ReturnString); return ERR_NONE; } static GSM_Error ALCATEL_DeleteField(GSM_StateMachine *s, int id, int field) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[] = {0x00, 0x04, 0x00, /* type */ 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */ 0x65, 0x01, 0x00, /* field */ 0x01}; smprintf(s,"Deleting field (%08x.%02x)\n", id, field); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); buffer[11] = (field & 0xff); error=GSM_WaitFor (s, buffer, 13, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteField); if (error != ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_DeleteItem(GSM_StateMachine *s, int id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[] = {0x00, 0x04, 0x00, /* type */ 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */ 0x42}; smprintf(s,"Deleting item (%08x)\n", id); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x0, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem2); if (error != ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_ReplyDeleteItem(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[8] != 0x25) return ERR_UNKNOWNRESPONSE; return ERR_NONE; } static GSM_Error ALCATEL_BuildWriteBuffer(unsigned char * buffer, GSM_Alcatel_FieldType type, int field, void *data) { int len; buffer[1] = field & 0xff; switch(type) { case Alcatel_date: if (!CheckDate((GSM_DateTime *)data)) return ERR_INVALIDDATETIME; buffer[3] = 0x05; buffer[4] = 0x67; buffer[0] = 0x09; buffer[5] = 0x04; buffer[6] = ((GSM_DateTime *)data)->Day & 0xff; buffer[7] = ((GSM_DateTime *)data)->Month & 0xff; buffer[8] = ((GSM_DateTime *)data)->Year >> 8; buffer[9] = ((GSM_DateTime *)data)->Year & 0xff; buffer[10] = 0x00; break; case Alcatel_time: if (!CheckTime((GSM_DateTime *)data)) return ERR_INVALIDDATETIME; buffer[3] = 0x06; buffer[4] = 0x68; buffer[0] = 0x08; buffer[5] = 0x03; buffer[6] = ((GSM_DateTime *)data)->Hour & 0xff; buffer[7] = ((GSM_DateTime *)data)->Minute & 0xff; buffer[8] = ((GSM_DateTime *)data)->Second & 0xff; buffer[9] = 0x00; break; case Alcatel_string: buffer[3] = 0x08; buffer[4] = 0x3c; len = MIN(UnicodeLength((char *)data),62); EncodeDefault(buffer + 6, (char *)data, &len, true, GSM_AlcatelAlphabet); buffer[5] = len; buffer[0] = 5 + len; buffer[6 + len] = 0x00; break; case Alcatel_phone: buffer[3] = 0x07; buffer[4] = 0x3c; len = MIN(UnicodeLength((char *)data),50); EncodeDefault(buffer + 6, (char *)data, &len, true, GSM_AlcatelAlphabet); buffer[5] = len; buffer[0] = 5 + len; buffer[6 + len] = 0x00; break; case Alcatel_enum: buffer[3] = 0x04; buffer[4] = 0x38; buffer[0] = 0x05; buffer[5] = *(int *)data & 0xff; buffer[6] = 0x00; break; case Alcatel_bool: buffer[3] = 0x03; buffer[4] = 0x3b; buffer[0] = 0x05; buffer[5] = *(int *)data & 0xff; buffer[6] = 0x00; break; case Alcatel_int: buffer[3] = 0x02; buffer[4] = 0x3a; buffer[0] = 0x08; buffer[5] = *(unsigned int *)data >> 24; buffer[6] = (*(unsigned int *)data >> 16) & 0xff; buffer[7] = (*(unsigned int *)data >> 8) & 0xff; buffer[8] = *(unsigned int *)data & 0xff; buffer[9] = 0x00; break; case Alcatel_byte: buffer[3] = 0x00; buffer[4] = 0x38; buffer[0] = 0x05; buffer[5] = *(int *)data & 0xff; buffer[6] = 0x00; break; } return ERR_NONE; } static GSM_Error ALCATEL_CreateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int field, void *data) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[200] = {0x00, 0x04, 0x00, /* type */ 0x25, 0x01, 0x65, 0x00, /* length of remaining part */ 0x00, /* field */ 0x37}; /* data follows here */ smprintf(s,"Creating field (%02x)\n", field); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } error = ALCATEL_BuildWriteBuffer(buffer + 6, type, field, data); if (error != ERR_NONE) return error; error = GSM_WaitFor (s, buffer, 8 + buffer[6], 0x02, ALCATEL_TIMEOUT, ID_AlcatelCreateField); if (error != ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_UpdateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int id, int field, void *data) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[200] = {0x00, 0x04, 0x00, /* type */ 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, /* id */ 0x65, 0x00, /* length of remaining part */ 0x00, /* field */ 0x37}; /* data follows here */ smprintf(s,"Updating field (%08x.%02x)\n", id, field); buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } error = ALCATEL_BuildWriteBuffer(buffer + 10, type, field, data); if (error != ERR_NONE) return error; error = GSM_WaitFor (s, buffer, 12 + buffer[10], 0x02, ALCATEL_TIMEOUT, ID_AlcatelUpdateField); if (error != ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_GetManufacturer(GSM_StateMachine *s) { strcpy(s->Phone.Data.Manufacturer, "Alcatel"); return ERR_NONE; } static GSM_Error ALCATEL_GetIMEI (GSM_StateMachine *s) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetIMEI(s); } static GSM_Error ALCATEL_GetFirmware(GSM_StateMachine *s) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetFirmware(s); } static GSM_Error ALCATEL_GetModel(GSM_StateMachine *s) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetModel(s); } static GSM_Error ALCATEL_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetDateTime(s, date_time); } static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; int j = 0; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) { entry->EntriesNum = 0; return error; } if ((error = ALCATEL_GetFields(s, entry->Location))!= ERR_NONE) return error; entry->EntriesNum = Priv->CurrentFieldsCount; for (i=0; i<Priv->CurrentFieldsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, entry->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error; entry->Entries[i].VoiceTag = 0; entry->Entries[i].SMSList[0] = 0; switch (Priv->CurrentFields[i]) { case 0: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 0, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_LastName; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 1: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 1, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_FirstName; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 2: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 2, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Company; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 3: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 3, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_JobTitle; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 4: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 4, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Note; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 5: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X for field 5, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Category; entry->Entries[i - j].Number = Priv->ReturnInt; break; case 6: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X for field 6, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Private; entry->Entries[i - j].Number = Priv->ReturnInt; break; case 7: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 7, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Work; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 8: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 8, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_General; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 9: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 9, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Fax; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 10: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 10, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Other; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 11: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 11, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Pager; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 12: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 12, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Mobile; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 13: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X for field 13, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Number_Home; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 14: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 14, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Email; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 15: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 15, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Email2; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 16: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 16, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_StreetAddress; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 17: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 17, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_City; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 18: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 18, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_State; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 19: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 19, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Zip; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 20: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 20, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Country; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 21: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 21, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Custom1; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 22: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 22, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Custom2; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 23: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 23, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Custom3; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 24: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X for field 24, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } entry->Entries[i - j].EntryType = PBK_Text_Custom4; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 25: if (Priv->ReturnType != Alcatel_int) { smprintf(s,"WARNING: Received unexpected type %02X for field 25, ignoring\n", Priv->ReturnType); entry->EntriesNum--; j++; break; } if (Priv->ReturnInt != 0) { entry->Entries[i - j].EntryType = PBK_PictureID; entry->Entries[i - j].Number = Priv->ReturnInt; } else { entry->EntriesNum--; j++; } break; default: entry->EntriesNum--; j++; smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType); switch (Priv->ReturnType) { case Alcatel_date: smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year); break; case Alcatel_time: smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second); break; case Alcatel_string: case Alcatel_phone: smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString)); break; case Alcatel_enum: case Alcatel_bool: case Alcatel_int: case Alcatel_byte: smprintf(s, "%d", Priv->ReturnInt); break; } smprintf(s,"\n"); } } return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetMemory(s, entry); } } static GSM_Error ALCATEL_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->ContactsItemsCount == 0) return ERR_EMPTY; if (start) entry->Location = 0; if ((error = ALCATEL_GetNextId(s, &(entry->Location))) != ERR_NONE) return error; return ALCATEL_GetMemory(s, entry); } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNextMemory(s, entry, start); } } static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int NamePosition = -1; bool NameSet = false; int i; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, 0))!= ERR_NONE) return error; for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { case PBK_Number_General: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Mobile: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 12, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Work: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 7, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Fax: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Home: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 13, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Pager: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 11, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Other: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 10, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Note: if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Email: if ((error = ALCATEL_CreateField(s, Alcatel_string, 14, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Email2: if ((error = ALCATEL_CreateField(s, Alcatel_string, 15, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_LastName: if ((error = ALCATEL_CreateField(s, Alcatel_string, 0, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_FirstName: if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_Company: if ((error = ALCATEL_CreateField(s, Alcatel_string, 2, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_JobTitle: if ((error = ALCATEL_CreateField(s, Alcatel_string, 3, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Category: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Private: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Text_StreetAddress: if ((error = ALCATEL_CreateField(s, Alcatel_string, 16, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_City: if ((error = ALCATEL_CreateField(s, Alcatel_string, 17, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_State: if ((error = ALCATEL_CreateField(s, Alcatel_string, 18, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Zip: if ((error = ALCATEL_CreateField(s, Alcatel_string, 19, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Country: if ((error = ALCATEL_CreateField(s, Alcatel_string, 20, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom1: if ((error = ALCATEL_CreateField(s, Alcatel_string, 21, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom2: if ((error = ALCATEL_CreateField(s, Alcatel_string, 22, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom3: if ((error = ALCATEL_CreateField(s, Alcatel_string, 23, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom4: if ((error = ALCATEL_CreateField(s, Alcatel_string, 24, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_PictureID: if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_CreateField(s, Alcatel_int, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error; } else { smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); } break; case PBK_Text_Name: NamePosition = i; break; /* Following fields are not supported: */ case PBK_Text_UserID: case PBK_SMSListID: case PBK_RingtoneFileSystemID: case PBK_Date: case PBK_Caller_Group: case PBK_RingtoneID: case PBK_Text_Postal: case PBK_Text_URL: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); break; } } if (NamePosition != -1) { if (NameSet) { smprintf(s,"WARNING: Ignoring name, not supported by phone\n"); } else { if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != ERR_NONE) return error; } } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; entry->Location = Priv->CommitedRecord; /* Refresh list */ if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_AddMemory(s, entry); } } static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int NamePosition = -1; bool NameSet = false; int i; bool UpdatedFields[26]; if (entry->Location == 0) return ERR_INVALIDLOCATION; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; /* Save modified entry */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddMemory(s, entry); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, entry->Location))!= ERR_NONE) return error; for (i = 0; i < 26; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, entry->Location))!= ERR_NONE) return error; for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { case PBK_Number_General: UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 8, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Mobile: UpdatedFields[12] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 12, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Work: UpdatedFields[7] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 7, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Fax: UpdatedFields[9] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 9, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Home: UpdatedFields[13] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 13, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Pager: UpdatedFields[11] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 11, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Number_Other: UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Note: UpdatedFields[4] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 4, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Email: UpdatedFields[14] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 14, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Email2: UpdatedFields[15] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 15, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_LastName: UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 0, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_FirstName: UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_Company: UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 2, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_JobTitle: UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 3, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Category: UpdatedFields[5] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, entry->Location, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Private: UpdatedFields[6] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_bool, entry->Location, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Text_StreetAddress: UpdatedFields[16] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 16, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_City: UpdatedFields[17] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 17, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_State: UpdatedFields[18] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 18, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Zip: UpdatedFields[19] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 19, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Country: UpdatedFields[20] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 20, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom1: UpdatedFields[21] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 21, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom2: UpdatedFields[22] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 22, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom3: UpdatedFields[23] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 23, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom4: UpdatedFields[24] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 24, entry->Entries[i].Text)) != ERR_NONE) return error ; break; case PBK_PictureID: if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { UpdatedFields[25] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, entry->Location, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error; } else { smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); } break; case PBK_Text_Name: NamePosition = i; break; /* Following fields are not supported: */ case PBK_SMSListID: case PBK_Text_UserID: case PBK_RingtoneFileSystemID: case PBK_Date: case PBK_Caller_Group: case PBK_RingtoneID: case PBK_Text_Postal: case PBK_Text_URL: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); break; } } if (NamePosition != -1) { if (NameSet) { smprintf(s,"WARNING: Ignoring name, not supported by phone\n"); } else { UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error; } } /* If we didn't update some field, we have to delete it... */ for (i=0; i<Priv->CurrentFieldsCount; i++) { if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, entry->Location, Priv->CurrentFields[i])) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; entry->Location = Priv->CommitedRecord; return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetMemory(s, entry); } } static GSM_Error ALCATEL_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } /* Do real delete */ error = ALCATEL_DeleteItem(s, entry->Location); if (error != ERR_NONE) return error; /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DeleteMemory(s, entry); } } static GSM_Error ALCATEL_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if (type == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->ContactsItemsCount; i++) { error = ALCATEL_DeleteItem(s, Priv->ContactsItems[i]); if (error != ERR_NONE) return error; } /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DeleteAllMemory(s, type); } } static GSM_Error ALCATEL_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSC(s, smsc); } static GSM_Error ALCATEL_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; if (Status->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; Status->MemoryUsed = Priv->ContactsItemsCount; Status->MemoryFree = ALCATEL_FREE_MEMORY; return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetMemoryStatus(s, Status); } } static GSM_Error ALCATEL_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMS(s, sms); } static GSM_Error ALCATEL_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DeleteSMS(s, sms); } static GSM_Error ALCATEL_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_AddSMS(s, sms); } static GSM_Error ALCATEL_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetBatteryCharge(s, bat); } static GSM_Error ALCATEL_GetSignalStrength(GSM_StateMachine *s, GSM_SignalQuality *sig) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSignalQuality(s, sig); } static GSM_Error ALCATEL_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSFolders(s, folders); } static GSM_Error ALCATEL_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNextSMS(s, sms, start); } static GSM_Error ALCATEL_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSStatus(s, status); } static GSM_Error ALCATEL_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DialVoice(s, number, ShowNumber); } static GSM_Error ALCATEL_AnswerCall(GSM_StateMachine *s, int ID, bool all) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_AnswerCall(s,ID,all); } static GSM_Error ALCATEL_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNetworkInfo(s, netinfo); } static GSM_Error ALCATEL_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetDisplayStatus(s, features); } static GSM_Error ALCATEL_SetAutoNetworkLogin(GSM_StateMachine *s) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetAutoNetworkLogin(s); } static GSM_Error ALCATEL_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_PressKey(s, Key, Press); } static GSM_Error ALCATEL_Reset(GSM_StateMachine *s, bool hard) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_Reset(s, hard); } static GSM_Error ALCATEL_CancelCall(GSM_StateMachine *s, int ID, bool all) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_CancelCall(s,ID,all); } static GSM_Error ALCATEL_SendSavedSMS(GSM_StateMachine *s, int Folder, int Location) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendSavedSMS(s, Folder, Location); } static GSM_Error ALCATEL_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendSMS(s, sms); } static GSM_Error ALCATEL_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetDateTime(s, date_time); } static GSM_Error ALCATEL_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetSMSC(s, smsc); } static GSM_Error ALCATEL_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_EnterSecurityCode(s, Code); } static GSM_Error ALCATEL_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSecurityStatus(s, Status); } static GSM_Error ALCATEL_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_ResetPhoneSettings(s, Type); } static GSM_Error ALCATEL_SendDTMF(GSM_StateMachine *s, char *sequence) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendDTMF(s, sequence); } static GSM_Error ALCATEL_GetSIMIMSI(GSM_StateMachine *s, char *IMSI) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSIMIMSI(s, IMSI); } static GSM_Error ALCATEL_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *status) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; status->Used = 0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; status->Used = Priv->CalendarItemsCount; return ERR_NONE; } static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; GSM_DateTime *dt = NULL; GSM_DateTime evdate; bool evdateused = true; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; int j=0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { Note->EntriesNum = 0; return error; } if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error; Note->EntriesNum = Priv->CurrentFieldsCount; for (i=0; i < Priv->CurrentFieldsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Note->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error; switch (Priv->CurrentFields[i]) { case 0: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } j++; Note->EntriesNum--; evdate = Priv->ReturnDateTime; evdateused = false; break; case 1: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_START_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; Note->Entries[i-j].Date.Day = evdate.Day; Note->Entries[i-j].Date.Month = evdate.Month; Note->Entries[i-j].Date.Year = evdate.Year; Note->Entries[i-j].Date.Timezone = evdate.Timezone; evdateused = true; break; case 2: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_END_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; Note->Entries[i-j].Date.Day = evdate.Day; Note->Entries[i-j].Date.Month = evdate.Month; Note->Entries[i-j].Date.Year = evdate.Year; Note->Entries[i-j].Date.Timezone = evdate.Timezone; evdateused = true; break; case 3: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } if (dt == NULL) { Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(Note->Entries[i-j].Date); } else { j++; Note->EntriesNum--; dt->Day = Priv->ReturnDateTime.Day; dt->Month = Priv->ReturnDateTime.Month; dt->Year = Priv->ReturnDateTime.Year; dt->Timezone = Priv->ReturnDateTime.Timezone; dt = NULL; } break; case 4: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } if (dt == NULL) { Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(Note->Entries[i-j].Date); } else { j++; Note->EntriesNum--; dt->Hour = Priv->ReturnDateTime.Hour; dt->Minute = Priv->ReturnDateTime.Minute; dt->Second = Priv->ReturnDateTime.Second; dt = NULL; } break; case 5: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_TEXT; CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString); break; case 6: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_PRIVATE; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 7: if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } switch (Priv->ReturnInt) { case 0: Note->Type = GSM_CAL_MEETING; break; case 2: Note->Type = GSM_CAL_BIRTHDAY; break; case 3: Note->Type = GSM_CAL_CALL; break; case 4: Note->Type = GSM_CAL_ALARM; break; case 5: Note->Type = GSM_CAL_DAILY_ALARM; break; case 9: /* I'd call this repeating event, but it makes no sense creating one more type ... */ Note->Type = GSM_CAL_MEETING; break; default: smprintf(s,"WARNING: Received unknown event type %02X!\n", Priv->ReturnInt); break; } j++; Note->EntriesNum--; break; case 8: if (Priv->ReturnType != Alcatel_int) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } /* 0xffffffff indicates that there is phone (BF5), 0 means none (BF5, BE5)*/ if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) { j++; Note->EntriesNum--; } else { Note->Entries[i-j].EntryType = CAL_CONTACTID; Note->Entries[i-j].Number = Priv->ReturnInt; } break; case 9: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_PHONE; CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString); break; case 10: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_DAYOFWEEK; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 11: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_DAY; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 12: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_WEEKOFMONTH; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 13: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_MONTH; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 17: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } /* In BF5 birthday has frequency = 1 */ if (Note->Type == GSM_CAL_BIRTHDAY) { Note->EntriesNum--; j++; } else { Note->Entries[i-j].EntryType = CAL_REPEAT_FREQUENCY; Note->Entries[i-j].Number = Priv->ReturnInt; } break; case 18: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_STARTDATE; Note->Entries[i-j].Date = Priv->ReturnDateTime; break; case 19: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_STOPDATE; Note->Entries[i-j].Date = Priv->ReturnDateTime; break; case 20: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } /* This entry had always same value as the 3rd (alarm date) */ j++; Note->EntriesNum--; break; case 21: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } /* This entry had always same value as the 4th (alarm time) */ j++; Note->EntriesNum--; break; default: Note->EntriesNum--; j++; smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType); switch (Priv->ReturnType) { case Alcatel_date: smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year); break; case Alcatel_time: smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second); break; case Alcatel_string: case Alcatel_phone: smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString)); break; case Alcatel_enum: case Alcatel_bool: case Alcatel_int: case Alcatel_byte: smprintf(s, "%d", Priv->ReturnInt); break; } smprintf(s,"\n"); } } /* The event didn't have start/stop time -> we need only date */ if (!evdateused) { Note->EntriesNum++; Note->Entries[i-j].EntryType = CAL_START_DATETIME; Note->Entries[i-j].Date = evdate; } return ERR_NONE; } static GSM_Error ALCATEL_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->CalendarItemsCount == 0) return ERR_EMPTY; if (start) Note->Location = 0; if ((error = ALCATEL_GetNextId(s, &(Note->Location))) != ERR_NONE) return error; return ALCATEL_GetCalendar(s, Note); } static GSM_Error ALCATEL_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; /* Delete Calendar */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } error = ALCATEL_DeleteItem(s, Note->Location); if (error != ERR_NONE) return error; /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool date_set = false; bool repeating = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, 0))!= ERR_NONE) return error; for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } if ((error = ALCATEL_CreateField(s, Alcatel_time, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_END_DATETIME: if (!date_set) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } if ((error = ALCATEL_CreateField(s, Alcatel_time, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_ALARM_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error; if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error; } break; case CAL_TEXT: if ((error = ALCATEL_CreateField(s, Alcatel_string, 5, Note->Entries[i].Text)) != ERR_NONE) return error; break; case CAL_PRIVATE: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error; break; case CAL_CONTACTID: if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; case CAL_REPEAT_DAYOFWEEK: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_WEEKOFMONTH: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_MONTH: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_FREQUENCY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STARTDATE: if ((error = ALCATEL_CreateField(s, Alcatel_date, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STOPDATE: if ((error = ALCATEL_CreateField(s, Alcatel_date, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: val = 4; break; case GSM_CAL_DAILY_ALARM: val = 5; break; default: if (repeating) { val = 9; } else { val = 0; } } if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error; if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; Note->Location = Priv->CommitedRecord; /* Refresh list */ if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool date_set = false; bool repeating = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; bool UpdatedFields[22]; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddCalendar(s, Note); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error; for (i = 0; i < 22; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, Note->Location))!= ERR_NONE) return error; for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_END_DATETIME: if (!date_set) { UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_ALARM_DATETIME: UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[4] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error; if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) { UpdatedFields[20] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[21] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error; } break; case CAL_TEXT: UpdatedFields[5] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, Note->Location, 5, Note->Entries[i].Text)) != ERR_NONE) return error; break; case CAL_PRIVATE: UpdatedFields[6] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_bool, Note->Location, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error; break; case CAL_CONTACTID: UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: UpdatedFields[9] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, Note->Location, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; case CAL_REPEAT_DAYOFWEEK: UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: UpdatedFields[11] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_WEEKOFMONTH: UpdatedFields[12] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_MONTH: UpdatedFields[13] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_FREQUENCY: UpdatedFields[17] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STARTDATE: UpdatedFields[18] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STOPDATE: UpdatedFields[19] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: val = 4; break; case GSM_CAL_DAILY_ALARM: val = 5; break; default: if (repeating) { val = 9; } else { val = 0; } } UpdatedFields[7] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_enum, Note->Location, 7, &val)) != ERR_NONE) return error; if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &val)) != ERR_NONE) return error; } /* If we didn't update some field, we have to delete it... */ for (i=0; i<Priv->CurrentFieldsCount; i++) { if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, Note->Location, Priv->CurrentFields[i])) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_DeleteAllCalendar (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { error = ALCATEL_DeleteItem(s, Priv->CalendarItems[i]); if (error != ERR_NONE) return error; } /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { GSM_Error error; GSM_CalendarEntry Note; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; bool Found = false; bool DateSet = false; int alarm_number = alarm->Location; static GSM_DateTime nulldt = {0,0,0,0,0,0,0}; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error; if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); continue; } if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; if (alarm_number == 0) { Found = true; break; } } } if (!Found) return ERR_EMPTY; Note.Location = Priv->CalendarItems[i]; if ((error = ALCATEL_GetCalendar(s, &Note))!= ERR_NONE) return error; if (Note.Type == GSM_CAL_ALARM) { alarm->Repeating = false; } else { alarm->Repeating = true; } alarm->Text[0] = 0; alarm->Text[1] = 0; for (i = 0; i < Note.EntriesNum; i++) { if (Note.Entries[i].EntryType == CAL_TEXT) { CopyUnicodeString(alarm->Text, Note.Entries[i].Text); } else if (Note.Entries[i].EntryType == CAL_ALARM_DATETIME) { alarm->DateTime = Note.Entries[i].Date; DateSet = false; } } if (!DateSet) { alarm->DateTime = nulldt; } return ERR_NONE; } static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) { GSM_Error error; GSM_CalendarEntry Note; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_DateTime dt; int i; bool Found = false; int alarm_number = alarm->Location; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error; if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); continue; } if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; if (alarm_number == 0) { Found = true; break; } } } if (Found) { Note.Location = Priv->CalendarItems[i]; } Note.EntriesNum = 1; Note.Entries[0].EntryType = CAL_ALARM_DATETIME; Note.Entries[0].Date = alarm->DateTime; if (alarm->Repeating) { Note.Type = GSM_CAL_DAILY_ALARM; GSM_GetCurrentDateTime(&dt); Note.Entries[0].Date.Day = dt.Day; Note.Entries[0].Date.Month = dt.Month; Note.Entries[0].Date.Year = dt.Year; } else { Note.Type = GSM_CAL_ALARM; } if (alarm->Text[0] != 0 || alarm->Text[1] != 0) { Note.EntriesNum++; Note.Entries[1].EntryType = CAL_TEXT; CopyUnicodeString(Note.Entries[1].Text, alarm->Text); } if (Found) { return ALCATEL_SetCalendar(s, &Note); } else { return ALCATEL_AddCalendar(s, &Note); } } static GSM_Error ALCATEL_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; status->Used = 0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; status->Used = Priv->ToDoItemsCount; return ERR_NONE; } static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_DateTime *dt = NULL; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; int j=0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { ToDo->EntriesNum = 0; return error; } if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error; ToDo->EntriesNum = Priv->CurrentFieldsCount; for (i=0; i < Priv->CurrentFieldsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, ToDo->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error; switch (Priv->CurrentFields[i]) { case 0: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_END_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; break; case 1: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_COMPLETED; ToDo->Entries[i-j].Number = Priv->ReturnInt; break; case 2: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } if (dt == NULL) { ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(ToDo->Entries[i-j].Date); } else { j++; ToDo->EntriesNum--; dt->Day = Priv->ReturnDateTime.Day; dt->Month = Priv->ReturnDateTime.Month; dt->Year = Priv->ReturnDateTime.Year; dt->Timezone = Priv->ReturnDateTime.Timezone; dt = NULL; } break; case 3: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } if (dt == NULL) { ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(ToDo->Entries[i-j].Date); } else { j++; ToDo->EntriesNum--; dt->Hour = Priv->ReturnDateTime.Hour; dt->Minute = Priv->ReturnDateTime.Minute; dt->Second = Priv->ReturnDateTime.Second; dt = NULL; } break; case 4: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_TEXT; CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString); break; case 5: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_PRIVATE; ToDo->Entries[i-j].Number = Priv->ReturnInt; break; case 6: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (Priv->ReturnInt == 255) { /* 255 means no category */ j++; ToDo->EntriesNum--; } else { ToDo->Entries[i-j].EntryType = TODO_CATEGORY; ToDo->Entries[i-j].Number = Priv->ReturnInt; } break; case 7: /* This one seems to be byte for BF5 and enum for BE5 */ if (Priv->ReturnType != Alcatel_enum && Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } switch (Priv->ReturnInt) { case 0: ToDo->Priority = GSM_Priority_High; break; case 1: ToDo->Priority = GSM_Priority_Medium; break; case 2: ToDo->Priority = GSM_Priority_Low; break; default: ToDo->Priority = 0; smprintf(s,"WARNING: Received unexpected priority %02X, ignoring\n", Priv->ReturnInt); } j++; ToDo->EntriesNum--; break; case 8: if (Priv->ReturnType != Alcatel_int) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } /* 0xffffffff indicates that there is phone, 0 means none */ if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) { j++; ToDo->EntriesNum--; } else { ToDo->Entries[i-j].EntryType = TODO_CONTACTID; ToDo->Entries[i-j].Number = Priv->ReturnInt; } break; case 9: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_PHONE; CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString); break; case 10: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } /* This entry had always same value as the 2nd (alarm date) */ j++; ToDo->EntriesNum--; break; case 11: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } /* This entry had always same value as the 3rd (alarm time) */ j++; ToDo->EntriesNum--; break; default: ToDo->EntriesNum--; j++; smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType); switch (Priv->ReturnType) { case Alcatel_date: smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year); break; case Alcatel_time: smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second); break; case Alcatel_string: case Alcatel_phone: smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString)); break; case Alcatel_enum: case Alcatel_bool: case Alcatel_int: case Alcatel_byte: smprintf(s, "%d", Priv->ReturnInt); break; } smprintf(s,"\n"); } } return ERR_NONE; } static GSM_Error ALCATEL_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->ToDoItemsCount == 0) return ERR_EMPTY; if (start) ToDo->Location = 0; if ((error = ALCATEL_GetNextId(s, &(ToDo->Location))) != ERR_NONE) return error; return ALCATEL_GetToDo(s, ToDo); } static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->ToDoItemsCount; i++) { error = ALCATEL_DeleteItem(s, Priv->ToDoItems[i]); if (error != ERR_NONE) return error; } /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, 0))!= ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; break; case GSM_Priority_Medium: default: val = 1; break; } /* This one seems to be byte for BF5 and enum for BE5 */ if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_CreateField(s, Alcatel_byte, 7, &val)) != ERR_NONE) return error; } else { if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error; } for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_COMPLETED: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_ALARM_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_date, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_TEXT: if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; break; case TODO_PRIVATE: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_CATEGORY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_CONTACTID: if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case TODO_PHONE: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; ToDo->Location = Priv->CommitedRecord; /* Refresh list */ if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool UpdatedFields[12]; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; /* Save modified ToDo */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddToDo(s, ToDo); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error; for (i = 0; i < 12; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, ToDo->Location))!= ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; break; case GSM_Priority_Medium: default: val = 1; break; } /* This one seems to be byte for BF5 and enum for BE5 */ if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 7, &val)) != ERR_NONE) return error; } else { if ((error = ALCATEL_UpdateField(s, Alcatel_enum, ToDo->Location, 7, &val)) != ERR_NONE) return error; } UpdatedFields[7] = true; for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[0] = true; break; case TODO_COMPLETED: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[1] = true; break; case TODO_ALARM_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[11] = true; break; case TODO_TEXT: if ((error = ALCATEL_UpdateField(s, Alcatel_string, ToDo->Location, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; UpdatedFields[4] = true; break; case TODO_PRIVATE: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[5] = true; break; case TODO_CATEGORY: if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[6] = true; break; case TODO_CONTACTID: if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[8] = true; contact_set = true; break; case TODO_PHONE: if ((error = ALCATEL_UpdateField(s, Alcatel_phone, ToDo->Location, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error; UpdatedFields[9] = true; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &val)) != ERR_NONE) return error; UpdatedFields[8] = true; } /* If we didn't update some field, we have to delete it... */ for (i=0; i<Priv->CurrentFieldsCount; i++) { if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, ToDo->Location, Priv->CurrentFields[i])) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; /* Delete ToDo */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } error = ALCATEL_DeleteItem(s, ToDo->Location); if (error != ERR_NONE) return error; /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_GetCategoryStatus(GSM_StateMachine *s, GSM_CategoryStatus *Status) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Status->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error; Status->Used = Priv->CurrentCategoriesCount; return ERR_NONE; } static GSM_Error ALCATEL_GetCategory(GSM_StateMachine *s, GSM_Category *Category) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Category->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error; if ((error = ALCATEL_IsCategoryIdAvailable(s, Category->Location))!= ERR_NONE) return error; if ((error = ALCATEL_GetCategoryText(s, Category->Location))!= ERR_NONE) return error; CopyUnicodeString(Category->Name, Priv->ReturnString); return ERR_NONE; } static GSM_Error ALCATEL_AddCategory(GSM_StateMachine *s, GSM_Category *Category) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Category->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_AddCategoryText(s, Category->Name))!= ERR_NONE) return error; Category->Location = Priv->ReturnInt; return ERR_NONE; } static GSM_Error ALCATEL_GetProductCode(GSM_StateMachine *s, char *value) { strcpy(value, s->Phone.Data.ModelInfo->model); return ERR_NONE; } static GSM_Error ALCATEL_DispatchMessage(GSM_StateMachine *s) { if (s->Phone.Data.Priv.ALCATEL.Mode == ModeBinary) { return GSM_DispatchMessage(s); } else { return ATGEN_DispatchMessage(s); } } static GSM_Error ALCATEL_ReplyGeneric(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* All error values are just VERY wild guesses, but these seems to work * almost as expected ... */ switch (msg.Buffer[8]) { case 0x00: /* no error */ return ERR_NONE; case 0x10: /* same thing opened in phone menus */ return ERR_INSIDEPHONEMENU; case 0x13: /* This appears in more cases: * - phone needs PIN code * - we want to close not opened session * For normal users the second case shouldn't occur... */ return ERR_SECURITYERROR; case 0x14: /* Bad data */ case 0x2f: /* Closing session when not opened */ case 0x1f: /* Bad in/out counter in packet/ack */ case 0x0e: /* Openning session when not closed */ case 0x0C: /* Bad id (item/database) */ case 0x11: /* Bad list id */ case 0x2A: /* Nonexistant field/item id */ case 0x35: /* Too long text */ return ERR_BUG; case 0x23: /* Session opened */ case 0x80: /* Transfer started */ return ERR_NONE; case 0x82: /* Transfer canceled */ return ERR_CANCELED; default: smprintf(s, "WARNING: Packet seems to indicate some status by %02X, ignoring!\n", msg.Buffer[8]); return ERR_NONE; } } static GSM_Error ALCATEL_ReplyCommit(GSM_Protocol_Message msg, GSM_StateMachine *s) { s->Phone.Data.Priv.ALCATEL.CommitedRecord = msg.Buffer[12] + (msg.Buffer[11] << 8) + (msg.Buffer[10] << 16) + (msg.Buffer[9] << 24); smprintf(s, "Created record %08x\n", s->Phone.Data.Priv.ALCATEL.CommitedRecord); return ERR_NONE; } static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingCB(s, enable); } static GSM_Error ALCATEL_SetIncomingSMS (GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingSMS(s, enable); } static GSM_Error ALCATEL_SetFastSMSSending(GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetFastSMSSending(s, enable); } static GSM_Reply_Function ALCATELReplyFunctions[] = { {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDetach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCommit }, {ALCATEL_ReplyCommit, "\x02",0x00,0x00, ID_AlcatelCommit2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelEnd }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelClose }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelStart }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect1 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect3 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin1 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetIds1 }, {ALCATEL_ReplyGetIds, "\x02",0x00,0x00, ID_AlcatelGetIds2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategories1 }, {ALCATEL_ReplyGetCategories, "\x02",0x00,0x00, ID_AlcatelGetCategories2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategoryText1 }, {ALCATEL_ReplyGetCategoryText, "\x02",0x00,0x00, ID_AlcatelGetCategoryText2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAddCategoryText1 }, {ALCATEL_ReplyAddCategoryText, "\x02",0x00,0x00, ID_AlcatelAddCategoryText2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFields1 }, {ALCATEL_ReplyGetFields, "\x02",0x00,0x00, ID_AlcatelGetFields2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFieldValue1 }, {ALCATEL_ReplyGetFieldValue, "\x02",0x00,0x00, ID_AlcatelGetFieldValue2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteField }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteItem1 }, {ALCATEL_ReplyDeleteItem, "\x02",0x00,0x00, ID_AlcatelDeleteItem2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCreateField }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelUpdateField }, {NULL, "\x00",0x00,0x00, ID_None } }; GSM_Phone_Functions ALCATELPhone = { /* AFAIK, any 50[0123] phone should work, but I'm not sure whether all * they were ever really released, if yes add them here also. */ "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4", ALCATELReplyFunctions, ALCATEL_Initialise, ALCATEL_Terminate, ALCATEL_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ALCATEL_GetManufacturer, ALCATEL_GetModel, ALCATEL_GetFirmware, ALCATEL_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ ALCATEL_GetProductCode, NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ALCATEL_GetSIMIMSI, ALCATEL_GetDateTime, ALCATEL_SetDateTime, ALCATEL_GetAlarm, ALCATEL_SetAlarm, NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ ALCATEL_PressKey, ALCATEL_Reset, ALCATEL_ResetPhoneSettings, ALCATEL_EnterSecurityCode, ALCATEL_GetSecurityStatus, ALCATEL_GetDisplayStatus, ALCATEL_SetAutoNetworkLogin, ALCATEL_GetBatteryCharge, ALCATEL_GetSignalStrength, ALCATEL_GetNetworkInfo, ALCATEL_GetCategory, ALCATEL_AddCategory, ALCATEL_GetCategoryStatus, ALCATEL_GetMemoryStatus, ALCATEL_GetMemory, ALCATEL_GetNextMemory, ALCATEL_SetMemory, ALCATEL_AddMemory, ALCATEL_DeleteMemory, ALCATEL_DeleteAllMemory, NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ ALCATEL_GetSMSC, ALCATEL_SetSMSC, ALCATEL_GetSMSStatus, ALCATEL_GetSMS, ALCATEL_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ALCATEL_AddSMS, ALCATEL_DeleteSMS, ALCATEL_SendSMS, ALCATEL_SendSavedSMS, ALCATEL_SetFastSMSSending, ALCATEL_SetIncomingSMS, ALCATEL_SetIncomingCB, ALCATEL_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ALCATEL_DialVoice, ALCATEL_AnswerCall, ALCATEL_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NONEFUNCTION, /* SetIncomingCall */ NOTSUPPORTED, /* SetIncomingUSSD */ ALCATEL_SendDTMF, NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ ALCATEL_GetToDoStatus, ALCATEL_GetToDo, ALCATEL_GetNextToDo, ALCATEL_SetToDo, ALCATEL_AddToDo, ALCATEL_DeleteToDo, ALCATEL_DeleteAllToDo, ALCATEL_GetCalendarStatus, ALCATEL_GetCalendar, ALCATEL_GetNextCalendar, ALCATEL_SetCalendar, ALCATEL_AddCalendar, ALCATEL_DeleteCalendar, ALCATEL_DeleteAllCalendar, NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ NOTSUPPORTED, /* GetNoteStatus */ NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* SetNote */ NOTSUPPORTED, /* AddNote */ NOTSUPPORTED, /* DeleteNote */ NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #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/gammu/depend/nokia/dct3.c b/gammu/emb/gammu/depend/nokia/dct3.c index b9e47ea..bda7532 100644 --- a/gammu/emb/gammu/depend/nokia/dct3.c +++ b/gammu/emb/gammu/depend/nokia/dct3.c @@ -1,807 +1,807 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* MSID by Walek */ #include "../../../common/gsmstate.h" #ifdef GSM_ENABLE_NOKIA_DCT3 #include <string.h> #include <signal.h> #include "../../../common/misc/coding/coding.h" #include "../../../common/gsmcomon.h" #include "../../../common/service/gsmpbk.h" #include "../../../common/phone/nokia/dct3/dct3func.h" #include "../../../common/phone/pfunc.h" #include "../../gammu.h" -extern GSM_Reply_Function UserReplyFunctions3[]; +static GSM_Reply_Function UserReplyFunctions3[]; /* ------- some usefull functions ----------------------------------------- */ GSM_Error CheckDCT3Only() { bool found = false; /* Checking if phone is DCT3 */ #ifdef GSM_ENABLE_NOKIA6110 if (strstr(N6110Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif #ifdef GSM_ENABLE_NOKIA7110 if (strstr(N7110Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif #ifdef GSM_ENABLE_NOKIA9210 if (strstr(N9210Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif if (!found) return ERR_NOTSUPPORTED; if (s.ConnectionType!=GCT_MBUS2 && s.ConnectionType!=GCT_FBUS2 && s.ConnectionType!=GCT_FBUS2DLR3 && s.ConnectionType!=GCT_FBUS2BLUE && s.ConnectionType!=GCT_FBUS2IRDA && s.ConnectionType!=GCT_IRDAPHONET && s.ConnectionType!=GCT_BLUEFBUS2) { return ERR_OTHERCONNECTIONREQUIRED; } return ERR_NONE; } static void CheckDCT3() { GSM_Error error; error = CheckDCT3Only(); switch (error) { case ERR_NOTSUPPORTED: Print_Error(ERR_NOTSUPPORTED); break; case ERR_OTHERCONNECTIONREQUIRED: printf("Can't do it with current phone protocol\n"); GSM_TerminateConnection(&s); exit(-1); default: break; } } static bool answer_yes3(char *text) { int len; char ans[99]; while (1) { printf("%s (yes/no) ? ",text); len=GetLine(stdin, ans, 99); if (len==-1) exit(-1); if (mystrncasecmp(ans, "yes",0)) return true; if (mystrncasecmp(ans, "no" ,0)) return false; } } /* ------------------- functions ------------------------------------------- */ static FILE *DCT3T9File; static GSM_Error DCT3_ReplyGetT9(GSM_Protocol_Message msg, GSM_StateMachine *s) { int DCT3T9Size; DCT3T9Size = msg.Length - 6; fwrite(msg.Buffer+6,1,DCT3T9Size,DCT3T9File); return ERR_NONE; } void DCT3GetT9(int argc, char *argv[]) { int i; unsigned char req[] = {0x00, 0x01, 0xAE, 0x02, 0x00, 0x00}; /* Part number */ //"00 01 AE 00" gets some control values if (CheckDCT3Only()!=ERR_NONE) return; DCT3T9File = fopen("T9", "w"); if (DCT3T9File == NULL) return; s.User.UserReplyFunctions=UserReplyFunctions3; for (i=0;i<5;i++) { req[5] = i; error=GSM_WaitFor (&s, req, 6, 0x40, 4, ID_User3); Print_Error(error); } fclose(DCT3T9File); } void DCT3VibraTest(int argc, char *argv[]) { unsigned char ans[200]; unsigned char SetLevel[4] = {0x00, 0x01, 0xA3, 0xff}; /* Level */ if (CheckDCT3Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions3; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); error=GSM_WaitFor (&s, SetLevel, 4, 0x40, 4, ID_User3); Print_Error(error); printf("Press any key to continue...\n"); GetLine(stdin, ans, 99); SetLevel[3] = 0x00; error=GSM_WaitFor (&s, SetLevel, 4, 0x40, 4, ID_User3); } static GSM_Error DCT3_ReplyPhoneTests(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; for (i=0;i<msg.Buffer[3];i++) { switch (i) { case 0: printf("Unknown(%02i) ",i);break; case 1: printf("MCU ROM checksum (startup)"); break; case 2: printf("MCU RAM interface (startup)"); break; case 3: printf("MCU RAM component "); break; case 4: printf("MCU EEPROM interface (startup)"); break; case 5: printf("MCU EEPROM component "); break; case 6: printf("Real Time Clock battery (startup)"); break; case 7: printf("CCONT interface (startup)"); break; case 8: printf("AD converter (startup)"); break; case 9: printf("SW Reset "); break; case 10:printf("Power Off "); break; case 11:printf("Security Data "); break; case 12:printf("EEPROM Tune checksum (startup)"); break; case 13:printf("PPM checksum (startup)"); break; case 14:printf("MCU download DSP (startup)"); break; case 15:printf("DSP alive (startup)"); break; case 16:printf("COBBA serial (startup)"); break; case 17:printf("COBBA paraller (startup)"); break; case 18:printf("EEPROM security checksum (startup)"); break; case 19:printf("PPM validity (startup)"); break; case 20:printf("Warranty state (startup)"); break; case 21:printf("Simlock check/SW version (startup)"); break; case 22:printf("IMEI check? "); break;/*from PC-Locals1.3.is OK?*/ default:printf("Unknown(%02i) ",i);break; } switch (msg.Buffer[4+i]) { case 0: printf(" : passed"); break; case 0xff:printf(" : not executed"); break; case 254: printf(" : fail"); break; default: printf(" : result unknown(%i)",msg.Buffer[4+i]); break; } printf("\n"); } return ERR_NONE; } void DCT3SelfTests(int argc, char *argv[]) { unsigned char buffer[3] = {0x00,0x01,0xcf}; unsigned char buffer3[8] = {0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00}; int i; if (CheckDCT3Only()!=ERR_NONE) return; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); if (answer_yes3("Run all tests now ?")) { /* make almost all tests */ error = s.Protocol.Functions->WriteMessage(&s, buffer3, 8, 0x40); Print_Error(error); GSM_Terminate(); while (!false) { GSM_Init(false); if (error==ERR_NONE) break; GSM_Terminate(); } my_sleep(400); } s.User.UserReplyFunctions=UserReplyFunctions3; for (i=0;i<10;i++) { error=GSM_WaitFor (&s, buffer, 3, 0x40, 4, ID_User1); if (error == ERR_NONE) break; } } struct DCT3ADCInfo { char *name; char *unit; int x; int pos1; int pos2; }; static struct DCT3ADCInfo DCT3ADC[] = { {"Battery voltage:", "mV", 1, 3, 2}, // {"Charger voltage:", "mV", 1, -1, 7}, // {"Charger current:", "mA", 1, -1, 5}, {"Battery type:", "mAh", 1, 4, 3}, {"Battery temperature:", "mK", 10, 5, 4}, // {"Accessory detection:", "mV", 1, -1, -1}, {"RSSI:", "", 1, 2, -1}, // {"VCXO temperature:", "mV", 1, -1, -1}, // {"Hook information:", "mV", 1, -1, -1}, {"", "", 1, -1, -1} }; unsigned char DCT3ADCBuf[200]; int DCT3ADCInt; static GSM_Error DCT3_ReplyGetADC(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[2]) { case 0x68: memcpy(DCT3ADCBuf,msg.Buffer+4,msg.Length-4); return ERR_NONE; case 0x91: DCT3ADCInt = msg.Buffer[4]*256+msg.Buffer[5]; return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } void DCT3GetADC(int argc, char *argv[]) { int i = 0; unsigned char GetRaw[] = {0x00, 0x01, 0x68}; unsigned char GetUnit[] = {0x00, 0x01, 0x91, 0x02}; /* Test number */ if (CheckDCT3Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions3; error=DCT3_EnableSecurity (&s, 0x02); Print_Error(error); error=GSM_WaitFor (&s, GetRaw, 3, 0x40, 6, ID_User3); Print_Error(error); while (1) { printf(" %30s ",DCT3ADC[i].name); if (DCT3ADC[i].pos1 != -1) { printf("raw "); printf("%10i ", DCT3ADCBuf[(DCT3ADC[i].pos1-1)*2]*256+ DCT3ADCBuf[(DCT3ADC[i].pos1-1)*2+1]); } if (DCT3ADC[i].pos2 != -1) { printf("unit result "); GetUnit[3] = DCT3ADC[i].pos2; error=GSM_WaitFor (&s, GetUnit, 6, 0x40, 4, ID_User3); Print_Error(error); printf("%10i ",DCT3ADCInt*DCT3ADC[i].x); printf("%s\n",DCT3ADC[i].unit); } i++; if (DCT3ADC[i].name[0] == 0x00) break; } error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); } void DCT3DisplayTest(int argc, char *argv[]) { unsigned char ans[200]; unsigned char req[] = {0x00, 0x01, 0xD3, 0x03, /* 3=set, 2=clear */ 0x03}; /* test number */ if (CheckDCT3Only()!=ERR_NONE) return; if (atoi(argv[2]) != 1 && atoi(argv[2]) != 2) { printf("Give 1 or 2 as test number\n"); } s.User.UserReplyFunctions=UserReplyFunctions3; req[4] = atoi(argv[2]); s.Protocol.Functions->WriteMessage(&s, req, 5, 0x40); printf("Press any key to continue...\n"); GetLine(stdin, ans, 99); req[3] = 0x02; req[4] = 0x03; s.Protocol.Functions->WriteMessage(&s, req, 5, 0x40); error=DCT3_EnableSecurity (&s, 0x03); Print_Error(error); } void DCT3netmonitor(int argc, char *argv[]) { char value[100]; GSM_Init(true); CheckDCT3(); error=DCT3_Netmonitor(&s, atoi(argv[2]), value); Print_Error(error); printf("%s\n",value); #ifdef GSM_ENABLE_BEEP if (atoi(argv[2]) == 243) GSM_PhoneBeep(); #endif GSM_Terminate(); } static GSM_Error DCT3_ReplyGetMSID(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; printf("MSID : "); for (i=5;i<18;i++) printf("%02x",msg.Buffer[i]); printf("\n"); return ERR_NONE; } static GSM_Error DCT3_ReplyGetDSPROM(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("DSP ROM : %c\n",msg.Buffer[5]); return ERR_NONE; } static GSM_Error DCT3_ReplySimlockInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i, j; char uni[100], buffer[50]; j=0; for (i=0; i < 12; i++) { if (j<24) { uni[j]='0' + (msg.Buffer[9+i] >> 4); j++; } if (j!=15) { if (j<24) { uni[j]='0' + (msg.Buffer[9+i] & 0x0f); j++; } } else j++; } strncpy(buffer,uni,5); buffer[5]=0; printf("Simlock 1 : MCC+MNC %10s, %s, %s, counter %i\n", buffer, ((msg.Buffer[6] & 1) == 1)==0?"opened":"CLOSED", ((msg.Buffer[5] & 1) != 1)==0?"user ":"factory", msg.Buffer[21]); strncpy(buffer,uni+16,4); buffer[4]=0; printf("Simlock 2 : GID1 %10s, %s, %s, counter %i\n", buffer, ((msg.Buffer[6] & 4) == 4)==0?"opened":"CLOSED", ((msg.Buffer[5] & 4) != 4)==0?"user ":"factory", msg.Buffer[23]); strncpy(buffer,uni+20,4); buffer[4]=0; printf("Simlock 3 : GID2 %10s, %s, %s, counter %i\n", buffer, ((msg.Buffer[6] & 8) == 8)==0?"opened":"CLOSED", ((msg.Buffer[5] & 8) != 8)==0?"user ":"factory", msg.Buffer[24]); strncpy(buffer,uni+5,10); buffer[10]=0; printf("Simlock 4 : MSIN %10s, %s, %s, counter %i\n", buffer, ((msg.Buffer[6] & 2) == 2)==0?"opened":"CLOSED", ((msg.Buffer[5] & 2) != 2)==0?"user ":"factory", msg.Buffer[22]); return ERR_NONE; } static GSM_Error DCT3_ReplyGetMCUchkSum(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; if (msg.Buffer[3] == 0x12) printf("Language Pack: %c\n",msg.Buffer[5]); if (msg.Buffer[3] == 0x02) { printf("MCU checksum : "); for (i=5;i<9;i++) printf("%c",msg.Buffer[i]); printf("\n"); } return ERR_NONE; } static unsigned char MSID1; GSM_Error DCT3_ReplyEnableSecurity2(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "State of security commands set\n"); MSID1 = msg.Buffer[5]; return ERR_NONE; } void DCT3Info(int argc, char *argv[]) { unsigned char req[] = {0x00, 0x01, 0x8A, 0x00}; /* Get simlock info */ unsigned char req2[] = {0x00, 0x01, 0xb4, 0x00, 0x00}; /* Get MSID */ unsigned char req3[] = {0x00, 0x01, 0xc8, 0x02}; /* Get MCU chksum */ unsigned char req4[] = {0x00, 0x01, 0xc8, 0x09}; /* Get DSP ROM */ if (CheckDCT3Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions3; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); error=GSM_WaitFor (&s, req, 4, 0x40, 4, ID_User3); Print_Error(error); req2[3] = MSID1; req2[4] = req2[2] + req2[3]; error=GSM_WaitFor (&s, req2, 5, 0x40, 4, ID_User8); Print_Error(error); error=GSM_WaitFor (&s, req3, 4, 0x40, 4, ID_User9); Print_Error(error); error=GSM_WaitFor (&s, req4, 4, 0x40, 4, ID_User10); Print_Error(error); } static GSM_Error DCT3_ReplyResetTest36(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Netmonitor test 36 cleaned OK\n"); return ERR_NONE; } void DCT3ResetTest36(int argc, char *argv[]) { unsigned char req[] = {0x00, 0x01, 0x65, 0x40, 0x00}; /* Reset test 36 in netmon */ GSM_Init(true); CheckDCT3(); error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctions3; error=GSM_WaitFor (&s, req, 5, 0x40, 4, ID_User2); Print_Error(error); #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif GSM_Terminate(); } static unsigned char PPS[32]; /* Product Profile Settings */ static GSM_Error DCT3_ReplyGetPPS(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i,j,z; #ifdef DEBUG dbgprintf("Product Profile Settings received -"); for (i=0;i<4;i++) dbgprintf(" %02x",msg.Buffer[3+i]); dbgprintf("\n"); #endif j=128;z=0; for (i=0;i<32;i++) { PPS[i]='0'; if (msg.Buffer[z+3]&j) PPS[i]='1'; if (j==1) { j=128; z++; } else j=j/2; } #ifdef DEBUG dbgprintf("After decoding: "); for (i=0;i<32;i++) dbgprintf("%c",PPS[i]); dbgprintf("\n"); #endif return ERR_NONE; } static GSM_Error DCT3_ReplySetPPS(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Setting done OK\n"); return ERR_NONE; } void DCT3SetPhoneMenus(int argc, char *argv[]) { char value[100]; int i,j,z; unsigned char reqGet[] = {0x00, 0x01, 0x6a}; unsigned char reqSet[] = { 0x00, 0x01, 0x6b, 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */ if (CheckDCT3Only()!=ERR_NONE) return; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctions3; error=GSM_WaitFor (&s, reqGet, 3, 0x40, 4, ID_User4); Print_Error(error); printf("ALS : enabling menu\n"); PPS[10] = '1'; if (!strcmp(s.Phone.Data.ModelInfo->model,"3310") && s.Phone.Data.VerNum>5.87) { printf("3310: enabling control of SMS charsets\n"); PPS[11] = '0';//0 = ON, 1 = OFF } if (!strcmp(s.Phone.Data.ModelInfo->model,"6150")) { printf("6150: enabling WellMate menu\n"); PPS[18] = '1'; } /* FIXME */ if (!strcmp(s.Phone.Data.ModelInfo->model,"3210")) { printf("3210: enabling vibra menu\n"); PPS[24] = '1'; } if (!strcmp(s.Phone.Data.ModelInfo->model,"3310") && s.Phone.Data.VerNum>5.13) { printf("3310: enabling 3315 features\n"); PPS[25] = '1'; } /* FIXME */ if (!strcmp(s.Phone.Data.ModelInfo->model,"3210") && s.Phone.Data.VerNum>=5.31) { printf("3210: enabling React and Logic game\n"); PPS[26] = '1'; } #ifdef DEBUG dbgprintf("After settings: "); for (i=0;i<32;i++) dbgprintf("%c",PPS[i]); dbgprintf("\n"); #endif j=128;z=0; for (i=0;i<32;i++) { if (PPS[i]=='1') reqSet[z+3]=reqSet[z+3]+j; if (j==1) { j=128; z++; } else j=j/2; } // reqSet[3]=0xe7; // reqSet[4]=0x25; // reqSet[5]=0x00; // reqSet[6]=0xe0; error=GSM_WaitFor (&s, reqSet, 7, 0x40, 4, ID_User4); Print_Error(error); printf("Enabling netmonitor\n"); error=DCT3_Netmonitor(&s, 243, value); Print_Error(error); } static GSM_Error DCT3_Reply61GetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Security Code is \"%s\"\n",msg.Buffer+5); return ERR_NONE; } static GSM_Error DCT3_Reply7191GetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Security Code is \"%s\"\n",msg.Buffer+6); return ERR_NONE; } void DCT3GetSecurityCode(int argc, char *argv[]) { #ifdef GSM_ENABLE_NOKIA6110 unsigned char req6110[] = {0x00, 0x01, 0x6e, 0x01}; /* Code type */ #endif #if defined(GSM_ENABLE_NOKIA7110) || defined(GSM_ENABLE_NOKIA9210) unsigned char req71_91[] = {N7110_FRAME_HEADER, 0xee, 0x1c}; /* Setting */ #endif if (CheckDCT3Only()!=ERR_NONE) return; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctions3; #ifdef GSM_ENABLE_NOKIA6110 if (strstr(N6110Phone.models, s.Phone.Data.ModelInfo->model) != NULL) { error=GSM_WaitFor (&s, req6110, 4, 0x40, 4, ID_User6); } #endif #ifdef GSM_ENABLE_NOKIA7110 if (strstr(N7110Phone.models, s.Phone.Data.ModelInfo->model) != NULL) { error=GSM_WaitFor (&s, req71_91, 5, 0x7a, 4, ID_User6); } #endif #ifdef GSM_ENABLE_NOKIA9210 if (strstr(N9210Phone.models, s.Phone.Data.ModelInfo->model) != NULL) { error=GSM_WaitFor (&s, req71_91, 5, 0x7a, 4, ID_User6); } #endif Print_Error(error); } #ifdef GSM_ENABLE_NOKIA6110 static GSM_Error DCT3_ReplyGetOperatorName(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[10]; NOKIA_DecodeNetworkCode(msg.Buffer+5, buffer); buffer[6] = 0; printf("Network : %s (%s ", buffer,DecodeUnicodeString(GSM_GetNetworkName(buffer))); printf(", %s)\n", DecodeUnicodeString(GSM_GetCountryName(buffer))); printf("Name : \"%s\"\n",msg.Buffer+8); return ERR_NONE; } void DCT3GetOperatorName(int argc, char *argv[]) { unsigned char req[] = {0x00,0x01,0x8c,0x00}; GSM_Init(true); if (strstr(N6110Phone.models, s.Phone.Data.ModelInfo->model) == NULL) Print_Error(ERR_NOTSUPPORTED); CheckDCT3(); error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctions3; error=GSM_WaitFor (&s, req, 4, 0x40, 4, ID_User5); Print_Error(error); GSM_Terminate(); } static GSM_Error DCT3_ReplySetOperatorName(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Operator name set OK\n"); return ERR_NONE; } void DCT3SetOperatorName(int argc, char *argv[]) { int i = 0; unsigned char req[256] = {0x00,0x01,0x8b,0x00, 0x00,0x00, /* MCC */ 0x00}; /* MNC */ GSM_Init(true); if (strstr(N6110Phone.models, s.Phone.Data.ModelInfo->model) == NULL) Print_Error(ERR_NOTSUPPORTED); CheckDCT3(); error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctions3; switch (argc) { case 2: case 3: NOKIA_EncodeNetworkCode(req+4,"000 00"); req[7] = 0x00; i = 1; break; case 4: NOKIA_EncodeNetworkCode(req+4,argv[2]); strncpy(req+7,argv[3],200); i = strlen(argv[3]); } error=GSM_WaitFor (&s, req, 8+i, 0x40, 4, ID_User7); Print_Error(error); GSM_Terminate(); } static GSM_Error DCT3_ReplyDisplayOutput(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buf[100]; switch (msg.Buffer[3]) { case 0x50: dbgprintf("Display string received\n"); memcpy(buf,msg.Buffer+8,msg.Buffer[7]*2); buf[msg.Buffer[7]*2] = 0; buf[msg.Buffer[7]*2+1] = 0; printf("X=%i, Y=%i, Text=\"%s\"\n",msg.Buffer[6],msg.Buffer[5],DecodeUnicodeString(buf)); return ERR_NONE; case 0x54: dbgprintf("Display output set\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } void DCT3DisplayOutput(int argc, char *argv[]) { unsigned char req[] = {N6110_FRAME_HEADER, 0x53, 0x01}; //1 = enable, 2 = disable GSM_Init(true); if (strstr(N6110Phone.models, s.Phone.Data.ModelInfo->model) == NULL) Print_Error(ERR_NOTSUPPORTED); CheckDCT3(); s.User.UserReplyFunctions=UserReplyFunctions3; error=GSM_WaitFor (&s, req, 5, 0x0d, 4, ID_User7); Print_Error(error); signal(SIGINT, interrupt); printf("Press Ctrl+C to break...\n"); printf("Entering monitor mode...\n\n"); while (!gshutdown) { GSM_ReadDevice(&s,true); my_sleep(10); } req[4] = 0x02; error=GSM_WaitFor (&s, req, 5, 0x0d, 4, ID_User7); Print_Error(error); GSM_Terminate(); } #endif static GSM_Reply_Function UserReplyFunctions3[] = { #ifdef GSM_ENABLE_NOKIA6110 {DCT3_ReplyDisplayOutput, "\x0D",0x03,0x50,ID_IncomingFrame }, {DCT3_ReplyDisplayOutput, "\x0D",0x03,0x54,ID_User7 }, #endif {DCT3_ReplyEnableSecurity2, "\x40",0x02,0x64,ID_EnableSecurity }, {DCT3_ReplyResetTest36, "\x40",0x02,0x65,ID_User2 }, {DCT3_ReplyGetADC, "\x40",0x02,0x68,ID_User3 }, {DCT3_ReplyGetPPS, "\x40",0x02,0x6A,ID_User4 }, {DCT3_ReplySetPPS, "\x40",0x02,0x6B,ID_User4 }, {DCT3_Reply61GetSecurityCode, "\x40",0x02,0x6E,ID_User6 }, {DCT3_ReplySimlockInfo, "\x40",0x02,0x8A,ID_User3 }, #ifdef GSM_ENABLE_NOKIA6110 {DCT3_ReplySetOperatorName, "\x40",0x02,0x8B,ID_User7 }, {DCT3_ReplyGetOperatorName, "\x40",0x02,0x8C,ID_User5 }, #endif {DCT3_ReplyGetADC, "\x40",0x02,0x91,ID_User3 }, {NoneReply, "\x40",0x02,0xA3,ID_User3 }, {DCT3_ReplyGetT9, "\x40",0x02,0xAE,ID_User3 }, {DCT3_ReplyGetMSID, "\x40",0x02,0xb5,ID_User8 }, {DCT3_ReplyGetDSPROM, "\x40",0x02,0xC8,ID_User10 }, {DCT3_ReplyGetMCUchkSum, "\x40",0x02,0xC8,ID_User9 }, {DCT3_ReplyPhoneTests, "\x40",0x02,0xCF,ID_User1 }, {DCT3_Reply7191GetSecurityCode, "\x7a",0x04,0x1C,ID_User6 }, {NULL, "\x00",0x00,0x00,ID_None } }; #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/gammu/depend/nokia/dct3trac/wmx.c b/gammu/emb/gammu/depend/nokia/dct3trac/wmx.c index 64eda37..e46d9dd 100644 --- a/gammu/emb/gammu/depend/nokia/dct3trac/wmx.c +++ b/gammu/emb/gammu/depend/nokia/dct3trac/wmx.c @@ -1,480 +1,480 @@ /** * Nokia DCT3 Firmware Debug Trace Monitor * wumpus 2003 -- www.blacksphere.tk * SIM stuff by The Monty * * Command line arguments: * gammu --nokiadebug v00-0F,20,21 * (v=verbose) */ #include "../../../../common/gsmstate.h" #ifdef GSM_ENABLE_NOKIA_DCT3 #include <string.h> #include <signal.h> #include "../../../../common/misc/coding/coding.h" #include "../../../../common/gsmcomon.h" #include "../../../../common/gsmstate.h" #include "../../../../common/service/gsmpbk.h" #include "../../../../common/phone/nokia/dct3/dct3func.h" #include "../../../gammu.h" #include "../dct3.h" #include "wmx.h" #include "wmx-util.h" #include "wmx-gsm.h" #include "wmx-sim.h" #include "wmx-list.h" -extern GSM_Reply_Function UserReplyFunctionsX[]; +static GSM_Reply_Function UserReplyFunctionsX[]; /* Global variables suck */ GSMDecoder *gsmdec; struct wmx_tracestruct *traces; static GSM_Error DCT3_ReplySwitchDebug(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch(msg.Buffer[2]) { case 0x70: printf("Debug Trace Enabled\n"); break; case 0x71: printf("Debug Trace Disabled\n"); break; } return ERR_NONE; } /** * RPC confirmation/reply */ static GSM_Error DCT3_ReplyRPC(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("RPC Reply "); printf("call=%02x rettype=%02x data=", msg.Buffer[2], msg.Buffer[3]); if(msg.Buffer[3] == 3) { /* string */ printf("%s", &msg.Buffer[4]); } else { dumpraw("RPC Reply data", &msg.Buffer[4], msg.Length-4); } printf("\n"); return ERR_NONE; } /* disassemble mdisnd (0x18xx) packet */ static void mdisnd_data(unsigned char type, unsigned char *buffer, size_t length) { GSMDecoder_l1l2data dat; size_t x; int ch; if(type==0x1B && length>2) { /* channel packet */ ch = buffer[1]; dat.tx = GSMDECODER_SEND; dat.ch = ch; printf("%02X ch=%02X ",buffer[0],ch); if (ch == 0x80 || ch == 0xB0) { printf("\n"); GSMDecoder_L2packet(gsmdec, &dat, &buffer[2], length-2); } else if (ch == 0x70) { dumpraw("MDI send ch70 prefix", &buffer[2], 2); printf("\n"); GSMDecoder_L2packet(gsmdec, &dat, &buffer[4], length-4); } else { dumpraw("MDI recv 1B packet", &buffer[2], length-2); } } else { /* hex */ for(x=0; x<length; x++) { printf("%02x ",buffer[x]&0xFF); } } } /* disassemble mdircv (0x19xx) packet */ static void mdircv_data(unsigned char type, unsigned char *buffer, size_t length) { size_t x; int ch; GSMDecoder_l1l2data dat; if (type==0x80 && length>1) { // buffer[0] channel // buffer[1] flag1 // buffer[2] flag2 // buffer[3..5] timestamp // buffer[6..7] unknown_hw1 // buffer[8..9] unknown_hw2 ch = buffer[0]; dat.tx = GSMDECODER_RECEIVE; dat.ch = ch; dat.bsic = buffer[1]; dat.err = buffer[2]; dat.seq = (buffer[3]<<16)|(buffer[4]<<8)|(buffer[5]); dat.arfcn = (buffer[6]<<8)|buffer[7]; dat.timeshift = (buffer[8]<<8)|buffer[9]; printf("ch=%02X bsic=%i err=%i t=%06X arfcn=%i shift=%i", ch, buffer[1], buffer[2], dat.seq, dat.arfcn, dat.timeshift ); //dumpraw("MDI recv 80 header", &buffer[6], 4); printf(" "); if(buffer[2] == 0) { /* unencrypted */ if(ch == 0x70) { /* Normal header + 2b prefix */ dumpraw("MDI recv ch70 prefix", &buffer[10], 2); printf("\n"); GSMDecoder_L2packet(gsmdec, &dat, &buffer[12], length-12); } else if (ch == 0x80 || ch == 0xB0) { /* Normal header */ printf("\n"); GSMDecoder_L2packet(gsmdec, &dat, &buffer[10], length-10); } else if (ch == 0x50 || ch == 0x60) { /* Short header */ printf("\n"); GSMDecoder_L2short_packet(gsmdec, &dat, &buffer[10], length-10); } else { dumpraw("MDI send 80 packet", &buffer[10], length-10); } } else { /* Encrypted (?) */ dumpraw("MDI send err 80", &buffer[10], length-10); } } else { /* hex */ for(x=0; x<length; x++) { printf("%02x ",buffer[x]&0xFF); } } } static GSM_Error DCT3_ReplyDebugTrace(GSM_Protocol_Message msg, GSM_StateMachine *s) { int x; int id,timestamp,number,length; struct wmx_tracetype *minor; char *desc; //printf("Debug Trace Received\n"); /* parse frame Debug trace packet: packet type 0x00 source subsystem 0x01 (LOCAL) verder formaat zie notebook 0x08 ID (payload=offset 0x02 here) 0x0A timestamp 0x0C seq nr 0x0D .. parameters */ id = ((msg.Buffer[2]&0xFF)<<8)|(msg.Buffer[3]&0xFF); timestamp = ((msg.Buffer[4]&0xFF)<<8)|(msg.Buffer[5]&0xFF); number = msg.Buffer[6]&0xFF; length = msg.Buffer[7]&0xFF; /* filter */ //if((id&0xFF00)==0x1900 && id != 0x1980) // return GE_NONE; //printf("%02x\n",msg.Buffer[10]); //if(msg.Buffer[10]!=0x40) // return GE_NONE; /* Query trace type name */ desc = "Unknown"; if(traces != NULL) { minor = wmx_tracestruct_queryminor(traces, id); if(minor != NULL) desc = minor->desc; } printf("<%04X> %s\n", id, desc); printf("t=%04x nr=%02x: ", timestamp, number); /* TODO -- decode debug types on phone type */ switch(id>>8) { case 0x33: case 0x34: case 0x35: case 0x37: case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x5F: /* text */ /* skip length byte */ printf("\""); for(x=8; x<msg.Length; x++) { printf("%c",msg.Buffer[x]&0xFF); } printf("\""); break; /* case 0x6801: for(x=8; x<msg.Length; x++) { printf("%02x%c ",msg.Buffer[x]&0xFF,msg.Buffer[x]&0xFF); } break; */ case 0x18: /* MDISND */ /* skip these: +00 length +01 type (also xx in 0x18xx) */ if(msg.Length<10 || msg.Buffer[9]!=(id&0xFF)) { printf("C %02X: param:%02x", id&0xFF, msg.Buffer[8]); } else { //printf("D %02X: ", id&0xFF); printf("D %02X: ", id&0xFF); mdisnd_data((unsigned char)(id&0xFF), (unsigned char*)&msg.Buffer[10], msg.Length-10); } break; case 0x19: /* MDIRCV */ if(msg.Length<10 || msg.Buffer[9]!=(id&0xFF)) { printf("C %02X: param:%02x", id&0xFF, msg.Buffer[8]); } else { printf("D %02X: ", id&0xFF); mdircv_data((unsigned char)(id&0xFF), (unsigned char*)&msg.Buffer[10], msg.Length-10); //dumpraw((unsigned char*)&msg.Buffer[10], msg.Length-10); } break; case 0x20: /* 0x25 SIM commands */ /* for(x=8;x<msg.Length;x++) printf("%02x ", msg.Buffer[x]&0xFF); */ printf("SIM command "); if(msg.Buffer[8]==0xa0) { // check if valid (class=a0) simCommand_data(msg.Buffer[9], (unsigned char)(id&0xFF), (unsigned char*)&msg.Buffer[10], msg.Length-10); // TODO: pass the msg.Buffer[9] and skip 1rst arg } else { printf("Unknown 0x25 packet (NOT SIM cmd): "); for(x=8;x<msg.Length;x++) printf("%02x ", msg.Buffer[x]&0xFF); printf("\n"); } break; case 0x22: /* 0x27 SIM answer to command (error/ok/etc..) */ if(msg.Length<10) { // Unknown response for(x=0;x<msg.Length-10;x++) printf("%02x ", msg.Buffer[x]&0xFF); printf(" (Unknown 0x27 packet ? ? )\n"); } else { simAnswer_Process((unsigned char)(id&0xFF), (unsigned char*)&msg.Buffer[8], length); } break; case 0x23: /* 0x28 SIM response data to commands */ if(msg.Length<10) { // Unknown response for(x=0;x<msg.Length-10;x++) printf("%02x ", msg.Buffer[x]&0xFF); printf(" (Unknown 0x28 packet)\n"); } else { simResponse_Process((unsigned char)(id&0xFF), (unsigned char*)&msg.Buffer[8], length); } break; default: /* hex */ for(x=8; x<msg.Length; x++) { printf("%02x ",msg.Buffer[x]&0xFF); } break; } printf("\n"); return ERR_NONE; } static GSM_Error DCT3_ReplyMyPacket(GSM_Protocol_Message msg, GSM_StateMachine *s) { int x; printf("MyPacket "); for(x=0; x<msg.Length; x++) { printf("%02x ",msg.Buffer[x]&0xFF); } printf("\n"); return ERR_NONE; } #define ID_DebugTrace 0x666 #define ID_DebugSwitch 0x667 #define ID_RPC 0x668 void DCT3SetDebug(int argc, char *argv[]) { int x,count; unsigned int y; unsigned char reqDisable[] = {0x01, 0x01, 0x71}; // unsigned char reqTest[] = {0x01, 0x01, 0x96, 0xFF, 0xFF}; /* RPC testing packets: */ /* RPC: Get version */ //unsigned char reqTest2[] = {0x01, 0x01, 0x00, 0x03, 0x00}; /* RPC: read I/O 0x6D mask 0xFF */ //unsigned char reqTest2[] = {0x01, 0x01, 0x02, 0x01, 0x02, 0x6D, 0xFF}; /* */ /* RPC: write I/O 0x03 mask 0xFF value 0x31 */ //unsigned char reqTest2[] = {0x01, 0x01, 0x01, 0x01, 0x07, 0x03, 0xFF, 0x31}; /* write I/O */ /* RPC: write forged FBUS packet to MDISND */ // unsigned char reqTest2[] = {0x01, 0x01, 0x16, 0x01, 0x06, // 0x14, // R0 -- length // 0x05, // R1 -- MDI type identifier 0x05(FBUS) // 0x1e, 0x0c, 0x00, 0x66, // 0x00, 0x0e, 0x01, 0x01, // 0x66, 0x55, 0x44, 0x33, // 0x0d, 0x01, 0x01, 0x01, // 0x1b, 0x58, 0x01, 0x44}; // 1805 t=cb37 nr=e2 :D 05: /* debug enable packet */ unsigned char reqEnable[] = { 0x00, 0x01, 0x70, /* Debug bits byte[bit>>3]&(1<<(7-(bit&7))) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC0 */ /* Debug verbose bits byte[bit>>3]&(1<<(7-(bit&7))) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; #define ENABLE_BIT(bit,verbose) reqEnable[3 + (bit>>3)] |= 1<<(7-(bit&7)); if(verbose){reqEnable[3 + 32 + (bit>>3)] |= 1<<(7-(bit&7));} /* Enable some bit TODO command line or GUI interface */ //ENABLE_BIT(0x18, 1); /* Enable MDISND debugging */ //ENABLE_BIT(0x19, 1); /* Enable MDIRCV debugging */ //ENABLE_BIT(0x31, 1); gsmdec = GSMDecoder_new(); /* Open XML file .. needs to be argument */ { FILE *xout = fopen("out.xml", "w"); GSMDecoder_xmlout(gsmdec, xout); } printf("Debug Trace Mode -- wumpus 2003\n"); traces = wmx_tracestruct_load(argv[2]); if(traces == NULL) printf("Warning: could not load trace description file %s\n", argv[2]); printf("Activating ranges:\n"); count = 0; for(x=3; x<argc; x++) { char *ptr = argv[x]; unsigned from,to,verbose; while(*ptr) { verbose = 0; if(*ptr == 'v') { verbose = 1; ptr++; } to = from = strtol(ptr, &ptr, 16); if(*ptr == '-') { ptr ++; to = strtol(ptr, &ptr, 16); } if(*ptr != ',' && *ptr != 0) { printf("Invalid parameter '%s'\n", argv[x]); return; } if(*ptr == ',') ptr++; if(from > 0xFF) from=0xFF; if(to > 0xFF) to=0xFF; printf(" %02x-%02x verbose=%i\n",from,to,verbose); for(y=from; y<=to; y++) { ENABLE_BIT(y, verbose); count++; } } } if(count == 0) { printf("Nothing activated -- bailing out\n"); return; } //ENABLE_BIT(0x20, 1); /* SIM commands (literal) */ //ENABLE_BIT(0x21, 1); /* SIML2 commands (literal) */ //ENABLE_BIT(0x22, 1); /* SIM commands (literal) */ //ENABLE_BIT(0x3B, 1); /* PHCTRL state */ GSM_Init(true); /* We Need DCT3 */ if (CheckDCT3Only()!=ERR_NONE) return; error=DCT3_EnableSecurity (&s, 0x01); Print_Error(error); s.User.UserReplyFunctions=UserReplyFunctionsX; //error=GSM_WaitFor (&s, reqTest, sizeof(reqTest), 0x40, 1, ID_DebugSwitch); //error=GSM_WaitFor (&s, reqTest2, sizeof(reqTest2), 0xD1, 4, ID_RPC); /* Enable Debug Mode */ error=GSM_WaitFor (&s, reqEnable, sizeof(reqEnable), 0x40, 4, ID_DebugSwitch); Print_Error(error); signal(SIGINT, interrupt); printf("Press Ctrl+C to interrupt...\n"); x=0; /* while(x<100) { //printf(": %02x\n",x); s.Phone.Data.RequestID = ID_DebugTrace; res = s.Device.Functions->ReadDevice(&s, buff, 255); if(res) { printf("%02x\n",x); for(y=0;y<res;y++) { //printf("%02x\n",x,buff[y]&0xFF); s.Protocol.Functions->StateMachine(&s,buff[y]); x++; } } } */ ; /* todo: wait and dump for some time */ while (!gshutdown) { GSM_ReadDevice(&s,true); my_sleep(10); } signal(SIGINT, SIG_DFL); printf("Disabling\n"); error=GSM_WaitFor (&s, reqDisable, sizeof(reqDisable), 0x40, 10, ID_DebugSwitch); Print_Error(error); GSMDecoder_free(gsmdec); } static GSM_Reply_Function UserReplyFunctionsX[] = { {DCT3_ReplySwitchDebug, "\x40",0x02,0x70,ID_DebugSwitch }, {DCT3_ReplySwitchDebug, "\x40",0x02,0x71,ID_DebugSwitch }, {DCT3_ReplyDebugTrace, "\x00",0x00,0x00,ID_IncomingFrame }, {DCT3_ReplyMyPacket, "\x40",0x00,0x00,ID_IncomingFrame }, {DCT3_ReplyRPC, "\xD2",0x00,0x00,ID_RPC }, {NULL, "\x00",0x00,0x00,ID_None } }; #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/gammu/depend/nokia/dct4.c b/gammu/emb/gammu/depend/nokia/dct4.c index 4bf958d..43d8f09 100644 --- a/gammu/emb/gammu/depend/nokia/dct4.c +++ b/gammu/emb/gammu/depend/nokia/dct4.c @@ -1,1350 +1,1350 @@ /* (c) 2002-2004 by Marcin Wiacek */ #include "../../../common/gsmstate.h" #ifdef GSM_ENABLE_NOKIA_DCT4 #include <string.h> #include "dct4.h" #include "../../gammu.h" #include "../../../common/phone/pfunc.h" #include "../../../common/phone/nokia/nfunc.h" #include "../../../common/phone/nokia/dct4/dct4func.h" #include "../../../common/misc/coding/coding.h" -extern GSM_Reply_Function UserReplyFunctions4[]; +static GSM_Reply_Function UserReplyFunctions4[]; /* ------- some usefull functions ----------------------------------------- */ GSM_Error CheckDCT4Only() { bool found = false; /* Checking if phone is DCT4 */ #ifdef GSM_ENABLE_NOKIA3650 if (strstr(N3650Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif #ifdef GSM_ENABLE_NOKIA6510 if (strstr(N6510Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif #ifdef GSM_ENABLE_NOKIA3320 if (strstr(N3320Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true; #endif if (!found) return ERR_NOTSUPPORTED; if (s.ConnectionType!=GCT_MBUS2 && s.ConnectionType!=GCT_FBUS2 && s.ConnectionType!=GCT_FBUS2DLR3 && s.ConnectionType!=GCT_PHONETBLUE && s.ConnectionType!=GCT_IRDAPHONET && s.ConnectionType!=GCT_BLUEPHONET && s.ConnectionType!=GCT_FBUS2DKU5) { return ERR_OTHERCONNECTIONREQUIRED; } return ERR_NONE; } static void CheckDCT4() { GSM_Error error; error = CheckDCT4Only(); switch (error) { case ERR_NOTSUPPORTED: Print_Error(ERR_NOTSUPPORTED); break; case ERR_OTHERCONNECTIONREQUIRED: printf("Can't do it with current phone protocol\n"); GSM_TerminateConnection(&s); exit(-1); default: break; } } static bool answer_yes2(char *text) { int len; char ans[99]; while (1) { printf("%s (yes/no) ? ",text); len=GetLine(stdin, ans, 99); if (len==-1) exit(-1); if (mystrncasecmp(ans, "yes",0)) return true; if (mystrncasecmp(ans, "no" ,0)) return false; } } /* ------------------- functions ------------------------------------------- */ static DCT4_Feature DCT4Features[] = { {DCT4_ALWAYS_ONLINE, "GPRS Always Online", {{0,"on (Context)"},{1,"off (Attach)"},{0,""}}},///?? {DCT4_GPRS_PCCH, "PCCH support for GPRS", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_GEA1, "GEA1 support indication", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_EOTD, "EOTD support", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_WAP_PUSH, "WAP push", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_USE_PREF_SIM_NET, "Use SIM preffered network list",{{1,"on"},{0,"off"},{0,""}}}, {DCT4_JAVA_TCK, "Java TCK support", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_ALS, "Alternate Line Service (ALS)", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_A52, "Ciphering alghoritm A52", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_CSP, "Customer Service Profile", {{0,"off"},{1,"on"},{0,""}}}, {DCT4_EONS, "EONS support", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_3GINDICATOR, "3G indicator", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_DISPLAY_PHONE_NAME, "Display both number and name for incoming calls",{{1,"on"},{0,"off"},{0,""}}}, {DCT4_DISPLAY_WAP_PROFILE, "Display selected WAP profile name instead of Home option menu in Services",{{1,"on"},{0,"off"},{0,""}}}, {DCT4_GAMES_WAP_DOWNLOAD, "Games WAP download", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_GAMES_SCORE_SEND, "Games WAP score send", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_GAMES_URL_CHECK, "Games URL check", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_BLUETOOTH_MENU, "Bluetooth menu", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_WAP_BOOKMARKS_MENU, "Bookmarks menu in Services", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_WAP_BOOKMARKS_MENU2, "Bookmarks menu in Services", {{3,"bookmarks & download"},{0,"off"},{0,""}}}, {DCT4_WAP_GOTO_MENU, "GoTo menu in Services", {{0,"on"},{1,"off"},{0,""}}}, {DCT4_WAP_SETTINGS_MENU, "Profiles menu in Services", {{0,"on"},{1,"off"},{0,""}}}, {DCT4_SERVICES_GAMES_APP_GALLERY,"Services menu in Games/Apps/Gallery",{{1,"on"},{0,"off"},{0,""}}}, {DCT4_JAVA_GAMES_MENU, "Java games menu in Games", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_SAT_CONFIRM_MENU, "Can use confirming SIM service actions", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_INSTANT_MESS_MENU, "Instant Messaging in Messages",{{1,"on"},{0,"off"},{0,""}}}, {DCT4_CONFIRM_ALS, "Confirm using ALS", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_BOOKMARK_GOTO_MENU, "Bookmarks in GoTo menu", {{1,"on"},{0,"off"},{0,""}}}, {DCT4_5100_IDENTIFY, "Phone identification", {{1,"NPM-6U"},{0,"NPM-6"},{0,""}}}, #ifdef DEBUG {DCT4_TEST,"",{{1,"1"},{0,"0"}}}, #endif {0, "", {{0,""}}} }; static DCT4_Phone_Features DCT4PhoneFeatures[] = { /*3100*/ {"RH-19", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,4},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {DCT4_EONS,28},{DCT4_3GINDICATOR,30},{DCT4_INSTANT_MESS_MENU,33}, {DCT4_CONFIRM_ALS,35}, {0,0}}}, /*3200*/ {"RH-30", {{DCT4_ALS,2},{DCT4_A52,4},{DCT4_CSP,5},{DCT4_GPRS_PCCH,14}, {DCT4_GEA1,15},{DCT4_EOTD,18},{DCT4_WAP_SETTINGS_MENU,20}, {DCT4_DISPLAY_PHONE_NAME,21},{DCT4_WAP_GOTO_MENU,23}, {DCT4_SERVICES_GAMES_APP_GALLERY,26},{DCT4_3GINDICATOR,28}, {DCT4_DISPLAY_WAP_PROFILE,31},{DCT4_SAT_CONFIRM_MENU,33}, {DCT4_CONFIRM_ALS,34},{DCT4_EONS,40},{DCT4_ALWAYS_ONLINE,45}, {0,0}}}, /*3200*/ {"RH-31", {{DCT4_ALS,2},{DCT4_A52,4},{DCT4_CSP,5},{DCT4_GPRS_PCCH,14}, {DCT4_GEA1,15},{DCT4_EOTD,18},{DCT4_WAP_SETTINGS_MENU,20}, {DCT4_DISPLAY_PHONE_NAME,21},{DCT4_WAP_GOTO_MENU,23}, {DCT4_SERVICES_GAMES_APP_GALLERY,26},{DCT4_3GINDICATOR,28}, {DCT4_DISPLAY_WAP_PROFILE,31},{DCT4_SAT_CONFIRM_MENU,33}, {DCT4_CONFIRM_ALS,34},{DCT4_EONS,40},{DCT4_ALWAYS_ONLINE,45}, {0,0}}}, /*3300*/ {"NEM-1", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, /*MORE*/ {0,0}}}, /*3510*/ {"NHM-8", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6}, {DCT4_GAMES_WAP_DOWNLOAD,7},{DCT4_GAMES_SCORE_SEND,8}, {DCT4_GAMES_URL_CHECK,9},{DCT4_GPRS_PCCH,13}, {DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}}, /*3510i*/{"RH-9", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,4},{DCT4_GPRS_PCCH,9}, {DCT4_DISPLAY_PHONE_NAME,14},{DCT4_WAP_GOTO_MENU,15}, {DCT4_WAP_SETTINGS_MENU,16},{DCT4_SERVICES_GAMES_APP_GALLERY,19}, {DCT4_DISPLAY_WAP_PROFILE,25},{0,0}}}, /*3650*/ {"NHL-8", {{DCT4_ALS,1},{0,0}}}, /*5100*/ {"NPM-6", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {DCT4_EONS,28}, // {DCT4_5100_IDENTIFY,10}, {0,0}}}, /*5100*/ {"NPM-6U", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {DCT4_EONS,28}, // {DCT4_5100_IDENTIFY,10}, {0,0}}}, /*6100*/ {"NPL-2", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {0,0}}}, /*6220*/ {"RH-20", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,4}, {DCT4_GEA1,14},{DCT4_EOTD,17},{DCT4_WAP_SETTINGS_MENU,19}, {DCT4_DISPLAY_PHONE_NAME,20},{DCT4_WAP_GOTO_MENU,22}, {DCT4_WAP_BOOKMARKS_MENU2,24},{DCT4_SERVICES_GAMES_APP_GALLERY,25}, {DCT4_3GINDICATOR,27},{DCT4_DISPLAY_WAP_PROFILE,30},{DCT4_SAT_CONFIRM_MENU,32}, {DCT4_CONFIRM_ALS,33},{DCT4_JAVA_TCK,36},{DCT4_BOOKMARK_GOTO_MENU,37}, {0,0}}}, /*6310*/ {"NPE-4", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7}, {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},{DCT4_BLUETOOTH_MENU,10}, {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}}, /*6310i*/{"NPL-1", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7}, {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9}, {DCT4_BLUETOOTH_MENU,10},{DCT4_USE_PREF_SIM_NET,11}, {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_EOTD,16}, {DCT4_ALWAYS_ONLINE,17},{DCT4_JAVA_GAMES_MENU,18}, {DCT4_WAP_BOOKMARKS_MENU,20},{DCT4_WAP_SETTINGS_MENU,21}, {DCT4_WAP_PUSH,28},{DCT4_WAP_GOTO_MENU,29},{0,0}}}, /*6510*/ {"NPM-9", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7}, {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9}, {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}}, /*6610*/ {"NHL-4U", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {0,0}}}, /*6800*/ {"NHL-6", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, /*MORE*/ {0,0}}}, /*7210*/ {"NHL-4", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {0,0}}}, /*7250*/ {"NHL-4J", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, {0,0}}}, /*7250i*/{"NHL-4JX", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8}, {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12}, {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18}, {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22}, {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27}, /*MORE*/ {0,0}}}, /*8310*/{"NHM-7", {{DCT4_ALS,1},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7}, {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},{DCT4_GPRS_PCCH,13}, {DCT4_ALWAYS_ONLINE,18},{0,0}}}, {"", {{0,0}}} }; static GSM_Error DCT4_ReplySetPPS(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("Setting done OK\n"); return ERR_NONE; } void DCT4SetPhoneMenus(int argc, char *argv[]) { int current = 10,i=0,j,z; unsigned char reqSet[200] = { N7110_FRAME_HEADER,0x04,0x00,0x01,0x47,0x48,0x02, 0x00}; /* Number of changed features */ if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; while (DCT4PhoneFeatures[i].Model[0] != 0x00) { if (!strcmp(DCT4PhoneFeatures[i].Model,s.Phone.Data.Model)) { j = 0; while (DCT4PhoneFeatures[i].Features[j].Name != 0x00) { z = 0; while (DCT4Features[z].Name != 0x00) { if (DCT4Features[z].Name == DCT4PhoneFeatures[i].Features[j].Name) { printf("%s : %s\n",DCT4Features[z].Text,DCT4Features[z].Values[0].Text); reqSet[9]++; /* Number of features */ reqSet[current++] = DCT4PhoneFeatures[i].Features[j].Number; /* Feature number */ reqSet[current++] = DCT4Features[z].Values[0].Value; /* Value */ break; } z++; } j++; } } i++; } if (current == 10) { printf("Sorry, but configuration matrix for this model is not added yet. Please report\n"); return; } reqSet[current++] = 0x00; reqSet[current++] = 0x00; error=GSM_WaitFor (&s, reqSet, current, 0x1b, 4, ID_User1); Print_Error(error); } DCT4_Phone_Tests DCT4Tests; static GSM_Error DCT4_ReplyTestsNames(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i,pos; DCT4Tests.Num = msg.Buffer[5]; pos = 6; smprintf(s,"%i names for phone tests received\n",msg.Buffer[5]); for (i=0;i<msg.Buffer[5];i++) { strcpy(DCT4Tests.Tests[i].Name,msg.Buffer+pos+4); DCT4Tests.Tests[i].ID = msg.Buffer[pos+2]; smprintf(s,"%x.\"%s\"\n",DCT4Tests.Tests[i].ID,DCT4Tests.Tests[i].Name); pos+=msg.Buffer[pos+1]; } return ERR_NONE; } static GSM_Error DCT4_ReplyTestsStartup(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i,pos,j; bool found; pos = 10; for (i=0;i<msg.Buffer[8];i++) { found = false; for (j=0;j<DCT4Tests.Num;j++) { if (DCT4Tests.Tests[j].ID == msg.Buffer[pos]) { DCT4Tests.Tests[j].Startup = true; found = true; break; } } if (!found) printf("%x ",msg.Buffer[pos]); pos++; } return ERR_NONE; } static GSM_Error DCT4_ReplyTestsStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i,pos,j; pos = 6; smprintf(s,"%i status entries for phone tests received\n",msg.Buffer[5]); for (i=0;i<msg.Buffer[5];i++) { for (j=0;j<DCT4Tests.Num;j++) { if (DCT4Tests.Tests[j].ID == msg.Buffer[pos+2]) { printf("\"%40s\" : ",DCT4Tests.Tests[j].Name); switch(msg.Buffer[pos+3]) { case 0x00: printf("Passed"); break; case 0x01: printf("Fail"); break; case 0x03: printf("Not executed"); break; case 0x06: printf("No signal"); break; case 0x0D: printf("Timeout"); break; default : printf("Unknown (%x)",msg.Buffer[pos+3]); } if (DCT4Tests.Tests[j].Startup) printf(" (startup)"); printf("\n"); break; } } pos+=msg.Buffer[pos+1]; } return ERR_NONE; } void DCT4SelfTests(int argc, char *argv[]) { int j; unsigned char GetDoneST[6] = {0x00, 0x08, 0x01, 0x04, 0x01, 0x00}; unsigned char GetDoneST2[6] = {0x00, 0x08, 0x02, 0x04, 0x02, 0x00}; unsigned char GetNames[6] = {0x00, 0x08, 0x03, 0x06, 0x03, 0x00}; unsigned char GetStatus[6] = {0x00, 0x08, 0x04, 0x02, 0x03, 0x00}; unsigned char RunALL[6] = {0x00, 0x06, 0x04, 0x00, 0x03, 0x00}; // unsigned char GetID[6] = {0x00, 0x08, 0x00, 0x04, 0x03, 0x00};//tests ID if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; if (answer_yes2("Run all tests now ?")) { error=GSM_WaitFor (&s, RunALL, 6, 0x35, 4, ID_User1); Print_Error(error); } error=GSM_WaitFor (&s, GetNames, 6, 0x35, 4, ID_User1); Print_Error(error); for (j=0;j<DCT4Tests.Num;j++) DCT4Tests.Tests[j].Startup = false; error=GSM_WaitFor (&s, GetDoneST, 6, 0x35, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, GetDoneST2, 6, 0x35, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, GetStatus, 6, 0x35, 4, ID_User2); Print_Error(error); } static GSM_Error DCT4_ReplyVibra(GSM_Protocol_Message msg, GSM_StateMachine *s) { #ifdef DEBUG switch (msg.Buffer[3]) { case 0x0D : dbgprintf("Vibra state set OK\n"); break; case 0x0F : dbgprintf("Vibra power set OK\n"); break; } #endif return ERR_NONE; } static GSM_Error DCT4EnableVibra(GSM_StateMachine *s, bool enable) { /* Enables or disables vibra */ unsigned char Control[6] = {N7110_FRAME_HEADER,0x0C, 0x01, /* 0x01 = On, 0x00 = Off */ 0x00}; if (!enable) Control[4] = 0x00; return GSM_WaitFor (s, Control, 6, 0x1C, 4, ID_User3); } void DCT4SetVibraLevel(int argc, char *argv[]) { GSM_DateTime Date; unsigned int i,j; /* Set vibra level */ unsigned char SetLevel[6] = {N7110_FRAME_HEADER,0x0E, 0x64, /* Vibra power (in percent) */ 0x00}; GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; SetLevel[4] = atoi(argv[2]); error=GSM_WaitFor (&s, SetLevel, 6, 0x1C, 4, ID_User3); Print_Error(error); error=DCT4EnableVibra(&s, true); Print_Error(error); for (i=0;i<3;i++) { GSM_GetCurrentDateTime (&Date); j=Date.Second; while (j==Date.Second) { my_sleep(10); GSM_GetCurrentDateTime(&Date); } } error=DCT4EnableVibra(&s, false); Print_Error(error); GSM_Terminate(); } void DCT4VibraTest(int argc, char *argv[]) { unsigned char ans[200]; if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; error=DCT4EnableVibra(&s, true); Print_Error(error); printf("Press any key to continue...\n"); GetLine(stdin, ans, 99); error=DCT4EnableVibra(&s, false); Print_Error(error); } #ifdef DEBUG static GSM_Error DCT4_ReplyResetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x05: printf("Security code set to \"12345\"\n"); return ERR_NONE; case 0x06: printf("Unknown reason. Can't reset your security code\n"); return ERR_UNKNOWN; } return ERR_UNKNOWNRESPONSE; } void DCT4ResetSecurityCode(int argc, char *argv[]) { unsigned int i; unsigned char ResetCode[30] = {0x00,0x06,0x03,0x04,0x01, '1','2','3','4','5','6','7','8','9','0', /* Old code */ 0x00, '1','2','3','4','5',0x00,0x00,0x00,0x00,0x00, /* New code */ 0x00}; if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; error=GSM_WaitFor (&s, ResetCode, 27, 0x08, 4, ID_User2); if (error == ERR_UNKNOWN) { if (answer_yes2("Try brutal force ?")) { for (i=10000;i<9999999;i++) { printf("Trying %i\n",i); memset(ResetCode+6,0,22); sprintf(ResetCode+5,"%i",i); sprintf(ResetCode+16,"12345"); error=GSM_WaitFor (&s, ResetCode, 27, 0x08, 4, ID_User2); if (error == ERR_NONE) break; } } } else Print_Error(error); } #endif char SecLength; static GSM_Error DCT4_ReplyGetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Length > 12) { SecLength = msg.Buffer[13]; if ((msg.Buffer[17]+18) == msg.Length) { printf("Security code is %s\n",msg.Buffer+18); // DumpMessage(stdout, msg.Buffer, msg.Length); } } return ERR_NONE; } void DCT4GetSecurityCode(int argc, char *argv[]) { GSM_Error error; unsigned char getlen[]={0x00, 0x08, 0x01, 0x0C, 0x00, 0x23, //ID 0x00, 0x00, //Index 0x00, 0x00}; unsigned char read[]={0x00, 0x08, 0x02, 0x04, 0x00, 0x23, //ID 0x00, 0x00, //Index 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //Length if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; SecLength = 0; error=GSM_WaitFor (&s, getlen, sizeof(getlen), 0x23, 1, ID_User1); Print_Error(error); if (SecLength != 0) { read[17] = SecLength; error=GSM_WaitFor (&s, read, sizeof(read), 0x23, 5, ID_User1); Print_Error(error); } } static GSM_Error DCT4_ReplyGetVoiceRecord(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i=18,j; unsigned char Buffer[100]; switch (msg.Buffer[3]) { case 0x05: dbgprintf("Part of voice record received\n"); if (msg.Length == 6) { dbgprintf("Empty\n"); return ERR_EMPTY; } *s->Phone.Data.VoiceRecord = 0; while (i<msg.Length) { s->Phone.Data.PhoneString[(*s->Phone.Data.VoiceRecord)++] = msg.Buffer[i+1]; s->Phone.Data.PhoneString[(*s->Phone.Data.VoiceRecord)++] = msg.Buffer[i]; i += 2; } return ERR_NONE; case 0x0D: dbgprintf("Last part of voice record is %02x %02x\n",msg.Buffer[11],msg.Buffer[12]); dbgprintf("Token is %02x\n",msg.Buffer[13]); s->Phone.Data.PhoneString[0] = msg.Buffer[11]; s->Phone.Data.PhoneString[1] = msg.Buffer[12]; s->Phone.Data.PhoneString[2] = msg.Buffer[13]; return ERR_NONE; break; case 0x31: dbgprintf("Names of voice records received\n"); j = 33; for (i=0;i<msg.Buffer[9];i++) { memcpy(Buffer,msg.Buffer+(j+1),msg.Buffer[j]); Buffer[msg.Buffer[j]] = 0; Buffer[msg.Buffer[j]+1] = 0; dbgprintf("%i. \"%s\"\n",i+1,DecodeUnicodeString(Buffer)); if (i==*s->Phone.Data.VoiceRecord) { sprintf(s->Phone.Data.PhoneString,"%s.wav",DecodeUnicodeString(Buffer)); return ERR_NONE; } if (i != msg.Buffer[9] - 1) { j+=msg.Buffer[j] + 1; if (msg.Buffer[j] == 0x00 && msg.Buffer[j+1]==0x00) j+=2; j+=23; } } return ERR_EMPTY; } return ERR_UNKNOWNRESPONSE; } void DCT4GetVoiceRecord(int argc, char *argv[]) { /* Voice records names */ unsigned char ReqNames[200] = { N7110_FRAME_HEADER, 0x30,0x01,0x55,0x00,0x00,0xFF,0xFF,0x01,0x01,0x55,0x55}; /* Voice record token */ unsigned char ReqToken[200] = { N7110_FRAME_HEADER,0x0C,0x00,0x44,0x00, 0x00, /* Location: 0, 1, ... */ 0x55,0x55}; /* Voice record part */ unsigned char ReqGet[200] = { N7110_FRAME_HEADER,0x04,0x00,0x44, 0x00,0x00, /* Location: 0, 1, ... */ 0x55,0x55,0x00, 0x00,0x00, /* Part Location */ 0x00,0x00,0x00, 0x04, /* ??? */ 0x00}; /* Token */ /* WAV file headers */ unsigned char WAV_Header[] = { 'R','I','F','F', 0x00,0x00,0x00,0x00, /* Length */ 'W','A','V','E'}; unsigned char FMT_Header[] = {'f','m','t',' ', 0x14,0x00,0x00,0x00,0x31,0x00,0x01,0x00,0x40,0x1f, 0x00,0x00,0x59,0x06,0x00,0x00,0x41,0x00,0x00,0x00, 0x02,0x00,0x40,0x01,'f', 'a', 'c', 't', 0x04,0x00, 0x00,0x00, 0x00,0x73,0x00,0x00}; /* Seems to be some length */ unsigned char DATA_Header[] = { 'd','a','t','a', 0x00,0x00,0x00,0x00}; /* Length */ long wavfilesize=0; unsigned char FileName[100], Buffer[10000], Token; unsigned int Location, size=0, CurrentLocation = 0, TokenLocation; int i; FILE *WAVFile; Location = atoi(argv[2]); if (Location == 0x00) { printf("Please numerate locations from 1\n"); return; } Location--; GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; s.Phone.Data.VoiceRecord = &Location; s.Phone.Data.PhoneString = FileName; dbgprintf("Getting voice record name\n"); error=GSM_WaitFor (&s, ReqNames, 14, 0x4A, 4, ID_User4); Print_Error(error); s.Phone.Data.PhoneString = Buffer; ReqToken[7] = Location; dbgprintf("Getting voice record token\n"); error=GSM_WaitFor (&s, ReqToken, 10, 0x23, 4, ID_User4); Print_Error(error); TokenLocation = Buffer[0] * 256 + Buffer[1]; Token = Buffer[2]; WAVFile = fopen(FileName, "wb"); fwrite(&WAV_Header, 1, sizeof(WAV_Header), WAVFile); fwrite(&FMT_Header, 1, sizeof(FMT_Header), WAVFile); fwrite(&DATA_Header, 1, sizeof(DATA_Header), WAVFile); s.Phone.Data.VoiceRecord = &size; s.Phone.Data.PhoneString = Buffer; ReqGet[7] = Location; fprintf(stderr,"Getting voice record and saving to \"%s\": ",FileName); while (1) { dbgprintf("Getting next part of voice record\n"); fprintf(stderr,"."); error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4); if (error == ERR_NONE) { wavfilesize += size; fwrite(Buffer,1,size,WAVFile); } if (error == ERR_EMPTY) break; Print_Error(error); CurrentLocation += 4; ReqGet[11] = CurrentLocation / 256; ReqGet[12] = CurrentLocation % 256; if (CurrentLocation+4 > TokenLocation) break; } dbgprintf("Getting first part in last sequence of voice record\n"); for (i=255;i>=0;i--) { ReqGet[16] = i; ReqGet[17] = Token; fprintf(stderr,"."); error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4); if (error == ERR_NONE) { wavfilesize += size; fwrite(Buffer,1,size,WAVFile); break; } if (error != ERR_EMPTY) Print_Error(error); } while (1) { dbgprintf("Getting next part of last sequence in voice record\n"); CurrentLocation += 4; ReqGet[11] = CurrentLocation / 256; ReqGet[12] = CurrentLocation % 256; fprintf(stderr,"."); error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4); if (error == ERR_NONE) { wavfilesize += size; fwrite(Buffer,1,size,WAVFile); } if (error == ERR_EMPTY) break; Print_Error(error); } fprintf(stderr,"\n"); wavfilesize += sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header); 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)); /* FIXME */ FMT_Header[36] = (unsigned char)(((wavfilesize - 238) * 5 ) % 256); FMT_Header[37] = (unsigned char)(((wavfilesize - 238) * 5 ) / 256); FMT_Header[38] = (unsigned char)(((wavfilesize - 238) * 5 ) / (256*256)); FMT_Header[39] = (unsigned char)(((wavfilesize - 238) * 5 ) / (256*256*256)); wavfilesize = wavfilesize - 54 - 6; 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( WAVFile, 0, SEEK_SET); fwrite(&WAV_Header, 1, sizeof(WAV_Header), WAVFile); fwrite(&FMT_Header, 1, sizeof(FMT_Header), WAVFile); fwrite(&DATA_Header, 1, sizeof(DATA_Header), WAVFile); fclose(WAVFile); GSM_Terminate(); } static GSM_Error DCT4_ReplyGetBTInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { printf("device address %02x%02x%02x%02x%02x%02x\n", msg.Buffer[9],msg.Buffer[10],msg.Buffer[11], msg.Buffer[12],msg.Buffer[13],msg.Buffer[14]); return ERR_NONE; } static GSM_Error DCT4_ReplyGetSimlock(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; switch (msg.Buffer[3]) { case 0x0D: dbgprintf("Simlock info received\n"); dbgprintf("Config_Data: "); for (i=14;i<22;i++) { dbgprintf("%02x",msg.Buffer[i]); } dbgprintf("\n"); dbgprintf("Profile_Bits: "); for (i=22;i<30;i++) { dbgprintf("%02x",msg.Buffer[i]); } dbgprintf("\n"); return ERR_NONE; case 0x13: dbgprintf("Simlock info received\n"); if (msg.Buffer[58] == 0x05 && msg.Buffer[59] == 0x02) { dbgprintf("SIM_PATH: "); for (i=44;i<52;i++) { dbgprintf("%02x",msg.Buffer[i]); } dbgprintf("\n"); printf("Simlock data : "); for (i=60;i<63;i++) { printf("%02x",msg.Buffer[i]); } printf("\n"); } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } void DCT4Info(int argc, char *argv[]) { unsigned char GetBTAddress[8] = {N6110_FRAME_HEADER, 0x09, 0x19, 0x01, 0x03, 0x06}; unsigned char GetSimlock[5] = {N6110_FRAME_HEADER, 0x12, 0x0D}; unsigned char value[10]; if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; if (IsPhoneFeatureAvailable(s.Phone.Data.ModelInfo, F_BLUETOOTH)) { printf("Bluetooth : "); error=GSM_WaitFor (&s, GetBTAddress, 8, 0xD7, 4, ID_User6); Print_Error(error); } error=GSM_WaitFor (&s, GetSimlock, 5, 0x53, 4, ID_User6); Print_Error(error); GetSimlock[4] = 0x0E; error=GSM_WaitFor (&s, GetSimlock, 5, 0x53, 4, ID_User6); Print_Error(error); GetSimlock[3] = 0x0C; error=GSM_WaitFor (&s, GetSimlock, 4, 0x53, 4, ID_User6); Print_Error(error); error=NOKIA_GetPhoneString(&s,"\x00\x03\x02\x07\x00\x08",6,0x1b,value,ID_User6,10); Print_Error(error); printf("UEM : %s\n",value); } static FILE *T9File; int T9Size; int T9FullSize; static GSM_Error DCT4_ReplyGetT9(GSM_Protocol_Message msg, GSM_StateMachine *s) { T9FullSize = msg.Buffer[18] * 256 + msg.Buffer[19]; T9Size = msg.Length - 18; fwrite(msg.Buffer+18,1,T9Size,T9File); return ERR_NONE; } void DCT4GetT9(int argc, char *argv[]) { int i,T9Dictionary=0; unsigned char req[] = {N7110_FRAME_HEADER, 0x04, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Start position */ 0x00, 0x00, 0x02, 0xBC}; /* How many bytes to read */ if (CheckDCT4Only()!=ERR_NONE) return; T9File = fopen("T9", "w"); if (T9File == NULL) return; s.User.UserReplyFunctions=UserReplyFunctions4; i = 0; while (1) { req[12] = i / 256; req[13] = i % 256; if (i != 0) { if (T9Dictionary - i < req[16]*256+req[17]) { req[16] = (T9Dictionary - i) / 256; req[17] = (T9Dictionary - i) % 256; } if (T9Dictionary - i == 0) break; } error=GSM_WaitFor (&s, req, 18, 0x23, 4, ID_User3); Print_Error(error); if (i==0) { T9Dictionary = T9FullSize; dbgprintf("T9 dictionary size is %i\n",T9Dictionary); } i+=T9Size; } fclose(T9File); } #ifdef GSM_ENABLE_NOKIA6510 extern GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, bool enable); void DCT4SetLight(int argc, char *argv[]) { int i; N6510_PHONE_LIGHTS type; bool enable; if (mystrncasecmp(argv[2],"display",0)) { type = N6510_LIGHT_DISPLAY; } else if (mystrncasecmp(argv[2],"keypad",0)) { type = N6510_LIGHT_KEYPAD; } else if (mystrncasecmp(argv[2],"torch",0)) { type = N6510_LIGHT_TORCH; } else { printf("What lights should I enable (\"%s\") ?\n",argv[2]); exit(-1); } if (mystrncasecmp(argv[3],"on",0)) { enable = true; } else if (mystrncasecmp(argv[3],"off",0)) { enable = false; } else { printf("What should I do (\"%s\") ?\n",argv[3]); exit(-1); } for (i=0;i<s.ConfigNum;i++) { s.Config[i].StartInfo = "false"; } GSM_Init(true); CheckDCT4(); error=N6510_SetLight(&s, type, enable); Print_Error(error); GSM_Terminate(); } #endif void DCT4DisplayTest(int argc, char *argv[]) { unsigned char ans[200]; unsigned char req0[] = {0x00, 0x08, 0x0D, 0x00, 0x0F, 0x00}; unsigned char req[] = {0x00, 0x08, 0x0E, 0x00, 0x12, 0x01, 0x00, 0x04, 0x09, /* test number */ 0x00}; if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; DCT4_SetPhoneMode(&s, DCT4_MODE_TEST); s.Protocol.Functions->WriteMessage(&s, req0, 6, 0x40); req[8] = atoi(argv[2]); s.Protocol.Functions->WriteMessage(&s, req, 10, 0x40); printf("Press any key to continue...\n"); GetLine(stdin, ans, 99); DCT4_SetPhoneMode(&s, DCT4_MODE_NORMAL); } int ADC; static GSM_Error DCT4_ReplyGetADC(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[6] == 0xff && msg.Buffer[7] == 0xff) return ERR_NONE; switch (msg.Buffer[3]) { case 0x10: printf("raw "); printf("%10i ",msg.Buffer[8]*256+msg.Buffer[9]); break; case 0x12: printf("unit result "); printf("%10i ",(msg.Buffer[8]*256+msg.Buffer[9])*ADC); break; } return ERR_NONE; } struct DCT4ADCInfo { char *name; char *unit; int x; }; static struct DCT4ADCInfo DCT4ADC[] = { {"Battery voltage, divided:", "mV", 1}, {"Battery voltage, scaled:", "mV", 1}, {"Charger voltage:", "mV", 1}, {"Charger current:", "mA", 1}, {"Battery size indicator:", "Ohms",100}, {"Battery temperature:", "K", 1}, {"Headset interconnection:", "mV", 1}, {"Hook interconnection:", "mV", 1}, {"Light sensor:", "mV", 1}, {"Power amplifier temperature:", "K", 1}, {"VCXO temperature:", "K", 1}, {"Resistive keyboard 1/headint2:", "mV", 1}, {"Resistive keyboard 1/auxdet:", "mV", 1}, {"Initial battery voltage:", "mV", 1}, {"Battery Current:", "mA", 1}, {"Battery Current Fast:", "mA", 1}, {"", "", 1} }; void DCT4GetADC(int argc, char *argv[]) { int i = 0; unsigned char GetRaw[] = {N6110_FRAME_HEADER, 0x0F, 0x00, /* Test number */ 0x01}; unsigned char GetUnit[] = {N6110_FRAME_HEADER, 0x11, 0x00, /* Test number */ 0x01}; if (CheckDCT4Only()!=ERR_NONE) return; s.User.UserReplyFunctions=UserReplyFunctions4; while (1) { printf(" %30s ",DCT4ADC[i].name); GetRaw[4] = i; error=GSM_WaitFor (&s, GetRaw, 6, 0x17, 4, ID_User3); Print_Error(error); GetUnit[4] = i; ADC = DCT4ADC[i].x; error=GSM_WaitFor (&s, GetUnit, 6, 0x17, 4, ID_User3); Print_Error(error); printf("%s\n",DCT4ADC[i].unit); i++; if (DCT4ADC[i].name[0] == 0x00) break; } } #ifdef GSM_ENABLE_NOKIA6510 static double RadioFreq; static unsigned char RadioName[100]; static GSM_Error DCT4_ReplyTuneRadio(GSM_Protocol_Message msg, GSM_StateMachine *s) { int length; unsigned char name[100]; switch (msg.Buffer[3]) { case 0x09: N6510_DecodeFMFrequency(&RadioFreq, msg.Buffer+16); length = msg.Buffer[8]; memcpy(name,msg.Buffer+18,length*2); name[length*2] = 0x00; name[length*2+1] = 0x00; CopyUnicodeString(RadioName,name); smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(RadioName)); return ERR_NONE; case 0x15: case 0x16: smprintf(s,"Response for enabling radio/headset status received\n"); if (msg.Buffer[5] == 0) { smprintf(s,"Connected\n"); return ERR_NONE; } smprintf(s,"Probably not connected\n"); return ERR_PERMISSION; } return ERR_UNKNOWNRESPONSE; } void DCT4TuneRadio(int argc, char *argv[]) { double Freq, diff; GSM_FMStation FMStation[50],FMStat; int i, j, num; bool found; unsigned char Enable[] = {N6110_FRAME_HEADER, 0x00, 0x00, 0x00}; unsigned char Disable[] = {N6110_FRAME_HEADER, 0x01, 0x0E, 0x00}; // unsigned char SetVolume[] = {N6110_FRAME_HEADER, 0x14, // 0x00, /* Volume level */ // 0x00}; // unsigned char MuteUnMute[] = {N6110_FRAME_HEADER, 0x0F, // 0x0C, /* 0x0B = mute, 0x0C = unmute */ // 0x00}; unsigned char SetFreq[] = {N6110_FRAME_HEADER, 0x08, 0x08, 0x14, 0x00, 0x01, 0x9A, 0x28}; /* Frequency */ // unsigned char Find1[] = {N6110_FRAME_HEADER, 0x08, // 0x04, 0x14, 0x00, 0x00, 0x00, 0x00}; unsigned char Find2[] = {N6110_FRAME_HEADER, 0x08, 0x05, 0x14, 0x00, 0x00, 0x00, 0x00}; // unsigned char SetStereo[] = {N6110_FRAME_HEADER, 0x19, // 0x0A, 0x00, 0x15}; // unsigned char SetMono[] = {N6110_FRAME_HEADER, 0x19, // 0x09, 0x00, 0x96}; GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; FMStat.Location = 1; error = Phone->GetFMStation(&s,&FMStat); if (error != ERR_NONE && error != ERR_EMPTY) { printf("Phone seems not to support radio\n"); GSM_Terminate(); exit(-1); } error=GSM_WaitFor (&s, Enable, 6, 0x3E, 4, ID_User3); if (error == ERR_PERMISSION) { printf("Please connect headset. Required as antenna\n"); GSM_Terminate(); exit(-1); } Print_Error(error); num=0; for (i=88;i<108;i++) { fprintf(stderr,"%cSearching: %i percent",13,(i-88)*100/(108-88)); Freq = i; N6510_EncodeFMFrequency(Freq, SetFreq+8); error=GSM_WaitFor (&s, SetFreq, 10, 0x3E, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, Find2, 10, 0x3E, 4, ID_User3); Print_Error(error); found = false; for (j=0;j<num;j++) { if (FMStation[j].Frequency > RadioFreq) { diff = FMStation[j].Frequency - RadioFreq; } else { diff = RadioFreq - FMStation[j].Frequency; } if (diff <= 0.2) { dbgprintf("diff is %f\n",diff); found = true; break; } } if (!found) { dbgprintf("Adding %f, num %i\n",RadioFreq,num); FMStation[num].Frequency = RadioFreq; CopyUnicodeString(FMStation[num].StationName,RadioName); num++; } } fprintf(stderr,"%cSearching: %i percent",13,100); fprintf(stderr,"\n\n"); i=0; while(1) { if (i==num || i==num-1) break; if (FMStation[i].Frequency > FMStation[i+1].Frequency) { memcpy(&FMStat,&FMStation[i],sizeof(GSM_FMStation)); memcpy(&FMStation[i],&FMStation[i+1],sizeof(GSM_FMStation)); memcpy(&FMStation[i+1],&FMStat,sizeof(GSM_FMStation)); i = 0; continue; } i++; } for (i=0;i<num;i++) { fprintf(stderr,"%02i.",i+1); if (FMStation[i].Frequency < 100) fprintf(stderr," "); fprintf(stderr,"%.1f MHz - \"%s\" \n", FMStation[i].Frequency, DecodeUnicodeString(FMStation[i].StationName)); } if (answer_yes2("Do you want to save found stations")) { fprintf(stderr,"Deleting old FM stations: "); error=Phone->ClearFMStations(&s); Print_Error(error); fprintf(stderr,"Done\n"); for (i=0;i<num;i++) { FMStation[i].Location = i+1; error=Phone->SetFMStation(&s,&FMStation[i]); Print_Error(error); fprintf(stderr,"%cWriting: %i percent",13,(i+1)*100/num); } fprintf(stderr,"\n"); } error=GSM_WaitFor (&s, Disable, 6, 0x3E, 4, ID_User3); Print_Error(error); GSM_Terminate(); } #endif void DCT4PlaySavedRingtone(int argc, char *argv[]) { unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00,0x64, //id 0x01, //group 0x01,0x00,0x00, 0x0A, //volume 0x00,0x00,0x00,0x00,0x00,0x00,0x00}; GSM_AllRingtonesInfo Info; GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; error=Phone->GetRingtonesInfo(&s,&Info); Print_Error(error); if (atoi(argv[2]) > Info.Number-1) { GSM_Terminate(); return; } req[4] = Info.Ringtone[atoi(argv[2])].ID / 256; req[5] = Info.Ringtone[atoi(argv[2])].ID % 256; req[6] = Info.Ringtone[atoi(argv[2])].Group; error=GSM_WaitFor (&s, req, 18, 0x1F, 4, ID_User3); Print_Error(error); // for (i=0;i<Info.Number;i++) printmsg("%i. \"%s\"\n",i,DecodeUnicodeConsole(Info.Ringtone[i].Name)); GSM_Terminate(); } static GSM_Error DCT4_ReplyMakeCameraShoot(GSM_Protocol_Message msg, GSM_StateMachine *s) { return ERR_NONE; } void DCT4MakeCameraShoot(int argc, char *argv[]) { unsigned char SetCamera[] = {N6110_FRAME_HEADER, 0x09, 0x01, 0x02}; unsigned char CameraON[] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00, 0x00, 0x00 , 0x00, 0x00}; unsigned char CameraON2[] = {N6110_FRAME_HEADER, 0xF0, 0x02, 0x00}; unsigned char MakeShot[200] = {N6110_FRAME_HEADER, 0x06, 0x01, 0x06, 0x01, 0x00, 0x00, 0x02, 0x00, 0x04, 0x32, 0x00, 0x01, 0x1D, //length of rest 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, //master folder id 0x00, 0x14}; //length unsigned char CameraOFF[] = {N6110_FRAME_HEADER, 0x04, 0x01, 0x00}; GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; error=GSM_WaitFor (&s, SetCamera, 6, 0x61, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, CameraON, 10, 0x61, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, CameraON2, 6, 0x61, 4, ID_User3); Print_Error(error); EncodeUnicode(MakeShot+24,"GammuShot",9); MakeShot[15] = 9+9*2; MakeShot[23] = 9*2; error=GSM_WaitFor (&s, MakeShot, 24+MakeShot[23], 0x61, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, SetCamera, 6, 0x61, 4, ID_User3); Print_Error(error); error=GSM_WaitFor (&s, CameraOFF, 6, 0x61, 4, ID_User3); Print_Error(error); GSM_Terminate(); } int len; static GSM_Error DCT4_ReplyGetScreenDump(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[7] == 0x0C) len = 1; return ERR_NONE; } void DCT4GetScreenDump(int argc, char *argv[]) { unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00}; //n6110_frameheader 06//screen info GSM_Init(true); CheckDCT4(); s.User.UserReplyFunctions=UserReplyFunctions4; error=GSM_WaitFor (&s, req, 6, 0x0E, 4, ID_User3); Print_Error(error); len = 2000; while (len >= 200) GSM_ReadDevice(&s,true); GSM_Terminate(); } static GSM_Reply_Function UserReplyFunctions4[] = { #ifdef DEBUG {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x05,ID_User2 }, {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x06,ID_User2 }, #endif {DCT4_ReplyGetScreenDump, "\x0E",0x00,0x00,ID_User3 }, {DCT4_ReplyGetScreenDump, "\x0E",0x00,0x00,ID_IncomingFrame}, {DCT4_ReplyGetADC, "\x17",0x03,0x10,ID_User3 }, {DCT4_ReplyGetADC, "\x17",0x03,0x12,ID_User3 }, {DCT4_ReplySetPPS, "\x1b",0x03,0x05,ID_User1 }, {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_User6 }, {DCT4_ReplyVibra, "\x1C",0x03,0x0D,ID_User3 }, {DCT4_ReplyVibra, "\x1C",0x03,0x0F,ID_User3 }, {NoneReply, "\x1F",0x03,0x02,ID_User3 }, {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x05,ID_User1 }, {DCT4_ReplyGetT9, "\x23",0x03,0x05,ID_User3 }, {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x05,ID_User4 }, {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x0D,ID_User4 }, {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x0D,ID_User1 }, {DCT4_ReplyTestsStartup, "\x35",0x02,0x01,ID_User3 }, {DCT4_ReplyTestsStartup, "\x35",0x02,0x02,ID_User3 }, {DCT4_ReplyTestsNames, "\x35",0x02,0x03,ID_User1 }, {DCT4_ReplyTestsStatus, "\x35",0x02,0x04,ID_User2 }, #ifdef GSM_ENABLE_NOKIA6510 {DCT4_ReplyTuneRadio, "\x3E",0x03,0x09,ID_User3 }, {DCT4_ReplyTuneRadio, "\x3E",0x03,0x15,ID_User3 }, {DCT4_ReplyTuneRadio, "\x3E",0x03,0x15,ID_SetFMStation}, {DCT4_ReplyTuneRadio, "\x3E",0x03,0x16,ID_User3 }, #endif {DCT4_ReplyGetVoiceRecord, "\x4A",0x03,0x31,ID_User4 }, {DCT4_ReplyGetSimlock, "\x53",0x03,0x0D,ID_User6 }, {DCT4_ReplyGetSimlock, "\x53",0x03,0x13,ID_User6 }, {DCT4_ReplyMakeCameraShoot, "\x61",0x03,0x03,ID_User3 }, {DCT4_ReplyMakeCameraShoot, "\x61",0x03,0x07,ID_User3 }, {DCT4_ReplyMakeCameraShoot, "\x61",0x03,0x08,ID_User3 }, {DCT4_ReplyMakeCameraShoot, "\x61",0x03,0x0A,ID_User3 }, {DCT4_ReplyMakeCameraShoot, "\x61",0x03,0xF0,ID_User3 }, {DCT4_ReplyGetBTInfo, "\xD7",0x03,0x0A,ID_User6 }, {NULL, "\x00",0x00,0x00,ID_None } }; #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/gammu/depend/siemens/dsiemens.c b/gammu/emb/gammu/depend/siemens/dsiemens.c index dc54102..a34bc3b 100644 --- a/gammu/emb/gammu/depend/siemens/dsiemens.c +++ b/gammu/emb/gammu/depend/siemens/dsiemens.c @@ -1,363 +1,363 @@ /* (c) by Walek */ #include "../../../common/gsmstate.h" #ifdef GSM_ENABLE_ATGEN #include <string.h> #include "../../../common/misc/coding/coding.h" #include "../../../common/gsmcomon.h" #include "../../../common/service/gsmnet.h" #include "../../../common/phone/at/atgen.h" #include "../../gammu.h" #include "dsiemens.h" #include "chiffre.h" extern GSM_Error ATGEN_GetSIMIMSI (GSM_StateMachine *s, char *IMSI); extern GSM_Error ATGEN_GetMemoryStatus (GSM_StateMachine *s, GSM_MemoryStatus *status); extern GSM_Error ATGEN_SetMemory (GSM_StateMachine *s, GSM_MemoryEntry *pbk); -extern GSM_Reply_Function UserReplyFunctionsAtS[]; +static GSM_Reply_Function UserReplyFunctionsAtS[]; bool new_variable; GSM_Error CheckSiemens() { if (s.Phone.Data.Priv.ATGEN.Manufacturer != AT_Siemens) return ERR_NOTSUPPORTED; return ERR_NONE; } GSM_Error ATSIEMENS_Reply_GetSAT(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_SAT_Measure_results MeasureResult; unsigned char buf[256]; int length,i,rep,ChNo=1,j=0,result=0,origARFCN=0; int freq_tmp,frequency[24]; GSM_NetworkInfo Network; if (Priv->ReplyState!=AT_Reply_OK) return ERR_UNKNOWN; if (s->Protocol.Data.AT.EditMode) s->Protocol.Data.AT.EditMode = false; if (strstr(GetLineString(msg.Buffer,Priv->Lines,2),"SSTK")) { length = strlen(GetLineString(msg.Buffer,Priv->Lines,2))-7; DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,2)+7,length); if (buf[0]==0x7f) { new_variable=true; return ERR_NONE; } else return ERR_UNKNOWN; } if (!strstr(GetLineString(msg.Buffer,Priv->Lines,3),"SSTK")) return ERR_UNKNOWN; length = strlen(GetLineString(msg.Buffer,Priv->Lines,3))-7; DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,3)+7,length); if (buf[3]!=0x26) return ERR_UNKNOWN; #ifdef DEBUG dbgprintf ("SAT command: Provide Local Information\nFunction: "); switch (buf[4]) { case 00: dbgprintf ("Loc Info\n"); break; case 01: dbgprintf ("IMEI\n"); break; case 02: dbgprintf ("Network Measure\n"); break; case 03: dbgprintf ("Date time and timezone\n"); break; case 04: dbgprintf ("Language setting\n"); break; case 05: dbgprintf ("Timing advance\n"); break; } #endif /* Loc Info (MCC, MNC, LAC, Cell ID) */ if (buf[4]==00) { DecodeBCD (Network.NetworkCode,buf+14,2); Network.NetworkCode[3] = ' '; DecodeBCD (Network.NetworkCode+4,buf+16,1); EncodeHexBin (Network.LAC,buf+17,2); EncodeHexBin (Network.CID,buf+19,2); printf(" Network code : %s\n",Network.NetworkCode); printf(" Network name for Gammu : %s\n", DecodeUnicodeString(GSM_GetNetworkName(Network.NetworkCode))); printf(" CID : %s\n",Network.CID); printf(" LAC : %s\n",Network.LAC); } /* Network Measure */ if (buf[4]==02) { for (i=0;i<24;i++) frequency[i]=0; if (!new_variable) { GetBufferI(buf+32,&j,&result,7); result &= 0x67; if (result !=0x47) return ERR_NOTSUPPORTED; } #ifdef DEBUG if (new_variable) dbgprintf ("New variable Bitmap format\n"); else dbgprintf ("Old variable Bitmap format\n"); #endif GetBufferI(buf+32,&j,&origARFCN,10); /* 10 bit origin ARFCN or first frequency (new variable format) */ #ifdef DEBUG dbgprintf("Origin BCCH = %i\n",origARFCN); #endif rep = buf[31]*8; if (!new_variable ){ for (i=0;i<rep;i++){ result = 0; GetBufferI(buf+32,&j,&result,1); if (result) { frequency[ChNo]=i+origARFCN+1; ChNo++; } } } else { frequency[ChNo++]=origARFCN; for (i=0; i<rep; i+=10){ result = 0; GetBufferI(buf+32,&j,&result,10); if (!result) break; frequency[ChNo++]=result; } j=1; while (j) { j=0; for (i=0; i<ChNo-1; i++){ if (frequency[i] > frequency[i+1]){ freq_tmp=frequency[i]; frequency[i]=frequency[i+1]; frequency[i+1]=freq_tmp; j=1; } } } }; #ifdef DEBUG dbgprintf("Neighbor BCCH list: "); for (i=1;i<ChNo;i++) dbgprintf ("%d ",frequency[i]); dbgprintf ("\n"); #endif j = 0; result = 0; GetBufferI(buf+14,&j,&result,1); if (result) MeasureResult.BA_used=true; else MeasureResult.BA_used=false; result = 0; GetBufferI(buf+14,&j,&result,1); if (result) MeasureResult.DTX_used=true; else MeasureResult.DTX_used=false; result = 0; GetBufferI(buf+14,&j,&result,6); MeasureResult.RXLEV_FullServicingCell=result-110; j++; //skip spare bit result = 0; GetBufferI(buf+14,&j,&result,1); if (result) MeasureResult.MeasValid=true; else MeasureResult.MeasValid=false; result = 0; GetBufferI(buf+14,&j,&result,6); MeasureResult.RXLEV_SubServicingCell=result-110; j++; //skip spare bit result = 0; GetBufferI(buf+14,&j,&result,3); MeasureResult.RXQUAL_FullServicingCell=result; result = 0; GetBufferI(buf+14,&j,&result,3); MeasureResult.RXQUAL_SubServicingCell=result; printf ("RX Level FULL Servicing Cell = %i\n",MeasureResult.RXLEV_FullServicingCell); printf ("RX Level Sub Servicing Cell = %i\n",MeasureResult.RXLEV_FullServicingCell); printf ("RX Quality Full Servicing Cell = %i\n",MeasureResult.RXQUAL_FullServicingCell); printf ("RX Quality Sub Servicing Cell = %i\n",MeasureResult.RXQUAL_SubServicingCell); result = 0; GetBufferI(buf+14,&j,&result,3); MeasureResult.NO_NCELL_M=result; rep=MeasureResult.NO_NCELL_M; for (i=0;i<MeasureResult.NO_NCELL_M;i++) { result = 0; GetBufferI(buf+14,&j,&result,6); MeasureResult.NeighbourCell[i].RxLev = result-110; result = 0; GetBufferI(buf+14,&j,&result,5); if (new_variable) MeasureResult.NeighbourCell[i].ChFreq = frequency[result+1]; else MeasureResult.NeighbourCell[i].ChFreq = frequency[result]; result = 0; GetBufferI(buf+14,&j,&result,3); MeasureResult.NeighbourCell[i].NB = 10 * result; result = 0; GetBufferI(buf+14,&j,&result,3); MeasureResult.NeighbourCell[i].NB += result; if (MeasureResult.NeighbourCell[i].ChFreq) printf("CH = %i,\t",MeasureResult.NeighbourCell[i].ChFreq); else printf("CH = Unknown\t"); printf("RX Lev = %i dBm\t",MeasureResult.NeighbourCell[i].RxLev); printf("BSIC CELL = %i\n",MeasureResult.NeighbourCell[i].NB); } } #ifdef DEBUG if (buf[4]==05) { //Timing Advance if (buf[11]) dbgprintf ("Unknown Timing Advance\n"); else dbgprintf ("Timing Advance = %i\n",buf[14] & 0x3f); } #endif return ERR_NONE; } GSM_Error ATSIEMENS_Reply_GetNetmon(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int i=2; if (!strstr(GetLineString(msg.Buffer,Priv->Lines,1),"AT^S^MI")) return ERR_UNKNOWN; while (strlen(GetLineString(msg.Buffer,Priv->Lines,i+1))) printf("%s\n",GetLineString(msg.Buffer,Priv->Lines,i++)); printf("\n"); return ERR_NONE; } GSM_Error ATSIEMENS_GetSAT(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; unsigned char *reqSAT[]= {"D009810301260082028182", "D009810301260282028182", "D009810301260582028182"},req[32]; int i,len; if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; sprintf(req, "AT^SSTK=?\r"); error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_User1); for (i=0;i<3;i++){ len = strlen(reqSAT[i]); s->Protocol.Data.AT.EditMode = true; sprintf(req, "AT^SSTK=%i,1\r",len/2); error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_User1); s->Phone.Data.DispatchError = ERR_TIMEOUT; s->Phone.Data.RequestID = ID_User1; error = s->Protocol.Functions->WriteMessage(s, reqSAT[i], len, 0x00); if (error!=ERR_NONE) return error; error = s->Protocol.Functions->WriteMessage(s, "\x1A", 1, 0x00); if (error!=ERR_NONE) return error; error = GSM_WaitForOnce (s, NULL,0x00, 0x00, 4); if (error!=ERR_NONE) return error; } return ERR_NONE; } GSM_Error ATSIEMENS_GetNetmon(GSM_StateMachine *s,int test_no) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[32]; if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; sprintf(req, "AT^S^MI=%d\r",test_no); printf ("Siemens NetMonitor test #%i\n",test_no); return GSM_WaitFor(s, req, strlen(req), 0x00, 3, ID_User2); } GSM_Error ATSIEMENS_ActivateNetmon (GSM_StateMachine *s,int netmon_type) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[32]; if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; sprintf(req, "AT\r"); printf ("Activate Siemens NetMonitor\n"); siemens_code (req,req,2); return GSM_WaitFor(s, req, strlen(req), 0x00, 3, ID_User2); } void ATSIEMENSActivateNetmon(int argc, char *argv[]) { GSM_MemoryStatus status; GSM_MemoryEntry pbk; int netmon_type, pbk_maxlocation; char imsi[15], NetMonCode[32]; GSM_Init(true); if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); s.User.UserReplyFunctions=UserReplyFunctionsAtS; printf ("Activate NetMonitor...\n"); netmon_type = atoi(argv[2]); if ((netmon_type==1) || (netmon_type==2)) { error = ATGEN_GetSIMIMSI (&s,imsi); Print_Error(error); siemens_code(imsi,NetMonCode,netmon_type); status.MemoryType = MEM_SM; error = ATGEN_GetMemoryStatus (&s,&status); Print_Error(error); pbk_maxlocation = status.MemoryUsed+status.MemoryFree; pbk.MemoryType = MEM_SM; pbk.Location = pbk_maxlocation; pbk.EntriesNum = 2; pbk.Entries[0].EntryType = PBK_Number_General; EncodeUnicode (pbk.Entries[0].Text,NetMonCode,strlen(NetMonCode)); pbk.Entries[1].EntryType = PBK_Text_Name; sprintf (NetMonCode,"Net Monitor"); EncodeUnicode (pbk.Entries[1].Text,NetMonCode,strlen(NetMonCode)); error = ATGEN_SetMemory (&s, &pbk); Print_Error(error); } else printf ("NetMonitor type should be:\n1 - full Netmon\n2 - simple NetMon\n"); GSM_Terminate(); } void ATSIEMENSSATNetmon(int argc, char *argv[]) { GSM_Init(true); if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); s.User.UserReplyFunctions=UserReplyFunctionsAtS; printf ("Getting Siemens Sim Aplication Toolkit NetMonitor...\n"); error=ATSIEMENS_GetSAT(&s); Print_Error(error); GSM_Terminate(); } void ATSIEMENSNetmonitor(int argc, char *argv[]) { int test_no; GSM_Init(true); if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); s.User.UserReplyFunctions=UserReplyFunctionsAtS; printf ("Getting Siemens NetMonitor...\n"); test_no = atoi(argv[2]); error = ATSIEMENS_GetNetmon (&s,test_no+1); Print_Error(error); GSM_Terminate(); } static GSM_Reply_Function UserReplyFunctionsAtS[] = { {ATSIEMENS_Reply_GetSAT, "AT^SSTK", 0x00,0x00,ID_User1 }, {ATSIEMENS_Reply_GetNetmon, "AT^S^MI", 0x00,0x00,ID_User2 }, {NULL, "\x00", 0x00,0x00,ID_None } }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/kaddressbook/addresseeeditorwidget.h b/kaddressbook/addresseeeditorwidget.h index df9965d..816bbb5 100644 --- a/kaddressbook/addresseeeditorwidget.h +++ b/kaddressbook/addresseeeditorwidget.h @@ -1,192 +1,193 @@ /* This file is part of KAddressBook. Copyright (c) 2002 Mike Pilone <mpilone@slac.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef ADDRESSEEEDITORWIDGET_H #define ADDRESSEEEDITORWIDGET_H #include <qdatetime.h> #include <qpopupmenu.h> +#include <qcombobox.h> #include <kabc/addressee.h> #include <kdialogbase.h> #include <kjanuswidget.h> #include "extensionwidget.h" class AddresseeConfig; class QCheckBox; class QSpinBox; class QTabWidget; #ifndef KAB_EMBEDDED class QTextEdit; #else //KAB_EMBEDDED class QMultiLineEdit; #endif //KAB_EMBEDDED class KComboBox; class KDateEdit; class KLineEdit; class KSqueezedTextLabel; class AddressEditWidget; class EmailEditWidget; class GeoWidget; class ImageWidget; class KABCore; class KeyWidget; class PhoneEditWidget; class SecrecyWidget; class SoundWidget; namespace KPIM { class CategorySelectDialog; class CategoryEditDialog; } namespace KABC { class AddressBook; } class AddresseeEditorWidget : public ExtensionWidget { Q_OBJECT public: AddresseeEditorWidget( KABCore *core, bool isExtension, QWidget *parent, const char *name = 0 ); ~AddresseeEditorWidget(); void setAddressee( const KABC::Addressee& ); const KABC::Addressee &addressee(); void contactsSelectionChanged(); void load(); void save(); bool dirty(); QString title() const; QString identifier() const; protected slots: void showCatPopup(); void selectedCatPopup( int ); void setRole2FN(); void setCompany2FN(); void textChanged( const QString& ); void pageChanged( QWidget *wdg ); /** Emits the modified signal and sets the dirty flag. Any slot that modifies data should use this method instead of calling emit modified() directly. */ void emitModified(); void dateChanged( QDate ); void invalidDate(); void nameTextChanged( const QString& ); void nameBoxChanged(); void nameButtonClicked(); void categoryButtonClicked(); /** Called whenever the categories change in the categories dialog. */ void categoriesSelected( const QStringList& ); /** Edits which categories are available in the CategorySelectDialog. */ void editCategories(); private: AddresseeConfig * mAConfig; void initGUI(); void setupTab1(); void setupTab1_1(); void setupTab2(); void setupTab2_1(); void setupTab3(); void setupTab3_1(); KABC::Addressee mAddressee; int mFormattedNameType; bool mDirty; bool mIsExtension; bool mBlockSignals; // GUI KPIM::CategorySelectDialog *mCategoryDialog; KPIM::CategoryEditDialog *mCategoryEditDialog; QTabWidget *mTabWidget; // Tab1 and Tab1_1 KLineEdit *mNameEdit; KLineEdit *mRoleEdit; KLineEdit *mOrgEdit; KSqueezedTextLabel *mFormattedNameLabel; AddressEditWidget *mAddressEditWidget; EmailEditWidget *mEmailWidget; PhoneEditWidget *mPhoneEditWidget; KLineEdit *mURLEdit; KLineEdit *mIMAddressEdit; QPushButton *mCategoryEdit; QPopupMenu *mCatPopup; SecrecyWidget *mSecrecyWidget; KSqueezedTextLabel *mNameLabel; // Tab2 and Tab2_2 KLineEdit *mDepartmentEdit; KLineEdit *mOfficeEdit; KLineEdit *mProfessionEdit; KLineEdit *mManagerEdit; KLineEdit *mAssistantEdit; KLineEdit *mNicknameEdit; KLineEdit *mSpouseEdit; KLineEdit *mChildEdit; QComboBox *mGenderBox; KDateEdit *mBirthdayPicker; KDateEdit *mAnniversaryPicker; #ifndef KAB_EMBEDDED QTextEdit *mNoteEdit; #else //KAB_EMBEDDED QMultiLineEdit *mNoteEdit; #endif //KAB_EMBEDDED QSpinBox *mTimeZoneSpin; QSpinBox *mGeoLat; QSpinBox *mGeoLon; // Tab3 GeoWidget *mGeoWidget; ImageWidget *mImageWidget; #ifndef KAB_EMBEDDED SoundWidget *mSoundWidget; #endif //KAB_EMBEDDED KeyWidget *mKeyWidget; }; #endif diff --git a/pwmanager/libcrypt/cipher/serpent.c b/pwmanager/libcrypt/cipher/serpent.c index d606d9f..fb5df20 100644 --- a/pwmanager/libcrypt/cipher/serpent.c +++ b/pwmanager/libcrypt/cipher/serpent.c @@ -1,979 +1,979 @@ /* serpent.c - Implementation of the Serpent encryption algorithm. * Copyright (C) 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include <config.h> #include <string.h> #include <stdio.h> #include "types.h" #include "g10lib.h" #include "cipher.h" #include "bithelp.h" /* Number of rounds per Serpent encrypt/decrypt operation. */ #define ROUNDS 32 /* Magic number, used during generating of the subkeys. */ #define PHI 0x9E3779B9 /* Internal types. */ typedef byte byte_t; typedef u32 u32_t; /* Serpent works on 128 bit blocks. */ typedef u32_t serpent_block_t[4]; /* Serpent key, provided by the user. If the original key is shorter than 256 bits, it is padded. */ typedef u32_t serpent_key_t[8]; /* The key schedule consists of 33 128 bit subkeys. */ typedef u32_t serpent_subkeys_t[ROUNDS + 1][4]; /* A Serpent context. */ typedef struct serpent_context { serpent_subkeys_t keys; /* Generated subkeys. */ } serpent_context_t; #define byte_swap_32(x) \ (0 \ | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \ | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)); /* These are the S-Boxes of Serpent. They are copied from Serpents reference implementation (the optimized one, contained in `floppy2') and are therefore: Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen. To quote the Serpent homepage (http://www.cl.cam.ac.uk/~rja14/serpent.html): "Serpent is now completely in the public domain, and we impose no restrictions on its use. This was announced on the 21st August at the First AES Candidate Conference. The optimised implementations in the submission package are now under the GNU PUBLIC LICENSE (GPL), although some comments in the code still say otherwise. You are welcome to use Serpent for any application." */ #define SBOX0(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t05, t06, t07, t08, t09; \ register unsigned long t11, t12, t13, t14, t15, t17, t01; \ t01 = b ^ c ; \ t02 = a | d ; \ t03 = a ^ b ; \ z = t02 ^ t01; \ t05 = c | z ; \ t06 = a ^ d ; \ t07 = b | c ; \ t08 = d & t05; \ t09 = t03 & t07; \ y = t09 ^ t08; \ t11 = t09 & y ; \ t12 = c ^ d ; \ t13 = t07 ^ t11; \ t14 = b & t06; \ t15 = t06 ^ t13; \ w = ~ t15; \ t17 = w ^ t14; \ x = t12 ^ t17; \ } #define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \ register unsigned long t12, t13, t14, t15, t17, t18, t01; \ t01 = c ^ d ; \ t02 = a | b ; \ t03 = b | c ; \ t04 = c & t01; \ t05 = t02 ^ t01; \ t06 = a | t04; \ y = ~ t05; \ t08 = b ^ d ; \ t09 = t03 & t08; \ t10 = d | y ; \ x = t09 ^ t06; \ t12 = a | t05; \ t13 = x ^ t12; \ t14 = t03 ^ t10; \ t15 = a ^ c ; \ z = t14 ^ t13; \ t17 = t05 & t13; \ t18 = t14 | t17; \ w = t15 ^ t18; \ } #define SBOX1(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t08; \ register unsigned long t10, t11, t12, t13, t16, t17, t01; \ t01 = a | d ; \ t02 = c ^ d ; \ t03 = ~ b ; \ t04 = a ^ c ; \ t05 = a | t03; \ t06 = d & t04; \ t07 = t01 & t02; \ t08 = b | t06; \ y = t02 ^ t05; \ t10 = t07 ^ t08; \ t11 = t01 ^ t10; \ t12 = y ^ t11; \ t13 = b & d ; \ z = ~ t10; \ x = t13 ^ t12; \ t16 = t10 | x ; \ t17 = t05 & t16; \ w = c ^ t17; \ } #define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t08; \ register unsigned long t09, t10, t11, t14, t15, t17, t01; \ t01 = a ^ b ; \ t02 = b | d ; \ t03 = a & c ; \ t04 = c ^ t02; \ t05 = a | t04; \ t06 = t01 & t05; \ t07 = d | t03; \ t08 = b ^ t06; \ t09 = t07 ^ t06; \ t10 = t04 | t03; \ t11 = d & t08; \ y = ~ t09; \ x = t10 ^ t11; \ t14 = a | y ; \ t15 = t06 ^ x ; \ z = t01 ^ t04; \ t17 = c ^ t15; \ w = t14 ^ t17; \ } #define SBOX2(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t05, t06, t07, t08; \ register unsigned long t09, t10, t12, t13, t14, t01; \ t01 = a | c ; \ t02 = a ^ b ; \ t03 = d ^ t01; \ w = t02 ^ t03; \ t05 = c ^ w ; \ t06 = b ^ t05; \ t07 = b | t05; \ t08 = t01 & t06; \ t09 = t03 ^ t07; \ t10 = t02 | t09; \ x = t10 ^ t08; \ t12 = a | d ; \ t13 = t09 ^ x ; \ t14 = b ^ t13; \ z = ~ t09; \ y = t12 ^ t14; \ } #define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t06, t07, t08, t09; \ register unsigned long t10, t11, t12, t15, t16, t17, t01; \ t01 = a ^ d ; \ t02 = c ^ d ; \ t03 = a & c ; \ t04 = b | t02; \ w = t01 ^ t04; \ t06 = a | c ; \ t07 = d | w ; \ t08 = ~ d ; \ t09 = b & t06; \ t10 = t08 | t03; \ t11 = b & t07; \ t12 = t06 & t02; \ z = t09 ^ t10; \ x = t12 ^ t11; \ t15 = c & z ; \ t16 = w ^ x ; \ t17 = t10 ^ t15; \ y = t16 ^ t17; \ } #define SBOX3(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t08; \ register unsigned long t09, t10, t11, t13, t14, t15, t01; \ t01 = a ^ c ; \ t02 = a | d ; \ t03 = a & d ; \ t04 = t01 & t02; \ t05 = b | t03; \ t06 = a & b ; \ t07 = d ^ t04; \ t08 = c | t06; \ t09 = b ^ t07; \ t10 = d & t05; \ t11 = t02 ^ t10; \ z = t08 ^ t09; \ t13 = d | z ; \ t14 = a | t07; \ t15 = b & t13; \ y = t08 ^ t11; \ w = t14 ^ t15; \ x = t05 ^ t04; \ } #define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t09; \ register unsigned long t11, t12, t13, t14, t16, t01; \ t01 = c | d ; \ t02 = a | d ; \ t03 = c ^ t02; \ t04 = b ^ t02; \ t05 = a ^ d ; \ t06 = t04 & t03; \ t07 = b & t01; \ y = t05 ^ t06; \ t09 = a ^ t03; \ w = t07 ^ t03; \ t11 = w | t05; \ t12 = t09 & t11; \ t13 = a & y ; \ t14 = t01 ^ t05; \ x = b ^ t12; \ t16 = b | t13; \ z = t14 ^ t16; \ } #define SBOX4(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t08, t09; \ register unsigned long t10, t11, t12, t13, t14, t15, t16, t01; \ t01 = a | b ; \ t02 = b | c ; \ t03 = a ^ t02; \ t04 = b ^ d ; \ t05 = d | t03; \ t06 = d & t01; \ z = t03 ^ t06; \ t08 = z & t04; \ t09 = t04 & t05; \ t10 = c ^ t06; \ t11 = b & c ; \ t12 = t04 ^ t08; \ t13 = t11 | t03; \ t14 = t10 ^ t09; \ t15 = a & t05; \ t16 = t11 | t12; \ y = t13 ^ t08; \ x = t15 ^ t16; \ w = ~ t14; \ } #define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t09; \ register unsigned long t10, t11, t12, t13, t15, t01; \ t01 = b | d ; \ t02 = c | d ; \ t03 = a & t01; \ t04 = b ^ t02; \ t05 = c ^ d ; \ t06 = ~ t03; \ t07 = a & t04; \ x = t05 ^ t07; \ t09 = x | t06; \ t10 = a ^ t07; \ t11 = t01 ^ t09; \ t12 = d ^ t04; \ t13 = c | t10; \ z = t03 ^ t12; \ t15 = a ^ t04; \ y = t11 ^ t13; \ w = t15 ^ t09; \ } #define SBOX5(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t07, t08, t09; \ register unsigned long t10, t11, t12, t13, t14, t01; \ t01 = b ^ d ; \ t02 = b | d ; \ t03 = a & t01; \ t04 = c ^ t02; \ t05 = t03 ^ t04; \ w = ~ t05; \ t07 = a ^ t01; \ t08 = d | w ; \ t09 = b | t05; \ t10 = d ^ t08; \ t11 = b | t07; \ t12 = t03 | w ; \ t13 = t07 | t10; \ t14 = t01 ^ t11; \ y = t09 ^ t13; \ x = t07 ^ t08; \ z = t12 ^ t14; \ } #define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t07, t08, t09; \ register unsigned long t10, t12, t13, t15, t16, t01; \ t01 = a & d ; \ t02 = c ^ t01; \ t03 = a ^ d ; \ t04 = b & t02; \ t05 = a & c ; \ w = t03 ^ t04; \ t07 = a & w ; \ t08 = t01 ^ w ; \ t09 = b | t05; \ t10 = ~ b ; \ x = t08 ^ t09; \ t12 = t10 | t07; \ t13 = w | x ; \ z = t02 ^ t12; \ t15 = t02 ^ t13; \ t16 = b ^ d ; \ y = t16 ^ t15; \ } #define SBOX6(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t07, t08, t09, t10; \ register unsigned long t11, t12, t13, t15, t17, t18, t01; \ t01 = a & d ; \ t02 = b ^ c ; \ t03 = a ^ d ; \ t04 = t01 ^ t02; \ t05 = b | c ; \ x = ~ t04; \ t07 = t03 & t05; \ t08 = b & x ; \ t09 = a | c ; \ t10 = t07 ^ t08; \ t11 = b | d ; \ t12 = c ^ t11; \ t13 = t09 ^ t10; \ y = ~ t13; \ t15 = x & t03; \ z = t12 ^ t07; \ t17 = a ^ b ; \ t18 = y ^ t15; \ w = t17 ^ t18; \ } #define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t07, t08, t09; \ register unsigned long t12, t13, t14, t15, t16, t17, t01; \ t01 = a ^ c ; \ t02 = ~ c ; \ t03 = b & t01; \ t04 = b | t02; \ t05 = d | t03; \ t06 = b ^ d ; \ t07 = a & t04; \ t08 = a | t02; \ t09 = t07 ^ t05; \ x = t06 ^ t08; \ w = ~ t09; \ t12 = b & w ; \ t13 = t01 & t05; \ t14 = t01 ^ t12; \ t15 = t07 ^ t13; \ t16 = d | t02; \ t17 = a ^ x ; \ z = t17 ^ t15; \ y = t16 ^ t14; \ } #define SBOX7(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \ register unsigned long t11, t13, t14, t15, t16, t17, t01; \ t01 = a & c ; \ t02 = ~ d ; \ t03 = a & t02; \ t04 = b | t01; \ t05 = a & b ; \ t06 = c ^ t04; \ z = t03 ^ t06; \ t08 = c | z ; \ t09 = d | t05; \ t10 = a ^ t08; \ t11 = t04 & z ; \ x = t09 ^ t10; \ t13 = b ^ x ; \ t14 = t01 ^ x ; \ t15 = c ^ t05; \ t16 = t11 | t13; \ t17 = t02 | t14; \ w = t15 ^ t17; \ y = a ^ t16; \ } #define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \ { \ register unsigned long t02, t03, t04, t06, t07, t08, t09; \ register unsigned long t10, t11, t13, t14, t15, t16, t01; \ t01 = a & b ; \ t02 = a | b ; \ t03 = c | t01; \ t04 = d & t02; \ z = t03 ^ t04; \ t06 = b ^ t04; \ t07 = d ^ z ; \ t08 = ~ t07; \ t09 = t06 | t08; \ t10 = b ^ d ; \ t11 = a | d ; \ x = a ^ t09; \ t13 = c ^ t06; \ t14 = c & t11; \ t15 = d | x ; \ t16 = t01 | t10; \ w = t13 ^ t15; \ y = t14 ^ t16; \ } /* XOR BLOCK1 into BLOCK0. */ #define BLOCK_XOR(block0, block1) \ { \ block0[0] ^= block1[0]; \ block0[1] ^= block1[1]; \ block0[2] ^= block1[2]; \ block0[3] ^= block1[3]; \ } /* Copy BLOCK_SRC to BLOCK_DST. */ #define BLOCK_COPY(block_dst, block_src) \ { \ block_dst[0] = block_src[0]; \ block_dst[1] = block_src[1]; \ block_dst[2] = block_src[2]; \ block_dst[3] = block_src[3]; \ } /* Apply SBOX number WHICH to to the block found in ARRAY0 at index INDEX, writing the output to the block found in ARRAY1 at index INDEX. */ #define SBOX(which, array0, array1, index) \ SBOX##which (array0[index + 0], array0[index + 1], \ array0[index + 2], array0[index + 3], \ array1[index + 0], array1[index + 1], \ array1[index + 2], array1[index + 3]); /* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at index INDEX, writing the output to the block found in ARRAY1 at index INDEX. */ #define SBOX_INVERSE(which, array0, array1, index) \ SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \ array0[index + 2], array0[index + 3], \ array1[index + 0], array1[index + 1], \ array1[index + 2], array1[index + 3]); /* Apply the linear transformation to BLOCK. */ #define LINEAR_TRANSFORMATION(block) \ { \ block[0] = rol (block[0], 13); \ block[2] = rol (block[2], 3); \ block[1] = block[1] ^ block[0] ^ block[2]; \ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ block[1] = rol (block[1], 1); \ block[3] = rol (block[3], 7); \ block[0] = block[0] ^ block[1] ^ block[3]; \ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ block[0] = rol (block[0], 5); \ block[2] = rol (block[2], 22); \ } /* Apply the inverse linear transformation to BLOCK. */ #define LINEAR_TRANSFORMATION_INVERSE(block) \ { \ block[2] = ror (block[2], 22); \ block[0] = ror (block[0] , 5); \ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ block[0] = block[0] ^ block[1] ^ block[3]; \ block[3] = ror (block[3], 7); \ block[1] = ror (block[1], 1); \ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ block[1] = block[1] ^ block[0] ^ block[2]; \ block[2] = ror (block[2], 3); \ block[0] = ror (block[0], 13); \ } /* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. This macro increments `round'. */ #define ROUND(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round++; \ SBOX (which, block, block_tmp, 0); \ LINEAR_TRANSFORMATION (block_tmp); \ BLOCK_COPY (block, block_tmp); \ } /* Apply the last Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. The result will be stored in BLOCK_TMP. This macro increments `round'. */ #define ROUND_LAST(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round++; \ SBOX (which, block, block_tmp, 0); \ BLOCK_XOR (block_tmp, subkeys[round]); \ round++; \ } /* Apply an inverse Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. This macro increments `round'. */ #define ROUND_INVERSE(which, subkey, block, block_tmp) \ { \ LINEAR_TRANSFORMATION_INVERSE (block); \ SBOX_INVERSE (which, block, block_tmp, 0); \ BLOCK_XOR (block_tmp, subkey[round]); \ round--; \ BLOCK_COPY (block, block_tmp); \ } /* Apply the first Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. The result will be stored in BLOCK_TMP. This macro increments `round'. */ #define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round--; \ SBOX_INVERSE (which, block, block_tmp, 0); \ BLOCK_XOR (block_tmp, subkeys[round]); \ round--; \ } /* Convert the user provided key KEY of KEY_LENGTH bytes into the internally used format. */ static void serpent_key_prepare (const byte_t *key, unsigned int key_length, serpent_key_t key_prepared) { int i; /* Copy key. */ for (i = 0; i < key_length / 4; i++) { #ifdef WORDS_BIGENDIAN key_prepared[i] = byte_swap_32 (((u32_t *) key)[i]); #else key_prepared[i] = ((u32_t *) key)[i]; #endif } if (i < 8) { /* Key must be padded according to the Serpent specification. */ key_prepared[i] = 0x00000001; for (i++; i < 8; i++) key_prepared[i] = 0; } } /* Derive the 33 subkeys from KEY and store them in SUBKEYS. */ static void serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys) { u32_t w_real[140]; /* The `prekey'. */ u32_t k[132]; u32_t *w = &w_real[8]; int i, j; /* Initialize with key values. */ for (i = 0; i < 8; i++) w[i - 8] = key[i]; /* Expand to intermediate key using the affine recurrence. */ for (i = 0; i < 132; i++) w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); /* Calculate subkeys via S-Boxes, in bitslice mode. */ SBOX (3, w, k, 0); SBOX (2, w, k, 4); SBOX (1, w, k, 8); SBOX (0, w, k, 12); SBOX (7, w, k, 16); SBOX (6, w, k, 20); SBOX (5, w, k, 24); SBOX (4, w, k, 28); SBOX (3, w, k, 32); SBOX (2, w, k, 36); SBOX (1, w, k, 40); SBOX (0, w, k, 44); SBOX (7, w, k, 48); SBOX (6, w, k, 52); SBOX (5, w, k, 56); SBOX (4, w, k, 60); SBOX (3, w, k, 64); SBOX (2, w, k, 68); SBOX (1, w, k, 72); SBOX (0, w, k, 76); SBOX (7, w, k, 80); SBOX (6, w, k, 84); SBOX (5, w, k, 88); SBOX (4, w, k, 92); SBOX (3, w, k, 96); SBOX (2, w, k, 100); SBOX (1, w, k, 104); SBOX (0, w, k, 108); SBOX (7, w, k, 112); SBOX (6, w, k, 116); SBOX (5, w, k, 120); SBOX (4, w, k, 124); SBOX (3, w, k, 128); /* Renumber subkeys. */ for (i = 0; i < ROUNDS + 1; i++) for (j = 0; j < 4; j++) subkeys[i][j] = k[4 * i + j]; } /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */ static void serpent_setkey_internal (serpent_context_t *context, const byte_t *key, unsigned int key_length) { serpent_key_t key_prepared; serpent_key_prepare (key, key_length, key_prepared); serpent_subkeys_generate (key_prepared, context->keys); _gcry_burn_stack (272 * sizeof (u32_t)); } - + static const char *serpent_test (void); /* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ static gcry_err_code_t serpent_setkey (void *ctx, const byte_t *key, unsigned int key_length) { serpent_context_t *context = ctx; static const char *serpent_test_ret; static int serpent_init_done; gcry_err_code_t ret = GPG_ERR_NO_ERROR; if (! serpent_init_done) { /* Execute a self-test the first time, Serpent is used. */ - static const char *serpent_test (void); + serpent_test_ret = serpent_test (); if (serpent_test_ret) log_error ("Serpent test failure: %s\n", serpent_test_ret); serpent_init_done = 1; } if (serpent_test_ret) ret = GPG_ERR_SELFTEST_FAILED; else { serpent_setkey_internal (context, key, key_length); _gcry_burn_stack (sizeof (serpent_key_t)); } return ret; } static void serpent_encrypt_internal (serpent_context_t *context, const serpent_block_t input, serpent_block_t output) { serpent_block_t b, b_next; int round = 0; #ifdef WORDS_BIGENDIAN b[0] = byte_swap_32 (input[0]); b[1] = byte_swap_32 (input[1]); b[2] = byte_swap_32 (input[2]); b[3] = byte_swap_32 (input[3]); #else b[0] = input[0]; b[1] = input[1]; b[2] = input[2]; b[3] = input[3]; #endif ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND_LAST (7, context->keys, b, b_next); #ifdef WORDS_BIGENDIAN output[0] = byte_swap_32 (b_next[0]); output[1] = byte_swap_32 (b_next[1]); output[2] = byte_swap_32 (b_next[2]); output[3] = byte_swap_32 (b_next[3]); #else output[0] = b_next[0]; output[1] = b_next[1]; output[2] = b_next[2]; output[3] = b_next[3]; #endif } static void serpent_decrypt_internal (serpent_context_t *context, const serpent_block_t input, serpent_block_t output) { serpent_block_t b, b_next; int round = ROUNDS; #ifdef WORDS_BIGENDIAN b_next[0] = byte_swap_32 (input[0]); b_next[1] = byte_swap_32 (input[1]); b_next[2] = byte_swap_32 (input[2]); b_next[3] = byte_swap_32 (input[3]); #else b_next[0] = input[0]; b_next[1] = input[1]; b_next[2] = input[2]; b_next[3] = input[3]; #endif ROUND_FIRST_INVERSE (7, context->keys, b_next, b); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); #ifdef WORDS_BIGENDIAN output[0] = byte_swap_32 (b_next[0]); output[1] = byte_swap_32 (b_next[1]); output[2] = byte_swap_32 (b_next[2]); output[3] = byte_swap_32 (b_next[3]); #else output[0] = b_next[0]; output[1] = b_next[1]; output[2] = b_next[2]; output[3] = b_next[3]; #endif } static void serpent_encrypt (void *ctx, byte_t *buffer_out, const byte_t *buffer_in) { serpent_context_t *context = ctx; serpent_encrypt_internal (context, (const u32_t *) buffer_in, (u32_t *) buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } static void serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; serpent_decrypt_internal (context, (const u32_t *) buffer_in, (u32_t *) buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } /* Serpent test. */ static const char * serpent_test (void) { serpent_context_t context; unsigned char scratch[16]; unsigned int i; static struct test { int key_length; unsigned char key[32]; unsigned char text_plain[16]; unsigned char text_cipher[16]; } test_data[] = { { 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E", "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D" }, { 24, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E", "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9" }, { 32, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E", "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B" }, { 32, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00", "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C" }, { 0 }, }; for (i = 0; test_data[i].key_length; i++) { serpent_setkey_internal (&context, test_data[i].key, test_data[i].key_length); serpent_encrypt_internal (&context, (const u32_t *) test_data[i].text_plain, (u32_t *) scratch); if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) switch (test_data[i].key_length) { case 16: return "Serpent-128 test encryption failed."; case 24: return "Serpent-192 test encryption failed."; case 32: return "Serpent-256 test encryption failed."; } serpent_decrypt_internal (&context, (const u32_t *) test_data[i].text_cipher, (u32_t *) scratch); if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) switch (test_data[i].key_length) { case 16: return "Serpent-128 test decryption failed."; case 24: return "Serpent-192 test decryption failed."; case 32: return "Serpent-256 test decryption failed."; } } return NULL; } /* "SERPENT" is an alias for "SERPENT128". */ static const char *cipher_spec_serpent128_aliases[] = { "SERPENT", NULL, }; gcry_cipher_spec_t _gcry_cipher_spec_serpent128 = { "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt, }; gcry_cipher_spec_t _gcry_cipher_spec_serpent192 = { "SERPENT192", NULL, NULL, 16, 192, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt, }; gcry_cipher_spec_t _gcry_cipher_spec_serpent256 = { "SERPENT256", NULL, NULL, 16, 256, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt, }; diff --git a/pwmanager/pwmanager/binentrygen.cpp b/pwmanager/pwmanager/binentrygen.cpp index 7d5ae45..f156a5e 100644 --- a/pwmanager/pwmanager/binentrygen.cpp +++ b/pwmanager/pwmanager/binentrygen.cpp @@ -1,71 +1,72 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ - #include "binentrygen.h" #include "base64.h" -#include "pwmexception.h" +#include "pwmexception.h" +#include "globalstuff.h" void BinEntryGen::encode(const QByteArray &data, PwMDataItem *ret, DataType type) { ret->clear(); ret->name = tostr(static_cast<int>(type)); ret->binary = true; if (data.size() == 0) return; Base64 b64; string d(data.data(), data.size()); ret->pw = b64.encode(d); } void BinEntryGen::decode(const PwMDataItem &data, QByteArray *ret, DataType *type) { BUG_ON(!data.binary); int t = strtol(data.name.c_str(), 0, 10); *type = static_cast<DataType>(t); switch (*type) { case None: case KWalletMap: case KWalletStream: break; default: *type = None; } if (data.pw == "") { ret->fill(0); ret->resize(0); return; } Base64 b64; string d(b64.decode(data.pw)); ret->duplicate(d.c_str(), d.length()); } BinEntryGen::DataType BinEntryGen::binType(const PwMDataItem &data) { if (!data.binary) return None; int type = strtol(data.name.c_str(), 0, 10); return (static_cast<DataType>(type)); } + diff --git a/pwmanager/pwmanager/binentrygen.h b/pwmanager/pwmanager/binentrygen.h index a58cd42..49288aa 100644 --- a/pwmanager/pwmanager/binentrygen.h +++ b/pwmanager/pwmanager/binentrygen.h @@ -1,65 +1,65 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __BINENTRYGEN_H #define __BINENTRYGEN_H -#include "pwmdoc.h" #include <qcstring.h> +#include "pwmdoc.h" /** Binary entry generator. * This generator generates a normal struct PwMDataItem * from binary data (using base64 encoding). * This mechanism is used to support the binary interface functions * of the KWallet emulation, for example. * * The format of the encoded binary data as a PwMDataItem is as follows: * * PwMDataItem::desc contains the normal description string for * this entry. Nothing surprising. * PwMDataItem::name contains the "DataType" number in ascii format. * PwMDataItem::pw contains the base64 encoded data stream. * PwMDataItem::binary is always true for binary entries. * All other PwMDataItems are currently unused by BinEntryGen. */ class BinEntryGen { public: enum DataType { None = 0, KWalletMap, KWalletStream }; public: BinEntryGen() { } /** Encode the binary "data" and return it in "ret" */ void encode(const QByteArray &data, PwMDataItem *ret, DataType type); /** Decode the "data" and return it as binary "ret" */ void decode(const PwMDataItem &data, QByteArray *ret, DataType *type); /** Return the data type for this binary data item */ DataType binType(const PwMDataItem &data); }; #endif // __BINENTRYGEN_H diff --git a/pwmanager/pwmanager/blowfish.cpp b/pwmanager/pwmanager/blowfish.cpp index 2ca58ce..ee29756 100644 --- a/pwmanager/pwmanager/blowfish.cpp +++ b/pwmanager/pwmanager/blowfish.cpp @@ -1,579 +1,579 @@ /* 2003.05.02: Derived from libgcrypt-1.1.12 by Michael Buesch */ /* blowfish.c - Blowfish encryption * Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * For a description of the algorithm, see: * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. * ISBN 0-471-11709-9. Pages 336 ff. */ /* Test values: * key "abcdefghijklmnopqrstuvwxyz"; * plain "BLOWFISH" * cipher 32 4E D0 FE F4 13 A2 03 * */ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #include <string.h> #include <stdlib.h> -#include "blowfish.h" #include "globalstuff.h" +#include "blowfish.h" /* precomputed S boxes */ static const uint32_t ks0[256] = { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }; static const uint32_t ks1[256] = { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }; static const uint32_t ks2[256] = { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }; static const uint32_t ks3[256] = { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }; static const uint32_t ps[BLOWFISH_ROUNDS + 2] = { 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B }; void Blowfish::burn_stack(int bytes) { char buf[64]; memset(buf, 0, sizeof buf); bytes -= sizeof buf; if (bytes > 0) burn_stack(bytes); } void Blowfish::do_encrypt(uint32_t * ret_xl, uint32_t * ret_xr) { #if BLOWFISH_ROUNDS == 16 uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; xl = *ret_xl; xr = *ret_xr; p = bc.p; s0 = bc.s0; s1 = bc.s1; s2 = bc.s2; s3 = bc.s3; R(xl, xr, 0, p, s0, s1, s2, s3); R(xr, xl, 1, p, s0, s1, s2, s3); R(xl, xr, 2, p, s0, s1, s2, s3); R(xr, xl, 3, p, s0, s1, s2, s3); R(xl, xr, 4, p, s0, s1, s2, s3); R(xr, xl, 5, p, s0, s1, s2, s3); R(xl, xr, 6, p, s0, s1, s2, s3); R(xr, xl, 7, p, s0, s1, s2, s3); R(xl, xr, 8, p, s0, s1, s2, s3); R(xr, xl, 9, p, s0, s1, s2, s3); R(xl, xr, 10, p, s0, s1, s2, s3); R(xr, xl, 11, p, s0, s1, s2, s3); R(xl, xr, 12, p, s0, s1, s2, s3); R(xr, xl, 13, p, s0, s1, s2, s3); R(xl, xr, 14, p, s0, s1, s2, s3); R(xr, xl, 15, p, s0, s1, s2, s3); xl ^= p[BLOWFISH_ROUNDS]; xr ^= p[BLOWFISH_ROUNDS + 1]; *ret_xl = xr; *ret_xr = xl; #else uint32_t xl, xr, temp, *p; int i; xl = *ret_xl; xr = *ret_xr; p = bc.p; for (i = 0; i < BLOWFISH_ROUNDS; i++) { xl ^= p[i]; xr ^= function_F(xl); temp = xl; xl = xr; xr = temp; } temp = xl; xl = xr; xr = temp; xr ^= p[BLOWFISH_ROUNDS]; xl ^= p[BLOWFISH_ROUNDS + 1]; *ret_xl = xl; *ret_xr = xr; #endif } void Blowfish::do_decrypt(uint32_t * ret_xl, uint32_t * ret_xr) { #if BLOWFISH_ROUNDS == 16 uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; xl = *ret_xl; xr = *ret_xr; p = bc.p; s0 = bc.s0; s1 = bc.s1; s2 = bc.s2; s3 = bc.s3; R(xl, xr, 17, p, s0, s1, s2, s3); R(xr, xl, 16, p, s0, s1, s2, s3); R(xl, xr, 15, p, s0, s1, s2, s3); R(xr, xl, 14, p, s0, s1, s2, s3); R(xl, xr, 13, p, s0, s1, s2, s3); R(xr, xl, 12, p, s0, s1, s2, s3); R(xl, xr, 11, p, s0, s1, s2, s3); R(xr, xl, 10, p, s0, s1, s2, s3); R(xl, xr, 9, p, s0, s1, s2, s3); R(xr, xl, 8, p, s0, s1, s2, s3); R(xl, xr, 7, p, s0, s1, s2, s3); R(xr, xl, 6, p, s0, s1, s2, s3); R(xl, xr, 5, p, s0, s1, s2, s3); R(xr, xl, 4, p, s0, s1, s2, s3); R(xl, xr, 3, p, s0, s1, s2, s3); R(xr, xl, 2, p, s0, s1, s2, s3); xl ^= p[1]; xr ^= p[0]; *ret_xl = xr; *ret_xr = xl; #else uint32_t xl, xr, temp, *p; int i; xl = *ret_xl; xr = *ret_xr; p = bc.p; for (i = BLOWFISH_ROUNDS + 1; i > 1; i--) { xl ^= p[i]; xr ^= function_F(xl); temp = xl; xl = xr; xr = temp; } temp = xl; xl = xr; xr = temp; xr ^= p[1]; xl ^= p[0]; *ret_xl = xl; *ret_xr = xr; #endif } void Blowfish::do_encrypt_block(byte * outbuf, byte * inbuf) { uint32_t d1, d2; d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; do_encrypt(&d1, &d2); outbuf[0] = (d1 >> 24) & 0xff; outbuf[1] = (d1 >> 16) & 0xff; outbuf[2] = (d1 >> 8) & 0xff; outbuf[3] = d1 & 0xff; outbuf[4] = (d2 >> 24) & 0xff; outbuf[5] = (d2 >> 16) & 0xff; outbuf[6] = (d2 >> 8) & 0xff; outbuf[7] = d2 & 0xff; } void Blowfish::encrypt_block(byte * outbuf, byte * inbuf) { do_encrypt_block(outbuf, inbuf); burn_stack(64); } void Blowfish::do_decrypt_block(byte * outbuf, byte * inbuf) { uint32_t d1, d2; d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; do_decrypt(&d1, &d2); outbuf[0] = (d1 >> 24) & 0xff; outbuf[1] = (d1 >> 16) & 0xff; outbuf[2] = (d1 >> 8) & 0xff; outbuf[3] = d1 & 0xff; outbuf[4] = (d2 >> 24) & 0xff; outbuf[5] = (d2 >> 16) & 0xff; outbuf[6] = (d2 >> 8) & 0xff; outbuf[7] = d2 & 0xff; } void Blowfish::decrypt_block(byte * outbuf, byte * inbuf) { do_decrypt_block(outbuf, inbuf); burn_stack(64); } bool Blowfish::selfTest() { byte plain1[] = "BLOWFISH"; byte key1[] = "abcdefghijklmnopqrstuvwxyz"; byte cipher1[] = "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03"; byte plain2[] = "\xFE\xDC\xBA\x98\x76\x54\x32\x10"; byte key2[] = "\x41\x79\x6E\xA0\x52\x61\x6E\xE4"; byte cipher2[] = "\xE1\x13\xF4\x10\x2C\xFC\xCE\x43"; byte buffer[8]; Blowfish blowfish; blowfish.bf_setkey(key1, array_size(key1) - 1); blowfish.bf_encrypt(buffer, plain1, array_size(plain1) - 1); if (unlikely(memcmp(buffer, cipher1, array_size(cipher1) - 1))) return false; blowfish.bf_decrypt(buffer, buffer, array_size(buffer)); if (unlikely(memcmp(buffer, plain1, array_size(plain1) - 1))) return false; blowfish.bf_setkey(key2, array_size(key2) - 1); blowfish.bf_encrypt(buffer, plain2, array_size(plain2) - 1); if (unlikely(memcmp(buffer, cipher2, array_size(cipher2) - 1))) return false; blowfish.bf_decrypt(buffer, buffer, array_size(buffer)); if (unlikely(memcmp(buffer, plain2, array_size(plain2) - 1))) return false; return true; } int Blowfish::do_bf_setkey(byte * key, unsigned int keylen) { int i, j; uint32_t data, datal, datar; for (i = 0; i < BLOWFISH_ROUNDS + 2; ++i) bc.p[i] = ps[i]; for (i = 0; i < 256; ++i) { bc.s0[i] = ks0[i]; bc.s1[i] = ks1[i]; bc.s2[i] = ks2[i]; bc.s3[i] = ks3[i]; } for (i = j = 0; i < BLOWFISH_ROUNDS + 2; ++i) { #ifdef BIG_ENDIAN_HOST ((byte *) & data)[0] = key[j]; ((byte *) & data)[1] = key[(j + 1) % keylen]; ((byte *) & data)[2] = key[(j + 2) % keylen]; ((byte *) & data)[3] = key[(j + 3) % keylen]; #else ((byte *) & data)[3] = key[j]; ((byte *) & data)[2] = key[(j + 1) % keylen]; ((byte *) & data)[1] = key[(j + 2) % keylen]; ((byte *) & data)[0] = key[(j + 3) % keylen]; #endif bc.p[i] ^= data; j = (j + 4) % keylen; } datal = datar = 0; for (i = 0; i < BLOWFISH_ROUNDS + 2; i += 2) { do_encrypt(&datal, &datar); bc.p[i] = datal; bc.p[i + 1] = datar; } for (i = 0; i < 256; i += 2) { do_encrypt(&datal, &datar); bc.s0[i] = datal; bc.s0[i + 1] = datar; } for (i = 0; i < 256; i += 2) { do_encrypt(&datal, &datar); bc.s1[i] = datal; bc.s1[i + 1] = datar; } for (i = 0; i < 256; i += 2) { do_encrypt(&datal, &datar); bc.s2[i] = datal; bc.s2[i + 1] = datar; } for (i = 0; i < 256; i += 2) { do_encrypt(&datal, &datar); bc.s3[i] = datal; bc.s3[i + 1] = datar; } /* Check for weak key. A weak key is a key in which a value in */ /* the P-array (here c) occurs more than once per table. */ for (i = 0; i < 255; ++i) { for (j = i + 1; j < 256; ++j) { if ((bc.s0[i] == bc.s0[j]) || (bc.s1[i] == bc.s1[j]) || (bc.s2[i] == bc.s2[j]) || (bc.s3[i] == bc.s3[j])) return 1; } } return 0; } int Blowfish::bf_setkey(byte * key, unsigned int keylen) { int rc = do_bf_setkey(key, keylen); burn_stack(64); return rc; } int Blowfish::bf_encrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) { if (unlikely(inbuf_len % 8)) return 1; unsigned int i = 0; while (i < inbuf_len) { encrypt_block(outbuf + i, inbuf + i); i += 8; } return 0; } int Blowfish::bf_decrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) { if (unlikely(inbuf_len % 8)) return 1; unsigned int i = 0; while (i < inbuf_len) { decrypt_block(outbuf + i, inbuf + i); i += 8; } return 0; } void Blowfish::padNull(string *buf) { buf->append(1, (char)0x01); string::size_type append_null = 8 - (buf->length() % 8); buf->append(append_null, (char)0x00); } bool Blowfish::unpadNull(string *buf) { if (unlikely(buf->size() % 8)) return false; string::size_type pos = buf->length() - 1; while ((*buf)[pos] != (char)0x01) { if (unlikely(pos == 0)) return false; --pos; } buf->erase(pos, buf->length() - pos); return true; } diff --git a/pwmanager/pwmanager/blowfish.h b/pwmanager/pwmanager/blowfish.h index 5129eab..862cccb 100644 --- a/pwmanager/pwmanager/blowfish.h +++ b/pwmanager/pwmanager/blowfish.h @@ -1,129 +1,131 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * blowfish.c - Blowfish encryption * * Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef BLOWFISH_H #define BLOWFISH_H -#include "pwmexception.h" +//#include "pwmexception.h" #ifndef _WIN32_ #include <stdint.h> #else #endif #include <string> using std::string; #define BLOWFISH_BLOCKSIZE 8 #define BLOWFISH_ROUNDS 16 #define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ #ifndef _WIN32_ typedef uint8_t byte; #else #define uint8_t Q_UINT8 #define byte Q_UINT8 #define uint32_t Q_UINT32 #endif +//#include "pwmexception.h" + /** blowfish encryption algorithm. * Derived from libgcrypt-1.1.12 */ class Blowfish { struct BLOWFISH_context { uint32_t s0[256]; uint32_t s1[256]; uint32_t s2[256]; uint32_t s3[256]; uint32_t p[BLOWFISH_ROUNDS+2]; }; public: Blowfish() {} static bool selfTest(); /** set key to encrypt. if return == 1, it is a weak key. */ int bf_setkey( byte *key, unsigned int keylen ); /** encrypt inbuf and return it in outbuf. * inbuf and outbuf have to be: buf % 8 == 0 * You may check this with getPaddedLen() and pad with NULL. */ int bf_encrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len ); /** decrypt inbuf and return it in outbuf. * inbuf and outbuf have to be: buf % 8 == 0 * You may check this with getPaddedLen() and pad with NULL. */ int bf_decrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len ); /** returns the length, the sting has to be padded to */ static unsigned int getPaddedLen(unsigned int inLen) { return ((8 - (inLen % 8)) + inLen); } /** pad up to 8 bytes. */ static void padNull(string *buf); /** remove padded data */ static bool unpadNull(string *buf); protected: #if BLOWFISH_ROUNDS != 16 uint32_t function_F( uint32_t x) { uint16_t a, b, c, d; #ifdef BIG_ENDIAN_HOST a = ((byte *) & x)[0]; b = ((byte *) & x)[1]; c = ((byte *) & x)[2]; d = ((byte *) & x)[3]; #else a = ((byte *) & x)[3]; b = ((byte *) & x)[2]; c = ((byte *) & x)[1]; d = ((byte *) & x)[0]; #endif return ((bc.s0[a] + bc.s1[b]) ^ bc.s2[c]) + bc.s3[d]; } #endif void R(uint32_t &l, uint32_t &r, uint32_t i, uint32_t *p, uint32_t *s0, uint32_t *s1, uint32_t *s2, uint32_t *s3) { l ^= p[i]; #ifdef BIG_ENDIAN_HOST r ^= (( s0[((byte*)&l)[0]] + s1[((byte*)&l)[1]]) ^ s2[((byte*)&l)[2]]) + s3[((byte*)&l)[3]]; #else r ^= (( s0[((byte*)&l)[3]] + s1[((byte*)&l)[2]]) ^ s2[((byte*)&l)[1]]) + s3[((byte*)&l)[0]]; #endif } void encrypt_block(byte *outbuf, byte *inbuf); void decrypt_block(byte *outbuf, byte *inbuf); void burn_stack(int bytes); void do_encrypt(uint32_t *ret_xl, uint32_t *ret_xr); void do_decrypt(uint32_t *ret_xl, uint32_t *ret_xr); void do_encrypt_block(byte *outbuf, byte *inbuf); void do_decrypt_block(byte *outbuf, byte *inbuf); int do_bf_setkey(byte *key, unsigned int keylen); protected: struct BLOWFISH_context bc; }; #endif diff --git a/pwmanager/pwmanager/genpasswd.cpp b/pwmanager/pwmanager/genpasswd.cpp index b0cceff..41078b3 100644 --- a/pwmanager/pwmanager/genpasswd.cpp +++ b/pwmanager/pwmanager/genpasswd.cpp @@ -1,192 +1,193 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #include "genpasswd.h" #include "pwmexception.h" #include "randomizer.h" +#include "globalstuff.h" /* how often can a char of the same charset be reused in order */ #define FILTER_MAX_CHARSET_REUSE 3 /* re-randomize all charsets on every iteration (0/1) */ #define RERAND_CHARSET 0 struct staticCharsetStruct { const char *lower; const char *upper; const char *num; const char *special; const char *blank; }; static struct staticCharsetStruct staticCharset = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "0123456789", "!\"§$%&/()=?,.-;:_+", " " }; GenPasswd::GenPasswd() : length (8) , useFilter (true) { dynCharset.setAutoDelete(true); } void GenPasswd::setCharset(bool lower, bool upper, bool num, bool special, bool blank, QString user) { unsigned int sanityCheck = 0; dynCharset_element *tmpElement; dynCharset.clear(); if (lower) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = staticCharset.lower; dynCharset.append(tmpElement); ++sanityCheck; } if (upper) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = staticCharset.upper; dynCharset.append(tmpElement); ++sanityCheck; } if (num) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = staticCharset.num; dynCharset.append(tmpElement); ++sanityCheck; } if (special) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = staticCharset.special; dynCharset.append(tmpElement); ++sanityCheck; } if (blank) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = staticCharset.blank; dynCharset.append(tmpElement); } if (!user.isEmpty()) { tmpElement = new dynCharset_element; tmpElement->refCnt = 0; tmpElement->data = user; dynCharset.append(tmpElement); if (likely(user.length() >= 2)) ++sanityCheck; } BUG_ON(!sanityCheck); rndDynCharset(); } void GenPasswd::rndDynCharset() { QString tmpData; int pos; Randomizer *rnd = Randomizer::obj(); // QPtrList<dynCharset_element>::iterator is not available in QT-3.1 unsigned int i, cnt = dynCharset.count(); dynCharset_element *p; for (i = 0; i < cnt; ++i) { p = dynCharset.at(i); PWM_ASSERT(p); tmpData = QString::null; while (p->data.length()) { pos = rnd->genRndInt() % p->data.length(); tmpData.append(p->data.at(pos)); p->data.remove(pos, 1); } p->data = tmpData; } } QString GenPasswd::gen() { BUG_ON(dynCharset.count() <= 0); BUG_ON(length < 1); dynCharset_element *curCharset; QString ret; int i; for (i = 0; i < length; ++i) { curCharset = selectNextCharset(); #if RERAND_CHARSET != 0 rndDynCharset(); #endif // RERAND_CHARSET ret += genNewRandom(curCharset); } return ret; } GenPasswd::dynCharset_element * GenPasswd::selectNextCharset() { dynCharset_element *ret; int numCharsets = dynCharset.count(); BUG_ON(numCharsets <= 0); if (numCharsets == 1) return dynCharset.at(0); Randomizer *rnd = Randomizer::obj(); if (useFilter) { // find out which charsets are allowed (filtering) QPtrList<dynCharset_element> allowedCharsets; // QPtrList<dynCharset_element>::iterator is not available in QT-3.1 unsigned int i, cnt = dynCharset.count(); dynCharset_element *p; for (i = 0; i < cnt; ++i) { p = dynCharset.at(i); PWM_ASSERT(p); if (p->refCnt < FILTER_MAX_CHARSET_REUSE) { allowedCharsets.append(p); } else { p->refCnt = 0; } } int numAllowedCharsets = allowedCharsets.count(); BUG_ON(numAllowedCharsets <= 0); // now get a random charset out of the allowed unsigned int randomPos = rnd->genRndUInt() % numAllowedCharsets; ret = allowedCharsets.at(randomPos); ret->refCnt++; return ret; } // all charsets are allowed here (no filtering). Get a random. unsigned int randomPos = rnd->genRndUInt() % numCharsets; ret = dynCharset.at(randomPos); return ret; } QChar GenPasswd::genNewRandom(const dynCharset_element *charset) { Randomizer *rnd = Randomizer::obj(); int pos = rnd->genRndInt() % charset->data.length(); return charset->data.at(pos); } diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h index 9a987a2..a08d678 100644 --- a/pwmanager/pwmanager/libgcryptif.h +++ b/pwmanager/pwmanager/libgcryptif.h @@ -1,177 +1,179 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * hashPassphrase() is derived from GnuPG and is * * Copyright (C) 1998, 1999, 2000, 2001, 2003 * * Free Software Foundation, Inc. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __LIBGCRYPTIF_H #define __LIBGCRYPTIF_H -#include "pwmexception.h" //#undef CONFIG_PWMANAGER_GCRY // for debugging only. #ifdef CONFIG_PWMANAGER_GCRY #include <stddef.h> #include <sys/types.h> #ifndef _WIN32_ #include <stdint.h> #else #define uint8_t Q_UINT8 #define byte Q_UINT8 #define uint32_t Q_UINT32 #endif #define STRING2KEY_SALTLEN 8 +#include "pwmexception.h" + + /** interface class for the libgcrypt cipher and hash algorithms * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding) */ class LibGCryptIf { protected: struct STRING2KEY { int mode; int hash_algo; uint8_t salt[STRING2KEY_SALTLEN]; uint32_t count; }; struct DEK { size_t keylen; uint8_t key[32]; // this is the largest used keylen (256 bit) }; public: LibGCryptIf() { } /** is libgcrypt available? */ static bool available() { return true; } /** encrypt data. _algo is the PWM_CRYPT_* ID * of the algorithm. */ PwMerror encrypt(unsigned char **outBuf, size_t *outBufLen, unsigned char *inBuf, size_t inBufLen, const unsigned char *key, size_t keylen, char _algo, char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase ); /** decrypt data. _algo is the PWM_CRYPT_* ID * of the algorithm. */ PwMerror decrypt(unsigned char **outBuf, size_t *outBufLen, const unsigned char *inBuf, size_t inBufLen, const unsigned char *key, size_t keylen, char _algo, char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase ); /** hash data. _algo is the PWM_HASH_* ID of the hash */ PwMerror hash(unsigned char **outBuf, size_t *outBufLen, const unsigned char *inBuf, size_t inBufLen, char _algo); /** returns the length of the hash. _algo is the PWM_HASH_* * id of the hash. returns 0 on error. */ unsigned int hashLength(char _algo); protected: /** returns the total buffer length */ size_t getBufLen(size_t inBufLen, size_t boundary) { return ((boundary - (inBufLen % boundary)) + inBufLen); } /** pad the data up to the given boundary. * "buf" has to be big enough! */ void padData(unsigned char *buf, size_t bufLen, size_t boundary); /** unpad the data */ void unpadData(const unsigned char *buf, size_t *bufLen); /** maps the PWM_CRYPT_* ID of an algorithm * to the libgcrypt GCRY_CIPHER_* ID */ int mapCipherId(char algo); /** maps the PWM_HASH_* ID of an algorithm * to the libgcrypt GCRY_MD_* ID */ int mapHashId(char algo); /** hash a passphrase to a cipher key */ bool hashPassphrase(const unsigned char *pw, size_t pwlen, unsigned char *salt, unsigned char *key, size_t keylen, bool create, char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase ); /** hash a passphrase to a cipher key */ bool doHashPassphrase(DEK *dek, const unsigned char *pw, size_t pwlen, STRING2KEY *s2k, bool create); }; #else // CONFIG_PWMANAGER_GCRY /** libgcrypt is not installed. This is a NOP wrapper. */ class LibGCryptIf { public: LibGCryptIf() { } static bool available() { return false; } PwMerror encrypt(unsigned char **, size_t *, unsigned char *, size_t, const unsigned char *, size_t, char) { return e_cryptNotImpl; } PwMerror decrypt(unsigned char **, size_t *, const unsigned char *, size_t, const unsigned char *, size_t, char) { return e_cryptNotImpl; } PwMerror hash(unsigned char **, size_t *, const unsigned char *, size_t, char) { return e_hashNotImpl; } unsigned int hashLength(char) { return 0; } }; #endif // CONFIG_PWMANAGER_GCRY #endif // __LIBGCRYPTIF_H diff --git a/pwmanager/pwmanager/pwmexception.h b/pwmanager/pwmanager/pwmexception.h index 301ebd7..7f5a3a6 100644 --- a/pwmanager/pwmanager/pwmexception.h +++ b/pwmanager/pwmanager/pwmexception.h @@ -1,217 +1,218 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __PWMEXCEPTION_H #define __PWMEXCEPTION_H -#include "globalstuff.h" +//#include "globalstuff.h" #include <iostream> #include <string> using std::string; using std::cerr; using std::cout; using std::endl; /* This is an internal function to reduce code-overhead * of the BUG(), WARN(), TOD0() and FiXME() macros. Please use * these macros instead of calling this function directly. */ void pwmFatal(const char *id, const char *file, int line); /** Use PWM_ASSERT(condition) for debugging assertions. * "condition" is eaten up and replaced with a NOP * when debugging is disabled. * * PWM_ASSERT_NOEAT(condition) is the same as PWM_ASSERT(condition), * but it does _not_ eat up "condition" and ensures that * condition is always evaluated. */ #ifdef PWM_ASSERT # undef PWM_ASSERT #endif #ifdef PWM_ASSERT_NOEAT # undef PWM_ASSERT_NOEAT #endif #ifdef PWM_DEBUG # define PWM_ASSERT(x) do { \ if (unlikely(!(x))) { \ cerr << "PWM_ASSERT failed: (" << #x \ << ") in " << __FILE__ \ << ":" << __LINE__ \ << endl; \ } \ } while (0) # define PWM_ASSERT_NOEAT(x) do { PWM_ASSERT(x); } while (0) #else // PWM_DEBUG # define PWM_ASSERT(x) do { } while (0) # define PWM_ASSERT_NOEAT(x) do { if (x) ; } while (0) #endif // PWM_DEBUG /** Insert a BUG() into code paths which clearly show * a bug in the code and which should, under normal * circumstances, never execute. */ #ifdef BUG # undef BUG #endif #define BUG() do { pwmFatal("BUG", __FILE__, __LINE__); } while (0) /** Use BUG_ON(condition) to print a bug-message if "condition" * is true. This is also enabled in non-debugging code. */ #ifdef BUG_ON # undef BUG_ON #endif #define BUG_ON(x) do { if (unlikely(x)) BUG(); } while (0) /** Insert a WARN() into code-paths which should not * execute normally, but if they do it's non-fatal. */ #ifdef WARN # undef WARN #endif #define WARN() do { pwmFatal("badness", __FILE__, __LINE__); } while (0) /** Same as BUG_ON() but prints a warning-message */ #ifdef WARN_ON # undef WARN_ON #endif #define WARN_ON(x) do { if (unlikely(x)) WARN(); } while (0) /** Insert this into code which is incomplete */ #ifdef TODO # undef TODO #endif #define TODO() do { pwmFatal("TODO", __FILE__, __LINE__); } while (0) /** Insert this into code which likely contains bugs */ #ifdef FIXME # undef FIXME #endif #define FIXME() do { pwmFatal("FIXME", __FILE__, __LINE__); } while (0) /** PwM error codes */ enum PwMerror { e_success = 0, // file access errors e_filename, e_readFile, e_writeFile, e_openFile, e_accessFile, // permission error, etc... e_fileGeneric, e_alreadyOpen, // other file errors e_fileVer, e_fileFormat, // format error e_unsupportedFormat, // completely unsupported format e_setFilePointer, e_fileBackup, e_fileCorrupt, // file data has correct format, // but is corrupt (checksum error, etc) // password errors e_wrongPw, e_getPw, e_weakPw, e_noPw, // action not implemented errors e_hashNotImpl, e_cryptNotImpl, // argument/parameter errors e_incompleteArg, e_invalidArg, // misc e_writeHeader, e_serializeDta, e_enc, e_entryExists, e_categoryExists, e_maxAllowedEntr, // no more entries can be added. e_outOfMem, e_lock, // error while (un)locking e_docNotSaved, // doc wasn't saved to a file, yet. e_docIsEmpty, e_binEntry, e_normalEntry, e_syncError, e_generic }; /** can be used for general exception faults */ class PwMException { public: enum exceptionId { EX_GENERIC = 0, EX_OPEN, EX_CLOSE, EX_READ, EX_WRITE, EX_LOAD_MODULE, EX_PARSE }; public: PwMException(exceptionId id = EX_GENERIC, const char *message = "") { exId = id; exMsg = message; } exceptionId getId() { return exId; } const char* getMessage() { return exMsg; } protected: /** ID of this exception */ exceptionId exId; /** additional error-message for this exception */ const char *exMsg; }; void __printInfo(const string &msg); void __printWarn(const string &msg); void __printError(const string &msg); #ifdef PWM_DEBUG void __printDebug(const string &msg); # define printDebug(x) __printDebug(x) #else # define printDebug(x) do { } while (0) #endif #define printInfo(x) __printInfo(x) #define printWarn(x) __printWarn(x) #define printError(x) __printError(x) +#include "globalstuff.h" #endif // __PWMEXCEPTION_H diff --git a/pwmanager/pwmanager/randomizer.h b/pwmanager/pwmanager/randomizer.h index f2a6015..44cc28e 100644 --- a/pwmanager/pwmanager/randomizer.h +++ b/pwmanager/pwmanager/randomizer.h @@ -1,86 +1,87 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __RANDOMIZER_H #define __RANDOMIZER_H #include "pwmexception.h" +#include "globalstuff.h" #ifndef PWM_EMBEDDED #include <qmutex.h> #endif #include <string> using std::string; class QFile; /** Randomizer to get random values. * This class is thread-safe. * You should always use the instance returned by * obj() to use it. */ class Randomizer { public: Randomizer(); ~Randomizer(); static Randomizer * obj() { PWM_ASSERT(rndObj); return rndObj; } static void init() { PWM_ASSERT(!rndObj); rndObj = new Randomizer; } static void cleanup() { delete_ifnot_null(rndObj); } /** generate random char */ char genRndChar(); /** generate random int */ int genRndInt(); /** generate a random unsigned int */ unsigned int genRndUInt(); /** returns a buffer with random data */ string genRndBuf(size_t len); /** returns a buffer with random data */ void genRndBuf(unsigned char *buf, size_t len); protected: /** random-device-node (if available. Otherwise NULL) */ QFile *rndDev; #ifndef PWM_EMBEDDED /** mutex for accessing the public functions thread-save */ QMutex mutex; #endif /** seed value for fallback - rand_r() */ unsigned int seed; /** static Randomizer object returned by obj() */ static Randomizer *rndObj; }; #endif // __RANDOMIZER_H |