Gammu internals  1.38.0
6510cal.c
Go to the documentation of this file.
1 /* (c) 2002-2005 by Marcin Wiacek */
2 
3 #include <gammu-config.h>
4 
5 #ifdef GSM_ENABLE_NOKIA6510
6 
7 #include <string.h>
8 #include <time.h>
9 
10 #include "../../../../misc/coding/coding.h"
11 #include "../../../../gsmcomon.h"
12 #include "../../../../service/gsmlogo.h"
13 #include "../../../../service/gsmcal.h"
14 #include "../../nfunc.h"
15 #include "../../nfuncold.h"
16 #include "../../../pfunc.h"
17 #include "../dct4func.h"
18 #include "n6510.h"
19 
20 /* method 3 */
21 GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message *msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last)
22 {
23  size_t i=0,j=0;
24 
25  while (Last->Location[j] != 0x00) j++;
26  if (j >= GSM_MAXCALENDARTODONOTES) {
27  smprintf(s, "Increase GSM_MAXCALENDARTODONOTES\n");
28  return ERR_MOREMEMORY;
29  }
30  if (j == 0) {
31  Last->Number = msg->Buffer[8]*256 + msg->Buffer[9];
32  smprintf(s, "Number of Entries: %i\n", Last->Number);
33  }
34  smprintf(s, "Locations: ");
35  while (14+(i*4) <= msg->Length) {
36  Last->Location[j] = msg->Buffer[12+i*4]*256 + msg->Buffer[13+i*4];
37  smprintf(s, "%i ", Last->Location[j]);
38  i++;
39  j++;
40  }
41  smprintf(s, "\nNumber of Entries in frame: %ld\n", (long)i);
42  Last->Location[j] = 0;
43  smprintf(s, "\n");
44  if (i == 1 && msg->Buffer[12+0*4]*256+msg->Buffer[13+0*4] == 0) return ERR_EMPTY;
45  if (i == 0) return ERR_EMPTY;
46  return ERR_NONE;
47 }
48 
49 /* method 3 */
50 GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, char Type)
51 {
52  GSM_Error error = ERR_UNKNOWN;
53  int i;
54  unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00,
55  0x00, 0x00, /* First location */
56  0x00}; /* 0 = calendar, 1 = ToDo in 6610 style, 2 = Notes */
57 
58  Last->Location[0] = 0x00;
59  Last->Number = 0;
60 
61  req[10] = Type;
62  if (Type == 0) {
63  smprintf(s, "Getting locations for calendar method 3\n");
64  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
65  } else if (Type == 1) {
66  smprintf(s, "Getting locations for ToDo method 2\n");
67  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
68  } else if (Type == 2) {
69  smprintf(s, "Getting locations for Notes\n");
70  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote);
71  }
72  if (error != ERR_NONE && error != ERR_EMPTY) return error;
73 
74  while (1) {
75  i=0;
76  while (Last->Location[i] != 0x00) i++;
77  smprintf(s, "i = %i last_number = %i\n",i,Last->Number);
78  if (i == Last->Number) break;
79  if (i != Last->Number && error == ERR_EMPTY) {
80  smprintf(s, "Phone doesn't support some notes with this method. Workaround\n");
81  Last->Number = i;
82  break;
83  }
84  req[8] = Last->Location[i-1] / 256;
85  req[9] = Last->Location[i-1] % 256;
86  if (Type == 0) {
87  smprintf(s, "Getting locations for calendar method 3\n");
88  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
89  } else if (Type == 1) {
90  smprintf(s, "Getting locations for todo method 2\n");
91  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
92  } else if (Type == 2) {
93  smprintf(s, "Getting locations for Notes\n");
94  error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote);
95  }
96  if (error != ERR_NONE && error != ERR_EMPTY) return error;
97  }
98  return ERR_NONE;
99 }
100 
101 /* method 3 */
103 {
104  GSM_CalendarEntry *entry = s->Phone.Data.Cal;
105  unsigned long diff;
106  int i;
107  gboolean found = FALSE;
108  GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
109  int len;
110 
111  smprintf(s, "Calendar note received method 3\n");
112 
113  smprintf(s,"Note type %02i: ",msg->Buffer[27]);
114  switch(msg->Buffer[27]) {
115  case 0x00: smprintf(s,"Reminder\n"); entry->Type = GSM_CAL_REMINDER; break;
116  case 0x01: smprintf(s,"Meeting\n"); entry->Type = GSM_CAL_MEETING; break;
117  case 0x02: smprintf(s,"Call\n"); entry->Type = GSM_CAL_CALL; break;
118  case 0x04: smprintf(s,"Birthday\n"); entry->Type = GSM_CAL_BIRTHDAY; break;
119  case 0x08: smprintf(s,"Memo\n"); entry->Type = GSM_CAL_MEMO; break;
120  case 0x20: smprintf(s,"Birthday\n"); entry->Type = GSM_CAL_BIRTHDAY; break;
121  default : smprintf(s,"unknown\n"); entry->Type = GSM_CAL_MEMO;
122  }
123 
124  smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
125  msg->Buffer[28]*256+msg->Buffer[29],
126  msg->Buffer[30],msg->Buffer[31],msg->Buffer[32],
127  msg->Buffer[33]);
128  GSM_GetCurrentDateTime(&entry->Entries[0].Date);
129  entry->Entries[0].Date.Year = msg->Buffer[28]*256+msg->Buffer[29];
130  if (entry->Type == GSM_CAL_BIRTHDAY) {
131  entry->Entries[0].Date.Year = entry->Entries[0].Date.Year;
132  smprintf(s,"%i\n",entry->Entries[0].Date.Year);
133  }
134  entry->Entries[0].Date.Month = msg->Buffer[30];
135  entry->Entries[0].Date.Day = msg->Buffer[31];
136  entry->Entries[0].Date.Hour = msg->Buffer[32];
137  entry->Entries[0].Date.Minute = msg->Buffer[33];
138  /* Garbage seen with 3510i 3.51 */
139  if (entry->Entries[0].Date.Month == 0 &&
140  entry->Entries[0].Date.Day == 0 &&
141  entry->Entries[0].Date.Hour == 0 &&
142  entry->Entries[0].Date.Minute == 0)
143  return ERR_EMPTY;
144  entry->Entries[0].Date.Second = 0;
146  entry->EntriesNum++;
147 
148  GSM_GetCalendarRecurranceRepeat(&(s->di), msg->Buffer+40, msg->Buffer+46, entry);
149 
150  if (entry->Type != GSM_CAL_BIRTHDAY) {
151  smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
152  msg->Buffer[34]*256+msg->Buffer[35],
153  msg->Buffer[36],msg->Buffer[37],msg->Buffer[38],
154  msg->Buffer[39]);
155  entry->Entries[entry->EntriesNum].Date.Year = msg->Buffer[34]*256+msg->Buffer[35];
156  entry->Entries[entry->EntriesNum].Date.Month = msg->Buffer[36];
157  entry->Entries[entry->EntriesNum].Date.Day = msg->Buffer[37];
158  entry->Entries[entry->EntriesNum].Date.Hour = msg->Buffer[38];
159  entry->Entries[entry->EntriesNum].Date.Minute = msg->Buffer[39];
160  entry->Entries[entry->EntriesNum].Date.Second = 0;
161  entry->Entries[entry->EntriesNum].EntryType = CAL_END_DATETIME;
162  entry->EntriesNum++;
163  }
164 
165  smprintf(s, "Note icon: %02x\n",msg->Buffer[21]);
166  for(i=0;i<Priv->CalendarIconsNum;i++) {
167  if (Priv->CalendarIconsTypes[i] == entry->Type) {
168  found = TRUE;
169  }
170  }
171  if (!found) {
172  Priv->CalendarIconsTypes[Priv->CalendarIconsNum] = entry->Type;
173  Priv->CalendarIcons [Priv->CalendarIconsNum] = msg->Buffer[21];
174  Priv->CalendarIconsNum++;
175  }
176 
177  if (msg->Buffer[14] == 0xFF && msg->Buffer[15] == 0xFF && msg->Buffer[16] == 0xff && msg->Buffer[17] == 0xff) {
178  smprintf(s, "No alarm\n");
179  } else {
180  diff = ((unsigned int)msg->Buffer[14]) << 24;
181  diff += ((unsigned int)msg->Buffer[15]) << 16;
182  diff += ((unsigned int)msg->Buffer[16]) << 8;
183  diff += msg->Buffer[17];
184 
185  memcpy(&entry->Entries[entry->EntriesNum].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
186  GetTimeDifference(diff, &entry->Entries[entry->EntriesNum].Date, FALSE, 60);
187  smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
188  entry->Entries[entry->EntriesNum].Date.Day, entry->Entries[entry->EntriesNum].Date.Month,
189  entry->Entries[entry->EntriesNum].Date.Year, entry->Entries[entry->EntriesNum].Date.Hour,
190  entry->Entries[entry->EntriesNum].Date.Minute,entry->Entries[entry->EntriesNum].Date.Second);
191 
193  if (msg->Buffer[22]==0x00 && msg->Buffer[23]==0x00 &&
194  msg->Buffer[24]==0x00 && msg->Buffer[25]==0x00) {
196  smprintf(s, "Alarm type : Silent\n");
197  }
198  entry->EntriesNum++;
199  }
200 
201  if (entry->Type == GSM_CAL_BIRTHDAY) {
202  if (msg->Buffer[42] == 0xff && msg->Buffer[43] == 0xff) {
203  entry->Entries[0].Date.Year = 0;
204  } else {
205  entry->Entries[0].Date.Year = msg->Buffer[42]*256+msg->Buffer[43];
206  }
207  }
208 
209  len = msg->Buffer[50] * 256 + msg->Buffer[51];
210  if (len > GSM_MAX_CALENDAR_TEXT_LENGTH) {
211  smprintf(s, "Calendar text too long (%d), truncating to %d\n", len, GSM_MAX_CALENDAR_TEXT_LENGTH);
213  }
214  memcpy(entry->Entries[entry->EntriesNum].Text,
215  msg->Buffer + 54,
216  len * 2);
217  entry->Entries[entry->EntriesNum].Text[len * 2] = 0;
218  entry->Entries[entry->EntriesNum].Text[len * 2 + 1] = 0;
219  entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
220  entry->EntriesNum++;
221  smprintf(s, "Note text: \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum-1].Text));
222 
223  if (entry->Type == GSM_CAL_CALL) {
224  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+(54+msg->Buffer[51]*2), msg->Buffer[52]*2);
225  entry->Entries[entry->EntriesNum].Text[msg->Buffer[52]*2] = 0;
226  entry->Entries[entry->EntriesNum].Text[msg->Buffer[52]*2+1] = 0;
227  entry->Entries[entry->EntriesNum].EntryType = CAL_PHONE;
228  entry->EntriesNum++;
229  }
230  if (entry->Type == GSM_CAL_MEETING) {
231  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+(54+msg->Buffer[51]*2), msg->Buffer[52]*2);
232  entry->Entries[entry->EntriesNum].Text[msg->Buffer[52]*2] = 0;
233  entry->Entries[entry->EntriesNum].Text[msg->Buffer[52]*2+1] = 0;
234  entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION;
235  entry->EntriesNum++;
236  }
237 
238  return ERR_NONE;
239 }
240 
241 static GSM_Error N6510_PrivGetGenericCalendar3(GSM_StateMachine *s, int Location, GSM_Phone_RequestID ID)
242 {
243  unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00,
244  0x00,0x99, /* Location */
245  0xff,0xff,0xff,0xff};
246 
247  req[8] = Location / 256;
248  req[9] = Location % 256;
249 
250  return GSM_WaitFor (s, req, 14, 0x13, 4, ID);
251 }
252 
253 static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start, int *LastCalendarYear)
254 {
255  GSM_Error error;
256  GSM_DateTime date_time;
257 
258  if (start) {
259  /* We have to get current year. It's NOT written in frame for
260  * Birthday
261  */
262  error=s->Phone.Functions->GetDateTime(s,&date_time);
263  switch (error) {
264  case ERR_EMPTY:
265  case ERR_NOTIMPLEMENTED:
266  GSM_GetCurrentDateTime(&date_time);
267  break;
268  case ERR_NONE:
269  break;
270  default:
271  return error;
272  }
273  *LastCalendarYear = date_time.Year;
274  }
275 
276  Note->EntriesNum = 0;
277  Note->Entries[0].Date.Year = *LastCalendarYear;
278 
279  s->Phone.Data.Cal=Note;
280  smprintf(s, "Getting calendar note method 3\n");
281  return N6510_PrivGetGenericCalendar3(s, Note->Location, ID_GetCalendarNote);
282 }
283 
284 /* method 3 */
285 static GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
286 {
287  GSM_Error error;
288  gboolean start2;
289 
290  if (start) {
291  error=N6510_GetCalendarInfo3(s,LastCalendar,0);
292  if (error!=ERR_NONE) return error;
293  if (LastCalendar->Number == 0) return ERR_EMPTY;
294 
295  *LastCalendarPos = 0;
296  } else {
297  (*LastCalendarPos)++;
298  }
299 
300  error = ERR_EMPTY;
301  start2 = start;
302  while (error == ERR_EMPTY) {
303  if (*LastCalendarPos >= LastCalendar->Number) return ERR_EMPTY;
304 
305  Note->Location = LastCalendar->Location[*LastCalendarPos];
306  error=N6510_PrivGetCalendar3(s, Note, start2, LastCalendarYear);
307  if (error == ERR_EMPTY) (*LastCalendarPos)++;
308 
309  start2 = FALSE;
310  }
311  return error;
312 }
313 
315 {
316  switch (msg->Buffer[3]) {
317  case 0x3B:
318  /* Old method 1 for accessing calendar */
319  return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
320  case 0x9F:
321  smprintf(s, "Info with calendar notes locations received method 3\n");
322  return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
323  }
324  return ERR_UNKNOWNRESPONSE;
325 }
326 
327 /* method 3 */
328 GSM_Error N6510_ReplyGetCalendarNotePos3(GSM_Protocol_Message *msg, GSM_StateMachine *s,int *FirstCalendarPos)
329 {
330  smprintf(s, "First calendar location: %i\n",msg->Buffer[8]*256+msg->Buffer[9]);
331  *FirstCalendarPos = msg->Buffer[8]*256+msg->Buffer[9];
332  return ERR_NONE;
333 }
334 
335 /* method 3 */
336 static GSM_Error N6510_GetCalendarNotePos3(GSM_StateMachine *s)
337 {
338  unsigned char req[] = {N6110_FRAME_HEADER, 0x95, 0x00};
339 
340  smprintf(s, "Getting first free calendar note location\n");
341  return GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNotePos);
342 }
343 
345 {
346  switch (msg->Buffer[3]) {
347  case 0xf0:
348  return ERR_NOTSUPPORTED;
349  case 0x32:
350  /* Old method 1 for accessing calendar */
351  return N71_65_ReplyGetCalendarNotePos1(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
352  case 0x96:
353  return N6510_ReplyGetCalendarNotePos3(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
354  }
355  return ERR_UNKNOWNRESPONSE;
356 }
357 
358 static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntry *Entry, unsigned char *ID)
359 {
360  int i,j,LastCalendarYear;
361  GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
362  GSM_CalendarEntry Note;
363  GSM_NOKIACalToDoLocations LastCalendar1,LastCalendar2;
364  GSM_Error error;
365  gboolean found;
366 
367  for(i=0;i<Priv->CalendarIconsNum;i++) {
368  if (Priv->CalendarIconsTypes[i] == Entry->Type) {
369  *ID = Priv->CalendarIcons[i];
370  return ERR_NONE;
371  }
372  }
373 
374  smprintf(s, "Starting finding note ID\n");
375 
376  error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0);
377  memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
378  if (error != ERR_NONE) return error;
379 
383  error=N71_65_AddCalendar2(s,Entry);
384  } else {
385  /* First method 1 was used for meeting only
386  * but it made problems with 6230 RH-12 4.44
387  * (probably for other Series 40 2.0 phones too)
388  * For now meeting, call and memo uses method 1
389  * Please note, that method 1 is the oldest one and in some
390  * moment Nokia can remove it from firmware
391  */
392 /* if (Entry->Type == GSM_CAL_MEETING) { */
393  if (Entry->Type == GSM_CAL_MEETING || Entry->Type == GSM_CAL_CALL || Entry->Type == GSM_CAL_MEMO) {
394  error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
395  } else {
396  error=N71_65_AddCalendar2(s,Entry);
397  }
398  }
399  if (error != ERR_NONE) return error;
400 
401  error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0);
402  memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
403  if (error != ERR_NONE) return error;
404 
405  smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number);
406 
407  for(i=0;i<LastCalendar2.Number;i++) {
408  found = TRUE;
409  for(j=0;j<LastCalendar1.Number;j++) {
410  if (LastCalendar1.Location[j] == LastCalendar2.Location[i]) {
411  found = FALSE;
412  break;
413  }
414  }
415  if (found) {
416  Note.Location = LastCalendar2.Location[i];
417  error=N6510_PrivGetCalendar3(s, &Note, TRUE, &LastCalendarYear);
418  if (error != ERR_NONE) return error;
419 
420  error=N71_65_DelCalendar(s, &Note);
421  if (error != ERR_NONE) return error;
422 
423  smprintf(s, "Ending finding note ID\n");
424 
425  for(j=0;j<Priv->CalendarIconsNum;j++) {
426  if (Priv->CalendarIconsTypes[j] == Entry->Type) {
427  *ID = Priv->CalendarIcons[j];
428  return ERR_NONE;
429  }
430  }
431  return ERR_UNKNOWN;
432  }
433  }
434 
435  return ERR_UNKNOWN;
436 }
437 
438 /* method 3 */
440 {
441  smprintf(s, "Calendar note added\n");
442  return ERR_NONE;
443 }
444 
445 /* method 3 */
446 static GSM_Error N6510_AddCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
447 {
448  GSM_CalendarNoteType NoteType, OldNoteType;
449  time_t t_time1,t_time2;
450  long diff;
451  GSM_Error error;
452  GSM_DateTime DT,date_time;
453  int Text, Time, Alarm, Phone, EndTime, Location, count=54;
454  unsigned char req[5000] = {
455  N6110_FRAME_HEADER, 0x65,
456  0x00, /* 0 = calendar, 1 = todo */
457  0x00, 0x00, 0x00,
458  0x00, 0x00, /* location */
459  0x00, 0x00, 0x00, 0x00,
460  0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
461  0x80, 0x00, 0x00,
462  0x01, /* note icon */
463  0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
464  0x00, /* 0x02 or 0x00 */
465  0x01, /* note type */
466  0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
467  0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
468  0x00, 0x00, /* recurrance */
469  0x00, 0x00, /* birth year */
470  0x20, /* ToDo priority */
471  0x00, /* ToDo completed ? */
472  0x00, 0x00, /* How many times repeat cal note or 0 */
473  0x00,
474  0x00, /* note text length */
475  0x00, /* phone length/meeting place */
476  0x00, 0x00, 0x00};
477 
478  error=N6510_GetCalendarNotePos3(s);
479  if (error!=ERR_NONE) return error;
480  Note->Location = *FirstCalendarPos;
481  req[8] = *FirstCalendarPos/256;
482  req[9] = *FirstCalendarPos%256;
483 
484  NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo);
485 
486  switch(NoteType) {
487  case GSM_CAL_REMINDER : req[27]=0x00; req[26]=0x02; break;
488  case GSM_CAL_MEETING : req[27]=0x01; break;
489  case GSM_CAL_CALL : req[27]=0x02; break;
490  case GSM_CAL_BIRTHDAY : req[27]=0x04; break;
491  case GSM_CAL_MEMO : req[27]=0x08; break;
492  default : return ERR_UNKNOWN;
493  }
494 
495  OldNoteType = Note->Type;
496  Note->Type = NoteType;
497  error=N6510_FindCalendarIconID3(s, Note, &req[21]);
498  Note->Type = OldNoteType;
499  if (error!=ERR_NONE) return error;
500 
501  GSM_CalendarFindDefaultTextTimeAlarmPhone(Note, &Text, &Time, &Alarm, &Phone, &EndTime, &Location);
502 
503  if (Time == -1) {
504  smprintf(s,"No time!\n");
505  return ERR_UNKNOWN;
506  }
507  smprintf(s, "Time OK\n");
508  memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
509  req[28] = DT.Year / 256;
510  req[29] = DT.Year % 256;
511  req[30] = DT.Month;
512  req[31] = DT.Day;
513  req[32] = DT.Hour;
514  req[33] = DT.Minute;
515 
516  if (NoteType == GSM_CAL_BIRTHDAY) {
517  error=s->Phone.Functions->GetDateTime(s,&date_time);
518  switch (error) {
519  case ERR_EMPTY:
520  case ERR_NOTIMPLEMENTED:
521  GSM_GetCurrentDateTime(&date_time);
522  break;
523  case ERR_NONE:
524  break;
525  default:
526  return error;
527  }
528  req[28] = date_time.Year / 256;
529  req[29] = date_time.Year % 256;
530  if (DT.Year == 0) {
531  req[42] = 0xff;
532  req[43] = 0xff;
533  } else {
534  req[42] = DT.Year / 256;
535  req[43] = DT.Year % 256;
536  }
537  }
538 
539  if (EndTime != -1) memcpy(&DT,&Note->Entries[EndTime].Date,sizeof(GSM_DateTime));
540 
541  req[34] = DT.Year / 256;
542  req[35] = DT.Year % 256;
543  req[36] = DT.Month;
544  req[37] = DT.Day;
545  req[38] = DT.Hour;
546  req[39] = DT.Minute;
547  if (NoteType == GSM_CAL_BIRTHDAY) {
548  req[34] = date_time.Year / 256;
549  req[35] = date_time.Year % 256;
550  }
551 
552  GSM_SetCalendarRecurranceRepeat(&(s->di), req+40, req+52, Note);
553 
554  if (Alarm != -1) {
555  memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
556  if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) {
557  req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
558  }
559  if (NoteType == GSM_CAL_BIRTHDAY) DT.Year = date_time.Year;
560  t_time2 = Fill_Time_T(DT);
561  t_time1 = Fill_Time_T(Note->Entries[Alarm].Date);
562  diff = (t_time1-t_time2)/60;
563 
564  smprintf(s, " Difference : %li seconds or minutes\n", -diff);
565  req[14] = (unsigned char)(-diff >> 24);
566  req[15] = (unsigned char)(-diff >> 16);
567  req[16] = (unsigned char)(-diff >> 8);
568  req[17] = (unsigned char)(-diff);
569  }
570 
571  if (Text != -1) {
572  req[48] = UnicodeLength(Note->Entries[Text].Text) / 256;
573  req[49] = UnicodeLength(Note->Entries[Text].Text) % 256;
574  CopyUnicodeString(req + 54, Note->Entries[Text].Text);
575  count += req[49] * 2 + (req[48] * 256) * 2;
576  }
577 
578  if (Phone != -1 && NoteType == GSM_CAL_CALL) {
579  req[50] = UnicodeLength(Note->Entries[Phone].Text);
580  CopyUnicodeString(req+54+req[49]*2,Note->Entries[Phone].Text);
581  count+= req[50]*2;
582  }
583 
584  if (Location != -1 && NoteType == GSM_CAL_MEETING) {
588  } else {
589  req[50] = UnicodeLength(Note->Entries[Location].Text);
590  CopyUnicodeString(req+54+req[49]*2,Note->Entries[Location].Text);
591  count+= req[50]*2;
592  }
593  }
594 
595  req[count++] = 0x00;
596 
597  smprintf(s, "Writing calendar note method 3\n");
598  return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetCalendarNote);
599 }
600 
602 {
603 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
604  /* Method 1. Some features missed. Not working with some notes in 3510 */
605  return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
606 #endif
607 
609  /* Method 1. Some features missed. Not working with some notes in 3510 */
610  return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
611 
612  /* Method 2. In known phones texts of notes cut to 50 chars. Some features missed */
613 /* return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos); */
614  } else {
615  /* Method 3. All DCT4 features supported. Not supported by 8910 */
616  return N6510_GetNextCalendar3(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
617  }
618 }
619 
621 {
622  GSM_Error error;
623 
624 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
625  /* Method 1 */
626  error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
627  if (error!=ERR_NONE) return error;
628  Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
629  return ERR_NONE;
630 #endif
631 
635  Status->Free = 100;
636 
638  /* Method 1 */
639  error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
640  if (error!=ERR_NONE) return error;
641  Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
642  return ERR_NONE;
643 
644  /* Method 2 */
645 /* return ERR_NOTSUPPORTED; */
646  } else {
647  /* Method 3 */
648  error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,0);
649  if (error!=ERR_NONE) return error;
650  Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
651  return ERR_NONE;
652  }
653 }
654 
656 {
657 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
658  return N71_65_AddCalendar2(s,Note);
659 #endif
660 
662  return N71_65_AddCalendar2(s,Note);
663 /* return N71_65_AddCalendar1(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos); */
664  } else {
665  /* Method 3. All DCT4 features supported. Not supported by 8910 */
666  return N6510_AddCalendar3(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
667  }
668 }
669 
671 {
672  return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastNote);
673 }
674 
676 {
677  int len;
678 
679  smprintf(s, "Note received\n");
680  len = msg->Buffer[50] * 256 + msg->Buffer[51];
681  if (len > GSM_MAX_NOTE_TEXT_LENGTH) {
682  smprintf(s, "Note too long (%d), truncating to %d\n", len, GSM_MAX_NOTE_TEXT_LENGTH);
684  }
685  memcpy(s->Phone.Data.Note->Text,
686  msg->Buffer + 54,
687  len * 2);
688  s->Phone.Data.Note->Text[len * 2] = 0;
689  s->Phone.Data.Note->Text[(len * 2) + 1] = 0;
690  return ERR_NONE;
691 }
692 
694 {
695  GSM_Error error;
696  GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote;
697 
699 
700  if (start) {
701  error=N6510_GetCalendarInfo3(s,LastNote,2);
702  if (error!=ERR_NONE) return error;
703  Note->Location = 1;
704  } else {
705  Note->Location++;
706  }
707 
708  if (Note->Location > LastNote->Number) return ERR_EMPTY;
709 
710  s->Phone.Data.Note = Note;
711  smprintf(s, "Getting note\n");
712  return N6510_PrivGetGenericCalendar3(s, LastNote->Location[Note->Location-1], ID_GetNote);
713 }
714 
716 {
717  GSM_Error error;
718  GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote;
719  GSM_CalendarEntry Note;
720 
722 
723  error=N6510_GetCalendarInfo3(s,LastNote,2);
724  if (error!=ERR_NONE) return error;
725 
726  smprintf(s, "Deleting Note\n");
727 
728  if (Not->Location > LastNote->Number || Not->Location == 0) return ERR_INVALIDLOCATION;
729 
730  Note.Location = LastNote->Location[Not->Location-1];
731  return N71_65_DelCalendar(s,&Note);
732 }
733 
735 {
736  smprintf(s, "First Note location: %i\n",msg->Buffer[8]*256+msg->Buffer[9]);
737  s->Phone.Data.Note->Location = msg->Buffer[8]*256+msg->Buffer[9];
738  return ERR_NONE;
739 }
740 
742 {
743  smprintf(s, "Note added\n");
744  return ERR_NONE;
745 }
746 
748 {
749  GSM_Error error;
750  int count=54;
751  unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95,
752  0x02}; /* 1 = todo, 2 = note */
753  unsigned char req[GSM_MAX_NOTE_TEXT_LENGTH + 500] = {
754  N6110_FRAME_HEADER, 0x65,
755  0x02, /* 0 = calendar, 1 = todo, 2 = note */
756  0x00, 0x00, 0x00,
757  0x00, 0x00, /* location */
758  0x00, 0x00, 0x00, 0x00,
759  0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
760  0x80, 0x00, 0x00,
761  0xA9, /* note icon */
762  0x00, 0x00, 0x00, 0x00, /* alarm type */
763  0x00, /* 0x02 or 0x00 */
764  0x80, /* note type */
765  0x07, 0xD2, 0x01, 0x01, 0x00, 0x00, /* start date/time */
766  0x07, 0xD2, 0x01, 0x11, 0x00, 0x00, /* end date/time */
767  0x00, 0x00, /* recurrance */
768  0xFF, 0xFF, /* birth year */
769  0x00, /* ToDo priority */
770  0x00, /* ToDo completed ? */
771  0x00, 0x00, 0x00,
772  0x00, /* note text length */
773  0x00, /* phone length/meeting place */
774  0x00, 0x00, 0x00};
775  size_t length;
776 
777  s->Phone.Data.Note = Not;
778 
779  smprintf(s, "Getting first free Note location\n");
780  error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetNote);
781  if (error!=ERR_NONE) return error;
782  req[8] = Not->Location / 256;
783  req[9] = Not->Location % 256;
784 
785  length = UnicodeLength(Not->Text);
786  req[48] = length / 256;
787  req[49] = length % 256;
788  CopyUnicodeString(req + 54, Not->Text);
789  count += length * 2;
790 
791  req[count++] = 0x00;
792 
793  smprintf(s, "Adding Note\n");
794  return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetNote);
795 }
796 
798 {
799  GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote;
800  GSM_Error error;
801 
802  error = N6510_GetCalendarInfo3(s,LastNote,2);
803  if (error!=ERR_NONE) return error;
804 
805  status->Used = LastNote->Number;
806  return ERR_NONE;
807 }
808 
809 /* ToDo support - 6310 style */
811 {
812  int i;
813  GSM_NOKIACalToDoLocations *Last = &s->Phone.Data.Priv.N6510.LastToDo;
814 
815  smprintf(s, "TODO locations received\n");
816  Last->Number=msg->Buffer[6]*256+msg->Buffer[7];
817  smprintf(s, "Number of Entries: %i\n",Last->Number);
818  smprintf(s, "Locations: ");
819  for (i=0;i<Last->Number;i++) {
820  Last->Location[i]=msg->Buffer[12+(i*4)]*256+msg->Buffer[(i*4)+13];
821  smprintf(s, "%i ",Last->Location[i]);
822  }
823  smprintf(s, "\n");
824  return ERR_NONE;
825 }
826 
827 /* ToDo support - 6310 style */
828 static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *status)
829 {
830  GSM_Error error;
831  GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
832  unsigned char reqLoc[] = {
834  0x15, 0x01, 0x00, 0x00,
835  0x00, 0x00, 0x00};
836 
837  smprintf(s, "Getting ToDo locations\n");
838  error = GSM_WaitFor (s, reqLoc, 10, 0x55, 4, ID_GetToDo);
839  if (error != ERR_NONE) return error;
840 
841  status->Used = LastToDo->Number;
845  status->Free = 100;
846  return ERR_NONE;
847 }
848 
849 static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status)
850 {
851  GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
852  GSM_Error error;
853 
854  error = N6510_GetCalendarInfo3(s,LastToDo,1);
855  if (error!=ERR_NONE) return error;
856 
857  status->Used = LastToDo->Number;
861  status->Free = 100;
862  return ERR_NONE;
863 }
864 
866 {
867  status->Used = 0;
868 
870  return N6510_GetToDoStatus1(s, status);
872  return N6510_GetToDoStatus2(s, status);
873  } else {
874  return ERR_NOTSUPPORTED;
875  }
876 }
877 
878 /* ToDo support - 6310 style */
880 {
881  GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
882 
883  smprintf(s, "TODO received method 1\n");
884 
888  Last->Type = GSM_CAL_MEMO;
889 
890  switch (msg->Buffer[4]) {
891  case 1 : Last->Priority = GSM_Priority_High; break;
892  case 2 : Last->Priority = GSM_Priority_Medium; break;
893  case 3 : Last->Priority = GSM_Priority_Low; break;
894  default : return ERR_UNKNOWN;
895  }
896  smprintf(s, "Priority: %i\n",msg->Buffer[4]);
897 
898  CopyUnicodeString(Last->Entries[0].Text,msg->Buffer+14);
899  Last->Entries[0].EntryType = TODO_TEXT;
900  Last->EntriesNum = 1;
901  smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
902 
903  return ERR_NONE;
904 }
905 
906 /* ToDo support - 6310 style */
907 static GSM_Error N6510_GetNextToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean refresh)
908 {
909  GSM_Error error;
910  GSM_ToDoStatus status;
911  GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
912  unsigned char reqGet[] = {
914  0x03, 0x00, 0x00, 0x80, 0x00,
915  0x00, 0x17}; /* Location */
916 
917  if (refresh) {
918  error = N6510_GetToDoStatus(s, &status);
919  if (error != ERR_NONE) return error;
920  ToDo->Location = 1;
921  } else {
922  ToDo->Location++;
923  }
924  if (ToDo->Location > LastToDo->Number) return ERR_EMPTY;
925 
926  reqGet[8] = LastToDo->Location[ToDo->Location-1] / 256;
927  reqGet[9] = LastToDo->Location[ToDo->Location-1] % 256;
928  s->Phone.Data.ToDo = ToDo;
929  smprintf(s, "Getting ToDo\n");
930  return GSM_WaitFor (s, reqGet, 10, 0x55, 4, ID_GetToDo);
931 }
932 
934 {
935  return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastToDo);
936 }
937 
938 /* Similiar to getting calendar method 3 */
940 {
941  GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
942  GSM_DateTime Date;
943  unsigned long diff;
944  int len;
945 
946  smprintf(s, "ToDo received method 2\n");
947 
951  Last->Type = GSM_CAL_MEMO;
952 
953  switch (msg->Buffer[44]) {
954  case 0x10: Last->Priority = GSM_Priority_Low; break;
955  case 0x20: Last->Priority = GSM_Priority_Medium; break;
956  case 0x30: Last->Priority = GSM_Priority_High; break;
957  default : return ERR_UNKNOWN;
958  }
959 
960  len = msg->Buffer[50] * 256 + msg->Buffer[51];
961  if (len > GSM_MAX_TODO_TEXT_LENGTH) {
962  smprintf(s, "Todo text too long (%d), truncating to %d\n", len, GSM_MAX_TODO_TEXT_LENGTH);
964  }
965  memcpy(Last->Entries[0].Text,
966  msg->Buffer + 54,
967  len * 2);
968  Last->Entries[0].Text[len * 2] = 0;
969  Last->Entries[0].Text[(len * 2) + 1] = 0;
970  Last->Entries[0].EntryType = TODO_TEXT;
971  smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
972 
973  smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
974  msg->Buffer[34]*256+msg->Buffer[35],
975  msg->Buffer[36],msg->Buffer[37],msg->Buffer[38],
976  msg->Buffer[39]);
977  Date.Year = msg->Buffer[34]*256+msg->Buffer[35];
978  Date.Month = msg->Buffer[36];
979  Date.Day = msg->Buffer[37];
980  Date.Hour = msg->Buffer[38];
981  Date.Minute = msg->Buffer[39];
982  Date.Second = 0;
983  Date.Timezone = 0;
985  memcpy(&Last->Entries[1].Date, &Date, sizeof(GSM_DateTime));
986 
987  smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
988  msg->Buffer[28]*256+msg->Buffer[29],
989  msg->Buffer[30],msg->Buffer[31],msg->Buffer[32],
990  msg->Buffer[33]);
991  Date.Year = msg->Buffer[28]*256+msg->Buffer[29];
992  Date.Month = msg->Buffer[30];
993  Date.Day = msg->Buffer[31];
994  Date.Hour = msg->Buffer[32];
995  Date.Minute = msg->Buffer[33];
996  Date.Second = 0;
997  Date.Timezone = 0;
998 
999  Last->EntriesNum = 2;
1000 
1001  if (msg->Buffer[45] == 0x01) {
1002  Last->Entries[2].Number = msg->Buffer[45];
1003  Last->Entries[2].EntryType = TODO_COMPLETED;
1004  Last->EntriesNum++;
1005  smprintf(s,"Completed\n");
1006  }
1007 
1008  if (msg->Buffer[14] == 0xFF && msg->Buffer[15] == 0xFF && msg->Buffer[16] == 0xff && msg->Buffer[17] == 0xff) {
1009  smprintf(s, "No alarm\n");
1010  } else {
1011  diff = ((unsigned int)msg->Buffer[14]) << 24;
1012  diff += ((unsigned int)msg->Buffer[15]) << 16;
1013  diff += ((unsigned int)msg->Buffer[16]) << 8;
1014  diff += msg->Buffer[17];
1015 
1016  memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime));
1017  GetTimeDifference(diff, &Last->Entries[Last->EntriesNum].Date, FALSE, 60);
1018  smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
1019  Last->Entries[Last->EntriesNum].Date.Day, Last->Entries[Last->EntriesNum].Date.Month,
1020  Last->Entries[Last->EntriesNum].Date.Year, Last->Entries[Last->EntriesNum].Date.Hour,
1021  Last->Entries[Last->EntriesNum].Date.Minute,Last->Entries[Last->EntriesNum].Date.Second);
1022 
1024  if (msg->Buffer[22]==0x00 && msg->Buffer[23]==0x00 &&
1025  msg->Buffer[24]==0x00 && msg->Buffer[25]==0x00)
1026  {
1028  smprintf(s, "Alarm type : Silent\n");
1029  }
1030  Last->EntriesNum++;
1031  }
1032 
1033  return ERR_NONE;
1034 }
1035 
1036 /* ToDo support - 6610 style */
1037 static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean refresh)
1038 {
1039  GSM_Error error;
1040  GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
1041 
1042  if (refresh) {
1043  error=N6510_GetCalendarInfo3(s,LastToDo,1);
1044  if (error!=ERR_NONE) return error;
1045  ToDo->Location = 1;
1046  } else {
1047  ToDo->Location++;
1048  }
1049 
1050  if (ToDo->Location > LastToDo->Number) return ERR_EMPTY;
1051 
1052  s->Phone.Data.ToDo = ToDo;
1053  smprintf(s, "Getting todo method 2\n");
1054  return N6510_PrivGetGenericCalendar3(s, LastToDo->Location[ToDo->Location-1], ID_GetToDo);
1055 }
1056 
1058 {
1060  return N6510_GetNextToDo1(s, ToDo, refresh);
1062  return N6510_GetNextToDo2(s, ToDo, refresh);
1063  } else {
1064  return ERR_NOTSUPPORTED;
1065  }
1066 }
1067 
1068 /* ToDo support - 6310 style */
1070 {
1071  smprintf(s, "All TODO deleted\n");
1072  return ERR_NONE;
1073 }
1074 
1075 /* ToDo support - 6310 style */
1077 {
1078  unsigned char req[] = {N6110_FRAME_HEADER, 0x11};
1079 
1081  return ERR_NOTSUPPORTED;
1082  }
1083 
1084  smprintf(s, "Deleting all ToDo method 1\n");
1085  return GSM_WaitFor (s, req, 4, 0x55, 4, ID_DeleteAllToDo);
1086 }
1087 
1089 {
1090  GSM_Error error;
1091  GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
1092  GSM_CalendarEntry Note;
1093 
1095  return ERR_NOTSUPPORTED;
1096  }
1097 
1098  error=N6510_GetCalendarInfo3(s,LastToDo,1);
1099  if (error!=ERR_NONE) return error;
1100 
1101  smprintf(s, "Deleting ToDo method 2\n");
1102 
1103  if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return ERR_INVALIDLOCATION;
1104 
1105  Note.Location = LastToDo->Location[ToDo->Location-1];
1106  return N71_65_DelCalendar(s,&Note);
1107 }
1108 
1109 /* ToDo support - 6310 style */
1111 {
1112  smprintf(s, "TODO first location received method 1: %02x\n",msg->Buffer[9]);
1113  s->Phone.Data.ToDo->Location = msg->Buffer[9];
1114  return ERR_NONE;
1115 }
1116 
1117 /* ToDo support - 6310 style */
1119 {
1120  smprintf(s, "TODO set OK\n");
1121  return ERR_NONE;
1122 }
1123 
1124 /* ToDo support - 6310 style */
1125 static GSM_Error N6510_AddToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
1126 {
1127  int Text, Alarm, EndTime, Completed, ulen, Phone;
1128  GSM_Error error;
1129  unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x0F};
1130  unsigned char reqSet[500] = {
1131  N6110_FRAME_HEADER, 0x01,
1132  0x03, /* Priority */
1133  0x00, /* Length of text */
1134  0x80,0x00,0x00,
1135  0x18}; /* Location */
1136 
1137  s->Phone.Data.ToDo = ToDo;
1138 
1139  smprintf(s, "Getting first ToDo location\n");
1140  error = GSM_WaitFor (s, reqLoc, 4, 0x55, 4, ID_SetToDo);
1141  if (error != ERR_NONE) return error;
1142  reqSet[9] = ToDo->Location;
1143 
1144  switch (ToDo->Priority) {
1145  case GSM_Priority_Low : reqSet[4] = 3; break;
1146  case GSM_Priority_Medium: reqSet[4] = 2; break;
1147  case GSM_Priority_High : reqSet[4] = 1; break;
1148  default: break;
1149  }
1150 
1151  GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
1152 
1153  if (Text == -1) return ERR_NOTSUPPORTED; /* XXX: shouldn't this be handled different way? */
1154  ulen = UnicodeLength(ToDo->Entries[Text].Text);
1155  reqSet[5] = ulen+1;
1156  CopyUnicodeString(reqSet+10,ToDo->Entries[Text].Text);
1157  reqSet[10+ulen*2] = 0x00;
1158  reqSet[10+ulen*2+1] = 0x00;
1159  smprintf(s, "Adding ToDo method 1\n");
1160  return GSM_WaitFor (s, reqSet, 12+ulen*2, 0x55, 4, ID_SetToDo);
1161 }
1162 
1164 {
1165  smprintf(s, "ToDo added method 2\n");
1166  return ERR_NONE;
1167 }
1168 
1170 {
1171  smprintf(s, "First ToDo location method 2: %i\n",msg->Buffer[8]*256+msg->Buffer[9]);
1172  s->Phone.Data.ToDo->Location = msg->Buffer[8]*256+msg->Buffer[9];
1173  return ERR_NONE;
1174 }
1175 
1176 static GSM_Error N6510_AddToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
1177 {
1178  GSM_CalendarEntry Note;
1179  time_t t_time1,t_time2;
1180  long diff;
1181  GSM_Error error;
1182  GSM_DateTime DT;
1183  int Text, Alarm, EndTime, Completed, count=54, Phone;
1184  unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95,
1185  0x01}; /* 1 = todo, 2 = note */
1186  unsigned char req[GSM_MAX_TODO_TEXT_LENGTH + 500] = {
1187  N6110_FRAME_HEADER, 0x65,
1188  0x01, /* 0 = calendar, 1 = todo */
1189  0x00, 0x00, 0x00,
1190  0x00, 0x00, /* location */
1191  0x00, 0x00, 0x00, 0x00,
1192  0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
1193  0x80, 0x00, 0x00,
1194  0x01, /* note icon */
1195  0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
1196  0x00, /* 0x02 or 0x00 */
1197  0x01, /* note type */
1198  0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
1199  0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
1200  0x00, 0x00, /* recurrance */
1201  0x00, 0x00, /* birth year */
1202  0x20, /* ToDo priority */
1203  0x00, /* ToDo completed ? */
1204  0x00, 0x00, /* How many times repeat cal note or 0 */
1205  0x00,
1206  0x00, /* note text length */
1207  0x00, /* phone length/meeting place */
1208  0x00, 0x00, 0x00};
1209 
1210  s->Phone.Data.ToDo = ToDo;
1211 
1212  smprintf(s, "Getting first free ToDo location method 2\n");
1213  error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetToDo);
1214  if (error!=ERR_NONE) return error;
1215  req[8] = ToDo->Location/256;
1216  req[9] = ToDo->Location%256;
1217 
1218  Note.Type = GSM_CAL_MEETING;
1219  DT.Year = 2004; DT.Month = 1; DT.Day = 1;
1220  DT.Hour = 12; DT.Minute = 12; DT.Second = 0;
1221  DT.Timezone = 0;
1222  memcpy(&Note.Entries[0].Date,&DT,sizeof(GSM_DateTime));
1224  memcpy(&Note.Entries[1].Date,&DT,sizeof(GSM_DateTime));
1226  EncodeUnicode(Note.Entries[2].Text,"ala",3);
1227  Note.Entries[2].EntryType = CAL_TEXT;
1228  Note.EntriesNum = 3;
1229  error=N6510_FindCalendarIconID3(s, &Note, &req[21]);
1230  if (error!=ERR_NONE) return error;
1231 
1232  switch (ToDo->Priority) {
1233  case GSM_Priority_Low : req[44] = 0x10; break;
1234  case GSM_Priority_Medium: req[44] = 0x20; break;
1235  case GSM_Priority_High : req[44] = 0x30; break;
1236  default: break;
1237  }
1238 
1239  GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
1240 
1241  if (Completed != -1) req[45] = 0x01;
1242 
1243  if (EndTime == -1) {
1245  } else {
1246  memcpy(&DT,&ToDo->Entries[EndTime].Date,sizeof(GSM_DateTime));
1247  }
1248  /*Start time*/
1249  req[28] = DT.Year / 256;
1250  req[29] = DT.Year % 256;
1251  req[30] = DT.Month;
1252  req[31] = DT.Day;
1253  req[32] = DT.Hour;
1254  req[33] = DT.Minute;
1255  /*End time*/
1256  req[34] = DT.Year / 256;
1257  req[35] = DT.Year % 256;
1258  req[36] = DT.Month;
1259  req[37] = DT.Day;
1260  req[38] = DT.Hour;
1261  req[39] = DT.Minute;
1262 
1263  if (Alarm != -1) {
1264  if (ToDo->Entries[Alarm].EntryType == TODO_SILENT_ALARM_DATETIME)
1265  {
1266  req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
1267  }
1268  t_time2 = Fill_Time_T(DT);
1269  t_time1 = Fill_Time_T(ToDo->Entries[Alarm].Date);
1270  diff = (t_time1-t_time2)/60;
1271 
1272  smprintf(s, " Difference : %li seconds or minutes\n", -diff);
1273  req[14] = (unsigned char)(-diff >> 24);
1274  req[15] = (unsigned char)(-diff >> 16);
1275  req[16] = (unsigned char)(-diff >> 8);
1276  req[17] = (unsigned char)(-diff);
1277  }
1278 
1279  if (Text != -1) {
1280  req[48] = UnicodeLength(ToDo->Entries[Text].Text) / 256;
1281  req[49] = UnicodeLength(ToDo->Entries[Text].Text) % 256;
1282  CopyUnicodeString(req + 54, ToDo->Entries[Text].Text);
1283  count += req[49] * 2 + (req[48] * 256) * 2;
1284  }
1285 
1286  req[count++] = 0x00;
1287 
1288  smprintf(s, "Adding ToDo method 2\n");
1289  return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetToDo);
1290 }
1291 
1293 {
1295  return N6510_AddToDo1(s, ToDo);
1297  return N6510_AddToDo2(s, ToDo);
1298  } else {
1299  return ERR_NOTSUPPORTED;
1300  }
1301 }
1302 
1304 {
1306 
1307  switch (msg->Buffer[3]) {
1308  case 0x86:
1309  smprintf(s, "Auto deleting setting received\n");
1310  sett->AutoDelete = msg->Buffer[4];
1311  return ERR_NONE;
1312  case 0x8E:
1313  smprintf(s, "Start day for calendar received\n");
1314  switch(msg->Buffer[4]) {
1315  case 0x04:
1316  sett->StartDay = 1;
1317  return ERR_NONE;
1318  case 0x03:
1319  sett->StartDay = 6;
1320  return ERR_NONE;
1321  case 0x02:
1322  sett->StartDay = 7;
1323  return ERR_NONE;
1324  case 0x01:
1325  sett->StartDay = 1;
1326  return ERR_NONE;
1327  }
1328  break;
1329  }
1330  return ERR_UNKNOWNRESPONSE;
1331 }
1332 
1334 {
1335  GSM_Error error;
1336  unsigned char req1[] = {N6110_FRAME_HEADER, 0x85};
1337  unsigned char req2[] = {N6110_FRAME_HEADER, 0x8D};
1338 
1339  s->Phone.Data.CalendarSettings = settings;
1340 
1341  smprintf(s, "Getting auto delete\n");
1342  error = GSM_WaitFor (s, req1, 4, 0x13, 4, ID_GetCalendarSettings);
1343  if (error != ERR_NONE) return error;
1344 
1345  smprintf(s, "Getting start day for week\n");
1346  return GSM_WaitFor (s, req2, 4, 0x13, 4, ID_GetCalendarSettings);
1347 }
1348 
1349 #endif
1350 
1351 /* How should editor hadle tabs in this file? Add editor commands here.
1352  * vim: noexpandtab sw=8 ts=8 sts=8:
1353  */
int CalendarIconsNum
Definition: n6510.h:29
GSM_Error N6510_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, gboolean start)
void GSM_ToDoFindDefaultTextTimeAlarmCompleted(GSM_ToDoEntry *entry, int *Text, int *Alarm, int *Completed, int *EndTime, int *Phone)
Definition: gsmcal.c:1005
GSM_Error N6510_ReplyGetCalendarInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
GSM_ToDo_Priority Priority
GSM_Error N71_65_AddCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyGetCalendarSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
unsigned int Number
#define GSM_MAX_CALENDAR_TEXT_LENGTH
Definition: gammu-limits.h:112
GSM_CalendarNoteType Type
void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, gboolean Plus, int multi)
Definition: misc.c:247
#define N6110_FRAME_HEADER
Definition: ncommon.h:8
GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s)
GSM_Error N71_65_DelCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_CalendarSettings * CalendarSettings
Definition: gsmstate.h:625
GSM_Error N71_65_GetCalendarInfo1(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *LastCalendar)
GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
GSM_ToDoEntry * ToDo
Definition: gsmstate.h:585
GSM_Error N6510_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
GSM_Error
Definition: gammu-error.h:23
GSM_Error N6510_ReplyGetNoteInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Debug_Info di
Definition: gsmstate.h:1412
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
GSM_Error N71_65_ReplyGetCalendarNotePos1(GSM_Protocol_Message *msg, GSM_StateMachine *s, int *FirstCalendarPos)
void GSM_SetCalendarRecurranceRepeat(GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
Definition: gsmcal.c:31
GSM_CalendarNoteType N71_65_FindCalendarType(GSM_CalendarNoteType Type, GSM_PhoneModel *model)
GSM_Error N6510_ReplyDeleteAllToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
int Location[GSM_MAXCALENDARTODONOTES+1]
Definition: ncommon.h:92
GSM_Error N6510_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
GSM_CalendarNoteType CalendarIconsTypes[10]
Definition: n6510.h:28
GSM_Error N6510_AddNote(GSM_StateMachine *s, GSM_NoteEntry *Not)
GSM_ToDoType EntryType
void GSM_GetCalendarRecurranceRepeat(GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
Definition: gsmcal.c:137
void GSM_CalendarFindDefaultTextTimeAlarmPhone(GSM_CalendarEntry *entry, int *Text, int *Time, int *Alarm, int *Phone, int *EndTime, int *Location)
Definition: gsmcal.c:279
char Text[(GSM_MAX_NOTE_TEXT_LENGTH+1) *2]
int gboolean
Definition: gammu-types.h:23
GSM_CalendarNoteType Type
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
GSM_Error N6510_ReplyGetCalendarNotePos(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char CalendarIcons[10]
Definition: n6510.h:27
struct GSM_Phone_Data::@2 Priv
GSM_Error N6510_ReplyGetNote(GSM_Protocol_Message *msg, GSM_StateMachine *s)
#define GSM_MAX_NOTE_TEXT_LENGTH
Definition: gammu-limits.h:119
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]
GSM_NOKIACalToDoLocations LastCalendar
Definition: n6510.h:25
GSM_Error GSM_WaitFor(GSM_StateMachine *s, unsigned const char *buffer, size_t length, int type, int timeout, GSM_Phone_RequestID request)
Definition: gsmstate.c:1029
#define GSM_MAXCALENDARTODONOTES
Definition: gammu-limits.h:84
GSM_Error N6510_ReplyGetToDoFirstLoc2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyAddCalendar3(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyGetToDoStatus1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N71_65_GetNextCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
GSM_CalendarType EntryType
GSM_CalendarNoteType
GSM_Error(* GetDateTime)(GSM_StateMachine *s, GSM_DateTime *date_time)
Definition: gsmstate.h:814
GSM_Error N71_65_ReplyGetCalendarInfo1(GSM_Protocol_Message *msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *LastCalendar)
GSM_Error N6510_ReplyGetToDoStatus2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyAddNote(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_Error N6510_GetNoteStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
GSM_Error N6510_ReplyGetNoteFirstLoc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
time_t Fill_Time_T(GSM_DateTime DT)
Definition: misc.c:189
gboolean GSM_IsPhoneFeatureAvailable(GSM_PhoneModel *model, GSM_Feature feature)
Definition: gsmphones.c:1026
GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error N6510_ReplyAddToDo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
GSM_Error N71_65_AddCalendar2(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_Error N6510_ReplyAddToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
#define GSM_MAX_TODO_TEXT_LENGTH
Definition: gammu-limits.h:133
#define TRUE
Definition: gammu-types.h:28
GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_DeleteNote(GSM_StateMachine *s, GSM_NoteEntry *Not)
unsigned char * Buffer
Definition: protocol.h:22
unsigned char Text[(GSM_MAX_TODO_TEXT_LENGTH+1) *2]
GSM_Error N6510_GetCalendarSettings(GSM_StateMachine *s, GSM_CalendarSettings *settings)
#define UNUSED
Definition: gammu-misc.h:105
GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean refresh)
GSM_NoteEntry * Note
Definition: gsmstate.h:589
GSM_Phone_RequestID
Definition: gsmreply.h:25
GSM_DateTime Date
GSM_Error N6510_ReplyGetToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261
GSM_CalendarEntry * Cal
Definition: gsmstate.h:549