summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/phone/nokia/nfunc.c
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/phone/nokia/nfunc.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/phone/nokia/nfunc.c14
1 files changed, 14 insertions, 0 deletions
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
@@ -1012,797 +1012,811 @@ GSM_Error DCT3DCT4_GetWAPBookmarkPart(GSM_StateMachine *s, GSM_WAPBookmark *book
error = GSM_WaitFor (s, req, 6, 0x3f, 4, ID_GetWAPBookmark);
if (error != ERR_NONE) {
if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
DCT3DCT4_DisableConnectionFunctions(s);
}
return error;
}
return DCT3DCT4_DisableConnectionFunctions(s);
}
GSM_Error DCT3DCT4_CancelCall(GSM_StateMachine *s, int ID)
{
unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
req[4] = (unsigned char)ID;
s->Phone.Data.CallID = ID;
smprintf(s, "Canceling single call\n");
return GSM_WaitFor (s, req, 6, 0x01, 4, ID_CancelCall);
}
GSM_Error DCT3DCT4_AnswerCall(GSM_StateMachine *s, int ID)
{
unsigned char req[] = {N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
req[4] = (unsigned char)ID;
s->Phone.Data.CallID = ID;
smprintf(s, "Answering single call\n");
return GSM_WaitFor (s, req, 6, 0x01, 4, ID_AnswerCall);
}
GSM_Error DCT3DCT4_ReplyGetModelFirmware(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_Lines lines;
GSM_Phone_Data *Data = &s->Phone.Data;
SplitLines(msg.Buffer, msg.Length, &lines, "\x20\x0A", 2, false);
strcpy(Data->Model,GetLineString(msg.Buffer, lines, 4));
smprintf(s, "Received model %s\n",Data->Model);
Data->ModelInfo = GetModelData(NULL,Data->Model,NULL);
strcpy(Data->VerDate,GetLineString(msg.Buffer, lines, 3));
smprintf(s, "Received firmware date %s\n",Data->VerDate);
strcpy(Data->Version,GetLineString(msg.Buffer, lines, 2));
smprintf(s, "Received firmware version %s\n",Data->Version);
GSM_CreateFirmwareNumber(s);
return ERR_NONE;
}
GSM_Error DCT3DCT4_GetModel (GSM_StateMachine *s)
{
unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
GSM_Error error;
if (strlen(s->Phone.Data.Model)>0) return ERR_NONE;
smprintf(s, "Getting model\n");
error=GSM_WaitFor (s, req, 5, 0xd1, 3, ID_GetModel);
if (error==ERR_NONE) {
if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
smprintf(s, "[Connected model - \"%s\"]\n",s->Phone.Data.Model);
smprintf(s, "[Firmware version - \"%s\"]\n",s->Phone.Data.Version);
smprintf(s, "[Firmware date - \"%s\"]\n",s->Phone.Data.VerDate);
}
}
return error;
}
GSM_Error DCT3DCT4_GetFirmware (GSM_StateMachine *s)
{
unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
GSM_Error error;
if (strlen(s->Phone.Data.Version)>0) return ERR_NONE;
smprintf(s, "Getting firmware version\n");
error=GSM_WaitFor (s, req, 5, 0xd1, 3, ID_GetFirmware);
if (error==ERR_NONE) {
if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
smprintf(s, "[Connected model - \"%s\"]\n",s->Phone.Data.Model);
smprintf(s, "[Firmware version - \"%s\"]\n",s->Phone.Data.Version);
smprintf(s, "[Firmware date - \"%s\"]\n",s->Phone.Data.VerDate);
}
}
return error;
}
/* ---------- Shared for n7110.c and n6510.c ------------------------------- */
GSM_Error N71_65_ReplyGetMemoryError(unsigned char error, GSM_StateMachine *s)
{
switch (error) {
case 0x27:
smprintf(s, "No PIN\n");
return ERR_SECURITYERROR;
case 0x30:
smprintf(s, "Invalid memory type\n");
if (s->Phone.Data.Memory->MemoryType == MEM_ME) return ERR_EMPTY;
if (s->Phone.Data.Memory->MemoryType == MEM_SM) return ERR_EMPTY;
return ERR_NOTSUPPORTED;
case 0x33:
smprintf(s, "Empty location\n");
s->Phone.Data.Memory->EntriesNum = 0;
return ERR_EMPTY;
case 0x34:
smprintf(s, "Too high location ?\n");
return ERR_INVALIDLOCATION;
default:
smprintf(s, "ERROR: unknown %i\n",error);
return ERR_UNKNOWNRESPONSE;
}
}
GSM_Error N71_65_ReplyWritePhonebook(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
smprintf(s, "Phonebook entry written ");
switch (msg.Buffer[6]) {
case 0x0f:
smprintf(s, " - error\n");
switch (msg.Buffer[10]) {
case 0x36:
smprintf(s, "Too long name\n");
return ERR_NOTSUPPORTED;
case 0x3c:
smprintf(s, "Can not add entry with 0 subentries\n");
return ERR_NOTSUPPORTED;
case 0x3d:
smprintf(s, "Wrong entry type\n");
return ERR_NOTSUPPORTED;
case 0x3e:
smprintf(s, "Too much entries\n");
return ERR_NOTSUPPORTED;
default:
smprintf(s, "ERROR: unknown %i\n",msg.Buffer[10]);
return ERR_UNKNOWNRESPONSE;
}
default:
smprintf(s, " - OK\n");
return ERR_NONE;
}
}
bool NOKIA_FindPhoneFeatureValue(GSM_StateMachine *s,
GSM_Profile_PhoneTableValue ProfileTable[],
GSM_Profile_Feat_ID FeatureID,
GSM_Profile_Feat_Value FeatureValue,
unsigned char *PhoneID,
unsigned char *PhoneValue)
{
int i=0;
smprintf(s, "Trying to find feature %i with value %i\n",FeatureID,FeatureValue);
while (ProfileTable[i].ID != 0x00) {
if (ProfileTable[i].ID == FeatureID &&
ProfileTable[i].Value == FeatureValue) {
*PhoneID = ProfileTable[i].PhoneID;
*PhoneValue = ProfileTable[i].PhoneValue;
return true;
}
i++;
}
return false;
}
#define PROFILE_CALLERGROUPS_GROUP1 0x01
#define PROFILE_CALLERGROUPS_GROUP2 0x02
#define PROFILE_CALLERGROUPS_GROUP3 0x04
#define PROFILE_CALLERGROUPS_GROUP4 0x08
#define PROFILE_CALLERGROUPS_GROUP5 0x10
void NOKIA_FindFeatureValue(GSM_StateMachine *s,
GSM_Profile_PhoneTableValue ProfileTable[],
unsigned char ID,
unsigned char Value,
GSM_Phone_Data *Data,
bool CallerGroups)
{
int i;
if (CallerGroups) {
smprintf(s, "Caller groups: %i\n", Value);
Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_CallerGroups;
Data->Profile->FeaturesNumber++;
for (i=0;i<5;i++) Data->Profile->CallerGroups[i] = false;
if ((Value & PROFILE_CALLERGROUPS_GROUP1)==PROFILE_CALLERGROUPS_GROUP1) Data->Profile->CallerGroups[0] = true;
if ((Value & PROFILE_CALLERGROUPS_GROUP2)==PROFILE_CALLERGROUPS_GROUP2) Data->Profile->CallerGroups[1] = true;
if ((Value & PROFILE_CALLERGROUPS_GROUP3)==PROFILE_CALLERGROUPS_GROUP3) Data->Profile->CallerGroups[2] = true;
if ((Value & PROFILE_CALLERGROUPS_GROUP4)==PROFILE_CALLERGROUPS_GROUP4) Data->Profile->CallerGroups[3] = true;
if ((Value & PROFILE_CALLERGROUPS_GROUP5)==PROFILE_CALLERGROUPS_GROUP5) Data->Profile->CallerGroups[4] = true;
return;
}
i = 0;
while (ProfileTable[i].ID != 0x00) {
if (ProfileTable[i].PhoneID == ID &&
ProfileTable[i].PhoneValue == Value) {
#ifdef DEBUG
switch (ProfileTable[i].ID) {
case Profile_KeypadTone : smprintf(s, "Keypad tones\n"); break;
case Profile_CallAlert : smprintf(s, "Call alert\n"); break;
case Profile_RingtoneVolume : smprintf(s, "Ringtone volume\n"); break;
case Profile_MessageTone : smprintf(s, "SMS message tones\n"); break;
case Profile_Vibration : smprintf(s, "Vibration\n"); break;
case Profile_WarningTone : smprintf(s, "Warning (ang games) tones\n"); break;
case Profile_AutoAnswer : smprintf(s, "Automatic answer\n"); break;
case Profile_Lights : smprintf(s, "Lights\n"); break;
case Profile_ScreenSaver : smprintf(s, "Screen Saver\n"); break;
case Profile_ScreenSaverTime : smprintf(s, "Screen Saver timeout\n"); break;
default : break;
}
#endif
Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = ProfileTable[i].ID;
Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = ProfileTable[i].Value;
Data->Profile->FeaturesNumber++;
break;
}
i++;
}
}
GSM_Profile_PhoneTableValue Profile71_65[] = {
{Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0x00},
{Profile_KeypadTone, PROFILE_KEYPAD_LEVEL1, 0x00,0x01},
{Profile_KeypadTone, PROFILE_KEYPAD_LEVEL2, 0x00,0x02},
{Profile_KeypadTone, PROFILE_KEYPAD_LEVEL3, 0x00,0x03},
/* Lights ? */
{Profile_CallAlert, PROFILE_CALLALERT_RINGING, 0x02,0x00},
{Profile_CallAlert, PROFILE_CALLALERT_ASCENDING, 0x02,0x01},
{Profile_CallAlert, PROFILE_CALLALERT_RINGONCE, 0x02,0x02},
{Profile_CallAlert, PROFILE_CALLALERT_BEEPONCE, 0x02,0x03},
{Profile_CallAlert, PROFILE_CALLALERT_OFF, 0x02,0x05},
/* {Profile_CallAlert, PROFILE_CALLALERT_CALLERGROUPS,0x02,0x07}, */
/* Ringtone ID */
{Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL1, 0x04,0x00},
{Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL2, 0x04,0x01},
{Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL3, 0x04,0x02},
{Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL4, 0x04,0x03},
{Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL5, 0x04,0x04},
{Profile_MessageTone, PROFILE_MESSAGE_NOTONE, 0x05,0x00},
{Profile_MessageTone, PROFILE_MESSAGE_STANDARD, 0x05,0x01},
{Profile_MessageTone, PROFILE_MESSAGE_SPECIAL, 0x05,0x02},
{Profile_MessageTone, PROFILE_MESSAGE_BEEPONCE, 0x05,0x03},
{Profile_MessageTone, PROFILE_MESSAGE_ASCENDING, 0x05,0x04},
{Profile_Vibration, PROFILE_VIBRATION_OFF, 0x06,0x00},
{Profile_Vibration, PROFILE_VIBRATION_ON, 0x06,0x01},
{Profile_WarningTone, PROFILE_WARNING_OFF, 0x07,0x00},
{Profile_WarningTone, PROFILE_WARNING_ON, 0x07,0x01},
/* Caller groups */
{Profile_AutoAnswer, PROFILE_AUTOANSWER_OFF, 0x09,0x00},
{Profile_AutoAnswer, PROFILE_AUTOANSWER_ON, 0x09,0x01},
{0x00, 0x00, 0x00,0x00}
};
GSM_Error NOKIA_SetIncomingSMS(GSM_StateMachine *s, bool enable)
{
s->Phone.Data.EnableIncomingSMS = enable;
#ifdef DEBUG
if (enable) {
smprintf(s, "Enabling incoming SMS\n");
} else {
smprintf(s, "Disabling incoming SMS\n");
}
#endif
return ERR_NONE;
}
GSM_Error N71_65_ReplyUSSDInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
unsigned char buffer[2000],buffer2[4000];
if (s->Phone.Data.RequestID == ID_Divert) return ERR_NONE;
memcpy(buffer,msg.Buffer+8,msg.Buffer[7]);
buffer[msg.Buffer[7]] = 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 NOKIA_SetIncomingUSSD(GSM_StateMachine *s, bool enable)
{
s->Phone.Data.EnableIncomingUSSD = enable;
#ifdef DEBUG
if (enable) {
smprintf(s, "Enabling incoming USSD\n");
} else {
smprintf(s, "Disabling incoming USSD\n");
}
#endif
return ERR_NONE;
}
GSM_Error NOKIA_SetIncomingCall(GSM_StateMachine *s, bool enable)
{
if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOCALLINFO)) return ERR_NOTSUPPORTED;
s->Phone.Data.EnableIncomingCall = enable;
#ifdef DEBUG
if (enable) {
smprintf(s, "Enabling incoming Call\n");
} else {
smprintf(s, "Disabling incoming Call\n");
}
#endif
return ERR_NONE;
}
GSM_Error N71_65_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_Call call;
int tmp;
unsigned char buffer[200];
call.Status = 0;
call.CallIDAvailable = true;
smprintf(s, "Call info, ");
switch (msg.Buffer[3]) {
case 0x02:
smprintf(s, "Call established, waiting for answer\n");
call.Status = GSM_CALL_CallEstablished;
break;
case 0x03:
smprintf(s, "Call started\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_CallStart;
break;
case 0x04:
smprintf(s, "Remote end hang up\n");
smprintf(s, "Cause Type : %i\n",msg.Buffer[5]);//such interpretation is in gnokii
smprintf(s, "CC : %i\n",msg.Buffer[6]);
smprintf(s, "MM(?) : %i\n",msg.Buffer[7]);
smprintf(s, "RR(?) : %i\n",msg.Buffer[8]);
call.Status = GSM_CALL_CallRemoteEnd;
call.StatusCode = msg.Buffer[6];
break;
case 0x05:
smprintf(s, "Incoming 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_IncomingCall;
tmp = 6;
NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,call.PhoneNumber,false);
break;
case 0x07:
smprintf(s, "Call answer initiated\n");
break;
case 0x09:
smprintf(s, "Call released\n");
call.Status = GSM_CALL_CallLocalEnd;
break;
case 0x0a:
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) {
if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
return ERR_NEEDANOTHERANSWER;
}
}
return ERR_NONE;
}
void N71_65_GetCalendarRecurrance(GSM_StateMachine *s, unsigned char *buffer, GSM_CalendarEntry *entry)
{
int Recurrance;
Recurrance = buffer[0]*256 + buffer[1];
/* 8760 hours = 1 year */
if (Recurrance == 0xffff) Recurrance=8760;
if (Recurrance != 0) {
smprintf(s, "Recurrance : %i hours\n",Recurrance);
entry->Entries[entry->EntriesNum].EntryType = CAL_RECURRANCE;
entry->Entries[entry->EntriesNum].Number = Recurrance;
entry->EntriesNum++;
}
}
/* method 2 */
GSM_Error N71_65_ReplyAddCalendar2(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
smprintf(s, "Calendar note added\n");
return ERR_NONE;
}
/* method 2 */
GSM_Error N71_65_AddCalendar2(GSM_StateMachine *s, GSM_CalendarEntry *Note)
{
GSM_CalendarNoteType NoteType;
time_t t_time1,t_time2;
GSM_DateTime Date,date_time;
GSM_Error error;
long diff;
int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, length=25;
unsigned char req[5000] = {
N6110_FRAME_HEADER,
0x40,
0x00, /* frame length - 7 */
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, /* start time saved as difference */
0x00,0x00,0xff,0xff, /* alarm saved as difference */
0x00, /* frame length - 7 */
0x00, /* note type */
0x00,0x00, /* recurrance */
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00}; /* rest depends on note type */
NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo);
if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62) ||
IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65)) {
switch(NoteType) {
case GSM_CAL_MEETING : req[18] = 0x01; length = 25; break;
case GSM_CAL_CALL : req[18] = 0x02; length = 27; break;
case GSM_CAL_BIRTHDAY: req[18] = 0x04; length = 28; break;
case GSM_CAL_MEMO : req[18] = 0x08; length = 25; break;
default : return ERR_UNKNOWN;
}
} else {
switch(NoteType) {
case GSM_CAL_REMINDER: req[18] = 0x01; length = 25; break;
case GSM_CAL_CALL : req[18] = 0x02; length = 27; break;
case GSM_CAL_BIRTHDAY: req[18] = 0x04; length = 28; break;
case GSM_CAL_MEMO : req[18] = 0x08; length = 25; break;
default : return ERR_UNKNOWN;
}
}
GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
if (Time == -1) return ERR_UNKNOWN;
if (NoteType != GSM_CAL_BIRTHDAY) {
Date.Year = 2030; Date.Month = 01; Date.Day = 01;
Date.Hour = 00; Date.Minute = 00; Date.Second = 00;
} else {
Date.Year = 2029; Date.Month = 12; Date.Day = 31;
Date.Hour = 22; Date.Minute = 59; Date.Second = 58;
}
t_time1 = Fill_Time_T(Date,8);
memcpy(&Date,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
if (NoteType != GSM_CAL_BIRTHDAY) {
Date.Year -= 20;
} else {
Date.Year = 1980;
Date.Hour = 22; Date.Minute = 58; Date.Second = 58;
}
t_time2 = Fill_Time_T(Date,8);
diff = t_time1-t_time2;
smprintf(s, " Difference : %li seconds\n", -diff);
req[9] = (unsigned char)(-diff >> 24);
req[10] = (unsigned char)(-diff >> 16);
req[11] = (unsigned char)(-diff >> 8);
req[12] = (unsigned char)(-diff);
if (NoteType == GSM_CAL_BIRTHDAY) {
req[25] = Note->Entries[Time].Date.Year / 256;
req[26] = Note->Entries[Time].Date.Year % 256;
/* Recurrance = 1 year */
req[19] = 0xff;
req[20] = 0xff;
}
if (NoteType == GSM_CAL_CALL && Phone != -1) {
req[25] = UnicodeLength(Note->Entries[Phone].Text);
CopyUnicodeString(req+length,Note->Entries[Phone].Text);
length += UnicodeLength(Note->Entries[Phone].Text)*2;
}
if (Alarm != -1) {
if (NoteType == GSM_CAL_BIRTHDAY) {
if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) req[27] = 0x01;
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;
}
Date.Year = date_time.Year;
Date.Hour = 23;
Date.Minute = 59;
} else {
Date.Year += 20;
}
t_time2 = Fill_Time_T(Date,8);
t_time1 = Fill_Time_T(Note->Entries[Alarm].Date,8);
diff = t_time1-t_time2;
/* Sometimes we have difference in minutes */
if (NoteType == GSM_CAL_MEETING) diff = diff / 60;
if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35)) {
if (NoteType == GSM_CAL_MEMO || NoteType == GSM_CAL_CALL) {
diff = diff / 60;
}
}
smprintf(s, " Difference : %li seconds or minutes\n", -diff);
req[13] = (unsigned char)(-diff >> 24);
req[14] = (unsigned char)(-diff >> 16);
req[15] = (unsigned char)(-diff >> 8);
req[16] = (unsigned char)(-diff);
}
if (Recurrance != -1) {
/* 8760 hours = 1 year */
if (Note->Entries[Recurrance].Number >= 8760) {
req[19] = 0xff;
req[20] = 0xff;
} else {
req[19] = Note->Entries[Recurrance].Number / 256;
req[20] = Note->Entries[Recurrance].Number % 256;
}
}
if (Text != -1) {
switch (NoteType) {
case GSM_CAL_CALL:
req[26] = UnicodeLength(Note->Entries[Text].Text);
break;
default:
req[length++] = UnicodeLength(Note->Entries[Text].Text);
if (NoteType == GSM_CAL_MEMO || NoteType == GSM_CAL_MEETING) req[length++] = 0x00;
}
CopyUnicodeString(req+length,Note->Entries[Text].Text);
length += UnicodeLength(Note->Entries[Text].Text)*2;
}
req[length++] = 0x00;
req[length++] = 0x00;
req[4] = req[17] = length-7;
smprintf(s, "Writing calendar note method 2\n");
return GSM_WaitFor (s, req, length, 0x13, 4, ID_SetCalendarNote);
}
/* method 1*/
GSM_Error N71_65_ReplyGetCalendarNotePos1(GSM_Protocol_Message msg, GSM_StateMachine *s,int *FirstCalendarPos)
{
smprintf(s, "First calendar location: %i\n",msg.Buffer[4]*256+msg.Buffer[5]);
*FirstCalendarPos = msg.Buffer[4]*256+msg.Buffer[5];
return ERR_NONE;
}
/* method 1*/
static GSM_Error N71_65_GetCalendarNotePos1(GSM_StateMachine *s)
{
unsigned char req[] = {N6110_FRAME_HEADER, 0x31};
smprintf(s, "Getting first free calendar note location\n");
return GSM_WaitFor (s, req, 4, 0x13, 4, ID_GetCalendarNotePos);
}
/* method 1 */
GSM_Error N71_65_ReplyAddCalendar1(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
#ifdef DEBUG
smprintf(s, "Written calendar note type ");
switch ((msg.Buffer[3]/2)-1) {
case 0: smprintf(s, "Meeting"); break;
case 1: smprintf(s, "Call"); break;
case 2: smprintf(s, "Birthday");break;
case 3: smprintf(s, "Reminder");break;
}
smprintf(s, " on location %d\n",msg.Buffer[4]*256+msg.Buffer[5]);
#endif
return ERR_NONE;
}
/* method 1 */
GSM_Error N71_65_AddCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
{
long seconds;
GSM_Error error;
GSM_DateTime DT;
int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, count=12;
unsigned char req[5000] = {
N6110_FRAME_HEADER,
0x01, /* note type */
0x00, 0x00, /* location ? */
0x00, /* entry type */
0x00,
0x00, 0x00, /* Year */
0x00, /* Month */
0x00, /* Day */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
error=N71_65_GetCalendarNotePos1(s);
if (error!=ERR_NONE) return error;
if (FirstCalendarPos != NULL) {
req[4] = *FirstCalendarPos/256;
req[5] = *FirstCalendarPos%256;
}
switch(Note->Type) {
case GSM_CAL_CALL : req[3]=0x03; req[6]=0x02; break;
case GSM_CAL_BIRTHDAY: req[3]=0x05; req[6]=0x04; break;
case GSM_CAL_MEMO : req[3]=0x07; req[6]=0x08; break;
case GSM_CAL_MEETING :
default : req[3]=0x01; req[6]=0x01; break;
}
GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
if (Time == -1) return ERR_UNKNOWN;
memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
req[8] = DT.Year / 256;
req[9] = DT.Year % 256;
req[10] = DT.Month;
req[11] = DT.Day;
switch(Note->Type) {
case GSM_CAL_BIRTHDAY:
/* byte 12 and 13 */
req[count++] = 0x00;
req[count++] = 0x00;
/* Alarm - bytes 14 to 17 */
req[count++] = 0x00;
req[count++] = 0x00;
req[count++] = 0xff;
req[count++] = 0xff;
if (Alarm != -1) {
#ifndef ENABLE_LGPL
/* Comment from original source by Gabriele Zappi:
* I try with Time.Year = Alarm.Year. If negative, I increase 1 year,
* but only once ! This thing, because I may have Alarm period across
* a year. (eg. Birthday on 2001-01-10 and Alarm on 2000-12-27)
*/
#endif
DT.Year = Note->Entries[Alarm].Date.Year;
seconds = Fill_Time_T(DT,8)-Fill_Time_T(Note->Entries[Alarm].Date,8);
if (seconds<0L) {
DT.Year++;
seconds = Fill_Time_T(DT,8)-Fill_Time_T(Note->Entries[Alarm].Date,8);
}
if (seconds>=0L) {
count -= 4;
/* bytes 14 to 17 */
req[count++] = (unsigned char)(seconds>>24);
req[count++] = (unsigned char)((seconds>>16) & 0xff);
req[count++] = (unsigned char)((seconds>>8) & 0xff);
req[count++] = (unsigned char)(seconds & 0xff);
}
/* byte 18 */
if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) req[count++] = 0x01; else req[count++] = 0x00;
}
/* byte 19 and next */
if (Text != -1) {
req[count++] = UnicodeLength(Note->Entries[Text].Text);
CopyUnicodeString(req+count,Note->Entries[Text].Text);
count=count+2*UnicodeLength(Note->Entries[Text].Text);
} else {
req[count++] = 0x00;
}
break;
case GSM_CAL_MEMO:
/* byte 12 and 13 */
if (Recurrance != -1) {
/* 8760 hours = 1 year */
if (Note->Entries[Recurrance].Number >= 8760) {
req[count++] = 0xff;
req[count++] = 0xff;
} else {
req[count++] = Note->Entries[Recurrance].Number / 256;
req[count++] = Note->Entries[Recurrance].Number % 256;
}
} else {
req[count++] = 0x00;
req[count++] = 0x00;
}
/* byte 14 and next */
if (Text != -1) {
req[count++] = UnicodeLength(Note->Entries[Text].Text);
req[count++] = 0x00;
CopyUnicodeString(req+count,Note->Entries[Text].Text);
count=count+2*UnicodeLength(Note->Entries[Text].Text);
} else {
req[count++] = 0x00;
req[count++] = 0x00;
}
break;
case GSM_CAL_MEETING:
case GSM_CAL_CALL:
default:
/* byte 12 and 13 */
req[count++] = DT.Hour;
req[count++] = DT.Minute;
/* Alarm - byte 14 and 15 */
req[count++] = 0xff;
req[count++] = 0xff;
if (Alarm != -1) {
seconds=Fill_Time_T(DT,8)-Fill_Time_T(Note->Entries[Alarm].Date,8);
if (seconds>=0L) {
count -= 2;
req[count++] = ((unsigned char)(seconds/60L)>>8);
req[count++] = (unsigned char)((seconds/60L)&0xff);
}
}
/* byte 16 and 17 */
if (Recurrance != -1) {
/* 8760 hours = 1 year */
if (Note->Entries[Recurrance].Number >= 8760) {
req[count++] = 0xff;
req[count++] = 0xff;
} else {
req[count++] = Note->Entries[Recurrance].Number / 256;
req[count++] = Note->Entries[Recurrance].Number % 256;
}
} else {
req[count++] = 0x00;
req[count++] = 0x00;
}
/* byte 18 */
if (Text != -1) {
req[count++] = UnicodeLength(Note->Entries[Text].Text);
} else {
req[count++] = 0x00;
}
/* byte 19 */