summaryrefslogtreecommitdiffabout
path: root/gammu/emb
authorzautrix <zautrix>2006-02-24 19:41:06 (UTC)
committer zautrix <zautrix>2006-02-24 19:41:06 (UTC)
commit4e2553b95b2787ed7917073f6b628819b1f017c3 (patch) (side-by-side diff)
treeda5cb746bf3373cb2a368afda082999e6c22751f /gammu/emb
parent08605356c77351d64e14e0fdd69bdb769f933909 (diff)
downloadkdepimpi-4e2553b95b2787ed7917073f6b628819b1f017c3.zip
kdepimpi-4e2553b95b2787ed7917073f6b628819b1f017c3.tar.gz
kdepimpi-4e2553b95b2787ed7917073f6b628819b1f017c3.tar.bz2
gcc4 fixes
Diffstat (limited to 'gammu/emb') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/phone/alcatel/alcatel.c2
-rw-r--r--gammu/emb/gammu/depend/nokia/dct3.c2
-rw-r--r--gammu/emb/gammu/depend/nokia/dct3trac/wmx.c2
-rw-r--r--gammu/emb/gammu/depend/nokia/dct4.c2
-rw-r--r--gammu/emb/gammu/depend/siemens/dsiemens.c2
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:
*/