-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 |
5 files changed, 5 insertions, 5 deletions
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: */ |