21 files changed, 1216 insertions, 312 deletions
diff --git a/gammu/emb/common/phone/alcatel/alcatel.c b/gammu/emb/common/phone/alcatel/alcatel.c index f004ad4..3821f13 100644 --- a/gammu/emb/common/phone/alcatel/alcatel.c +++ b/gammu/emb/common/phone/alcatel/alcatel.c @@ -1,26 +1,26 @@ /* (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 + * 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 @@ -92,40 +92,41 @@ extern GSM_Error ATGEN_GetSecurityStatus (GSM_StateMachine *s, GSM_SecurityCodeT 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 */ @@ -159,123 +160,123 @@ unsigned char GSM_AlcatelAlphabet[] = 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" @@ -306,38 +307,38 @@ GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachi 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; @@ -367,25 +368,25 @@ static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_Binary {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, 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) { @@ -434,25 +435,25 @@ static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_Binary 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"); @@ -535,24 +536,26 @@ static GSM_Error ALCATEL_SetATMode(GSM_StateMachine *s) 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; } @@ -619,29 +622,29 @@ static GSM_Error ALCATEL_IsIdAvailable(GSM_StateMachine *s, int id) { 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); @@ -837,25 +840,25 @@ static GSM_Error ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message msg, GSM_StateM 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)) { @@ -1087,52 +1090,52 @@ static GSM_Error ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message msg, GSM_Stat 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, @@ -1204,27 +1207,27 @@ static GSM_Error ALCATEL_DeleteItem(GSM_StateMachine *s, int id) { 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; @@ -1320,68 +1323,68 @@ static GSM_Error ALCATEL_CreateField(GSM_StateMachine *s, GSM_Alcatel_FieldType 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, + 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; @@ -1734,59 +1737,59 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *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: + 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: + 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: @@ -1800,61 +1803,61 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) 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: + case PBK_Text_JobTitle: if ((error = ALCATEL_CreateField(s, Alcatel_string, 3, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Category: + case PBK_Category: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; - case PBK_Private: + 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; + 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: + 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: @@ -1897,131 +1900,131 @@ static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) 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; + 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; + 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; + 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; + 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; + 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; + 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; + if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Note: + 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; + 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; + 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; + 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; + 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; + 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; + 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: + 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; + 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: + 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; + 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; + 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; + 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; + 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: + 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; + 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: + 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: @@ -2060,29 +2063,29 @@ static GSM_Error ALCATEL_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entr 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; @@ -2219,25 +2222,25 @@ static GSM_Error ALCATEL_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *ne 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; @@ -2328,27 +2331,27 @@ static GSM_Error ALCATEL_SendDTMF(GSM_StateMachine *s, char *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; @@ -2718,25 +2721,25 @@ static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not } 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; @@ -2759,25 +2762,25 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not { 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; @@ -2797,25 +2800,25 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not 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; + 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; @@ -2833,25 +2836,25 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not 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; @@ -2891,34 +2894,34 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not 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; + 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; } @@ -2944,25 +2947,25 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not 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; + 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; @@ -2987,25 +2990,25 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not 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; @@ -3063,52 +3066,52 @@ 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) { @@ -3137,25 +3140,25 @@ static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) 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); @@ -3175,27 +3178,27 @@ static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) 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; @@ -3442,25 +3445,25 @@ static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) } 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; @@ -3481,25 +3484,25 @@ static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s) 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; } @@ -3509,25 +3512,25 @@ static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) } 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: + 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: @@ -3570,27 +3573,27 @@ static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) 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; @@ -3599,60 +3602,60 @@ static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) /* 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; + 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; + UpdatedFields[1] = true; break; - case TODO_ALARM_DATETIME: + 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; + UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[3] = true; + UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[10] = true; + UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[11] = true; + 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; + 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; + 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; + 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; + 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; + UpdatedFields[9] = true; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } @@ -3813,24 +3816,32 @@ static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable) 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 }, @@ -3904,24 +3915,25 @@ GSM_Phone_Functions ALCATELPhone = { 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 */ @@ -3958,25 +3970,25 @@ GSM_Phone_Functions ALCATELPhone = { 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, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/at/atgen.c b/gammu/emb/common/phone/at/atgen.c index 1834f15..ba23eb2 100644 --- a/gammu/emb/common/phone/at/atgen.c +++ b/gammu/emb/common/phone/at/atgen.c @@ -3,55 +3,35 @@ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" + #include "atgen.h" +#include "samsung.h" +#include "siemens.h" +#include "sonyeric.h" + #ifdef GSM_ENABLE_ALCATEL -extern GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s); +GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message, GSM_StateMachine *); #endif -extern GSM_Error ATGEN_CMS35ReplyGetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyGetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyGetNextCal (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyDeleteCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_SL45ReplyGetMemory (GSM_Protocol_Message msg, GSM_StateMachine *s); - -extern GSM_Error ATGEN_GetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone); -extern GSM_Error ATGEN_SetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength); -extern GSM_Error ATGEN_GetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap); -extern GSM_Error ATGEN_SetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap); -extern GSM_Error SIEMENS_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start); -extern GSM_Error SIEMENS_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SIEMENS_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); - -extern GSM_Error SONYERIC_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start); -extern GSM_Error SONYERIC_GetNextToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start); -extern GSM_Error SONYERIC_GetToDoStatus (GSM_StateMachine *s, GSM_ToDoStatus *status); -extern GSM_Error SONYERIC_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SONYERIC_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); -extern GSM_Error SONYERIC_DeleteAllToDo (GSM_StateMachine *s); -extern GSM_Error SONYERIC_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SONYERIC_GetCalendarStatus (GSM_StateMachine *s, GSM_CalendarStatus *Status); typedef struct { int Number; char Text[60]; } ATErrorCode; static ATErrorCode CMSErrorCodes[] = { /* * Error codes not specified here were either undefined or reserved in my * copy of specifications, if you have newer one, please fill in the gaps. */ /* 0...127 from GSM 04.11 Annex E-2 */ @@ -166,24 +146,26 @@ GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->ErrorCode == 0) { smprintf(s, "CME Error occured, but it's type not detected\n"); } else if (Priv->ErrorText == NULL) { smprintf(s, "CME Error %i, no description available\n", Priv->ErrorCode); } else { smprintf(s, "CME Error %i: \"%s\"\n", Priv->ErrorCode, Priv->ErrorText); } /* For error codes descriptions see table a bit above */ switch (Priv->ErrorCode) { + case -1: + return ERR_EMPTY; case 3: return ERR_PERMISSION; case 4: return ERR_NOTSUPPORTED; case 5: case 11: case 12: case 16: case 17: case 18: return ERR_SECURITYERROR; case 20: @@ -247,26 +229,34 @@ int ATGEN_ExtractOneParameter(unsigned char *input, unsigned char *output) *output=*input; input ++; output ++; position++; } *output=0; position++; return position; } void ATGEN_DecodeDateTime(GSM_DateTime *dt, unsigned char *input) { - dt->Year=2000+(*input-'0')*10; input++; + /* Samsung phones report year as %d instead of %02d */ + if (input[2] == '/') { + dt->Year=(*input-'0')*10; + input++; + } else { + dt->Year=0; + } + dt->Year=dt->Year+(*input-'0'); input++; + dt->Year+=2000; input++; dt->Month=(*input-'0')*10; input++; dt->Month=dt->Month+(*input-'0'); input++; input++; dt->Day=(*input-'0')*10; input++; dt->Day=dt->Day+(*input-'0'); input++; input++; dt->Hour=(*input-'0')*10; input++; dt->Hour=dt->Hour+(*input-'0'); input++; @@ -313,24 +303,36 @@ GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s) if (!strcmp(line,"OK")) Priv->ReplyState = AT_Reply_OK; if (!strcmp(line,"> ")) Priv->ReplyState = AT_Reply_SMSEdit; if (!strcmp(line,"CONNECT")) Priv->ReplyState = AT_Reply_Connect; if (!strcmp(line,"ERROR" )) Priv->ReplyState = AT_Reply_Error; if (!strncmp(line,"+CME ERROR:",11)) { Priv->ReplyState = AT_Reply_CMEError; ErrorCodes = CMEErrorCodes; } if (!strncmp(line,"+CMS ERROR:",11)) { Priv->ReplyState = AT_Reply_CMSError; ErrorCodes = CMSErrorCodes; } + + /* FIXME: Samsung phones can answer +CME ERROR:-1 meaning empty location */ + if (Priv->ReplyState == AT_Reply_CMEError && Priv->Manufacturer == AT_Samsung) { + err = line + 11; + Priv->ErrorCode = atoi(err); + + if (Priv->ErrorCode == -1) { + Priv->ErrorText = "[Samsung] Empty location"; + return GSM_DispatchMessage(s); + } + } + if (Priv->ReplyState == AT_Reply_CMEError || Priv->ReplyState == AT_Reply_CMSError) { j = 0; /* One char behind +CM[SE] ERROR */ err = line + 12; while (err[j] && !isalnum(err[j])) j++; if (isdigit(err[j])) { Priv->ErrorCode = atoi(&(err[j])); k = 0; while (ErrorCodes[k].Number != -1) { if (ErrorCodes[k].Number == Priv->ErrorCode) { Priv->ErrorText = (char *)&(ErrorCodes[k].Text); break; @@ -361,52 +363,90 @@ GSM_Error ATGEN_GenericReply(GSM_Protocol_Message msg, GSM_StateMachine *s) case AT_Reply_Error: return ERR_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } +GSM_Error ATGEN_ReplyGetUSSD(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + unsigned char buffer[2000],buffer2[4000]; + int i = 10; + + /* Ugly hack */ + while (msg.Buffer[i]!=13) i++; + i = i - 6; + memcpy(buffer,msg.Buffer+10,i-11); + buffer[i-11] = 0x00; + + smprintf(s, "USSD reply: \"%s\"\n",buffer); + + if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { + EncodeUnicode(buffer2,buffer,strlen(buffer)); + s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); + } + + return ERR_NONE; +} + +GSM_Error ATGEN_SetIncomingUSSD(GSM_StateMachine *s, bool enable) +{ + GSM_Error error; + + if (enable) { + smprintf(s, "Enabling incoming USSD\n"); + error=GSM_WaitFor (s, "AT+CUSD=1\r", 10, 0x00, 3, ID_SetUSSD); + } else { + smprintf(s, "Disabling incoming USSD\n"); + error=GSM_WaitFor (s, "AT+CUSD=0\r", 10, 0x00, 3, ID_SetUSSD); + } + if (error==ERR_NONE) s->Phone.Data.EnableIncomingUSSD = enable; + return error; +} + GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Phone_Data *Data = &s->Phone.Data; if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_NOTSUPPORTED; if (strlen(GetLineString(msg.Buffer, Priv->Lines, 2)) <= MAX_MODEL_LENGTH) { CopyLineString(Data->Model, msg.Buffer, Priv->Lines, 2); /* Sometimes phone adds this before manufacturer (Sagem) */ if (strncmp("+CGMM: ", Data->Model, 7) == 0) { memmove(Data->Model, Data->Model + 7, strlen(Data->Model + 7) + 1); } Data->ModelInfo = GetModelData(NULL,Data->Model,NULL); if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(NULL,NULL,Data->Model); if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(Data->Model,NULL,NULL); if (Data->ModelInfo->number[0] != 0) strcpy(Data->Model,Data->ModelInfo->number); if (strstr(msg.Buffer,"Nokia")) Priv->Manufacturer = AT_Nokia; else if (strstr(msg.Buffer,"M20")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer,"MC35")) Priv->Manufacturer = AT_Siemens; + else if (strstr(msg.Buffer,"TC35")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer, "iPAQ")) Priv->Manufacturer = AT_HP; if (strstr(msg.Buffer,"M20")) strcpy(Data->Model,"M20"); else if (strstr(msg.Buffer,"MC35")) strcpy(Data->Model,"MC35"); + else if (strstr(msg.Buffer,"TC35")) strcpy(Data->Model,"TC35"); else if (strstr(msg.Buffer, "iPAQ")) strcpy(Data->Model,"iPAQ"); } else { smprintf(s, "WARNING: Model name too long, increase MAX_MODEL_LENGTH to at least %zd\n", strlen(GetLineString(msg.Buffer, Priv->Lines, 2))); } return ERR_NONE; } GSM_Error ATGEN_GetModel(GSM_StateMachine *s) { GSM_Error error; @@ -472,24 +512,29 @@ GSM_Error ATGEN_ReplyGetManufacturer(GSM_Protocol_Message msg, GSM_StateMachine Priv->Manufacturer = AT_HP; } if (strstr(msg.Buffer,"ALCATEL")) { smprintf(s, "Alcatel\n"); strcpy(s->Phone.Data.Manufacturer,"Alcatel"); Priv->Manufacturer = AT_Alcatel; } if (strstr(msg.Buffer,"SAGEM")) { smprintf(s, "Sagem\n"); strcpy(s->Phone.Data.Manufacturer,"Sagem"); Priv->Manufacturer = AT_Sagem; } + if (strstr(msg.Buffer,"Samsung")) { + smprintf(s, "Samsung\n"); + strcpy(s->Phone.Data.Manufacturer,"Samsung"); + Priv->Manufacturer = AT_Samsung; + } return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetManufacturer(GSM_StateMachine *s) { if (s->Phone.Data.Manufacturer[0] != 0) return ERR_NONE; @@ -665,34 +710,44 @@ GSM_Error ATGEN_ReplyGetSMSMemories(GSM_Protocol_Message msg, GSM_StateMachine * case AT_Reply_OK: /* Reply here is: * (memories for reading)[, (memories for writing)[, (memories for storing received messages)]] * each memory is in quotes, * Example: ("SM"), ("SM"), ("SM") * * We need to get from this supported memories. For this case * we assume, that just appearence of memory makes it * available for everything. Then we need to find out whether * phone supports writing to memory. This is done by searching * for "), (", which will appear between lists. */ - s->Phone.Data.Priv.ATGEN.CanSaveSMS = (strstr(msg.Buffer, "), (") != NULL); + s->Phone.Data.Priv.ATGEN.CanSaveSMS = false; + if (strstr(msg.Buffer, "), (") != NULL || strstr(msg.Buffer, "),(") != NULL) { + s->Phone.Data.Priv.ATGEN.CanSaveSMS = true; + } + if (strstr(msg.Buffer, "\"SM\"") != NULL) s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_NOTAVAILABLE; + if (strstr(msg.Buffer, "\"ME\"") != NULL) s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_NOTAVAILABLE; - smprintf(s, "Available SMS memories received, ME = %d, SM = %d\n", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory); + + smprintf(s, "Available SMS memories received, ME = %d, SM = %d, cansavesms =", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory); + if (s->Phone.Data.Priv.ATGEN.CanSaveSMS) smprintf(s, "true"); + smprintf(s, "\n"); return ERR_NONE; case AT_Reply_Error: case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_GetSMSMemories(GSM_StateMachine *s) { smprintf(s, "Getting available SMS memories\n"); return GSM_WaitFor (s, "AT+CPMS=?\r", 10, 0x00, 4, ID_GetSMSMemories); } GSM_Error ATGEN_SetSMSMemory(GSM_StateMachine *s, bool SIM) @@ -849,26 +904,27 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s CopyLineString(buffer, msg.Buffer, Priv->Lines, 2); switch (buffer[7]) { case '0': sms->State = SMS_UnRead; break; case '1': sms->State = SMS_Read; break; case '2': sms->State = SMS_UnSent; break; default : sms->State = SMS_Sent; break;//case '3' } DecodeHexBin (buffer, GetLineString(msg.Buffer,Priv->Lines,3), strlen(GetLineString(msg.Buffer,Priv->Lines,3))); /* Siemens MC35 (only ?) */ if (strstr(msg.Buffer,"+CMGR: 0,,0")!=NULL) return ERR_EMPTY; /* Siemens M20 */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[1]!=NUMBER_UNKNOWN && buffer[1]!=NUMBER_INTERNATIONAL && - buffer[1]!=NUMBER_ALPHANUMERIC) { + /* we check for the most often visible */ + if (buffer[1]!=NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN && buffer[1]!=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN && + buffer[1]!=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { /* Seems to be Delivery Report */ smprintf(s, "SMS type - status report (M20 style)\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; smsframe[12]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPMR]=buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++]; smsframe[0] = 0; @@ -885,25 +941,25 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s switch (smsframe[12] & 0x03) { case 0x00: smprintf(s, "SMS type - deliver\n"); sms->PDU = SMS_Deliver; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 1; /*INBOX SIM*/ } else { sms->Folder = 3; /*INBOX ME*/ } sms->InboxFolder = true; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[current+1]==NUMBER_ALPHANUMERIC) { + if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSDeliver.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; } } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; } smsframe[PHONE_SMSDeliver.TPPID] = buffer[current++]; smsframe[PHONE_SMSDeliver.TPDCS] = buffer[current++]; @@ -916,49 +972,49 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s smprintf(s, "SMS type - submit\n"); sms->PDU = SMS_Submit; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 2; /*OUTBOX SIM*/ smprintf(s, "Outbox SIM\n"); } else { sms->Folder = 4; /*OUTBOX ME*/ } sms->InboxFolder = false; smsframe[PHONE_SMSSubmit.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[current+1]==NUMBER_ALPHANUMERIC) { + if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSSubmit.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; } } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; } smsframe[PHONE_SMSSubmit.TPPID] = buffer[current++]; smsframe[PHONE_SMSSubmit.TPDCS] = buffer[current++]; /* See GSM 03.40 9.2.3.3 - TPVP can not exist in frame */ if ((smsframe[12] & 0x18)!=0) current++; //TPVP is ignored now smsframe[PHONE_SMSSubmit.TPUDL] = buffer[current++]; for(i=0;i<smsframe[PHONE_SMSSubmit.TPUDL];i++) smsframe[i+PHONE_SMSSubmit.Text]=buffer[current++]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSSubmit); return ERR_NONE; case 0x02: smprintf(s, "SMS type - status report\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; - smprintf(s, "TPMR is %02x\n",buffer[current]); + smprintf(s, "TPMR is %d\n",buffer[current]); smsframe[PHONE_SMSStatusReport.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.SMSCTime+i]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPStatus]=buffer[current]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSStatusReport); return ERR_NONE; } break; case SMS_AT_TXT: current = 0; @@ -1631,35 +1687,35 @@ GSM_Error ATGEN_ReplySendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) if (s->Protocol.Data.AT.EditMode) { if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_SMSEdit) { return ERR_UNKNOWN; } s->Protocol.Data.AT.EditMode = false; return ERR_NONE; } switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "SMS sent OK\n"); if (s->User.SendSMSStatus!=NULL) { - start = strstr(msg.Buffer, "+CMGW: "); + start = strstr(msg.Buffer, "+CMGS: "); if (start != NULL) { s->User.SendSMSStatus(s->CurrentConfig->Device,0,atoi(start+7)); } else { - s->User.SendSMSStatus(s->CurrentConfig->Device,0,0); + s->User.SendSMSStatus(s->CurrentConfig->Device,0,-1); } } return ERR_NONE; case AT_Reply_CMSError: smprintf(s, "Error %i\n",Priv->ErrorCode); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,-1); return ATGEN_HandleCMSError(s); case AT_Reply_Error: return ERR_UNKNOWN; default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error,error2; int current, current2, Replies; @@ -1778,24 +1834,37 @@ GSM_Error ATGEN_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) GSM_Error ATGEN_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { if (alarm->Location != 1) return ERR_NOTSUPPORTED; alarm->Repeating = true; alarm->Text[0] = 0; alarm->Text[1] = 0; s->Phone.Data.Alarm = alarm; smprintf(s, "Getting alarm\n"); return GSM_WaitFor (s, "AT+CALA?\r", 9, 0x00, 4, ID_GetAlarm); } +/* R320 only takes HH:MM. Do other phones understand full date? */ +GSM_Error ATGEN_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) +{ + char req[20]; + + if (alarm->Location != 1) return ERR_INVALIDLOCATION; + + sprintf(req, "AT+CALA=\"%02i:%02i\"\r",alarm->DateTime.Hour,alarm->DateTime.Minute); + + smprintf(s, "Setting Alarm\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetAlarm); +} + GSM_Error ATGEN_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSC *SMSC = s->Phone.Data.SMSC; int current; int len; unsigned char buffer[100]; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "SMSC info received\n"); current = 0; @@ -2193,24 +2262,26 @@ GSM_Error ATGEN_GetMemoryInfo(GSM_StateMachine *s, GSM_MemoryStatus *Status, GSM char req[20]; int start; int end; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; smprintf(s, "Getting memory information\n"); Priv->MemorySize = 0; Priv->TextLength = 0; Priv->NumberLength = 0; error = GSM_WaitFor (s, "AT+CPBR=?\r", 10, 0x00, 4, ID_GetMemoryStatus); + if (Priv->Manufacturer == AT_Samsung) + error = GSM_WaitFor (s, "", 0, 0x00, 4, ID_GetMemoryStatus); if (error != ERR_NONE) return error; if (NeededInfo == AT_Total || NeededInfo == AT_Sizes || NeededInfo == AT_First) return ERR_NONE; smprintf(s, "Getting memory status by reading values\n"); s->Phone.Data.MemoryStatus = Status; Status->MemoryUsed = 0; Status->MemoryFree = 0; start = Priv->FirstMemoryEntry; Priv->NextMemoryEntry = 0; while (1) { end = start + 20; @@ -2259,24 +2330,30 @@ GSM_Error ATGEN_SetPBKCharset(GSM_StateMachine *s, bool PreferUnicode) /* If we want unicode charset and we have it already or setting of it * failed, we have nothing to do. */ if (PreferUnicode && (Priv->PBKCharset==AT_PBK_UCS2 || Priv->UCS2CharsetFailed)) return ERR_NONE; /* If we don't need unicode charset and we have some (or have unicode * charset when other failed), we have nothing to do. */ if (!PreferUnicode && (Priv->PBKCharset!=AT_PBK_UCS2 || Priv->NonUCS2CharsetFailed)) return ERR_NONE; } error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; + /* Samsung (and Sagem?) phones use only PCCP437? */ + if (Priv->Manufacturer == AT_Samsung) { + Priv->PBKCharset = AT_PBK_PCCP437; + return ERR_NONE; + } + if (PreferUnicode && !Priv->UCS2CharsetFailed) { smprintf(s, "Setting charset to UCS2\n"); error=GSM_WaitFor (s, "AT+CSCS=\"UCS2\"\r", 15, 0x00, 3, ID_SetMemoryCharset); if (error == ERR_NONE) { Priv->PBKCharset = AT_PBK_UCS2; return ERR_NONE; } else { Priv->UCS2CharsetFailed = true; } } smprintf(s, "Setting charset to HEX\n"); @@ -2376,25 +2453,55 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) Memory->Entries[1].EntryType=PBK_Text_Name; switch (Priv->PBKCharset) { case AT_PBK_HEX: DecodeHexBin(buffer2,buffer+1,strlen(buffer)-2); DecodeDefault(Memory->Entries[1].Text,buffer2,strlen(buffer2),false,NULL); break; case AT_PBK_GSM: DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); break; case AT_PBK_UCS2: DecodeHexUnicode(Memory->Entries[1].Text,buffer+1,strlen(buffer+1) - 1); break; + case AT_PBK_PCCP437: + /* FIXME: correctly decode PCCP437 */ + DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); + break; + } + + /* Samsung number type */ + if (Priv->Manufacturer == AT_Samsung) { + int type; + + pos += ATGEN_ExtractOneParameter(pos, buffer); + smprintf(s, "Number type: %s\n",buffer); + type = strtoul(buffer, NULL, 0); + switch (type) { + case 0: + Memory->Entries[0].EntryType = PBK_Number_Mobile; + break; + case 1: + Memory->Entries[0].EntryType = PBK_Number_Work; + break; + case 2: + Memory->Entries[0].EntryType = PBK_Number_Home; + break; + case 3: + Memory->Entries[0].EntryType = PBK_Text_Email; + break; + default: + Memory->Entries[0].EntryType = PBK_Number_General; + } } + return ERR_NONE; case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_Error: smprintf(s, "Error - too high location ?\n"); return ERR_INVALIDLOCATION; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; @@ -2553,24 +2660,26 @@ GSM_Error ATGEN_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber GSM_Error ATGEN_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Security code was OK\n"); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Incorrect security code\n"); return ERR_SECURITYERROR; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { unsigned char req[50]; switch (Code.Type) { case SEC_Pin : @@ -2915,24 +3024,30 @@ GSM_Error ATGEN_PrivSetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) EncodeHexBin(name, DecodeUnicodeString(entry->Entries[Name].Text), UnicodeLength(entry->Entries[Name].Text)); len = strlen(name); break; case AT_PBK_GSM: smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); len = UnicodeLength(entry->Entries[Name].Text); EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); break; case AT_PBK_UCS2: EncodeHexUnicode(name, entry->Entries[Name].Text, UnicodeLength(entry->Entries[Name].Text)); len = strlen(name); break; + case AT_PBK_PCCP437: + /* FIXME: correctly decode PCCP437 */ + smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); + len = UnicodeLength(entry->Entries[Name].Text); + EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); + break; } } else { smprintf(s, "WARNING: No usable name found!\n"); len = 0; } if (Number != -1) { GSM_PackSemiOctetNumber(entry->Entries[Number].Text, number, false); NumberType = number[0]; sprintf(number,"%s",DecodeUnicodeString(entry->Entries[Number].Text)); } else { smprintf(s, "WARNING: No usable number found!\n"); @@ -3243,24 +3358,61 @@ GSM_Error ATGEN_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) return ERR_NOTSUPPORTED; } GSM_Error ATGEN_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_DelCalendarNote(s, Note); if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_DelCalendarNote(s, Note); return ERR_NOTSUPPORTED; } + +GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetBitmap(s, Bitmap); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetBitmap(s, Bitmap); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetBitmap(s, Bitmap); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetBitmap(s, Bitmap); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetRingtone(s, Ringtone, PhoneRingtone); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetRingtone(s, Ringtone, PhoneRingtone); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetRingtone(s, Ringtone, maxlength); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetRingtone(s, Ringtone, maxlength); + return ERR_NOTSUPPORTED; +} + GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { GSM_Error error; unsigned char Frame[] = "AT+CKPD=\"?\"\r"; if (Press) { switch (Key) { case GSM_KEY_1 : Frame[9] = '1'; break; case GSM_KEY_2 : Frame[9] = '2'; break; case GSM_KEY_3 : Frame[9] = '3'; break; case GSM_KEY_4 : Frame[9] = '4'; break; case GSM_KEY_5 : Frame[9] = '5'; break; @@ -3337,24 +3489,35 @@ GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, bool enable) return GSM_WaitFor(s, "AT+CNMI=3,,2\r", 13, 0x00, 4, ID_SetIncomingCB); } else { smprintf(s, "Disabling incoming CB\n"); return GSM_WaitFor(s, "AT+CNMI=3,,0\r", 13, 0x00, 4, ID_SetIncomingCB); } } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } +GSM_Error ATGEN_SetFastSMSSending(GSM_StateMachine *s, bool enable) +{ + if (enable) { + smprintf(s, "Enabling fast SMS sending\n"); + return GSM_WaitFor(s, "AT+CMMS=2\r", 10, 0x00, 4, ID_SetFastSMSSending); + } else { + smprintf(s, "Disabling fast SMS sending\n"); + return GSM_WaitFor(s, "AT+CMMS=0\r", 10, 0x00, 4, ID_SetFastSMSSending); + } +} + GSM_Error ATGEN_IncomingSMSInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Incoming SMS\n"); return ERR_NONE; } GSM_Error ATGEN_IncomingSMSDeliver(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_SMSMessage sms; int current = 0, current2, i=0; unsigned char buffer[300],smsframe[800]; @@ -3415,32 +3578,49 @@ GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, bool enable) GSM_WaitFor(s, "AT+CNMI=3,,,1\r", 14, 0x00, 4, ID_SetIncomingSMS); /* SMS deliver */ return GSM_WaitFor(s, "AT+CNMI=3,3\r", 12, 0x00, 4, ID_SetIncomingSMS); } else { smprintf(s, "Disabling incoming SMS\n"); return GSM_WaitFor(s, "AT+CNMI=3,0\r", 12, 0x00, 4, ID_SetIncomingSMS); } } return ERR_NONE; } +GSM_Error ATGEN_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_GetLocale(s,locale); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_SetLocale(s,locale); + return ERR_NOTSUPPORTED; +} + GSM_Reply_Function ATGENReplyFunctions[] = { {ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_EnableEcho }, {ATGEN_GenericReply, "AT+CMEE=" ,0x00,0x00,ID_EnableErrorInfo }, {ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey }, {ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI }, {ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX }, +{ERICSSON_ReplyGetDateLocale, "*ESDF:" ,0x00,0x00,ID_GetLocale }, +{ERICSSON_ReplyGetTimeLocale, "*ESTF:" ,0x00,0x00,ID_GetLocale }, +{ATGEN_GenericReply, "AT*ESDF=" ,0x00,0x00,ID_SetLocale }, +{ATGEN_GenericReply, "AT*ESTF=" ,0x00,0x00,ID_SetLocale }, + #ifdef GSM_ENABLE_CELLBROADCAST {ATGEN_ReplyIncomingCB, "+CBM:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CNMI" ,0x00,0x00,ID_SetIncomingCB }, #endif {ATGEN_IncomingBattery, "_OBS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetBatteryCharge, "AT+CBC" ,0x00,0x00,ID_GetBatteryCharge }, {ATGEN_ReplyGetModel, "AT+CGMM" ,0x00,0x00,ID_GetModel }, {ATGEN_ReplyGetManufacturer, "AT+CGMI" ,0x00,0x00,ID_GetManufacturer }, {ATGEN_ReplyGetFirmwareCGMR, "AT+CGMR" ,0x00,0x00,ID_GetFirmware }, {ATGEN_ReplyGetFirmwareATI, "ATI" ,0x00,0x00,ID_GetFirmware }, @@ -3453,122 +3633,134 @@ GSM_Reply_Function ATGENReplyFunctions[] = { {ATGEN_GenericReply, "AT+CSDH" ,0x00,0x00,ID_GetSMSMode }, {ATGEN_ReplyGetSMSMessage, "AT+CMGR" ,0x00,0x00,ID_GetSMSMessage }, {ATGEN_GenericReply, "AT+CPMS" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_ReplyGetSMSStatus, "AT+CPMS" ,0x00,0x00,ID_GetSMSStatus }, {ATGEN_ReplyGetSMSMemories, "AT+CPMS=?" ,0x00,0x00,ID_GetSMSMemories }, {ATGEN_ReplyAddSMSMessage, "AT+CMGW" ,0x00,0x00,ID_SaveSMSMessage }, {ATGEN_GenericReply, "AT+CSMP" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "AT+CSCA" ,0x00,0x00,ID_SetSMSC }, {ATGEN_ReplyGetSMSC, "AT+CSCA?" ,0x00,0x00,ID_GetSMSC }, {ATGEN_ReplyDeleteSMSMessage, "AT+CMGD" ,0x00,0x00,ID_DeleteSMSMessage }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "\x1b\x0D" ,0x00,0x00,ID_SetSMSParameters }, +{ATGEN_GenericReply, "AT+CMMS" ,0x00,0x00,ID_SetFastSMSSending }, {ATGEN_IncomingSMSInfo, "+CMTI:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSDeliver, "+CMT:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSReport, "+CDS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSCInfo, "^SCN:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CCLK?" ,0x00,0x00,ID_GetDateTime }, {ATGEN_GenericReply, "AT+CCLK=" ,0x00,0x00,ID_SetDateTime }, +{ATGEN_GenericReply, "AT+CALA=" ,0x00,0x00,ID_SetAlarm }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CALA?" ,0x00,0x00,ID_GetAlarm }, {ATGEN_ReplyGetNetworkLAC_CID, "AT+CREG?" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+CREG=2" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_SetAutoNetworkLogin}, {ATGEN_ReplyGetNetworkCode, "AT+COPS" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_ReplyGetSignalQuality, "AT+CSQ" ,0x00,0x00,ID_GetSignalQuality }, {ATGEN_IncomingNetworkLevel, "_OSIGQ:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingGPRS, "+CGREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetNetworkLAC_CID, "+CREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetPBKMemories, "AT+CPBS=?" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_GenericReply, "AT+CPBS=" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_ReplyGetCPBSMemoryStatus,"AT+CPBS?" ,0x00,0x00,ID_GetMemoryStatus }, +// /* Samsung phones reply +CPBR: after OK --claudio*/ {ATGEN_ReplyGetCPBRMemoryInfo, "AT+CPBR=?" ,0x00,0x00,ID_GetMemoryStatus }, +{ATGEN_ReplyGetCPBRMemoryInfo, "+CPBR:" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_ReplyGetCPBRMemoryStatus,"AT+CPBR=" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_GenericReply, "AT+CSCS=" ,0x00,0x00,ID_SetMemoryCharset }, {ATGEN_ReplyGetMemory, "AT+CPBR=" ,0x00,0x00,ID_GetMemory }, {ATGEN_GenericReply, "AT^SBNR=?" ,0x00,0x00,ID_GetMemory }, -{ATGEN_SL45ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, +{SIEMENS_ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, {ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory }, -{ATGEN_CMS35ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, -{ATGEN_CMS35ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, +{SIEMENS_ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, +{SIEMENS_ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, -{ATGEN_CMS35ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, -{ATGEN_CMS35ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, +{SIEMENS_ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, +{SIEMENS_ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, -{ATGEN_CMS35ReplyGetNextCal, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, -{ATGEN_CMS35ReplySetCalendar, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, -{ATGEN_CMS35ReplyDeleteCalendar,"AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote }, +{SIEMENS_ReplyGetNextCalendar, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, +{SIEMENS_ReplyAddCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, +{SIEMENS_ReplyDelCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN2=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyGetSecurityStatus, "AT+CPIN?" ,0x00,0x00,ID_GetSecurityStatus }, {ATGEN_ReplyOK, "OK" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+VTS" ,0x00,0x00,ID_SendDTMF }, {ATGEN_ReplyCancelCall, "AT+CHUP" ,0x00,0x00,ID_CancelCall }, {ATGEN_ReplyDialVoice, "ATDT" ,0x00,0x00,ID_DialVoice }, {ATGEN_ReplyCancelCall, "ATH" ,0x00,0x00,ID_CancelCall }, +{ATGEN_GenericReply, "AT+CUSD" ,0x00,0x00,ID_SetUSSD }, +{ATGEN_ReplyGetUSSD, "+CUSD" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CLIP=1" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+CLIP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+COLP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "RING" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "NO CARRIER" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyReset, "AT^SRESET" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyReset, "AT+CFUN=1,1" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyResetPhoneSettings, "AT&F" ,0x00,0x00,ID_ResetPhoneSettings }, +{SAMSUNG_ReplyGetBitmap, "AT+IMGR=" ,0x00,0x00,ID_GetBitmap }, +{SAMSUNG_ReplySetBitmap, "SDNDCRC =" ,0x00,0x00,ID_SetBitmap }, + +{SAMSUNG_ReplyGetRingtone, "AT+MELR=" ,0x00,0x00,ID_GetRingtone }, +{SAMSUNG_ReplySetRingtone, "SDNDCRC =" ,0x00,0x00,ID_SetRingtone }, + #ifdef GSM_ENABLE_ALCATEL /* Why do I give Alcatel specific things here? It's simple, Alcatel needs * some AT commands to start it's binary mode, so this needs to be in AT * related stuff. * * XXX: AT+IFC could later move outside this ifdef, because it is not Alcatel * specific and it's part of ETSI specifications */ {ATGEN_GenericReply, "AT+IFC" ,0x00,0x00,ID_SetFlowControl }, {ALCATEL_ProtocolVersionReply, "AT+CPROT=?" ,0x00,0x00,ID_AlcatelProtocol }, {ATGEN_GenericReply, "AT+CPROT" ,0x00,0x00,ID_AlcatelConnect }, #endif {NULL, "\x00" ,0x00,0x00,ID_None } }; GSM_Phone_Functions ATGENPhone = { - "A2D|iPAQ|at|M20|S25|MC35|C35i|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210", + "A2D|iPAQ|at|M20|S25|MC35|TC35|C35i|S300|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210", ATGENReplyFunctions, ATGEN_Initialise, ATGEN_Terminate, ATGEN_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ATGEN_GetManufacturer, ATGEN_GetModel, ATGEN_GetFirmware, ATGEN_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ATGEN_GetSIMIMSI, ATGEN_GetDateTime, ATGEN_SetDateTime, ATGEN_GetAlarm, - NOTIMPLEMENTED, /* SetAlarm */ - NOTSUPPORTED, /* GetLocale */ - NOTSUPPORTED, /* SetLocale */ + ATGEN_SetAlarm, + ATGEN_GetLocale, + ATGEN_SetLocale, ATGEN_PressKey, ATGEN_Reset, ATGEN_ResetPhoneSettings, ATGEN_EnterSecurityCode, ATGEN_GetSecurityStatus, ATGEN_GetDisplayStatus, ATGEN_SetAutoNetworkLogin, ATGEN_GetBatteryCharge, ATGEN_GetSignalQuality, ATGEN_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ @@ -3583,43 +3775,44 @@ GSM_Phone_Functions ATGENPhone = { NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ ATGEN_GetSMSC, ATGEN_SetSMSC, ATGEN_GetSMSStatus, ATGEN_GetSMS, ATGEN_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ATGEN_AddSMS, ATGEN_DeleteSMS, ATGEN_SendSMS, ATGEN_SendSavedSMS, + ATGEN_SetFastSMSSending, ATGEN_SetIncomingSMS, ATGEN_SetIncomingCB, ATGEN_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ATGEN_DialVoice, ATGEN_AnswerCall, ATGEN_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NONEFUNCTION, /* SetIncomingCall */ - NOTSUPPORTED, /* SetIncomingUSSD */ + ATGEN_SetIncomingUSSD, ATGEN_SendDTMF, ATGEN_GetRingtone, ATGEN_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ @@ -3637,25 +3830,25 @@ GSM_Phone_Functions ATGENPhone = { SONYERIC_AddToDo, NOTSUPPORTED, /* DeleteToDo */ SONYERIC_DeleteAllToDo, SONYERIC_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ ATGEN_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ ATGEN_AddCalendarNote, ATGEN_DelCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/at/atgen.h b/gammu/emb/common/phone/at/atgen.h index 0e08ee4..bb5c559 100644 --- a/gammu/emb/common/phone/at/atgen.h +++ b/gammu/emb/common/phone/at/atgen.h @@ -33,31 +33,33 @@ typedef enum { AT_Reply_CMEError, AT_Reply_SMSEdit } GSM_AT_Reply_State; typedef enum { AT_Nokia = 1, AT_Alcatel, AT_Siemens, AT_HP, AT_Falcom, AT_Ericsson, AT_Sagem, + AT_Samsung, AT_Unknown } GSM_AT_Manufacturer; typedef enum { AT_PBK_HEX = 1, AT_PBK_GSM, - AT_PBK_UCS2 + AT_PBK_UCS2, + AT_PBK_PCCP437 } GSM_AT_PBK_Charset; typedef enum { AT_AVAILABLE = 1, AT_NOTAVAILABLE } GSM_AT_SMSMemory; typedef enum { AT_SBNR_AVAILABLE = 1, AT_SBNR_NOTAVAILABLE } GSM_AT_SBNR; @@ -94,17 +96,21 @@ typedef struct { int LastSMSRead; int FirstCalendarPos; bool CanSaveSMS; GSM_AT_SMSMemory PhoneSMSMemory; /* Is phone SMS memory available ? */ GSM_AT_SMSMemory SIMSMSMemory; /* Is SIM SMS memory available ? */ GSM_MemoryType SMSMemory; /* Last read SMS memory */ GSM_AT_SMS_Modes SMSMode; /* PDU or TEXT mode for SMS ? */ bool OBEX; GSM_File file; } GSM_Phone_ATGENData; +GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *); +GSM_Error ATGEN_HandleCMEError (GSM_StateMachine *); +GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *); + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/at/samsung.c b/gammu/emb/common/phone/at/samsung.c new file mode 100644 index 0000000..55a42e5 --- a/dev/null +++ b/gammu/emb/common/phone/at/samsung.c @@ -0,0 +1,447 @@ +/* Samsung-specific functions + * Copyright (C) 2004 Claudio Matsuoka <cmatsuoka@gmail.com> + * Tested with S300 only! + */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_ATGEN + +#include <string.h> +#include <time.h> +#include <ctype.h> + +#include "../../misc/coding/coding.h" +#include "../../gsmcomon.h" +#include "../../service/sms/gsmsms.h" +#include "../pfunc.h" + +#include "atgen.h" +#include "samsung.h" + +/* Binary frame size */ +#define BLKSZ 1024 + +struct ModelRes { + char *model; + int width; + int height; +}; + +static struct ModelRes modres[] = { + { "S100", 128, 128 }, + { "S200", 128, 113 }, + { "S300", 128, 97 }, + { "S500", 128, 128 }, + { "T100", 128, 128 }, + { "E700", 128, 128 }, + { NULL, 0, 0 } +}; + +/* + * CRC functions from the Granch SBNI12 Linux driver by + * Denis I. Timofeev <timofeev@granch.ru> + */ +static unsigned int crc32tab[] = { + 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37, + 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E, + 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605, + 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C, + 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53, + 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A, + 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661, + 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278, + 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF, + 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6, + 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD, + 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4, + 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B, + 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82, + 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9, + 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0, + 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7, + 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE, + 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795, + 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C, + 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3, + 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA, + 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1, + 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8, + 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F, + 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76, + 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D, + 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344, + 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B, + 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12, + 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739, + 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320, + 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17, + 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E, + 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525, + 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C, + 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73, + 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A, + 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541, + 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158, + 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF, + 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6, + 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED, + 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4, + 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB, + 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2, + 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589, + 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190, + 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87, + 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E, + 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5, + 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC, + 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3, + 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA, + 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1, + 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8, + 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F, + 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856, + 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D, + 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064, + 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B, + 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832, + 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419, + 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000 +}; + +static unsigned int GetCRC(char *data, int size) +{ + unsigned int crc = 0; + + while (size--) + crc = crc32tab[(crc ^ *data++) & 0xff] ^ ((crc >> 8) & 0x00FFFFFF); + + return crc; +} + +/* + * Frame transfer + */ + +static GSM_Error WaitFor(GSM_StateMachine *s, char *t, int ttl) +{ + char readbuf[100]; + int n; + unsigned int sec; + GSM_DateTime Date; + + GSM_GetCurrentDateTime (&Date); + sec = Date.Second; + + n = s->Device.Functions->ReadDevice(s, readbuf, 80); + readbuf[n] = 0; + while (strstr(readbuf, t) == NULL && (sec + ttl) >= Date.Second) { + my_sleep(5000); + n = s->Device.Functions->ReadDevice(s, readbuf, 80); + readbuf[n] = 0; + GSM_GetCurrentDateTime (&Date); + } + + return (sec + ttl) >= Date.Second ? ERR_NONE : ERR_TIMEOUT; +} + +static GSM_Error SetSamsungFrame(GSM_StateMachine *s, unsigned char *buff, int size, GSM_Phone_RequestID id) +{ + GSM_Phone_Data *Phone = &s->Phone.Data; + GSM_Error error; + int i, count; + + count = size / BLKSZ; + + for (i = 0; i < count; i++) { + error = WaitFor(s, ">", 4); + if (error!=ERR_NONE) return error; + + error = s->Protocol.Functions->WriteMessage(s, + buff + i * BLKSZ, BLKSZ, 0x00); + if (error!=ERR_NONE) return error; + } + + error = WaitFor(s, ">", 4); + if (error!=ERR_NONE) return error; + error = s->Protocol.Functions->WriteMessage(s, + buff + i * BLKSZ, size%BLKSZ, 0x00); + if (error!=ERR_NONE) return error; + + error = GSM_WaitFor(s, "", 0, 0x00, 4, id); + if (error!=ERR_NONE) return error; + + return Phone->DispatchError; +} + +/* Answer format for binary data transfer + * + * SDNDCRC = 0xa : RECEIVECRC = 0xcbf53a1c : BINSIZE = 5 + * CRCERR + */ +static GSM_Error ReplySetSamsungFrame(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + unsigned long txcrc, rxcrc; + int binsize; + char *pos; + + /* Parse SDNDCRC */ + pos = strchr(msg.Buffer, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + txcrc = strtoul(pos, NULL, 0); + smprintf(s, "Sent CRC : 0x%lx\n", txcrc); + + /* Parse RECEIVECRC */ + pos = strchr(pos, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + rxcrc = strtoul(pos, NULL, 0); + smprintf(s, "Reveived CRC : 0x%lx\n", rxcrc); + + /* Parse BINSIZE */ + pos = strchr(pos, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + binsize = strtoul(pos, NULL, 0); + smprintf(s, "Binary size : %d\n", binsize); + + return txcrc == rxcrc ? ERR_NONE : ERR_WRONGCRC; +} + +/* + * Bitmaps + */ + +GSM_Error SAMSUNG_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + unsigned char buffer[32]; + char *pos; + int location, count; + + switch (Priv->ReplyState) { + case AT_Reply_OK: + smprintf(s, "Bitmap info received\n"); + /* Parse +IMGR:location,name,0,0,0,0 */ + + /* Parse location */ + pos = strchr(msg.Buffer, ':'); + if (!pos) return ERR_UNKNOWN; + pos++; + location = atoi(pos); + smprintf(s, "Location : %d\n", location); + + /* Parse name */ + pos = strchr(pos, '"'); + if (!pos) return ERR_UNKNOWN; + pos++; + for (count = 0; count < 31; count++) { + if (pos[count] == '"') + break; + buffer[count] = pos[count]; + } + buffer[count] = 0; + smprintf(s, "Name : %s\n", buffer); + s->Phone.Data.Bitmap->Name = malloc((strlen(buffer) + 1) * 2); + if (s->Phone.Data.Bitmap->Name == NULL) + return ERR_MOREMEMORY; + EncodeUnicode(s->Phone.Data.Bitmap->Name, buffer, strlen(buffer)); + + s->Phone.Data.Bitmap->Location = location; + + return ERR_NONE; + case AT_Reply_Error: + return ERR_UNKNOWN; + case AT_Reply_CMSError: + return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); + default: + return ERR_UNKNOWNRESPONSE; + } +} + +GSM_Error SAMSUNG_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Bitmap sent\n"); + return ReplySetSamsungFrame(msg, s); +} + +GSM_Error SAMSUNG_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + unsigned char req[100]; + + s->Phone.Data.Bitmap=Bitmap; + smprintf(s, "Getting bitmap\n"); + sprintf(req, "AT+IMGR=%d\r", Bitmap->Location-1); + return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap); +} + +GSM_Error SAMSUNG_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + unsigned char req[100]; + unsigned long crc; + GSM_Error error; + char name[50], *dot, *model; + GSM_Phone_Data *Data = &s->Phone.Data; + int i; + + s->Phone.Data.Bitmap = Bitmap; + smprintf(s, "Setting bitmap\n"); + + if (Bitmap->Type != GSM_PictureBinary) { + smprintf(s, "Invalid picture type\n"); + return ERR_INVALIDDATA; + } + + if (Bitmap->BinaryPic.Type != PICTURE_GIF) { + smprintf(s, "Invalid binary picture type\n"); + return ERR_INVALIDDATA; + } + + /* Check if picture size matches phone model */ + model = GetModelData(NULL,Data->Model,NULL)->model; + smprintf(s, "Checking picture size for %s\n", model); + for (i = 0; modres[i].model; i++) { + if (!strcmp(model, modres[i].model)) { + if (Bitmap->BitmapWidth != modres[i].width || + Bitmap->BitmapHeight != modres[i].height) { + smprintf(s, "Model %s must use %d x %d picture size\n", + modres[i].model, modres[i].width, + modres[i].height); + return ERR_INVALIDDATA; + } + break; + } + } + if (modres[i].model == NULL) { + smprintf(s, "Model \"%s\" is not supported.\n", Data->Model); + return ERR_NOTSUPPORTED; + } + + crc = GetCRC(Bitmap->BinaryPic.Buffer, Bitmap->BinaryPic.Length); + + /* Remove extension from file name */ + strncpy(name, DecodeUnicodeString(Bitmap->Name), 50); + if ((dot = strrchr(name, '.')) != NULL) + *dot = 0; + + sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%d,%u\r", name, + Bitmap->BinaryPic.Length, (unsigned int)crc); + + error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00); + if (error!=ERR_NONE) return error; + + return SetSamsungFrame(s, Bitmap->BinaryPic.Buffer, + Bitmap->BinaryPic.Length, ID_SetBitmap); +} + +/* + * Ringtones + */ + +GSM_Error SAMSUNG_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + unsigned char buffer[32]; + char *pos; + int location, length, count; + + switch (Priv->ReplyState) { + case AT_Reply_OK: + smprintf(s, "Ringtone info received\n"); + /* Parse +MELR:location,name,size */ + + /* Parse location */ + pos = strchr(msg.Buffer, ':'); + if (!pos) return ERR_UNKNOWN; + pos++; + location = atoi(pos); + smprintf(s, "Location : %d\n", location); + + /* Parse name */ + pos = strchr(pos, '"'); + if (!pos) return ERR_UNKNOWN; + pos++; + /* Ringtone.Name size is 20 chars */ + for (count = 0; count < 19; count++) { + if (pos[count] == '"') + break; + buffer[count] = pos[count]; + } + buffer[count] = 0; + smprintf(s, "Name : %s\n", buffer); + EncodeUnicode(s->Phone.Data.Ringtone->Name,buffer,strlen(buffer)); + + /* Parse ringtone length */ + pos = strchr(pos, ','); + if (!pos) return ERR_UNKNOWN; + pos++; + length = atoi(pos); + smprintf(s, "Length : %d\n", length); + + /* S300 ringtones are always MMF */ + s->Phone.Data.Ringtone->Format = RING_MMF; + s->Phone.Data.Ringtone->Location = location; + s->Phone.Data.Ringtone->BinaryTone.Length = length; + + return ERR_NONE; + case AT_Reply_Error: + return ERR_UNKNOWN; + case AT_Reply_CMSError: + return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); + default: + return ERR_UNKNOWNRESPONSE; + } +} + +GSM_Error SAMSUNG_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +{ + unsigned char req[100]; + + s->Phone.Data.Ringtone = Ringtone; + smprintf(s, "Getting ringtone\n"); + sprintf(req, "AT+MELR=%d\r", Ringtone->Location-1); + return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone); +} + +GSM_Error SAMSUNG_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Ringtone sent\n"); + return ReplySetSamsungFrame(msg, s); +} + +GSM_Error SAMSUNG_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +{ + unsigned char req[100]; + unsigned long crc; + GSM_Error error; + char name[50], *dot; + + s->Phone.Data.Ringtone = Ringtone; + smprintf(s, "Setting ringtone\n"); + + if (Ringtone->Format != RING_MMF) { + smprintf(s, "Not MMF ringtone\n"); + return ERR_INVALIDDATA; + } + + /* Remove extension from file name */ + strncpy(name, DecodeUnicodeString(Ringtone->Name), 50); + if ((dot = strrchr(name, '.')) != NULL) *dot = 0; + + crc = GetCRC(Ringtone->BinaryTone.Buffer, Ringtone->BinaryTone.Length); + sprintf(req, "AT+MELW=0,\"%s\",4,%d,%u\r", name, + Ringtone->BinaryTone.Length, (unsigned int)crc); + + error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00); + if (error!=ERR_NONE) return error; + + return SetSamsungFrame(s, Ringtone->BinaryTone.Buffer, + Ringtone->BinaryTone.Length, ID_SetRingtone); +} + +#endif diff --git a/gammu/emb/common/phone/at/samsung.h b/gammu/emb/common/phone/at/samsung.h new file mode 100644 index 0000000..3b2947c --- a/dev/null +++ b/gammu/emb/common/phone/at/samsung.h @@ -0,0 +1,16 @@ +#ifndef samsung_h +#define samsung_h + +#include "../../gsmstate.h" + +GSM_Error SAMSUNG_ReplyGetRingtone (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplySetRingtone (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplyGetBitmap (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplySetBitmap (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_GetRingtone (GSM_StateMachine *, GSM_Ringtone *, bool); +GSM_Error SAMSUNG_SetRingtone (GSM_StateMachine *, GSM_Ringtone *, int *); +GSM_Error SAMSUNG_GetBitmap (GSM_StateMachine *, GSM_Bitmap *); +GSM_Error SAMSUNG_SetBitmap (GSM_StateMachine *, GSM_Bitmap *); +GSM_Error SAMSUNG_GetCallLogs (GSM_StateMachine *, GSM_MemoryEntry *, int); + +#endif diff --git a/gammu/emb/common/phone/at/siemens.c b/gammu/emb/common/phone/at/siemens.c index ab7dd2c..7f66cf8 100644 --- a/gammu/emb/common/phone/at/siemens.c +++ b/gammu/emb/common/phone/at/siemens.c @@ -4,43 +4,29 @@ #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include <ctype.h> #include "../../misc/coding/coding.h" #include "../../gsmcomon.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" -extern GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s); +#include "atgen.h" +#include "siemens.h" -GSM_Error ATGEN_CMS35ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function) -{ - if (s->Protocol.Data.AT.EditMode) { - s->Protocol.Data.AT.EditMode = false; - return ERR_NONE; - } - dbgprintf ("Written %s",function); - if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){ - dbgprintf (" - OK\n"); - return ERR_NONE; - } else { - dbgprintf (" - error\n"); - return ERR_UNKNOWN; - } -} -GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ, +static GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ, unsigned char *buffer, int *len) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int i=2, pos=0, length=0; unsigned char buf[512]; if (strstr(GetLineString(msg.Buffer,Priv->Lines,2),"OK")) return ERR_EMPTY; if (!strstr(GetLineString(msg.Buffer,Priv->Lines,2),templ)) return ERR_UNKNOWN; while (1) { if (Priv->Lines.numbers[i*2+1]==0) break; if ((!strstr(GetLineString(msg.Buffer,Priv->Lines,i+1),templ)) && @@ -48,25 +34,25 @@ GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *t length = strlen(GetLineString(msg.Buffer,Priv->Lines,i+1)); DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,i+1),length); length = length/2; memcpy (buffer+pos,buf,length); pos+=length; } i++; } *len = pos; return ERR_NONE; } -GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ, +static GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ, int Location, GSM_Phone_RequestID RequestID, int len) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Error error; unsigned char req[20],req1[512],hexreq[2096]; int MaxFrame,CurrentFrame,size,sz,pos=0; EncodeHexBin(hexreq,buff,len); size = len * 2; MaxFrame = size / 352; if (size % 352) MaxFrame++; @@ -81,125 +67,135 @@ GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ if (error!=ERR_NONE) return error; memcpy (req1,hexreq+pos,sz); error = s->Protocol.Functions->WriteMessage(s, req1, sz, 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_TIMEOUT) return error; } return Phone->DispatchError; } -GSM_Error ATGEN_CMS35ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[4096]; int length; GSM_Error error; error = GetSiemensFrame(msg,s,"bmp",buffer,&length); if (error!=ERR_NONE) return error; dbgprintf ("Operator logo received lenght=%i\n",length); error = BMP2Bitmap (buffer,NULL,s->Phone.Data.Bitmap); if (error==ERR_NONE) return error; else return ERR_UNKNOWN; } -GSM_Error ATGEN_CMS35ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Operator Logo");
+ if (s->Protocol.Data.AT.EditMode) { + s->Protocol.Data.AT.EditMode = false; + return ERR_NONE; + } + dbgprintf ("Written %s",function); + if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){ + dbgprintf (" - OK\n"); + return ERR_NONE; + } else { + dbgprintf (" - error\n"); + return ERR_UNKNOWN; + } } -GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +GSM_Error SIEMENS_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + return SIEMENS_ReplySetFunction (msg, s, "Operator Logo");
+} + +GSM_Error SIEMENS_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char req[32]; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; if (Bitmap->Location-1 < 0) Bitmap->Location++; s->Phone.Data.Bitmap=Bitmap; sprintf(req, "AT^SBNR=\"bmp\",%i\r", Bitmap->Location-1); smprintf(s, "Getting Bitmap\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap); } -GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +GSM_Error SIEMENS_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char buffer[4096]; int length; GSM_Error error; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; error = Bitmap2BMP (buffer,NULL,Bitmap); if (error!=ERR_NONE) return error; length = 0x100 * buffer[3] + buffer[2]; buffer[58]=0xff; buffer[59]=0xff; buffer[60]=0xff; if (Bitmap->Location-1 < 0) Bitmap->Location++; s->Phone.Data.Bitmap=Bitmap; return SetSiemensFrame(s, buffer,"bmp",Bitmap->Location-1, ID_SetBitmap,length); } -GSM_Error ATGEN_CMS35ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[32]; int length; GSM_Error error; error = GetSiemensFrame(msg,s,"mid",s->Phone.Data.Ringtone->NokiaBinary.Frame,&length); if (error!=ERR_NONE) return error; dbgprintf ("Midi ringtone received\n"); s->Phone.Data.Ringtone->Format = RING_MIDI; s->Phone.Data.Ringtone->NokiaBinary.Length = length; sprintf(buffer,"Individual"); EncodeUnicode (s->Phone.Data.Ringtone->Name,buffer,strlen(buffer)); return ERR_NONE; } -GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +GSM_Error SIEMENS_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { unsigned char req[32]; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; - s->Phone.Data.Ringtone=Ringtone; sprintf(req, "AT^SBNR=\"mid\",%i\r", Ringtone->Location-1); smprintf(s, "Getting RingTone\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone); } -GSM_Error ATGEN_CMS35ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Ringtone"); + return SIEMENS_ReplySetFunction (msg, s, "Ringtone"); } -GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +GSM_Error SIEMENS_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Phone_Data *Phone = &s->Phone.Data; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; - if (Ringtone->Location==255) Ringtone->Location=1; if (Ringtone->Location-1 > 1) return ERR_INVALIDLOCATION; s->Phone.Data.Ringtone = Ringtone; Phone->Ringtone = Ringtone; return SetSiemensFrame(s, Ringtone->NokiaBinary.Frame,"mid",Ringtone->Location-1, ID_SetRingtone,Ringtone->NokiaBinary.Length); } -GSM_Error ATGEN_CMS35ReplyGetNextCal(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetNextCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_CalendarEntry *Calendar = Data->Cal; GSM_ToDoEntry ToDo; GSM_Error error; unsigned char buffer[354]; int len, pos=0; if (Data->Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_UNKNOWN; error = GetSiemensFrame(msg,s,"vcs",buffer,&len); if (error!=ERR_NONE) return error; @@ -226,30 +222,30 @@ GSM_Error SIEMENS_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, Location++; sprintf(req, "AT^SBNR=\"vcs\",%i\r",Location); error = GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetCalendarNote); if ((error!=ERR_NONE) && (error!=ERR_EMPTY)) return ERR_INVALIDLOCATION; Note->Location = Location; Priv->FirstCalendarPos = Location; if (Location > MAX_VCALENDAR_LOCATION) return ERR_EMPTY; if (error==ERR_NONE) return error; } return error; } -GSM_Error ATGEN_CMS35ReplySetCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyAddCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Calendar Note"); + return SIEMENS_ReplySetFunction (msg, s, "Calendar Note"); } -GSM_Error ATGEN_CMS35ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyDelCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; if (Data->Cal->Location > MAX_VCALENDAR_LOCATION) return ERR_UNKNOWN; if (Data->Priv.ATGEN.ReplyState== AT_Reply_OK) { smprintf(s, "Calendar note deleted\n"); return ERR_NONE; } else { smprintf(s, "Can't delete calendar note\n"); return ERR_UNKNOWN; } @@ -274,25 +270,25 @@ GSM_Error SIEMENS_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) int size=0; if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; // if (Note->Location==0x00) return ERR_INVALIDLOCATION; s->Phone.Data.Cal = Note; error=GSM_EncodeVCALENDAR(req,&size,Note,true,Siemens_VCalendar); return SetSiemensFrame (s,req,"vcs",Note->Location,ID_SetCalendarNote,size); } /* (c) by Timo Teras */ -GSM_Error ATGEN_SL45ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { #ifndef ENABLE_LGPL GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_MemoryEntry *Memory = s->Phone.Data.Memory; unsigned char buffer[500],buffer2[500]; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Phonebook entry received\n"); CopyLineString(buffer, msg.Buffer, Priv->Lines, 3); DecodeHexBin(buffer2,buffer,strlen(buffer)); Memory->EntriesNum = 0; diff --git a/gammu/emb/common/phone/at/sonyeric.c b/gammu/emb/common/phone/at/sonyeric.c index 4b2670a..8eeb39b 100644 --- a/gammu/emb/common/phone/at/sonyeric.c +++ b/gammu/emb/common/phone/at/sonyeric.c @@ -2,35 +2,33 @@ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" -extern GSM_Reply_Function ATGENReplyFunctions[]; -extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s); +#include "atgen.h" +#include "sonyeric.h" #ifdef GSM_ENABLE_OBEXGEN -extern GSM_Reply_Function OBEXGENReplyFunctions[]; -extern GSM_Error OBEXGEN_GetFilePart (GSM_StateMachine *s, GSM_File *File); -extern GSM_Error OBEXGEN_AddFilePart (GSM_StateMachine *s, GSM_File *File, int *Pos); -extern GSM_Error OBEXGEN_Disconnect (GSM_StateMachine *s); +#include "../obex/obexgen.h" -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +extern GSM_Reply_Function OBEXGENReplyFunctions[]; +extern GSM_Reply_Function ATGENReplyFunctions[]; static GSM_Error SONYERIC_SetOBEXMode(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; if (Priv->OBEX) return ERR_NONE; dbgprintf ("Changing to OBEX\n"); error=GSM_WaitFor (s, "AT*EOBEX\r", 9, 0x00, 4, ID_SetOBEX); if (error != ERR_NONE) return error; @@ -117,25 +115,25 @@ static GSM_Error SONYERIC_SetFile(GSM_StateMachine *s, unsigned char *FileName, error = ERR_NONE; while (error == ERR_NONE) error = OBEXGEN_AddFilePart(s,&File,&Pos); free(File.Buffer); if (error != ERR_EMPTY) return error; return SONYERIC_SetATMode(s); } #endif GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (start) { error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Note->Location = 1; } else { Note->Location++; @@ -153,25 +151,25 @@ GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, num++; if (num == Loc) return ERR_NONE; } } return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_CalendarEntry Calendar; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; if (start) { error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; ToDo->Location = 1; @@ -192,25 +190,25 @@ GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool st if (num == Loc) return ERR_NONE; } } return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Getting ToDo status\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; @@ -223,60 +221,60 @@ GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) if (error != ERR_NONE) return error; if (ToDo.EntriesNum != 0) status->Used++; } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN unsigned char req[5000]; int size=0; smprintf(s,"Adding calendar note\n"); GSM_EncodeVCALENDAR(req,&size,Note,true,SonyEricsson_VCalendar); return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[5000]; int size=0; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Adding ToDo\n"); GSM_EncodeVTODO(req,&size,ToDo,true,SonyEricsson_VToDo); return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; int Pos,Level = 0,Used; unsigned char *Buf; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Deleting all ToDo\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; @@ -310,25 +308,25 @@ GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s) } error = SONYERIC_SetFile(s, "telecom/cal.vcs", Buf, Used); // if (Buf != NULL) free(Buf); return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; int Pos,Level = 0,Loc=0,Used; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; unsigned char *Buf; smprintf(s, "Deleting calendar note %i\n",Note->Location); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Pos = 0; @@ -365,25 +363,25 @@ GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) DumpMessage(s->di.df, s->di.dl, Buf, Used); error = SONYERIC_SetFile(s, "telecom/cal.vcs", Buf, Used); if (Buf != NULL) free(Buf); return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s, "Getting calendar status\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; @@ -394,18 +392,129 @@ GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *St error = GSM_DecodeVCALENDAR_VTODO(Priv->file.Buffer, &Pos, &Calendar, &ToDo, SonyEricsson_VCalendar, SonyEricsson_VToDo); if (error == ERR_EMPTY) break; if (error != ERR_NONE) return error; if (Calendar.EntriesNum != 0) Status->Used++; } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } -#endif +GSM_Error ERICSSON_ReplyGetDateLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ /* Author: Peter Ondraska, based on code by Marcin Wiacek and Michal Cihar + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + GSM_Locale *locale = s->Phone.Data.Locale; + char format; + + switch (s->Phone.Data.Priv.ATGEN.ReplyState) { + case AT_Reply_OK: + smprintf(s, "Date settings received\n"); + format=atoi(msg.Buffer); + switch (format) { + case 0: locale->DateFormat = GSM_Date_OFF; + locale->DateSeparator = 0; + break; + case 1: locale->DateFormat = GSM_Date_DDMMMYY; + locale->DateSeparator = '-'; + break; + case 2: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '-'; + break; + case 3: locale->DateFormat = GSM_Date_MMDDYY; + locale->DateSeparator = '/'; + break; + case 4: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '/'; + break; + case 5: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '.'; + break; + case 6: locale->DateFormat = GSM_Date_YYMMDD; + locale->DateSeparator = 0; + break; + case 7: locale->DateFormat = GSM_Date_YYMMDD; + locale->DateSeparator = '-'; + break; + default:return ERR_UNKNOWNRESPONSE; + } + default: + return ERR_NOTSUPPORTED; + } +} + +GSM_Error ERICSSON_ReplyGetTimeLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ /* Author: Peter Ondraska + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + char format; + + switch (s->Phone.Data.Priv.ATGEN.ReplyState) { + case AT_Reply_OK: + smprintf(s, "Time settings received\n"); + format=atoi(msg.Buffer); + switch (format) { + case 1: + case 2: s->Phone.Data.Locale->AMPMTime=(format==2); + return ERR_NONE; + default:return ERR_UNKNOWNRESPONSE; + } + default: return ERR_NOTSUPPORTED; + } +} + +GSM_Error ERICSSON_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + GSM_Error error; + + s->Phone.Data.Locale = locale; + + smprintf(s, "Getting date format\n"); + error=GSM_WaitFor (s, "AT+ESDF?\r", 9, 0x00, 3, ID_GetLocale); + if (error!=ERR_NONE) return error; + + smprintf(s, "Getting time format\n"); + return GSM_WaitFor (s, "AT+ESTF?\r", 9, 0x00, 3, ID_GetLocale); +} + + +GSM_Error ERICSSON_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ /* Author: Peter Ondraska + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + /* this is not yet supported by gammu.c */ + int format=0; + char req[12]; + + if (locale->DateFormat==GSM_Date_OFF) { format=0; } else + if ((locale->DateFormat==GSM_Date_DDMMMYY)&&(locale->DateSeparator=='-')) { format=1; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='-')) { format=2; } else + if ((locale->DateFormat==GSM_Date_MMDDYY)&&(locale->DateSeparator=='/')) { format=3; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='/')) { format=4; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='.')) { format=5; } else + if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator==0)) { format=6; } else + if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator=='-')) { format=7; } + else { return ERR_NOTSUPPORTED; } /* ERR_WRONGINPUT */ + + sprintf(req,"AT+ESDF=%i\r",format); + smprintf(s, "Setting date format\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); + + if (locale->AMPMTime) { format=2; } else { format=1; } + sprintf(req,"AT+ESTF=%i\r",format); + smprintf(s, "Setting time format\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); +} + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.c b/gammu/emb/common/phone/nokia/dct3/dct3func.c index beef33c..17cd0a4 100644 --- a/gammu/emb/common/phone/nokia/dct3/dct3func.c +++ b/gammu/emb/common/phone/nokia/dct3/dct3func.c @@ -1,15 +1,18 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail, Pavel Janik, others and Gnokii */ /* resetting DCT4 phones settings (c) by Walek */ +/* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <string.h> /* memcpy only */ #include <stdio.h> #include <ctype.h> #include "../../../gsmstate.h" #include "../../../misc/coding/coding.h" #include "../../../service/sms/gsmsms.h" #include "../../pfunc.h" #include "../nfunc.h" #include "dct3func.h" @@ -385,24 +388,25 @@ GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) switch (msg.Buffer[3]) { case 0x34: smprintf(s, "SMSC received\n"); Data->SMSC->Format = SMS_FORMAT_Text; switch (msg.Buffer[6]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[8]; + if (msg.Buffer[8] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; i=33; while (msg.Buffer[i]!=0) {i++;} i=i-33; if (i>GSM_MAX_SMSC_NAME_LENGTH) { smprintf(s, "Too long name\n"); return ERR_UNKNOWNRESPONSE; } EncodeUnicode(Data->SMSC->Name,msg.Buffer+33,i); smprintf(s, "Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name)); GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+9,true); @@ -433,43 +437,43 @@ GSM_Error DCT3_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC); } GSM_Error DCT3_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG GSM_NetworkInfo NetInfo; char name[100]; smprintf(s, "Network info received\n"); - smprintf(s, " Status : "); + smprintf(s, "Status : "); switch (msg.Buffer[8]) { case 0x01: smprintf(s, "home network"); break; case 0x02: smprintf(s, "roaming network"); break; case 0x03: smprintf(s, "requesting network"); break; case 0x04: smprintf(s, "not registered in the network"); break; default : smprintf(s, "unknown"); } smprintf(s, "\n"); - smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic"); + smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic"); if (msg.Buffer[8]<0x03) { sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]); smprintf(s, "CID : %s\n", NetInfo.CID); sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]); smprintf(s, "LAC : %s\n", NetInfo.LAC); - smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); NOKIA_DecodeNetworkCode(msg.Buffer+14,NetInfo.NetworkCode); + smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); smprintf(s, "Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode))); if (msg.Length>18) { if (msg.Buffer[18]==0x00) { /* In 6210 name is in "normal" Unicode */ memcpy(name,msg.Buffer+18,msg.Buffer[17]*2); name[msg.Buffer[17]*2] =0x00; name[msg.Buffer[17]*2+1]=0x00; smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name)); } else { @@ -1199,29 +1203,29 @@ GSM_Error DCT3_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *setting } error = DCT3DCT4_SetActiveConnectSet(s, settings); if (error != ERR_NONE) return error; return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error DCT3_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x02: smprintf(s, "SMS sent OK\n"); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[5]); return ERR_NONE; case 0x03: smprintf(s, "Error %i\n",msg.Buffer[6]); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],-1); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length; GSM_Error error; unsigned char req[256] = {N6110_FRAME_HEADER, 0x01, 0x02, 0x00}; error=PHONE_EncodeSMSFrame(s,sms,req+6,PHONE_SMSSubmit,&length, true); diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.h b/gammu/emb/common/phone/nokia/dct3/dct3func.h index 66b67ec..18b2026 100644 --- a/gammu/emb/common/phone/nokia/dct3/dct3func.h +++ b/gammu/emb/common/phone/nokia/dct3/dct3func.h @@ -1,17 +1,19 @@ /* (c) 2002-2003 by Marcin Wiacek */ #ifndef phone_nokia_dct3_h #define phone_nokia_dct3_h +#include "../ncommon.h" + GSM_Error DCT3_ReplyPressKey (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyPlayTone (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyEnableSecurity (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetIMEI (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetSMSC (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySIMLogin (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySIMLogout (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetDateTime (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetAlarm (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySetDateTime (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySetAlarm (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyDialCommand (GSM_Protocol_Message msg, GSM_StateMachine *s); diff --git a/gammu/emb/common/phone/nokia/dct3/n6110.c b/gammu/emb/common/phone/nokia/dct3/n6110.c index 263d12b..dac6c12 100644 --- a/gammu/emb/common/phone/nokia/dct3/n6110.c +++ b/gammu/emb/common/phone/nokia/dct3/n6110.c @@ -1,16 +1,18 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail and Gnokii */ -/* Authentication function (c) 1999 or earlier by Pavel Janik */ /* 5210 calendar IDs by Frederick Ros */ +/* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6110 #include <string.h> #include "../../../../cfg/config.h" #include "../../../misc/coding/coding.h" #include "../../../service/sms/gsmsms.h" #include "../../../gsmcomon.h" #include "../../pfunc.h" @@ -118,24 +120,25 @@ static void N6110_EncodeUnicode(GSM_StateMachine *s, unsigned char *dest, const if (!found) { i_len += EncodeWithUnicodeAlphabet(&src[i_len], &wc); dest[o_len*2] = (wc >> 8) & 0xff; dest[(o_len*2)+1] = wc & 0xff; } } dest[o_len*2] = 0; dest[(o_len*2)+1] = 0; } #ifndef ENABLE_LGPL +/* Pavel Janik */ /* This function provides Nokia authentication protocol. * Nokia authentication protocol is used in the communication between Nokia * mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software, * commercially sold by Nokia Corp. * The authentication scheme is based on the token send by the phone to the * software. The software does it's magic (see the function * N6110_GetNokiaAuthentication) and returns the result back to the phone. * If the result is correct the phone responds with the message "Accessory * connected!" displayed on the LCD. Otherwise it will display "Accessory not * supported" and some functions will not be available for use (?). * The specification of the protocol is not publicly available, no comment. */ @@ -815,24 +818,25 @@ static GSM_Error N6110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, memcpy(reqBin+current,DecodeUnicodeString(Ringtone->Name),UnicodeLength(Ringtone->Name)); current += UnicodeLength(Ringtone->Name); reqBin[current++] = 0x00; reqBin[current++] = 0x00; reqBin[current++] = 0x00;/*xxx*/ memcpy(reqBin+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length); current=current+Ringtone->NokiaBinary.Length; reqBin[3]=Ringtone->Location-1; if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) reqBin[5]=0x10; smprintf(s, "Setting binary ringtone\n"); return GSM_WaitFor (s, reqBin, current, 0x40, 4, ID_SetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6110_ReplyGetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count=5; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Operator logo received\n"); NOKIA_DecodeNetworkCode(msg.Buffer+count,Data->Bitmap->NetworkCode); @@ -1515,24 +1519,25 @@ static GSM_Error N6110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachi } i++; if (i==msg.Length-3) return ERR_EMPTY; } /* Copying frame */ memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+start,end-start); Data->Ringtone->NokiaBinary.Length=end-start; #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, Data->Ringtone->NokiaBinary.Frame, Data->Ringtone->NokiaBinary.Length); #endif return ERR_NONE; case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } smprintf(s, "Ringtone format is %i\n",Data->Ringtone->Format); break; default: smprintf(s, "Invalid location. Too high ?\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) @@ -1552,24 +1557,25 @@ static GSM_Error N6110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, Ringtone->Format = RING_NOKIABINARY; } } switch (Ringtone->Format) { case RING_NOTETONE: if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_NOKIABINARY: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; req[3]=Ringtone->Location-1; s->Phone.Data.Ringtone=Ringtone; smprintf(s, "Getting (binary) ringtone\n"); return GSM_WaitFor (s, req, 4, 0x40, 4, ID_GetRingtone); } @@ -2434,26 +2440,26 @@ static GSM_Error N6110_GetNextCalendarNote(GSM_StateMachine *s, GSM_CalendarEntr if (error == ERR_NONE && Note->Entries[Time].Date.Year == 2090) { error=N6110_GetDateTime(s, &date_time); if (error == ERR_NONE) Note->Entries[Time].Date.Year = date_time.Year; } return error; } GSM_Error N6110_ReplyUSSDInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[2000],buffer2[4000]; int tmp; - tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, msg.Buffer+8, buffer); - msg.Buffer[tmp] = 0; + tmp=GSM_UnpackEightBitsToSeven(0, msg.Buffer[7], 82, msg.Buffer+8, buffer); + buffer[tmp] = 0; smprintf(s, "USSD reply: \"%s\"\n",buffer); if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { EncodeUnicode(buffer2,buffer,strlen(buffer)); s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); } return ERR_NONE; } GSM_Error N6110_AnswerCall(GSM_StateMachine *s, int ID, bool all) @@ -2798,24 +2804,25 @@ GSM_Phone_Functions N6110Phone = { N6110_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, DCT3_GetSMSStatus, N6110_GetSMSMessage, N6110_GetNextSMSMessage, N6110_SetSMS, N6110_AddSMS, N6110_DeleteSMSMessage, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, DCT3_SetIncomingCB, PHONE_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ N6110_DialVoice, N6110_AnswerCall, DCT3_CancelCall, N6110_HoldCall, N6110_UnholdCall, N6110_ConferenceCall, N6110_SplitCall, @@ -2852,25 +2859,25 @@ GSM_Phone_Functions N6110Phone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ N6110_GetNextCalendarNote, NOTIMPLEMENTED, /* SetCalendar */ N6110_AddCalendarNote, N6110_DeleteCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ N6110_GetProfile, N6110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/dct3/n7110.c b/gammu/emb/common/phone/nokia/dct3/n7110.c index 5a02c9c..b597f9b 100644 --- a/gammu/emb/common/phone/nokia/dct3/n7110.c +++ b/gammu/emb/common/phone/nokia/dct3/n7110.c @@ -1,14 +1,17 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail and Gnokii */ +/* based on some Markus Plail work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA7110 #include <string.h> #include <time.h> #include "../../../misc/coding/coding.h" #include "../../../gsmcomon.h" #include "../../../service/gsmlogo.h" #include "../../pfunc.h" @@ -517,24 +520,25 @@ static GSM_Error N7110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY; switch (Ringtone->Format) { case RING_NOTETONE: /* In the future get binary and convert */ return ERR_NOTSUPPORTED; case RING_NOKIABINARY: req[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location; s->Phone.Data.Ringtone=Ringtone; smprintf(s, "Getting binary ringtone\n"); return GSM_WaitFor (s, req, 6, 0x1f, 4, ID_GetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N7110_ReplyGetPictureImageInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; smprintf(s, "Received info for Picture Images\n"); smprintf(s, "Number : %i\n",msg.Buffer[4]*256+msg.Buffer[5]); @@ -1638,24 +1642,25 @@ GSM_Phone_Functions N7110Phone = { N7110_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, N7110_GetSMSStatus, N7110_GetSMSMessage, N7110_GetNextSMSMessage, N7110_SetSMS, N7110_AddSMS, N7110_DeleteSMS, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ N7110_SetIncomingSMS, DCT3_SetIncomingCB, N7110_GetSMSFolders, NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ DCT3_DialVoice, N7110_AnswerCall, DCT3_CancelCall, NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ @@ -1692,25 +1697,25 @@ GSM_Phone_Functions N7110Phone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ N7110_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N7110_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N7110_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ N7110_GetProfile, N7110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/dct3/n9210.c b/gammu/emb/common/phone/nokia/dct3/n9210.c index e82d530..ff71ad3 100644 --- a/gammu/emb/common/phone/nokia/dct3/n9210.c +++ b/gammu/emb/common/phone/nokia/dct3/n9210.c @@ -310,24 +310,25 @@ GSM_Phone_Functions N9210Phone = { NOTIMPLEMENTED, /* GetSpeedDial */ NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, /* FIXME: test it */ NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ N9210_SetIncomingSMS, DCT3_SetIncomingCB, NOTIMPLEMENTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ DCT3_DialVoice, N9210_AnswerCall, DCT3_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ @@ -364,25 +365,25 @@ GSM_Phone_Functions N9210Phone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTIMPLEMENTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3320.c b/gammu/emb/common/phone/nokia/dct4/n3320.c index 51e6f18..9b1d6cd 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3320.c +++ b/gammu/emb/common/phone/nokia/dct4/n3320.c @@ -185,24 +185,25 @@ GSM_Phone_Functions N3320Phone = { NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ @@ -239,25 +240,25 @@ GSM_Phone_Functions N3320Phone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ N3320_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N3320_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTIMPLEMENTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTIMPLEMENTED, /* DeleteFile */ NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3650.c b/gammu/emb/common/phone/nokia/dct4/n3650.c index 2da55bf..d4746a7 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3650.c +++ b/gammu/emb/common/phone/nokia/dct4/n3650.c @@ -306,24 +306,25 @@ GSM_Phone_Functions N3650Phone = { NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ @@ -360,25 +361,25 @@ GSM_Phone_Functions N3650Phone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ N3650_GetNextFileFolder, N3650_GetFilePart, NOTIMPLEMENTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTIMPLEMENTED, /* DeleteFile */ NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.c b/gammu/emb/common/phone/nokia/dct4/n6510.c index 67fe492..2208def 100644 --- a/gammu/emb/common/phone/nokia/dct4/n6510.c +++ b/gammu/emb/common/phone/nokia/dct4/n6510.c @@ -1,14 +1,17 @@ /* (c) 2002-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail, Pawel Kot and Gnokii */ +/* based on some Markus Plail, Pawel Kot work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ /* function for making CRC for filesystem (c) 2003 by Michael Schroeder */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6510 #include <string.h> #include <time.h> #include "../../../misc/coding/coding.h" #include "../../../gsmcomon.h" #include "../../../service/gsmlogo.h" @@ -110,24 +113,26 @@ static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine * } memset(Data->SMSC,0,sizeof(GSM_SMSC)); Data->SMSC->Location = msg.Buffer[8]; Data->SMSC->Format = SMS_FORMAT_Text; switch (msg.Buffer[10]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[12]; + if (msg.Buffer[12] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; + current = 14; for (i=0;i<msg.Buffer[13];i++) { switch (msg.Buffer[current]) { case 0x81: j=current+4; while (msg.Buffer[j]!=0) {j++;} j=j-33; if (j>GSM_MAX_SMSC_NAME_LENGTH) { smprintf(s, "Too long name\n"); return ERR_UNKNOWNRESPONSE; } CopyUnicodeString(Data->SMSC->Name,msg.Buffer+current+4); @@ -256,25 +261,25 @@ static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) smprintf(s, "Setting SMSC\n"); return GSM_WaitFor (s, req, count, 0x02, 4, ID_SetSMSC); } static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int current = msg.Buffer[7]+7, tmp; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG char name[100]; GSM_NetworkInfo NetInfo; - smprintf(s, "Network status: "); + smprintf(s, "Network status : "); switch (msg.Buffer[8]) { case 0x00 : smprintf(s, "home network\n"); break; case 0x01 : smprintf(s, "roaming network\n"); break; case 0x04 : smprintf(s, "not logged"); break; case 0x06 : smprintf(s, "SIM card rejected\n"); break; case 0x09 : smprintf(s, "not logged"); break; default : smprintf(s, "unknown %i!\n",msg.Buffer[8]); break; } if (msg.Buffer[8]==0x00 || msg.Buffer[8] == 0x01) { NOKIA_DecodeNetworkCode(msg.Buffer + (current + 7),NetInfo.NetworkCode); smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); smprintf(s, "Network name for Gammu : %s ", @@ -976,29 +981,29 @@ static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge * } static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s) { return DCT3DCT4_ReplyGetWAPBookmark (msg, s, true); } static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Operator logo received\n"); + if (msg.Length == 18) return ERR_EMPTY; NOKIA_DecodeNetworkCode(msg.Buffer+12,Data->Bitmap->NetworkCode); smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode); Data->Bitmap->BitmapWidth = msg.Buffer[20]; Data->Bitmap->BitmapHeight = msg.Buffer[21]; - if (msg.Length == 18) return ERR_EMPTY; PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg.Buffer+26,Data->Bitmap); return ERR_NONE; } GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry deleted\n"); return ERR_NONE; } GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { @@ -1756,25 +1761,26 @@ static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings 0x00, 0x00, 0x00, 0x31, 0x00, 0x01, //location 0x00, 0x00, 0x02, 0x46, 0x00, 0x00}; settings->Connection.Location = settings->Location; error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS); if (error != ERR_NONE) return error; settings->Active = settings->Connection.Active; settings->Name[0] = 0; settings->Name[1] = 0; -// s->Phone.Data.SyncMLSettings = settings; + s->Phone.Data.SyncMLSettings = settings; + // smprintf(s, "Getting SyncML settings name\n"); // error = GSM_WaitFor (s, NameReq, 16, 0x43, 4, ID_GetSyncMLName); // if (error != ERR_NONE) return error; req[9] = settings->Location - 1; smprintf(s, "Getting additional SyncML settings\n"); return GSM_WaitFor (s, req, 16, 0x43, 4, ID_GetSyncMLSettings); } static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_ChatSettings *Sett = s->Phone.Data.ChatSettings; @@ -2274,25 +2280,25 @@ static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms } req[6]=location / 256; req[7]=location; smprintf(s, "Deleting sms\n"); return GSM_WaitFor (s, req, 10, 0x14, 4, ID_DeleteSMSMessage); } static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[8]) { case 0x00: - smprintf(s, "SMS sent OK, TPMR for sent sms is %02x\n",msg.Buffer[10]); + smprintf(s, "SMS sent OK, TPMR for sent sms is %d\n",msg.Buffer[10]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[10]); return ERR_NONE; default: smprintf(s, "SMS not sent OK, error code probably %i\n",msg.Buffer[8]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[8],msg.Buffer[10]); return ERR_NONE; } } static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length = 11; @@ -2761,24 +2767,25 @@ static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, return ERR_NOTSUPPORTED; case RING_NOKIABINARY: s->Phone.Data.Ringtone = Ringtone; Info.Number = 0; error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone); if (error != ERR_NONE) return error; if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION; req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256; req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256; smprintf(s, "Getting binary ringtone\n"); return GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start) { GSM_Error error; unsigned char reqStart[] = { 0x00,0x06,0x01,0x00,0x07,0x00 }; unsigned char reqPlay[] = { 0x00,0x06,0x01,0x14,0x05,0x04, @@ -2977,24 +2984,27 @@ static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile) unsigned char req[150] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01}; unsigned char reqActive[] = {N6110_FRAME_HEADER, 0x05}; int i, length = 7; GSM_Error error; /* For now !!! */ if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) { if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED; } if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) { return ERR_NOTSUPPORTED; } + if (!strcmp(s->Phone.Data.ModelInfo->model,"5140")) { + return ERR_NOTSUPPORTED; + } if (Profile->Location>5) return ERR_INVALIDLOCATION; for (i = 0; i < 0x0a; i++) { req[length++] = 0x04; req[length++] = Profile->Location; req[length++] = i; req[length++] = 0x01; } req[length++] = 0x04; req[length++] = Profile->Location; @@ -3106,52 +3116,76 @@ static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachi sms.State = SMS_UnRead; sms.InboxFolder = true; N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { + unsigned int pos2 = 15; unsigned int pos = 4; + unsigned char req2[100] = {N6110_FRAME_HEADER,0x01, + 0x00,0x02,0x07,0x04, + 0x01, // 1 - voice, 2 - data + 0x00,0x03, + 0x18, // length of rest + 1 + 0x00,0x00,0x00}; unsigned char req[100] = {N6110_FRAME_HEADER,0x01, 0x0c}; /* Number length */ + GSM_Error error; + + /* USSD not supported */ + if (number[0] == '*') return ERR_NOTSUPPORTED; + if (number[0] == '#') return ERR_NOTSUPPORTED; req[pos++] = strlen(number); EncodeUnicode(req+pos,number,strlen(number)); pos += strlen(number)*2; req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */ req[pos++] = 0x01; req[pos++] = 0x05; req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00; req[pos++] = 0x00; switch (ShowNumber) { case GSM_CALL_HideNumber: req[pos++] = 0x02; break; case GSM_CALL_ShowNumber: req[pos++] = 0x03; break; case GSM_CALL_DefaultNumberPresence: req[pos++] = 0x01; break; } + smprintf(s, "Making voice call\n"); + error = GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); + if (error != ERR_NOTSUPPORTED) return error; + + if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED; + + req2[11] = strlen(number)*2+6; + req2[pos2++] = strlen(number); + EncodeUnicode(req2+pos2,number,strlen(number)); + pos2 += strlen(number)*2; smprintf(s, "Making voice call\n"); - return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); + error = GSM_WaitFor (s, req2, pos2, 0x01, 4, ID_DialVoice); + if (error == ERR_NOTSUPPORTED) return ERR_NONE; + return error; } /* method 3 */ static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last) { int i=0,j=0; while (Last->Location[j] != 0x00) j++; if (j >= GSM_MAXCALENDARTODONOTES) { smprintf(s, "Increase GSM_MAXCALENDARTODONOTES\n"); return ERR_UNKNOWN; } @@ -3165,63 +3199,69 @@ static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_State smprintf(s, "%i ",Last->Location[j-1]); i++; } smprintf(s, "\nNumber of Entries in frame: %i\n",i); Last->Location[j] = 0; smprintf(s, "\n"); if (i == 1 && msg.Buffer[12+0*4]*256+msg.Buffer[13+0*4] == 0) return ERR_EMPTY; if (i == 0) return ERR_EMPTY; return ERR_NONE; } /* method 3 */ -static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, bool Calendar) +static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, char Type) { - GSM_Error error; + GSM_Error error = ERR_UNKNOWN; int i; unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, /* First location */ - 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style */ + 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style, 2 = Notes */ Last->Location[0] = 0x00; Last->Number = 0; - if (Calendar) { + req[10] = Type; + if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); - } else { - req[10] = 0x01; + } else if (Type == 1) { smprintf(s, "Getting locations for ToDo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); + } else if (Type == 2) { + smprintf(s, "Getting locations for Notes\n"); + error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; while (1) { i=0; while (Last->Location[i] != 0x00) i++; smprintf(s, "i = %i %i\n",i,Last->Number); if (i == Last->Number) break; if (i != Last->Number && error == ERR_EMPTY) { smprintf(s, "Phone doesn't support some notes with this method. Workaround\n"); Last->Number = i; break; } req[8] = Last->Location[i-1] / 256; req[9] = Last->Location[i-1] % 256; - if (Calendar) { + if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); - } else { + } else if (Type == 1) { smprintf(s, "Getting locations for todo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); + } else if (Type == 2) { + smprintf(s, "Getting locations for Notes\n"); + error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; } return ERR_NONE; } /* method 3 */ GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_CalendarEntry *entry = s->Phone.Data.Cal; GSM_DateTime Date; unsigned long diff; @@ -3341,69 +3381,75 @@ GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) } if (entry->Type == GSM_CAL_MEETING) { memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2); entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0; entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0; entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION; entry->EntriesNum++; } return ERR_NONE; } +static GSM_Error N6510_PrivGetGenericCalendar3(GSM_StateMachine *s, int Location, GSM_Phone_RequestID ID) +{ + unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, + 0x00,0x99, /* Location */ + 0xff,0xff,0xff,0xff}; + + req[8] = Location / 256; + req[9] = Location % 256; + + return GSM_WaitFor (s, req, 14, 0x13, 4, ID); +} + static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, int *LastCalendarYear) { GSM_Error error; GSM_DateTime date_time; - unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, - 0x00,0x99, /* Location */ - 0xff,0xff,0xff,0xff,0x01}; if (start) { /* We have to get current year. It's NOT written in frame for * Birthday */ error=s->Phone.Functions->GetDateTime(s,&date_time); switch (error) { case ERR_EMPTY: case ERR_NOTIMPLEMENTED: GSM_GetCurrentDateTime(&date_time); break; case ERR_NONE: break; default: return error; } *LastCalendarYear = date_time.Year; } Note->EntriesNum = 0; Note->Entries[0].Date.Year = *LastCalendarYear; - req[8] = Note->Location / 256; - req[9] = Note->Location % 256; - s->Phone.Data.Cal=Note; smprintf(s, "Getting calendar note method 3\n"); - return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetCalendarNote); + return N6510_PrivGetGenericCalendar3(s, Note->Location, ID_GetCalendarNote); } /* method 3 */ GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos) { GSM_Error error; bool start2; if (start) { - error=N6510_GetCalendarInfo3(s,LastCalendar,true); + error=N6510_GetCalendarInfo3(s,LastCalendar,0); if (error!=ERR_NONE) return error; if (LastCalendar->Number == 0) return ERR_EMPTY; *LastCalendarPos = 0; } else { (*LastCalendarPos)++; } error = ERR_EMPTY; start2 = start; while (error == ERR_EMPTY) { if (*LastCalendarPos >= LastCalendar->Number) return ERR_EMPTY; @@ -3468,42 +3514,42 @@ static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntr GSM_Error error; bool found; for(i=0;i<Priv->CalendarIconsNum;i++) { if (Priv->CalendarIconsTypes[i] == Entry->Type) { *ID = Priv->CalendarIcons[i]; return ERR_NONE; } } smprintf(s, "Starting finding note ID\n"); - error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true); + error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { error=N71_65_AddCalendar2(s,Entry); } else { if (Entry->Type == GSM_CAL_MEETING) { error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos); } else { error=N71_65_AddCalendar2(s,Entry); } } if (error != ERR_NONE) return error; - error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true); + error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number); for(i=0;i<LastCalendar2.Number;i++) { found = true; for(j=0;j<LastCalendar1.Number;j++) { if (LastCalendar1.Location[j] == LastCalendar2.Location[i]) { found = false; break; } @@ -3728,25 +3774,25 @@ static GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { /* Method 1 */ error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; /* Method 2 */ // return ERR_NOTSUPPORTED; } else { /* Method 3 */ - error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,true); + error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,0); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; } } static GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { #ifdef GSM_FORCE_DCT4_CALENDAR_6210 return N71_65_AddCalendar2(s,Note); #endif @@ -3963,24 +4009,60 @@ static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, bool enable) return N6510_SetLight(s,N6510_LIGHT_KEYPAD,true); } else { error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,false); if (error != ERR_NONE) return error; error=N6510_SetLight(s,N6510_LIGHT_TORCH,false); if (error != ERR_NONE) return error; return N6510_SetLight(s,N6510_LIGHT_KEYPAD,false); } } +static GSM_Error N6510_ReplyGetNoteInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastNote); +} + +static GSM_Error N6510_ReplyGetNote(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Note received\n"); + memcpy(s->Phone.Data.Note->Text,msg.Buffer+54,(msg.Buffer[50]*256+msg.Buffer[51])*2); + s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2] = 0; + s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2+1] = 0; + return ERR_NONE; +} + +GSM_Error N6510_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, bool start) +{ + GSM_Error error; + GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote; + + if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOTES)) return ERR_NOTSUPPORTED; + + if (start) { + error=N6510_GetCalendarInfo3(s,LastNote,2); + if (error!=ERR_NONE) return error; + Note->Location = 1; + } else { + Note->Location++; + } + + if (Note->Location > LastNote->Number) return ERR_EMPTY; + + s->Phone.Data.Note = Note; + smprintf(s, "Getting note\n"); + return N6510_PrivGetGenericCalendar3(s, LastNote->Location[Note->Location-1], ID_GetNote); +} + static int N6510_FindFileCheckSum(unsigned char *ptr, int len) { int acc, i, accx; accx = 0; acc = 0xffff; while (len--) { accx = (accx & 0xffff00ff) | (acc & 0xff00); acc = (acc & 0xffff00ff) | *ptr++ << 8; for (i = 0; i < 8; i++) { acc <<= 1; if (acc & 0x10000) acc ^= 0x1021; @@ -4046,25 +4128,25 @@ static GSM_Error N6510_ReplyGetFileFolderInfo(GSM_Protocol_Message msg, GSM_Stat else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x05) File->Type = GSM_File_Image_GIF; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x09) File->Type = GSM_File_Image_WBMP; else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Sound_AMR; else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x02) File->Type = GSM_File_Sound_MIDI; else if (msg.Buffer[i]==0x08 && msg.Buffer[i+2]==0x05) File->Type = GSM_File_Video_3GP; else if (msg.Buffer[i]==0x10 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Java_JAR; -#if DEVELOP +#ifdef DEVELOP else if (msg.Buffer[i]==0x00 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_MMS; #endif } return ERR_NONE; case 0x2F: smprintf(s,"File or folder used bytes received\n"); File->Used = msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]; return ERR_NONE; @@ -4389,25 +4471,25 @@ static GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos 0x01, 0x28}; /* length */ unsigned char end[30] = { N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, /* file ID */ 0x00, 0x00, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; s->Phone.Data.File = File; if (*Pos == 0) { error = N6510_SearchForFileName(s,File); - if (error == ERR_NONE) return ERR_INVALIDLOCATION; + if (error == ERR_NONE) return ERR_FILEALREADYEXIST; if (error != ERR_EMPTY) return error; Header[8] = atoi(File->ID_FullName) / 256; Header[9] = atoi(File->ID_FullName) % 256; memset(Header+14, 0x00, 300); CopyUnicodeString(Header+14,File->Name); Header[222] = File->Used / (256*256*256); Header[223] = File->Used / (256*256); Header[224] = File->Used / 256; Header[225] = File->Used % 256; switch(File->Type) { case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break; @@ -4805,25 +4887,25 @@ static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *statu error = GSM_WaitFor (s, reqLoc, 10, 0x55, 4, ID_GetToDo); if (error != ERR_NONE) return error; status->Used = LastToDo->Number; return ERR_NONE; } static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_Error error; - error = N6510_GetCalendarInfo3(s,LastToDo,false); + error = N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; status->Used = LastToDo->Number; return ERR_NONE; } static GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { status->Used = 0; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_GetToDoStatus1(s, status); @@ -4935,26 +5017,25 @@ static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine Date.Minute = msg.Buffer[33]; Date.Second = 0; Last->EntriesNum = 2; if (msg.Buffer[45] == 0x01) { Last->Entries[2].Number = msg.Buffer[45]; Last->Entries[2].EntryType = TODO_COMPLETED; Last->EntriesNum++; smprintf(s,"Completed\n"); } - if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) - { + if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) { smprintf(s, "No alarm\n"); } else { diff = ((unsigned int)msg.Buffer[14]) << 24; diff += ((unsigned int)msg.Buffer[15]) << 16; diff += ((unsigned int)msg.Buffer[16]) << 8; diff += msg.Buffer[17]; memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime)); GetTimeDifference(diff, &Last->Entries[Last->EntriesNum].Date, false, 60); smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n", Last->Entries[Last->EntriesNum].Date.Day, Last->Entries[Last->EntriesNum].Date.Month, Last->Entries[Last->EntriesNum].Date.Year, Last->Entries[Last->EntriesNum].Date.Hour, @@ -4969,46 +5050,38 @@ static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine } Last->EntriesNum++; } return ERR_NONE; } /* ToDo support - 6610 style */ static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; - /* The same to getting calendar method 3 */ - unsigned char req[] = { - N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, - 0x00,0x99, /* Location */ - 0xff,0xff,0xff,0xff,0x01}; if (refresh) { - error=N6510_GetCalendarInfo3(s,LastToDo,false); + error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; ToDo->Location = 1; } else { ToDo->Location++; } if (ToDo->Location > LastToDo->Number) return ERR_EMPTY; - req[8] = LastToDo->Location[ToDo->Location-1] / 256; - req[9] = LastToDo->Location[ToDo->Location-1] % 256; - s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting todo method 2\n"); - return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetToDo); + return N6510_PrivGetGenericCalendar3(s, LastToDo->Location[ToDo->Location-1], ID_GetToDo); } static GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_GetNextToDo1(s, ToDo, refresh); } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return N6510_GetNextToDo2(s, ToDo, refresh); } else { return ERR_NOTSUPPORTED; } } @@ -5034,25 +5107,25 @@ static GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s) } static GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_CalendarEntry Note; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return ERR_NOTSUPPORTED; } - error=N6510_GetCalendarInfo3(s,LastToDo,false); + error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; smprintf(s, "Deleting ToDo method 2\n"); if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return ERR_INVALIDLOCATION; Note.Location = LastToDo->Location[ToDo->Location-1]; return N71_65_DelCalendar(s,&Note); } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message msg, GSM_StateMachine *s) @@ -5442,31 +5515,37 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x0F,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_DialVoice }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF }, {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF }, {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xA6,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xD2,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xD3,ID_IncomingFrame }, {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame }, {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC }, {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC }, {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus }, {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory }, {N6510_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory }, @@ -5499,31 +5578,33 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote }, {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/ {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/ {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/ #ifdef DEBUG {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote }, #endif {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/ {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/ {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo }, {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/ {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo }, + {N6510_ReplyGetNote, "\x13",0x03,0x7E,ID_GetNote }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings }, {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings }, {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/ {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo }, {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/ {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo }, + {N6510_ReplyGetNoteInfo, "\x13",0x03,0x9F,ID_GetNote }, {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage }, {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap }, {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage }, {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus }, {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus }, {N6510_ReplyGetSMSMessage, "\x14",0x03,0x0f,ID_GetSMSMessage }, {N6510_ReplyAddSMSFolder, "\x14",0x03,0x11,ID_AddSMSFolder }, {N6510_ReplyGetSMSFolders, "\x14",0x03,0x13,ID_GetSMSFolders }, {N6510_ReplySaveSMSMessage, "\x14",0x03,0x17,ID_SaveSMSMessage }, @@ -5642,25 +5723,25 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware }, /* 0xD7 - Bluetooth */ {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N6510Phone = { - "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6800|7210|7250|7250i|7600|8310|8390|8910|8910i", + "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|5140|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6610i|6800|6810|6820|7210|7250|7250i|7600|8310|8390|8910|8910i", N6510ReplyFunctions, N6510_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, N6510_ShowStartInfo, NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT4_GetIMEI, N6510_GetOriginalIMEI, N6510_GetManufactureMonth, DCT4_GetProductCode, @@ -5696,24 +5777,25 @@ GSM_Phone_Functions N6510Phone = { N6510_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ N6510_GetSMSC, N6510_SetSMSC, N6510_GetSMSStatus, N6510_GetSMSMessage, N6510_GetNextSMSMessage, N6510_SetSMS, N6510_AddSMS, N6510_DeleteSMSMessage, N6510_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, NOTIMPLEMENTED, /* SetIncomingCB */ N6510_GetSMSFolders, N6510_AddSMSFolder, NOTIMPLEMENTED, /* DeleteSMSFolder */ N6510_DialVoice, N6510_AnswerCall, N6510_CancelCall, NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ @@ -5750,25 +5832,25 @@ GSM_Phone_Functions N6510Phone = { N6510_AddToDo, N6510_DeleteToDo2, N6510_DeleteAllToDo1, N6510_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N6510_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N6510_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ N6510_GetCalendarSettings, NOTSUPPORTED, /* SetCalendarSettings */ - NOTIMPLEMENTED, /* GetNote */ + N6510_GetNextNote, N6510_GetProfile, N6510_SetProfile, N6510_GetFMStation, N6510_SetFMStation, N6510_ClearFMStations, N6510_GetNextFileFolder, N6510_GetFilePart, N6510_AddFilePart, N6510_GetFileSystemStatus, N6510_DeleteFile, N6510_AddFolder, N6510_GetGPRSAccessPoint, diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.h b/gammu/emb/common/phone/nokia/dct4/n6510.h index 4717aeb..26623d6 100644 --- a/gammu/emb/common/phone/nokia/dct4/n6510.h +++ b/gammu/emb/common/phone/nokia/dct4/n6510.h @@ -25,24 +25,26 @@ typedef struct { int LastCalendarPos; GSM_NOKIACalToDoLocations LastCalendar; int FirstCalendarPos; unsigned char CalendarIcons[10]; GSM_CalendarNoteType CalendarIconsTypes[10]; int CalendarIconsNum; GSM_NOKIASMSFolder LastSMSFolder; GSM_SMSFolders LastSMSFolders; GSM_NOKIACalToDoLocations LastToDo; + GSM_NOKIACalToDoLocations LastNote; + unsigned char RingtoneID; /* When set with preview */ int FilesLocations[1000]; int FilesLevels[1000]; int FilesLocationsUsed; int FilesLocationsCurrent; int FileToken; int ParentID; int FileCheckSum; unsigned char FMStatus[4000]; int FMStatusLength; diff --git a/gammu/emb/common/phone/nokia/nauto.c b/gammu/emb/common/phone/nokia/nauto.c index bf74bc9..3bb53ec 100644 --- a/gammu/emb/common/phone/nokia/nauto.c +++ b/gammu/emb/common/phone/nokia/nauto.c @@ -112,25 +112,25 @@ GSM_Phone_Functions NAUTOPhone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/nokia/nfunc.c b/gammu/emb/common/phone/nokia/nfunc.c index 3acfb10..d4d8b03 100644 --- a/gammu/emb/common/phone/nokia/nfunc.c +++ b/gammu/emb/common/phone/nokia/nfunc.c @@ -1384,53 +1384,67 @@ GSM_Error N71_65_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) smprintf(s, "Call is being released\n"); break; case 0x0b: smprintf(s, "Meaning not known\n"); call.CallIDAvailable = false; break; case 0x0c: smprintf(s, "Audio status\n"); if (msg.Buffer[4] == 0x01) smprintf(s, "Audio enabled\n"); else smprintf(s, "Audio disabled\n"); call.CallIDAvailable = false; break; + case 0x0f: + case 0x10: + smprintf(s, "Meaning not known\n"); + call.CallIDAvailable = false; + break; case 0x23: smprintf(s, "Call held\n"); call.Status = GSM_CALL_CallHeld; break; case 0x25: smprintf(s, "Call resumed\n"); call.Status = GSM_CALL_CallResumed; break; case 0x27: smprintf(s, "Call switched\n"); call.Status = GSM_CALL_CallSwitched; break; case 0x53: smprintf(s, "Outgoing call\n"); smprintf(s, "Call mode : %i\n",msg.Buffer[5]);//such interpretation is in gnokii tmp = 6; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,buffer,false); smprintf(s, "Number : \"%s\"\n",DecodeUnicodeString(buffer)); /* FIXME: read name from frame */ call.Status = GSM_CALL_OutgoingCall; tmp = 6; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,call.PhoneNumber,false); break; + case 0xA6: + case 0xD2: + case 0xD3: + smprintf(s, "Meaning not known\n"); + call.CallIDAvailable = false; + break; } if (call.CallIDAvailable) smprintf(s, "Call ID : %d\n",msg.Buffer[4]); if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL && call.Status != 0) { if (call.CallIDAvailable) call.CallID = msg.Buffer[4]; s->User.IncomingCall(s->CurrentConfig->Device, call); } + if (s->Phone.Data.RequestID == ID_DialVoice) { + if (msg.Buffer[3] == 0x10) return ERR_NOTSUPPORTED; + } if (s->Phone.Data.RequestID == ID_CancelCall) { if (msg.Buffer[3] == 0x09) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; /* when we canceled call and see frame about other * call releasing, we don't give ERR_NONE for "our" * call release command */ return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_AnswerCall) { if (msg.Buffer[3] == 0x07) { diff --git a/gammu/emb/common/phone/obex/obexgen.c b/gammu/emb/common/phone/obex/obexgen.c index dd14f8e..3106369 100644 --- a/gammu/emb/common/phone/obex/obexgen.c +++ b/gammu/emb/common/phone/obex/obexgen.c @@ -765,24 +765,25 @@ GSM_Phone_Functions OBEXGENPhone = { NOTIMPLEMENTED, /* GetSpeedDial */ NOTIMPLEMENTED, /* SetSpeedDial */ NOTIMPLEMENTED, /* GetSMSC */ NOTIMPLEMENTED, /* SetSMSC */ NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ NOTIMPLEMENTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTIMPLEMENTED, /* SetIncomingSMS */ NOTIMPLEMENTED, /* SetIncomingCB */ NOTIMPLEMENTED, /* GetSMSFolders */ NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ @@ -819,25 +820,25 @@ GSM_Phone_Functions OBEXGENPhone = { NOTIMPLEMENTED, /* AddToDo */ NOTIMPLEMENTED, /* DeleteToDo */ NOTIMPLEMENTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ NOTIMPLEMENTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTIMPLEMENTED, /* AddCalendar */ NOTIMPLEMENTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTIMPLEMENTED, /* GetProfile */ NOTIMPLEMENTED, /* SetProfile */ NOTIMPLEMENTED, /* GetFMStation */ NOTIMPLEMENTED, /* SetFMStation */ NOTIMPLEMENTED, /* ClearFMStations */ OBEXGEN_GetNextFileFolder, OBEXGEN_GetFilePart, OBEXGEN_AddFilePart, NOTIMPLEMENTED, /* GetFileSystemStatus */ OBEXGEN_DeleteFile, OBEXGEN_AddFolder, NOTIMPLEMENTED, /* GetGPRSAccessPoint */ diff --git a/gammu/emb/common/phone/obex/obexgen.h b/gammu/emb/common/phone/obex/obexgen.h index 466fef5..b7033de 100644 --- a/gammu/emb/common/phone/obex/obexgen.h +++ b/gammu/emb/common/phone/obex/obexgen.h @@ -22,17 +22,21 @@ typedef enum { typedef struct { int FileLev; int FilesLocationsUsed; int FilesLocationsCurrent; GSM_File Files[500]; bool FileLastPart; int FrameSize; OBEX_Service Service; } GSM_Phone_OBEXGENData; +GSM_Error OBEXGEN_GetFilePart (GSM_StateMachine *s, GSM_File *File); +GSM_Error OBEXGEN_AddFilePart (GSM_StateMachine *s, GSM_File *File, int *Pos); +GSM_Error OBEXGEN_Disconnect (GSM_StateMachine *s); + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/symbian/mroutgen.c b/gammu/emb/common/phone/symbian/mroutgen.c index 2c339be..a7382cf 100644 --- a/gammu/emb/common/phone/symbian/mroutgen.c +++ b/gammu/emb/common/phone/symbian/mroutgen.c @@ -134,24 +134,25 @@ GSM_Phone_Functions MROUTERGENPhone = { NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTSUPPORTED, /* DialVoice */ NOTSUPPORTED, /* AnswerCall */ NOTSUPPORTED, /* CancelCall */ NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ @@ -188,25 +189,25 @@ GSM_Phone_Functions MROUTERGENPhone = { NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ |