Gammu internals  1.38.0
Calendar parsing and encoding

Data Structures

struct  GSM_CalendarSettings
 
struct  GSM_CalendarStatus
 
struct  GSM_SubCalendarEntry
 
struct  GSM_CalendarEntry
 
struct  GSM_Alarm
 

Macros

#define _GNU_SOURCE
 

Enumerations

enum  GSM_TimeUnit {
  GSM_TimeUnit_Unknown = 0, GSM_TimeUnit_Days, GSM_TimeUnit_Hours, GSM_TimeUnit_Minutes,
  GSM_TimeUnit_Seconds
}
 
enum  GSM_CalendarNoteType {
  GSM_CAL_REMINDER = 1, GSM_CAL_CALL, GSM_CAL_MEETING, GSM_CAL_BIRTHDAY,
  GSM_CAL_MEMO, GSM_CAL_TRAVEL, GSM_CAL_VACATION, GSM_CAL_T_ATHL,
  GSM_CAL_T_BALL, GSM_CAL_T_CYCL, GSM_CAL_T_BUDO, GSM_CAL_T_DANC,
  GSM_CAL_T_EXTR, GSM_CAL_T_FOOT, GSM_CAL_T_GOLF, GSM_CAL_T_GYM,
  GSM_CAL_T_HORS, GSM_CAL_T_HOCK, GSM_CAL_T_RACE, GSM_CAL_T_RUGB,
  GSM_CAL_T_SAIL, GSM_CAL_T_STRE, GSM_CAL_T_SWIM, GSM_CAL_T_TENN,
  GSM_CAL_T_TRAV, GSM_CAL_T_WINT, GSM_CAL_ALARM, GSM_CAL_DAILY_ALARM,
  GSM_CAL_SHOPPING
}
 
enum  GSM_CalendarType {
  CAL_START_DATETIME = 1, CAL_END_DATETIME, CAL_TONE_ALARM_DATETIME, CAL_SILENT_ALARM_DATETIME,
  CAL_TEXT, CAL_DESCRIPTION, CAL_LOCATION, CAL_PHONE,
  CAL_PRIVATE, CAL_CONTACTID, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAY,
  CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_WEEKOFMONTH, CAL_REPEAT_MONTH, CAL_REPEAT_FREQUENCY,
  CAL_REPEAT_STARTDATE, CAL_REPEAT_STOPDATE, CAL_REPEAT_COUNT, CAL_LUID,
  CAL_LAST_MODIFIED
}
 
enum  GSM_VCalendarVersion { Nokia_VCalendar = 1, Siemens_VCalendar, SonyEricsson_VCalendar, Mozilla_iCalendar }
 

Functions

void GSM_SetCalendarRecurranceRepeat (GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
 
void GSM_GetCalendarRecurranceRepeat (GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
 
gboolean GSM_IsCalendarNoteFromThePast (GSM_CalendarEntry *note)
 
void GSM_CalendarFindDefaultTextTimeAlarmPhone (GSM_CalendarEntry *entry, int *Text, int *Time, int *Alarm, int *Phone, int *EndTime, int *Location)
 
GSM_DateTime VCALTimeDiff (GSM_DateTime *Alarm, GSM_DateTime *Time)
 
GSM_Error GSM_Translate_Category_From_VCal (const char *string, GSM_CalendarNoteType *Type)
 
GSM_Error GSM_Translate_Category_To_VCal (char *string, const GSM_CalendarNoteType Type)
 
GSM_Error GSM_EncodeVCAL_RRULE (char *Buffer, const size_t buff_len, size_t *Length, GSM_CalendarEntry *note, int TimePos UNUSED, GSM_VCalendarVersion Version)
 
void GSM_Calendar_AdjustDate (GSM_CalendarEntry *note, GSM_DeltaTime *delta)
 
void GSM_ToDo_AdjustDate (GSM_ToDoEntry *note, GSM_DeltaTime *delta)
 
GSM_Error GSM_EncodeVCALENDAR (char *Buffer, const size_t buff_len, size_t *Length, GSM_CalendarEntry *note, const gboolean header, const GSM_VCalendarVersion Version)
 
void GSM_ToDoFindDefaultTextTimeAlarmCompleted (GSM_ToDoEntry *entry, int *Text, int *Alarm, int *Completed, int *EndTime, int *Phone)
 
GSM_Error GSM_EncodeVTODO (char *Buffer, const size_t buff_len, size_t *Length, const GSM_ToDoEntry *note, const gboolean header, const GSM_VToDoVersion Version)
 
GSM_DeltaTime ReadVCALTriggerTime (unsigned char *Buffer)
 
int GSM_Make_VCAL_Lines (unsigned char *Buffer, int *lBuffer)
 
GSM_Error GSM_DecodeVCAL_DOW (const char *Buffer, int *Output)
 
GSM_Error GSM_DecodeVCAL_RRULE (GSM_Debug_Info *di, const char *Buffer, GSM_CalendarEntry *Calendar, int TimePos)
 
GSM_Error GSM_DecodeVCALENDAR_VTODO (GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_CalendarEntry *Calendar, GSM_ToDoEntry *ToDo, GSM_VCalendarVersion CalVer, GSM_VToDoVersion ToDoVer)
 
GSM_Error GSM_DecodeVNOTE (char *Buffer, size_t *Pos, GSM_NoteEntry *Note)
 
GSM_Error GSM_EncodeVNTFile (char *Buffer, const size_t buff_len, size_t *Length, GSM_NoteEntry *Note)
 
GSM_Error GSM_GetAlarm (GSM_StateMachine *s, GSM_Alarm *Alarm)
 
GSM_Error GSM_SetAlarm (GSM_StateMachine *s, GSM_Alarm *Alarm)
 
GSM_Error GSM_GetCalendarStatus (GSM_StateMachine *s, GSM_CalendarStatus *Status)
 
GSM_Error GSM_GetCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note)
 
GSM_Error GSM_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
 
GSM_Error GSM_SetCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note)
 
GSM_Error GSM_AddCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note)
 
GSM_Error GSM_DeleteCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note)
 
GSM_Error GSM_DeleteAllCalendar (GSM_StateMachine *s)
 
GSM_Error GSM_GetCalendarSettings (GSM_StateMachine *s, GSM_CalendarSettings *settings)
 
GSM_Error GSM_SetCalendarSettings (GSM_StateMachine *s, GSM_CalendarSettings *settings)
 

Detailed Description

This module implements calendar related opreations.

See also
http://www.imc.org/pdi/

Calendar events manipulations.

Macro Definition Documentation

§ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 13 of file gsmcal.c.

Enumeration Type Documentation

§ GSM_CalendarNoteType

Enum defines types of calendar notes

Enumerator
GSM_CAL_REMINDER 

Reminder or Date

GSM_CAL_CALL 

Call

GSM_CAL_MEETING 

Meeting

GSM_CAL_BIRTHDAY 

Birthday or Anniversary or Special Occasion

GSM_CAL_MEMO 

Memo or Miscellaneous

GSM_CAL_TRAVEL 

Travel

GSM_CAL_VACATION 

Vacation

GSM_CAL_T_ATHL 

Training - Athletism

GSM_CAL_T_BALL 

Training - Ball Games

GSM_CAL_T_CYCL 

Training - Cycling

GSM_CAL_T_BUDO 

Training - Budo

GSM_CAL_T_DANC 

Training - Dance

GSM_CAL_T_EXTR 

Training - Extreme Sports

GSM_CAL_T_FOOT 

Training - Football

GSM_CAL_T_GOLF 

Training - Golf

GSM_CAL_T_GYM 

Training - Gym

GSM_CAL_T_HORS 

Training - Horse Race

GSM_CAL_T_HOCK 

Training - Hockey

GSM_CAL_T_RACE 

Training - Races

GSM_CAL_T_RUGB 

Training - Rugby

GSM_CAL_T_SAIL 

Training - Sailing

GSM_CAL_T_STRE 

Training - Street Games

GSM_CAL_T_SWIM 

Training - Swimming

GSM_CAL_T_TENN 

Training - Tennis

GSM_CAL_T_TRAV 

Training - Travels

GSM_CAL_T_WINT 

Training - Winter Games

GSM_CAL_ALARM 

Alarm

GSM_CAL_DAILY_ALARM 

Alarm repeating each day.

GSM_CAL_SHOPPING 

Shopping

Definition at line 86 of file gammu-calendar.h.

86  {
90  GSM_CAL_REMINDER = 1,
106  GSM_CAL_MEMO,
GSM_CalendarNoteType

§ GSM_CalendarType

One value of calendar event.

Enumerator
CAL_START_DATETIME 

Date and time of event start.

CAL_END_DATETIME 

Date and time of event end.

CAL_TONE_ALARM_DATETIME 

Alarm date and time.

CAL_SILENT_ALARM_DATETIME 

Date and time of silent alarm.

CAL_TEXT 

Text.

CAL_DESCRIPTION 

Detailed description.

CAL_LOCATION 

Location.

CAL_PHONE 

Phone number.

CAL_PRIVATE 

Whether this entry is private.

CAL_CONTACTID 

Related contact id.

CAL_REPEAT_DAYOFWEEK 

Repeat each x'th day of week.

CAL_REPEAT_DAY 

Repeat each x'th day of month.

CAL_REPEAT_DAYOFYEAR 

Repeat each x'th day of year.

CAL_REPEAT_WEEKOFMONTH 

Repeat x'th week of month.

CAL_REPEAT_MONTH 

Repeat x'th month.

CAL_REPEAT_FREQUENCY 

Repeating frequency.

CAL_REPEAT_STARTDATE 

Repeating start.

CAL_REPEAT_STOPDATE 

Repeating end.

CAL_REPEAT_COUNT 

Number of repetitions.

CAL_LUID 

IrMC LUID which can be used for synchronisation.

CAL_LAST_MODIFIED 

Date and time of last modification.

Definition at line 210 of file gammu-calendar.h.

210  {
214  CAL_START_DATETIME = 1,
230  CAL_TEXT,
238  CAL_LOCATION,
242  CAL_PHONE,
246  CAL_PRIVATE,
250  CAL_CONTACTID, /* 10 */
290  CAL_LUID, /* 20 */
GSM_CalendarType

§ GSM_TimeUnit

Time Units.

Enumerator
GSM_TimeUnit_Unknown 
GSM_TimeUnit_Days 
GSM_TimeUnit_Hours 
GSM_TimeUnit_Minutes 
GSM_TimeUnit_Seconds 

Definition at line 29 of file gsmcal.h.

§ GSM_VCalendarVersion

Format of vCalendar export.

Enumerator
Nokia_VCalendar 

vCalendar specially hacked for Nokia .

Siemens_VCalendar 

vCalendar specially hacked for Siemens.

SonyEricsson_VCalendar 

Standard vCalendar (which works for Sony-Ericsson phones)

Mozilla_iCalendar 

iCalendar as compatible with Mozilla.

Definition at line 558 of file gammu-calendar.h.

Function Documentation

§ GSM_AddCalendar()

GSM_Error GSM_AddCalendar ( GSM_StateMachine s,
GSM_CalendarEntry Note 
)

Adds calendar entry.

Parameters
sState machine pointer.
NoteNote to add.
Returns
Error code

Adds calendar entry.

Definition at line 1468 of file api.c.

References GSM_Phone_Functions::AddCalendar, CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_CALENDAR_INFO, and PRINT_LOG_ERROR.

1469 {
1470  GSM_Error err;
1471 
1474 
1475  err = s->Phone.Functions->AddCalendar(s, Note);
1476  PRINT_LOG_ERROR(err);
1477  return err;
1478 }
#define PRINT_CALENDAR_INFO()
Definition: api.c:17
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* AddCalendar)(GSM_StateMachine *s, GSM_CalendarEntry *Note)
Definition: gsmstate.h:1184

§ GSM_Calendar_AdjustDate()

void GSM_Calendar_AdjustDate ( GSM_CalendarEntry note,
GSM_DeltaTime delta 
)

Adjusts all datetime information in calendar entry according to delta.

Definition at line 748 of file gsmcal.c.

References CAL_CONTACTID, CAL_DESCRIPTION, CAL_END_DATETIME, CAL_LAST_MODIFIED, CAL_LOCATION, CAL_LUID, CAL_PHONE, CAL_PRIVATE, CAL_REPEAT_COUNT, CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STARTDATE, CAL_REPEAT_STOPDATE, CAL_REPEAT_WEEKOFMONTH, CAL_SILENT_ALARM_DATETIME, CAL_START_DATETIME, CAL_TEXT, CAL_TONE_ALARM_DATETIME, GSM_SubCalendarEntry::Date, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, and GSM_AddTime().

Referenced by GSM_DecodeVCALENDAR_VTODO().

749 {
750  int i;
751 
752  /* Loop over entries */
753  for (i=0; i < note->EntriesNum; i++) {
754  switch (note->Entries[i].EntryType) {
755  case CAL_START_DATETIME :
756  case CAL_END_DATETIME :
759  case CAL_LAST_MODIFIED:
761  case CAL_REPEAT_STOPDATE:
762  note->Entries[i].Date = GSM_AddTime(note->Entries[i].Date, *delta);
763  break;
764  case CAL_TEXT:
765  case CAL_DESCRIPTION:
766  case CAL_PHONE:
767  case CAL_LOCATION:
768  case CAL_LUID:
770  case CAL_REPEAT_DAY:
772  case CAL_REPEAT_MONTH:
775  case CAL_REPEAT_COUNT:
776  case CAL_PRIVATE:
777  case CAL_CONTACTID:
778  /* No need to care */
779  break;
780  }
781  }
782 }
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_DateTime GSM_AddTime(GSM_DateTime DT, GSM_DeltaTime delta)
Definition: misc.c:223

§ GSM_CalendarFindDefaultTextTimeAlarmPhone()

void GSM_CalendarFindDefaultTextTimeAlarmPhone ( GSM_CalendarEntry entry,
int *  Text,
int *  Time,
int *  Alarm,
int *  Phone,
int *  EndTime,
int *  Location 
)

Finds inxedes of default entries.

Definition at line 279 of file gsmcal.c.

References CAL_END_DATETIME, CAL_LOCATION, CAL_PHONE, CAL_SILENT_ALARM_DATETIME, CAL_START_DATETIME, CAL_TEXT, CAL_TONE_ALARM_DATETIME, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, and GSM_SubCalendarEntry::EntryType.

Referenced by NOKIA_EncodeDateTime().

280 {
281  int i;
282 
283  *Text = -1;
284  *Time = -1;
285  *Alarm = -1;
286  *Phone = -1;
287  *EndTime = -1;
288  *Location = -1;
289  for (i = 0; i < entry->EntriesNum; i++) {
290  switch (entry->Entries[i].EntryType) {
291  case CAL_START_DATETIME :
292  if (*Time == -1) *Time = i;
293  break;
294  case CAL_END_DATETIME :
295  if (*EndTime == -1) *EndTime = i;
296  break;
299  if (*Alarm == -1) *Alarm = i;
300  break;
301  case CAL_TEXT:
302  if (*Text == -1) *Text = i;
303  break;
304  case CAL_PHONE:
305  if (*Phone == -1) *Phone = i;
306  break;
307  case CAL_LOCATION:
308  if (*Location == -1) *Location = i;
309  break;
310  default:
311  break;
312  }
313  }
314 }
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]

§ GSM_DecodeVCAL_DOW()

GSM_Error GSM_DecodeVCAL_DOW ( const char *  Buffer,
int *  Output 
)

Decode day of week to gammu enumeration (1 = Monday...7 = Sunday).

Definition at line 1261 of file gsmcal.c.

References ERR_NONE, and ERR_UNKNOWN.

1262 {
1263  if (toupper((int)Buffer[0])== 'M' && toupper((int)Buffer[1]) == 'O') {
1264  *Output = 1;
1265  return ERR_NONE;
1266  } else if (toupper((int)Buffer[0])== 'T' && toupper((int)Buffer[1]) == 'U') {
1267  *Output = 2;
1268  return ERR_NONE;
1269  } else if (toupper((int)Buffer[0])== 'W' && toupper((int)Buffer[1]) == 'E') {
1270  *Output = 3;
1271  return ERR_NONE;
1272  } else if (toupper((int)Buffer[0])== 'T' && toupper((int)Buffer[1]) == 'H') {
1273  *Output = 4;
1274  return ERR_NONE;
1275  } else if (toupper((int)Buffer[0])== 'F' && toupper((int)Buffer[1]) == 'R') {
1276  *Output = 5;
1277  return ERR_NONE;
1278  } else if (toupper((int)Buffer[0])== 'S' && toupper((int)Buffer[1]) == 'A') {
1279  *Output = 6;
1280  return ERR_NONE;
1281  } else if (toupper((int)Buffer[0])== 'S' && toupper((int)Buffer[1]) == 'U') {
1282  *Output = 7;
1283  return ERR_NONE;
1284  }
1285  return ERR_UNKNOWN;
1286 }

§ GSM_DecodeVCAL_RRULE()

GSM_Error GSM_DecodeVCAL_RRULE ( GSM_Debug_Info di,
const char *  Buffer,
GSM_CalendarEntry Calendar,
int  TimePos 
)

Decodes vCalendar RRULE recurrance format into calendar entry. It should be implemented according to following grammar:

{} 0 or more
[] 0 or 1
start ::= <daily> [<enddate>] |
<weekly> [<enddate>] |
<monthlybypos> [<enddate>] |
<monthlybyday> [<enddate>] |
<yearlybymonth> [<enddate>] |
<yearlybyday> [<enddate>]
digit ::= <0|1|2|3|4|5|6|7|8|9>
digits ::= <digit> {<digits>}
enddate ::= ISO 8601_date_time value(e.g., 19940712T101530Z)
interval ::= <digits>
duration ::= #<digits>
lastday ::= LD
plus ::= +
minus ::= -
daynumber ::= <1-31> [<plus>|<minus>]| <lastday>
daynumberlist ::= daynumber {<daynumberlist>}
month ::= <1-12>
monthlist ::= <month> {<monthlist>}
day ::= <1-366>
daylist ::= <day> {<daylist>}
occurrence ::= <1-5><plus> | <1-5><minus>
weekday ::= <SU|MO|TU|WE|TH|FR|SA>
weekdaylist ::= <weekday> {<weekdaylist>}
occurrenceweekday ::= [<occurrence>] <weekday>
occurenceweekdaylist ::= <occurenceweekday>
{<occurenceweekdaylist>}
daily ::= D<interval> [<duration>]
weekly ::= W<interval> [<weekdaylist>] [<duration>]
monthlybypos ::= MP<interval> [<occurrenceweekdaylist>]
[<duration>]
monthlybyday ::= MD<interval> [<daynumberlist>] [<duration>]
yearlybymonth ::= YM<interval> [<monthlist>] [<duration>]
yearlybyday ::= YD<interval> [<daylist>] [<duration>]
  • enddate Controls when a repeating event terminates. The enddate is the last time an event can occur.
  • Interval Defines the frequency in which a rule repeats.
  • duration Controls the number of events a rule generates.
  • Lastday Can be used as a replacement to daynumber to indicate the last day of the month.
  • daynumber A number representing a day of the month.
  • month A number representing a month of the year.
  • day A number representing a day of the year.
  • occurrence Controls which week of the month a particular weekday event occurs.
  • weekday A symbol representing a day of the week.
  • daily Defines a rule that repeats on a daily basis.
  • weekly Defines a rule that repeats on a weekly basis.
  • monthlybypos Defines a rule that repeats on a monthly basis on a relative day and week.
  • monthlybyday Defines a rule that repeats on a monthly basis on an absolute day.
  • yearlybymonth Defines a rule that repeats on specific months of the year.
  • yearlybyday Defines a rule that repeats on specific days of the year.
Todo:
Negative week of month and day of month are not supported.

Definition at line 1404 of file gsmcal.c.

References GSM_SubCalendarEntry::AddError, CAL_REPEAT_COUNT, CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_MONTH, CAL_REPEAT_STOPDATE, CAL_REPEAT_WEEKOFMONTH, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, ERR_NONE, ERR_UNKNOWN, FALSE, GET_DOW, GET_FREQUENCY, GET_NUMBER, GetDayOfWeek(), GetDayOfYear(), GetWeekOfMonth(), GSM_DateTime::Month, NEXT_CHAR, NEXT_NOSPACE, GSM_SubCalendarEntry::Number, ReadVCALDateTime(), smfprintf(), TRUE, and GSM_DateTime::Year.

Referenced by GSM_DecodeVCALENDAR_VTODO().

1405 {
1406  const char *pos = Buffer;
1407  gboolean have_info;
1408 
1409 /* Skip spaces */
1410 #define NEXT_NOSPACE(terminate) \
1411  while (isspace((int)*pos) && *pos) pos++; \
1412  if (terminate && *pos == 0) return ERR_NONE;
1413 /* Skip numbers */
1414 #define NEXT_NONUMBER(terminate) \
1415  while (isdigit((int)*pos) && *pos) pos++; \
1416  if (terminate && *pos == 0) return ERR_NONE;
1417 /* Go to next char */
1418 #define NEXT_CHAR(terminate) \
1419  if (*pos) pos++; \
1420  if (terminate && *pos == 0) return ERR_UNKNOWN;
1421 /* Go to next char */
1422 #define NEXT_CHAR_NOERR(terminate) \
1423  if (*pos) pos++; \
1424  if (terminate && *pos == 0) return ERR_NONE;
1425 
1426 #define GET_DOW(type, terminate) \
1427  Calendar->Entries[Calendar->EntriesNum].EntryType = type; \
1428  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE; \
1429  if (GSM_DecodeVCAL_DOW(pos, &(Calendar->Entries[Calendar->EntriesNum].Number)) != ERR_NONE) return ERR_UNKNOWN; \
1430  Calendar->EntriesNum++; \
1431  NEXT_CHAR(1); \
1432  NEXT_CHAR_NOERR(terminate);
1433 
1434 #define GET_NUMBER(type, terminate) \
1435  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE; \
1436  Calendar->Entries[Calendar->EntriesNum].EntryType = type; \
1437  Calendar->Entries[Calendar->EntriesNum].Number = atoi(pos); \
1438  Calendar->EntriesNum++; \
1439  NEXT_NONUMBER(terminate);
1440 
1441 #define GET_FREQUENCY(terminate) \
1442  GET_NUMBER(CAL_REPEAT_FREQUENCY, terminate);
1443 
1444  /* This should not happen */
1445  if (TimePos == -1) {
1446  return ERR_UNKNOWN;
1447  }
1448 
1449  NEXT_NOSPACE(1);
1450 
1451  /* Detect primary rule type */
1452  switch (*pos) {
1453  /* Daily */
1454  case 'D':
1455  NEXT_CHAR(1);
1456  GET_FREQUENCY(1);
1457  break;
1458  /* Weekly */
1459  case 'W':
1460  NEXT_CHAR(1);
1461  GET_FREQUENCY(0);
1462  NEXT_NOSPACE(0);
1463  /* There might be now list of months, if there is none, we use date */
1464  have_info = FALSE;
1465 
1466  while (isalpha((int)*pos)) {
1467  have_info = TRUE;
1469  NEXT_NOSPACE(0);
1470  }
1471 
1472  if (!have_info) {
1473  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAYOFWEEK;
1474  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1475  Calendar->Entries[Calendar->EntriesNum].Number =
1476  GetDayOfWeek(
1477  Calendar->Entries[TimePos].Date.Year,
1478  Calendar->Entries[TimePos].Date.Month,
1479  Calendar->Entries[TimePos].Date.Day);
1480  if (Calendar->Entries[Calendar->EntriesNum].Number == 0) {
1481  Calendar->Entries[Calendar->EntriesNum].Number = 7;
1482  }
1483  Calendar->EntriesNum++;
1484  }
1485  break;
1486  /* Monthly */
1487  case 'M':
1488  NEXT_CHAR(1);
1489  switch (*pos) {
1490  /* Monthly by position */
1491  case 'P':
1492  NEXT_CHAR(1);
1493  GET_FREQUENCY(0);
1494  NEXT_NOSPACE(0);
1495  if (isdigit((int)*pos)) {
1497  if (*pos == '+') {
1498  pos++;
1499  } else if (*pos == '-') {
1500  pos++;
1501  smfprintf(di, "WARNING: Negative week position not supported!");
1502  }
1503  NEXT_NOSPACE(0);
1504 
1505  while (isalpha((int)*pos)) {
1507  NEXT_NOSPACE(0);
1508  }
1509  } else {
1510  /* Need to fill in info from current date */
1511  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_WEEKOFMONTH;
1512  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1513  Calendar->Entries[Calendar->EntriesNum].Number =
1515  Calendar->Entries[TimePos].Date.Year,
1516  Calendar->Entries[TimePos].Date.Month,
1517  Calendar->Entries[TimePos].Date.Day);
1518  Calendar->EntriesNum++;
1519 
1520  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAYOFWEEK;
1521  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1522  Calendar->Entries[Calendar->EntriesNum].Number =
1523  GetDayOfWeek(
1524  Calendar->Entries[TimePos].Date.Year,
1525  Calendar->Entries[TimePos].Date.Month,
1526  Calendar->Entries[TimePos].Date.Day);
1527  if (Calendar->Entries[Calendar->EntriesNum].Number == 0) {
1528  Calendar->Entries[Calendar->EntriesNum].Number = 7;
1529  }
1530  Calendar->EntriesNum++;
1531  }
1532  break;
1533  /* Monthly by day */
1534  case 'D':
1535  NEXT_CHAR(1);
1536  GET_FREQUENCY(0);
1537  NEXT_NOSPACE(0);
1538  if (isdigit((int)*pos)) {
1539  while (isdigit((int)*pos)) {
1541  if (*pos == '+') {
1542  pos++;
1543  } else if (*pos == '-') {
1544  pos++;
1545  smfprintf(di, "WARNING: Negative day position not supported!");
1546  }
1547  NEXT_NOSPACE(0);
1548  }
1549  } else {
1550  /* Need to fill in info from current date */
1551  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAY;
1552  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1553  Calendar->Entries[Calendar->EntriesNum].Number = Calendar->Entries[TimePos].Date.Day;
1554  Calendar->EntriesNum++;
1555  }
1556 
1557  break;
1558  default:
1559  smfprintf(di, "Could not decode recurrency: %s\n", pos);
1560  return ERR_UNKNOWN;
1561  }
1562  break;
1563  /* Yearly */
1564  case 'Y':
1565  NEXT_CHAR(1);
1566  switch (*pos) {
1567  /* Yearly by month */
1568  case 'M':
1569  NEXT_CHAR(1);
1570  GET_FREQUENCY(0);
1571  NEXT_NOSPACE(0);
1572  /* We need date of event */
1573  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAY;
1574  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1575  Calendar->Entries[Calendar->EntriesNum].Number =
1576  Calendar->Entries[TimePos].Date.Day;
1577  Calendar->EntriesNum++;
1578  /* There might be now list of months, if there is none, we use date */
1579  have_info = FALSE;
1580 
1581  while (isdigit((int)*pos)) {
1582  have_info = TRUE;
1584  NEXT_NOSPACE(0);
1585  }
1586 
1587  if (!have_info) {
1588  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_MONTH;
1589  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1590  Calendar->Entries[Calendar->EntriesNum].Number =
1591  Calendar->Entries[TimePos].Date.Month;
1592  Calendar->EntriesNum++;
1593  }
1594  break;
1595  /* Yearly by day */
1596  case 'D':
1597  NEXT_CHAR(1);
1598  GET_FREQUENCY(0);
1599  NEXT_NOSPACE(0);
1600  /* There might be now list of days, if there is none, we use date */
1601  have_info = FALSE;
1602 
1603  while (isdigit((int)*pos)) {
1604  have_info = TRUE;
1606  NEXT_NOSPACE(0);
1607  }
1608 
1609  if (!have_info) {
1610 #if 0
1611  /*
1612  * This seems to be according to specification,
1613  * however several vendors (Siemens, some web based
1614  * calendars use YD1 for simple year repeating. So
1615  * we handle this as YM1 just to be compatbile with
1616  * those.
1617  */
1618  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAYOFYEAR;
1619  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1620  Calendar->Entries[Calendar->EntriesNum].Number =
1621  GetDayOfYear(
1622  Calendar->Entries[TimePos].Date.Year,
1623  Calendar->Entries[TimePos].Date.Month,
1624  Calendar->Entries[TimePos].Date.Day);
1625  Calendar->EntriesNum++;
1626 #endif
1627  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_DAY;
1628  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1629  Calendar->Entries[Calendar->EntriesNum].Number =
1630  Calendar->Entries[TimePos].Date.Day;
1631  Calendar->EntriesNum++;
1632 
1633  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_MONTH;
1634  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1635  Calendar->Entries[Calendar->EntriesNum].Number =
1636  Calendar->Entries[TimePos].Date.Month;
1637  Calendar->EntriesNum++;
1638  }
1639  break;
1640  default:
1641  smfprintf(di, "Could not decode recurrency: %s\n", pos);
1642  return ERR_UNKNOWN;
1643  }
1644  break;
1645  default:
1646  smfprintf(di, "Could not decode recurrency: %s\n", pos);
1647  return ERR_UNKNOWN;
1648  }
1649 
1650  /* Go to duration */
1651  NEXT_NOSPACE(1);
1652 
1653  /* Do we have duration encoded? */
1654  if (*pos == '#') {
1655  pos++;
1656  if (*pos == 0) return ERR_UNKNOWN;
1658  }
1659 
1660  /* Go to end date */
1661  NEXT_NOSPACE(1);
1662 
1663  /* Do we have end date encoded? */
1664  if (ReadVCALDateTime(pos, &(Calendar->Entries[Calendar->EntriesNum].Date))) {
1665  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_REPEAT_STOPDATE;
1666  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1667  Calendar->EntriesNum++;
1668  }
1669 
1670  return ERR_NONE;
1671 }
#define GET_FREQUENCY(terminate)
int GetWeekOfMonth(unsigned int year, unsigned int month, unsigned int day)
Definition: misc.c:105
int GetDayOfYear(unsigned int year, unsigned int month, unsigned int day)
Definition: misc.c:93
#define NEXT_NOSPACE(terminate)
int GetDayOfWeek(unsigned int year, unsigned int month, unsigned int day)
Definition: misc.c:117
gboolean ReadVCALDateTime(const char *Buffer, GSM_DateTime *dt)
Definition: gsmmisc.c:254
#define GET_NUMBER(type, terminate)
int gboolean
Definition: gammu-types.h:23
#define NEXT_CHAR(terminate)
#define FALSE
Definition: gammu-types.h:25
GSM_CalendarType EntryType
#define GET_DOW(type, terminate)
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
int smfprintf(GSM_Debug_Info *d, const char *format,...)
Definition: debug.c:240
#define TRUE
Definition: gammu-types.h:28

§ GSM_DecodeVCALENDAR_VTODO()

GSM_Error GSM_DecodeVCALENDAR_VTODO ( GSM_Debug_Info di,
char *  Buffer,
size_t *  Pos,
GSM_CalendarEntry Calendar,
GSM_ToDoEntry ToDo,
GSM_VCalendarVersion  CalVer,
GSM_VToDoVersion  ToDoVer 
)

Decodes vCalendar and vTodo buffer.

Parameters
diPointer to debugging description.
BufferBuffer to decode.
PosCurrent position in buffer (will be updated).
CalendarStorage for calendar entry.
ToDoStorage for todo entry.
CalVerFormat of vCalendar.
ToDoVerFormat of vTodo.
Returns
Error code

Definition at line 1673 of file gsmcal.c.

References GSM_SubCalendarEntry::AddError, CAL_DESCRIPTION, CAL_END_DATETIME, CAL_LAST_MODIFIED, CAL_LOCATION, CAL_LUID, CAL_PRIVATE, CAL_SILENT_ALARM_DATETIME, CAL_START_DATETIME, CAL_TEXT, CAL_TONE_ALARM_DATETIME, CopyUnicodeString(), GSM_SubCalendarEntry::Date, GSM_SubToDoEntry::Date, GSM_DateTime::Day, DecodeUnicodeString(), GSM_CalendarEntry::Entries, GSM_ToDoEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_ToDoEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, GSM_SubToDoEntry::EntryType, ERR_EMPTY, ERR_NONE, ERR_UNKNOWN, FALSE, GSM_AddTime(), GSM_CAL_MEETING, GSM_CAL_MEMO, GSM_Calendar_AdjustDate(), GSM_DecodeVCAL_RRULE(), GSM_Make_VCAL_Lines(), GSM_Priority_High, GSM_Priority_Low, GSM_Priority_Medium, GSM_Priority_None, GSM_ToDo_AdjustDate(), GSM_Translate_Category_From_VCal(), GSM_DateTime::Hour, GSM_ToDoEntry::Location, GSM_DateTime::Minute, GSM_DateTime::Month, Mozilla_iCalendar, Mozilla_VToDo, MyGetLine(), mywstrncasecmp(), GSM_SubCalendarEntry::Number, GSM_SubToDoEntry::Number, GSM_ToDoEntry::Priority, ReadVCALDate(), ReadVCALInt(), ReadVCALText(), ReadVCALTriggerTime(), Siemens_VCalendar, smfprintf(), GSM_SubCalendarEntry::Text, GSM_SubToDoEntry::Text, GSM_DeltaTime::Timezone, TODO_ALARM_DATETIME, TODO_COMPLETED, TODO_COMPLETED_DATETIME, TODO_DESCRIPTION, TODO_END_DATETIME, TODO_LAST_MODIFIED, TODO_LOCATION, TODO_LUID, TODO_PRIVATE, TODO_SILENT_ALARM_DATETIME, TODO_START_DATETIME, TODO_TEXT, TRUE, GSM_CalendarEntry::Type, GSM_ToDoEntry::Type, and GSM_DateTime::Year.

1675 {
1676  unsigned char Line[2000],Buff[2000];
1677  int Level = 0;
1678  GSM_DateTime Date;
1679  GSM_DeltaTime OneHour = {0, 0, 0, 1, 0, 0, 0};
1680  GSM_DeltaTime trigger;
1681  GSM_Error error;
1682  int deltatime = 0;
1683  int dstflag = 0;
1684  gboolean is_date_only;
1685  gboolean date_only = FALSE;
1686  int lBuffer;
1687  int Time=-1;
1688  char *rrule = NULL;
1689 
1690  if (!Buffer) return ERR_EMPTY;
1691 
1692  Calendar->EntriesNum = 0;
1693  ToDo->EntriesNum = 0;
1694  ToDo->Location = 0;
1695  lBuffer = strlen(Buffer);
1696  trigger.Timezone = -999 * 3600;
1697 
1698  if (CalVer == Mozilla_iCalendar && *Pos ==0) {
1699  error = GSM_Make_VCAL_Lines (Buffer, &lBuffer);
1700  if (error != ERR_NONE) return error;
1701  }
1702 
1703  while (1) {
1704  error = MyGetLine(Buffer, Pos, Line, lBuffer, sizeof(Line), TRUE);
1705  if (error != ERR_NONE) return error;
1706  if (strlen(Line) == 0) break;
1707 
1708  switch (Level) {
1709  case 0:
1710  if (strstr(Line,"BEGIN:VEVENT")) {
1711  Calendar->Type = 0;
1712  date_only = TRUE;
1713  dstflag = 0;
1714  Time=-1;
1715  Level = 1;
1716  }
1717  if (strstr(Line,"BEGIN:VTODO")) {
1718  ToDo->Priority = GSM_Priority_None;
1719  ToDo->Type = GSM_CAL_MEMO;
1720  dstflag = 0;
1721  Time=-1;
1722  Level = 2;
1723  }
1724  break;
1725  case 1: /* Calendar note */
1726  if (strstr(Line,"END:VEVENT")) {
1727  if (Time == -1) {
1728  smfprintf(di, "vCalendar without date!\n");
1729  return ERR_UNKNOWN;
1730  }
1731  if (rrule != NULL) {
1732  if (CalVer == Mozilla_iCalendar) {
1733  /* @todo: We don't have parser for this right now */
1734  error = ERR_NONE;
1735  } else {
1736  error = GSM_DecodeVCAL_RRULE(di, rrule, Calendar, Time);
1737  }
1738  free(rrule);
1739  rrule=NULL;
1740 
1741  if (error != ERR_NONE) {
1742  return error;
1743  }
1744  }
1745  if (Calendar->EntriesNum == 0) return ERR_EMPTY;
1746 
1747  if (trigger.Timezone != -999 * 3600) {
1748  Calendar->Entries[Calendar->EntriesNum].Date = GSM_AddTime (Calendar->Entries[Time].Date, trigger);
1749  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME;
1750  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1751  Calendar->EntriesNum++;
1752  }
1753 
1754  if (dstflag != 0) {
1755  /*
1756  * Day saving time was active while entry was created,
1757  * add one hour to adjust it.
1758  */
1759  if (dstflag == 4) {
1760  GSM_Calendar_AdjustDate(Calendar, &OneHour);
1761  smfprintf(di, "Adjusting DST: %i\n", dstflag);
1762  } else {
1763  smfprintf(di, "Unknown DST flag: %i\n", dstflag);
1764  }
1765  }
1766 
1767  /* If event type is undefined choose appropriate type. Memos carry dates only, no times.
1768  Use Meetings for events with full date+time settings. */
1769  if (Calendar->Type == 0) {
1770  if (date_only)
1771  Calendar->Type = GSM_CAL_MEMO;
1772  else
1773  Calendar->Type = GSM_CAL_MEETING;
1774  }
1775 
1776  return ERR_NONE;
1777  }
1778 
1779  /* Read Mozilla calendar entries. Some of them will not be used here. Notably alarm time
1780  can defined in several ways. We will use the trigger value only since this is the value
1781  Mozilla calendar uses when importing ics-files. */
1782  if (ReadVCALText(Line, "UID", Buff, CalVer == Mozilla_iCalendar, NULL)) {
1783  /* Any use for UIDs? */
1784  break;
1785  }
1786 
1787  if (strstr(Line,"X-MOZILLA-ALARM-DEFAULT-LENGTH:")) {
1788  if (ReadVCALInt(Line, "X-MOZILLA-ALARM-DEFAULT-LENGTH", &deltatime)) {
1789  break;
1790  }
1791  }
1792 
1793  if (strstr(Line,"BEGIN:VALARM")) {
1794  error = MyGetLine(Buffer, Pos, Line, lBuffer, sizeof(Line), TRUE);
1795  if (error != ERR_NONE) return error;
1796  if (strlen(Line) == 0) break;
1797  if (ReadVCALText(Line, "TRIGGER;VALUE=DURATION", Buff, CalVer == Mozilla_iCalendar, NULL)) {
1798  trigger = ReadVCALTriggerTime(DecodeUnicodeString(Buff));
1799  break;
1800  }
1801  }
1802 
1803  /* Event type. Must be set correctly to let phone calendar work as expected. For example
1804  without GSM_CAL_MEETING the time part of an event date/time will be dropped. */
1805  if (strstr(Line,"CATEGORIES:")) {
1806  GSM_Translate_Category_From_VCal(Line + 11, &Calendar->Type);
1807  break;
1808  }
1809 
1810  if (strstr(Line,"RRULE:")) {
1811  if (rrule == NULL) {
1812  rrule = strdup(Line + 6);
1813  } else {
1814  smfprintf(di, "Ignoring second recurrence: %s\n", Line);
1815  }
1816  break;
1817  }
1818 
1819  if ((ReadVCALText(Line, "SUMMARY", Buff, CalVer == Mozilla_iCalendar, NULL))) {
1820  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TEXT;
1821  CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text, Buff);
1822  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1823  Calendar->EntriesNum++;
1824  }
1825  if ((ReadVCALText(Line, "DESCRIPTION", Buff, CalVer == Mozilla_iCalendar, NULL))) {
1826  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_DESCRIPTION;
1827  CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text, Buff);
1828  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1829  Calendar->EntriesNum++;
1830  }
1831  if (ReadVCALText(Line, "LOCATION", Buff, CalVer == Mozilla_iCalendar, NULL)) {
1832  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_LOCATION;
1833  CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text, Buff);
1834  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1835  Calendar->EntriesNum++;
1836  }
1837  if ((ReadVCALText(Line, "X-IRMC-LUID", Buff, CalVer == Mozilla_iCalendar, NULL))) {
1838  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_LUID;
1839  CopyUnicodeString(Calendar->Entries[Calendar->EntriesNum].Text, Buff);
1840  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1841  Calendar->EntriesNum++;
1842  }
1843  if ((ReadVCALText(Line, "CLASS", Buff, CalVer == Mozilla_iCalendar, NULL))) {
1844  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_PRIVATE;
1845  if (mywstrncasecmp(Buff, "\0P\0U\0B\0L\0I\0C\0\0", 0)) {
1846  Calendar->Entries[Calendar->EntriesNum].Number = 0;
1847  } else {
1848  Calendar->Entries[Calendar->EntriesNum].Number = 1;
1849  }
1850  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1851  Calendar->EntriesNum++;
1852  }
1853  if (ReadVCALDate(Line, "DTSTART", &Date, &is_date_only)) {
1854  Calendar->Entries[Calendar->EntriesNum].Date = Date;
1855  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_START_DATETIME;
1856  Time = Calendar->EntriesNum;
1857  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1858  Calendar->EntriesNum++;
1859  if (!is_date_only) date_only = FALSE;
1860  }
1861  if (ReadVCALDate(Line, "DTEND", &Date, &is_date_only)) {
1862  Calendar->Entries[Calendar->EntriesNum].Date = Date;
1863  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_END_DATETIME;
1864  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1865  Calendar->EntriesNum++;
1866  if (!is_date_only) date_only = FALSE;
1867  }
1868  if (ReadVCALDate(Line, "DALARM", &Date, &is_date_only)) {
1869  Calendar->Entries[Calendar->EntriesNum].Date = Date;
1870  if (CalVer == Siemens_VCalendar) {
1871  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME;
1872  } else {
1873  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME;
1874  }
1875  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1876  Calendar->EntriesNum++;
1877  }
1878  if (ReadVCALDate(Line, "AALARM", &Date, &is_date_only)) {
1879  Calendar->Entries[Calendar->EntriesNum].Date = Date;
1880  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME;
1881  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1882  Calendar->EntriesNum++;
1883  }
1884  if (ReadVCALDate(Line, "LAST-MODIFIED", &Date, &is_date_only)) {
1885  Calendar->Entries[Calendar->EntriesNum].Date = Date;
1886  Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_LAST_MODIFIED;
1887  Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE;
1888  Calendar->EntriesNum++;
1889  }
1890  if (strstr(Line,"X-SONYERICSSON-DST:")) {
1891  if (ReadVCALInt(Line, "X-SONYERICSSON-DST", &dstflag)) {
1892  break;
1893  }
1894  }
1895  break;
1896 
1897  case 2: /* ToDo note */
1898  if (strstr(Line,"END:VTODO")) {
1899  if (ToDo->EntriesNum == 0) return ERR_EMPTY;
1900 
1901  if (dstflag != 0) {
1902  /*
1903  * Day saving time was active while entry was created,
1904  * add one hour to adjust it.
1905  */
1906  if (dstflag == 4) {
1907  GSM_ToDo_AdjustDate(ToDo, &OneHour);
1908  smfprintf(di, "Adjusting DST: %i\n", dstflag);
1909  } else {
1910  smfprintf(di, "Unknown DST flag: %i\n", dstflag);
1911  }
1912  }
1913 
1914  return ERR_NONE;
1915  }
1916 
1917  if (strstr(Line,"CATEGORIES:")) {
1918  GSM_Translate_Category_From_VCal(Line+11, &ToDo->Type);
1919  }
1920 
1921  if (ReadVCALText(Line, "UID", Buff, ToDoVer == Mozilla_VToDo, NULL)){
1922  /* Any use for UIDs? */
1923  break;
1924  }
1925 
1926  if (ReadVCALInt(Line, "X-MOZILLA-ALARM-DEFAULT-LENGTH", &deltatime)) {
1927  break;
1928  }
1929  if (ReadVCALInt(Line, "X-SONYERICSSON-DST", &dstflag)) {
1930  break;
1931  }
1932 
1933  if (ReadVCALDate(Line, "DUE", &Date, &is_date_only)) {
1934  if (ToDo->Entries[ToDo->EntriesNum].Date.Year != 2037 &&
1935  ToDo->Entries[ToDo->EntriesNum].Date.Month != 12 &&
1936  ToDo->Entries[ToDo->EntriesNum].Date.Day != 31 &&
1937  ToDo->Entries[ToDo->EntriesNum].Date.Hour != 23 &&
1938  ToDo->Entries[ToDo->EntriesNum].Date.Minute != 59 ) {
1939  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1941  ToDo->EntriesNum++;
1942  }
1943  }
1944  if (ReadVCALDate(Line, "COMLETED", &Date, &is_date_only)) {
1945  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1947  ToDo->EntriesNum++;
1948  }
1949  if (ReadVCALDate(Line, "DTSTART", &Date, &is_date_only)) {
1950  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1952  ToDo->EntriesNum++;
1953  }
1954  if (ReadVCALDate(Line, "DALARM", &Date, &is_date_only)) {
1955  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1957  ToDo->EntriesNum++;
1958  }
1959  if (ReadVCALDate(Line, "LAST-MODIFIED", &Date, &is_date_only)) {
1960  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1962  ToDo->EntriesNum++;
1963  }
1964  if (ReadVCALDate(Line, "AALARM", &Date, &is_date_only)) {
1965  ToDo->Entries[ToDo->EntriesNum].Date = Date;
1967  ToDo->EntriesNum++;
1968  }
1969 
1970  if ((ReadVCALText(Line, "SUMMARY", Buff, ToDoVer == Mozilla_VToDo, NULL))) {
1971  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_TEXT;
1972  CopyUnicodeString(ToDo->Entries[ToDo->EntriesNum].Text, Buff);
1973  ToDo->EntriesNum++;
1974  }
1975  if ((ReadVCALText(Line, "DESCRIPTION", Buff, ToDoVer == Mozilla_VToDo, NULL))) {
1977  CopyUnicodeString(ToDo->Entries[ToDo->EntriesNum].Text, Buff);
1978  ToDo->EntriesNum++;
1979  }
1980  if ((ReadVCALText(Line, "LOCATION", Buff, ToDoVer == Mozilla_VToDo, NULL))) {
1981  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_LOCATION;
1982  CopyUnicodeString(ToDo->Entries[ToDo->EntriesNum].Text, Buff);
1983  ToDo->EntriesNum++;
1984  }
1985  if (ReadVCALText(Line, "PRIORITY", Buff, ToDoVer == Mozilla_VToDo, NULL)) {
1986  if (ToDoVer == Mozilla_VToDo) {
1987  if (atoi(DecodeUnicodeString(Buff))>=9) ToDo->Priority = GSM_Priority_High;
1988  else if (atoi(DecodeUnicodeString(Buff))>=5) ToDo->Priority = GSM_Priority_Medium;
1989  else if (atoi(DecodeUnicodeString(Buff))>=1) ToDo->Priority = GSM_Priority_Low;
1990  else ToDo->Priority = GSM_Priority_None;
1991  } else {
1992  if (atoi(DecodeUnicodeString(Buff))==3) ToDo->Priority = GSM_Priority_Low;
1993  else if (atoi(DecodeUnicodeString(Buff))==2) ToDo->Priority = GSM_Priority_Medium;
1994  else if (atoi(DecodeUnicodeString(Buff))==1) ToDo->Priority = GSM_Priority_High;
1995  else ToDo->Priority = GSM_Priority_None;
1996  }
1997  }
1998  if (strstr(Line,"STATUS:COMPLETED")) {
1999  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_COMPLETED;
2000  ToDo->Entries[ToDo->EntriesNum].Number = 1;
2001  ToDo->EntriesNum++;
2002  }
2003  if (strstr(Line,"STATUS:NEEDS ACTION")) {
2004  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_COMPLETED;
2005  ToDo->Entries[ToDo->EntriesNum].Number = 0;
2006  ToDo->EntriesNum++;
2007  }
2008  if ((ReadVCALText(Line, "X-IRMC-LUID", Buff, ToDoVer == Mozilla_VToDo, NULL))) {
2009  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_LUID;
2010  CopyUnicodeString(ToDo->Entries[ToDo->EntriesNum].Text, Buff);
2011  ToDo->EntriesNum++;
2012  }
2013  if ((ReadVCALText(Line, "CLASS", Buff, ToDoVer == Mozilla_VToDo, NULL))) {
2014  ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_PRIVATE;
2015  if (mywstrncasecmp(Buff, "\0P\0U\0B\0L\0I\0C\0", 0)) {
2016  ToDo->Entries[ToDo->EntriesNum].Number = 0;
2017  } else {
2018  ToDo->Entries[ToDo->EntriesNum].Number = 1;
2019  }
2020  ToDo->EntriesNum++;
2021  }
2022  break;
2023  }
2024  }
2025 
2026  if (Calendar->EntriesNum == 0 && ToDo->EntriesNum == 0) return ERR_EMPTY;
2027  return ERR_NONE;
2028 }
int GSM_Make_VCAL_Lines(unsigned char *Buffer, int *lBuffer)
Definition: gsmcal.c:1239
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
unsigned int Number
GSM_CalendarNoteType Type
GSM_Error
Definition: gammu-error.h:23
gboolean mywstrncasecmp(unsigned const char *a, unsigned const char *b, int num)
Definition: coding.c:1437
void GSM_Calendar_AdjustDate(GSM_CalendarEntry *note, GSM_DeltaTime *delta)
Definition: gsmcal.c:748
gboolean ReadVCALDate(char *Buffer, const char *Start, GSM_DateTime *Date, gboolean *is_date_only)
Definition: gsmmisc.c:335
GSM_ToDoType EntryType
int gboolean
Definition: gammu-types.h:23
gboolean ReadVCALInt(char *Buffer, const char *Start, int *Value)
Definition: gsmmisc.c:313
GSM_CalendarNoteType Type
#define FALSE
Definition: gammu-types.h:25
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]
GSM_CalendarType EntryType
void GSM_ToDo_AdjustDate(GSM_ToDoEntry *note, GSM_DeltaTime *delta)
Definition: gsmcal.c:784
gboolean ReadVCALText(char *Buffer, const char *Start, unsigned char *Value, const gboolean UTF8, GSM_EntryLocation *location)
Definition: gsmmisc.c:468
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
int smfprintf(GSM_Debug_Info *d, const char *format,...)
Definition: debug.c:240
GSM_DeltaTime ReadVCALTriggerTime(unsigned char *Buffer)
Definition: gsmcal.c:1205
GSM_DateTime GSM_AddTime(GSM_DateTime DT, GSM_DeltaTime delta)
Definition: misc.c:223
GSM_Error GSM_DecodeVCAL_RRULE(GSM_Debug_Info *di, const char *Buffer, GSM_CalendarEntry *Calendar, int TimePos)
Definition: gsmcal.c:1404
#define TRUE
Definition: gammu-types.h:28
unsigned char Text[(GSM_MAX_TODO_TEXT_LENGTH+1) *2]
GSM_Error MyGetLine(char *Buffer, size_t *Pos, char *OutBuffer, size_t MaxLen, size_t MaxOutLen, gboolean MergeLines)
Definition: coding.c:1580
GSM_DateTime Date
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
GSM_Error GSM_Translate_Category_From_VCal(const char *string, GSM_CalendarNoteType *Type)
Definition: gsmcal.c:370

§ GSM_DecodeVNOTE()

GSM_Error GSM_DecodeVNOTE ( char *  Buffer,
size_t *  Pos,
GSM_NoteEntry Note 
)

Decodes vNote from buffer.

Parameters
BufferBuffer to decode.
PosCurrent position in buffer (will be updated).
NoteStorage for note entry.
Returns
Error code.

Definition at line 2030 of file gsmcal.c.

References CopyUnicodeString(), ERR_EMPTY, ERR_NONE, FALSE, MyGetLine(), ReadVCALText(), GSM_NoteEntry::Text, TRUE, and UnicodeLength().

2031 {
2032  unsigned char Line[2000],Buff[2000];
2033  int Level = 0;
2034  GSM_Error error;
2035  gboolean empty = TRUE;
2036 
2037  Note->Text[0] = 0;
2038  Note->Text[1] = 0;
2039 
2040  while (1) {
2041  error = MyGetLine(Buffer, Pos, Line, strlen(Buffer), sizeof(Line), TRUE);
2042  if (error != ERR_NONE) return error;
2043  if (strlen(Line) == 0) break;
2044  switch (Level) {
2045  case 0:
2046  if (strstr(Line,"BEGIN:VNOTE")) Level = 1;
2047  empty = TRUE;
2048  break;
2049  case 1:
2050  if (strstr(Line,"END:VNOTE")) {
2051  if (UnicodeLength(Note->Text) == 0) return ERR_EMPTY;
2052  return ERR_NONE;
2053  }
2054  if (ReadVCALText(Line, "BODY", Buff, FALSE, NULL)) {
2055  CopyUnicodeString(Note->Text, Buff);
2056  empty = FALSE;
2057  }
2058  break;
2059  }
2060  }
2061  if (empty) return ERR_EMPTY;
2062 
2063  return ERR_NONE;
2064 }
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
GSM_Error
Definition: gammu-error.h:23
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
char Text[(GSM_MAX_NOTE_TEXT_LENGTH+1) *2]
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
gboolean ReadVCALText(char *Buffer, const char *Start, unsigned char *Value, const gboolean UTF8, GSM_EntryLocation *location)
Definition: gsmmisc.c:468
#define TRUE
Definition: gammu-types.h:28
GSM_Error MyGetLine(char *Buffer, size_t *Pos, char *OutBuffer, size_t MaxLen, size_t MaxOutLen, gboolean MergeLines)
Definition: coding.c:1580

§ GSM_DeleteAllCalendar()

GSM_Error GSM_DeleteAllCalendar ( GSM_StateMachine s)

Deletes all calendar entries.

Parameters
sState machine pointer.
Returns
Error code

Deletes all calendar entries.

Definition at line 1496 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone_Functions::DeleteAllCalendar, GSM_Phone::Functions, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1497 {
1498  GSM_Error err;
1499 
1501 
1502  err = s->Phone.Functions->DeleteAllCalendar(s);
1503  PRINT_LOG_ERROR(err);
1504  return err;
1505 }
GSM_Error(* DeleteAllCalendar)(GSM_StateMachine *s)
Definition: gsmstate.h:1192
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_DeleteCalendar()

GSM_Error GSM_DeleteCalendar ( GSM_StateMachine s,
GSM_CalendarEntry Note 
)

Deletes calendar entry.

Parameters
sState machine pointer.
NoteNote to delete, must contain position.
Returns
Error code

Deletes calendar entry.

Definition at line 1482 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone_Functions::DeleteCalendar, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_CALENDAR_INFO, and PRINT_LOG_ERROR.

1483 {
1484  GSM_Error err;
1485 
1488 
1489  err = s->Phone.Functions->DeleteCalendar(s, Note);
1490  PRINT_LOG_ERROR(err);
1491  return err;
1492 }
#define PRINT_CALENDAR_INFO()
Definition: api.c:17
GSM_Error
Definition: gammu-error.h:23
GSM_Error(* DeleteCalendar)(GSM_StateMachine *s, GSM_CalendarEntry *Note)
Definition: gsmstate.h:1188
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_EncodeVCAL_RRULE()

GSM_Error GSM_EncodeVCAL_RRULE ( char *  Buffer,
const size_t  buff_len,
size_t *  Length,
GSM_CalendarEntry note,
int TimePos  UNUSED,
GSM_VCalendarVersion  Version 
)

Converts Gammu recurrence to vCal format. See GSM_DecodeVCAL_RRULE for grammar description.

Definition at line 441 of file gsmcal.c.

References CAL_CONTACTID, CAL_DESCRIPTION, CAL_END_DATETIME, CAL_LAST_MODIFIED, CAL_LOCATION, CAL_LUID, CAL_PHONE, CAL_PRIVATE, CAL_REPEAT_COUNT, CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STARTDATE, CAL_REPEAT_STOPDATE, CAL_REPEAT_WEEKOFMONTH, CAL_SILENT_ALARM_DATETIME, CAL_START_DATETIME, CAL_TEXT, CAL_TONE_ALARM_DATETIME, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, ERR_EMPTY, ERR_NONE, FALSE, Mozilla_iCalendar, GSM_SubCalendarEntry::Number, Siemens_VCalendar, TRUE, VC_Store(), VC_StoreDate(), and VC_StoreLine().

Referenced by GSM_EncodeVCALENDAR().

442 {
443  int i;
444  int j;
445  const char *DaysOfWeek[8] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA", "SU"};
446  gboolean repeating = FALSE;
447  int repeat_dayofweek = -1;
448  int repeat_day = -1;
449  int repeat_dayofyear = -1;
450  int repeat_weekofmonth = -1;
451  int repeat_month = -1;
452  int repeat_count = -1;
453  int repeat_frequency = -1;
454  gboolean header;
455 #if 0
456  GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0};
457 #endif
458  GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0};
459  GSM_Error error;
460 
461  /* First scan for entry, whether there is recurrence at all */
462  for (i = 0; i < note->EntriesNum; i++) {
463  switch (note->Entries[i].EntryType) {
464  /* We don't care about following here */
465  case CAL_PRIVATE:
466  case CAL_CONTACTID:
467  case CAL_START_DATETIME:
468  case CAL_END_DATETIME:
469  case CAL_LAST_MODIFIED:
472  case CAL_TEXT:
473  case CAL_DESCRIPTION:
474  case CAL_PHONE:
475  case CAL_LOCATION:
476  case CAL_LUID:
477  break;
479  repeat_dayofweek = note->Entries[i].Number;
480  repeating = TRUE;
481  break;
482  case CAL_REPEAT_DAY:
483  repeat_day = note->Entries[i].Number;
484  repeating = TRUE;
485  break;
487  repeat_dayofyear = note->Entries[i].Number;
488  repeating = TRUE;
489  break;
491  repeat_weekofmonth = note->Entries[i].Number;
492  repeating = TRUE;
493  break;
494  case CAL_REPEAT_MONTH:
495  repeat_month = note->Entries[i].Number;
496  repeating = TRUE;
497  break;
499  repeat_frequency = note->Entries[i].Number;
500  repeating = TRUE;
501  break;
502  case CAL_REPEAT_COUNT:
503  repeat_count = note->Entries[i].Number;
504  repeating = TRUE;
505  break;
507 #if 0
508  repeat_startdate = note->Entries[i].Date;
509  repeating = TRUE;
510 #endif
511  break;
512  case CAL_REPEAT_STOPDATE:
513  repeat_stopdate = note->Entries[i].Date;
514  repeating = TRUE;
515  break;
516  }
517  }
518  /* Did we found something? */
519  if (repeating) {
520  error = VC_Store(Buffer, buff_len, Length, "RRULE:");
521  if (error != ERR_NONE) return error;
522 
523  /* Safe fallback */
524  if (repeat_frequency == -1) {
525  repeat_frequency = 1;
526  }
527 
528  if ((repeat_dayofyear != -1) || (Version == Siemens_VCalendar && repeat_day != -1 && repeat_month != -1)) {
529  /* Yearly by day */
530  if (Version == Mozilla_iCalendar) {
531  error = VC_Store(Buffer, buff_len, Length, "FREQ=YEARLY");
532  if (error != ERR_NONE) return error;
533  } else {
534  error = VC_Store(Buffer, buff_len, Length, "YD%d", repeat_frequency);
535  if (error != ERR_NONE) return error;
536  }
537 
538  /* Store month numbers */
539  header = FALSE;
540  for (i = 0; i < note->EntriesNum; i++) {
541  if (note->Entries[i].EntryType == CAL_REPEAT_DAYOFYEAR) {
542  if (Version == Mozilla_iCalendar) {
543  if (!header) {
544  error = VC_Store(Buffer, buff_len, Length, ";BYYEARDAY=%d", note->Entries[i].Number);
545  if (error != ERR_NONE) return error;
546  header = TRUE;
547  } else {
548  error = VC_Store(Buffer, buff_len, Length, ",%d", note->Entries[i].Number);
549  if (error != ERR_NONE) return error;
550  }
551  } else {
552  error = VC_Store(Buffer, buff_len, Length, " %d", note->Entries[i].Number);
553  if (error != ERR_NONE) return error;
554  }
555  }
556  }
557  } else if (repeat_day != -1 && repeat_month != -1) {
558  /* Yearly by month and day */
559  if (Version == Mozilla_iCalendar) {
560  error = VC_Store(Buffer, buff_len, Length, "FREQ=YEARLY");
561  if (error != ERR_NONE) return error;
562  } else {
563  error = VC_Store(Buffer, buff_len, Length, "YM%d", repeat_frequency);
564  if (error != ERR_NONE) return error;
565  }
566 
567  /* Store month numbers */
568  header = FALSE;
569  for (i = 0; i < note->EntriesNum; i++) {
570  if (note->Entries[i].EntryType == CAL_REPEAT_MONTH) {
571  if (Version == Mozilla_iCalendar) {
572  if (!header) {
573  error = VC_Store(Buffer, buff_len, Length, ";BYMONTH=%d", note->Entries[i].Number);
574  if (error != ERR_NONE) return error;
575  header = TRUE;
576  } else {
577  error = VC_Store(Buffer, buff_len, Length, ",%d", note->Entries[i].Number);
578  if (error != ERR_NONE) return error;
579  }
580  } else {
581  error = VC_Store(Buffer, buff_len, Length, " %d", note->Entries[i].Number);
582  if (error != ERR_NONE) return error;
583  }
584  }
585  }
586  } else if (repeat_day != -1) {
587  /* Monthly by day */
588  if (Version == Mozilla_iCalendar) {
589  error = VC_Store(Buffer, buff_len, Length, "FREQ=MONTHLY");
590  if (error != ERR_NONE) return error;
591  } else {
592  error = VC_Store(Buffer, buff_len, Length, "MD%d", repeat_frequency);
593  if (error != ERR_NONE) return error;
594  }
595 
596  /* Store day numbers */
597  header = FALSE;
598  for (i = 0; i < note->EntriesNum; i++) {
599  if (note->Entries[i].EntryType == CAL_REPEAT_DAY) {
600  if (Version == Mozilla_iCalendar) {
601  if (!header) {
602  error = VC_Store(Buffer, buff_len, Length, ";BYMONTHDAY=%d", note->Entries[i].Number);
603  if (error != ERR_NONE) return error;
604  header = TRUE;
605  } else {
606  error = VC_Store(Buffer, buff_len, Length, ",%d", note->Entries[i].Number);
607  if (error != ERR_NONE) return error;
608  }
609  } else {
610  error = VC_Store(Buffer, buff_len, Length, " %d", note->Entries[i].Number);
611  if (error != ERR_NONE) return error;
612  }
613  }
614  }
615  } else if (repeat_dayofweek != -1 && repeat_weekofmonth != -1) {
616  /* Monthly by day and week */
617  if (Version == Mozilla_iCalendar) {
618  error = VC_Store(Buffer, buff_len, Length, "FREQ=MONTHLY");
619  if (error != ERR_NONE) return error;
620  } else {
621  error = VC_Store(Buffer, buff_len, Length, "MP%d", repeat_frequency);
622  if (error != ERR_NONE) return error;
623  }
624 
625  /* Store week numbers and week days */
626  if (Version != Mozilla_iCalendar) {
627  for (i = 0; i < note->EntriesNum; i++) {
628  if (note->Entries[i].EntryType == CAL_REPEAT_WEEKOFMONTH) {
629  error = VC_Store(Buffer, buff_len, Length, " %d+", note->Entries[i].Number);
630  if (error != ERR_NONE) return error;
631  for (j = 0; j < note->EntriesNum; j++) {
632  if (note->Entries[j].EntryType == CAL_REPEAT_DAYOFWEEK) {
633  error = VC_Store(Buffer, buff_len, Length, " %s", DaysOfWeek[note->Entries[j].Number]);
634  if (error != ERR_NONE) return error;
635  }
636  }
637  }
638  }
639  } else {
640  header = FALSE;
641  for (i = 0; i < note->EntriesNum; i++) {
642  if (note->Entries[i].EntryType == CAL_REPEAT_WEEKOFMONTH) {
643  if (!header) {
644  error = VC_Store(Buffer, buff_len, Length, ";BYSETPOS=%d", note->Entries[i].Number);
645  if (error != ERR_NONE) return error;
646  header = TRUE;
647  } else {
648  error = VC_Store(Buffer, buff_len, Length, ",%d", note->Entries[i].Number);
649  if (error != ERR_NONE) return error;
650  }
651  }
652  }
653  header = FALSE;
654  for (j = 0; j < note->EntriesNum; j++) {
655  if (note->Entries[j].EntryType == CAL_REPEAT_DAYOFWEEK) {
656  if (!header) {
657  error = VC_Store(Buffer, buff_len, Length, ";BYDAY=%s", DaysOfWeek[note->Entries[j].Number]);
658  if (error != ERR_NONE) return error;
659  header = TRUE;
660  } else {
661  error = VC_Store(Buffer, buff_len, Length, ",%s", DaysOfWeek[note->Entries[j].Number]);
662  if (error != ERR_NONE) return error;
663  }
664  }
665  }
666  }
667  } else if (repeat_dayofweek != -1) {
668  /* Weekly by day */
669  if (Version == Mozilla_iCalendar) {
670  error = VC_Store(Buffer, buff_len, Length, "FREQ=WEEKLY");
671  if (error != ERR_NONE) return error;
672  } else {
673  error = VC_Store(Buffer, buff_len, Length, "W%d", repeat_frequency);
674  if (error != ERR_NONE) return error;
675  }
676 
677  /* Store week days */
678  header = FALSE;
679  for (i = 0; i < note->EntriesNum; i++) {
680  if (note->Entries[i].EntryType == CAL_REPEAT_DAYOFWEEK) {
681  if (Version == Mozilla_iCalendar) {
682  if (!header) {
683  error = VC_Store(Buffer, buff_len, Length, ";BYDAY=%s", DaysOfWeek[note->Entries[i].Number]);
684  if (error != ERR_NONE) return error;
685  header = TRUE;
686  } else {
687  error = VC_Store(Buffer, buff_len, Length, ",%s", DaysOfWeek[note->Entries[i].Number]);
688  if (error != ERR_NONE) return error;
689  }
690  } else {
691  error = VC_Store(Buffer, buff_len, Length, " %s", DaysOfWeek[note->Entries[i].Number]);
692  if (error != ERR_NONE) return error;
693  }
694  }
695  }
696  } else {
697  /* Daily */
698  if (Version == Mozilla_iCalendar) {
699  error = VC_Store(Buffer, buff_len, Length, "FREQ=DAILY");
700  if (error != ERR_NONE) return error;
701  } else {
702  error = VC_Store(Buffer, buff_len, Length, "D%d", repeat_frequency);
703  if (error != ERR_NONE) return error;
704  }
705  }
706 
707  /* Store frequency */
708  if (Version == Mozilla_iCalendar && repeat_frequency > 1) {
709  error = VC_Store(Buffer, buff_len, Length, ";INTERVAL=%d", repeat_frequency);
710  if (error != ERR_NONE) return error;
711  }
712 
713  /* Store number of repetitions if available */
714  if (repeat_count != -1) {
715  if (Version == Mozilla_iCalendar) {
716  if (repeat_count > 0) {
717  error = VC_Store(Buffer, buff_len, Length, ";COUNT=%d", repeat_count);
718  if (error != ERR_NONE) return error;
719  }
720  } else {
721  error = VC_Store(Buffer, buff_len, Length, " #%d", repeat_count);
722  if (error != ERR_NONE) return error;
723  }
724  }
725 
726  /* Store end of repetition date if available */
727  if (repeat_stopdate.Day != 0) {
728  if (Version == Mozilla_iCalendar) {
729  error = VC_Store(Buffer, buff_len, Length, ";UNTIL=");
730  if (error != ERR_NONE) return error;
731  }
732  error = VC_StoreDate(Buffer, buff_len, Length, &repeat_stopdate, NULL);
733  if (error != ERR_NONE) return error;
734  } else {
735  /* Add EOL */
736  error = VC_StoreLine(Buffer, buff_len, Length, "");
737  if (error != ERR_NONE) return error;
738  }
739 
740  return ERR_NONE;
741  }
742  return ERR_EMPTY;
743 }
GSM_Error
Definition: gammu-error.h:23
GSM_Error VC_StoreLine(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:187
GSM_Error VC_Store(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:208
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
#define TRUE
Definition: gammu-types.h:28
GSM_Error VC_StoreDate(char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
Definition: gsmmisc.c:240

§ GSM_EncodeVCALENDAR()

GSM_Error GSM_EncodeVCALENDAR ( char *  Buffer,
const size_t  buff_len,
size_t *  Length,
GSM_CalendarEntry note,
const gboolean  header,
const GSM_VCalendarVersion  Version 
)

Encodes vCalendar to buffer.

Parameters
BufferStorage for data.
[in]buff_lenSize of output buffer.
LengthPointer to current position in data (will be incremented).
noteNote to encode.
headerWhether to include vCalendar header.
VersionFormat of vCalendar to create.
Returns
Error code.
Todo:
this looks wrong!

Definition at line 814 of file gsmcal.c.

References CAL_CONTACTID, CAL_DESCRIPTION, CAL_END_DATETIME, CAL_LAST_MODIFIED, CAL_LOCATION, CAL_LUID, CAL_PHONE, CAL_PRIVATE, CAL_REPEAT_COUNT, CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STARTDATE, CAL_REPEAT_STOPDATE, CAL_REPEAT_WEEKOFMONTH, CAL_SILENT_ALARM_DATETIME, CAL_START_DATETIME, CAL_TEXT, CAL_TONE_ALARM_DATETIME, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, ERR_EMPTY, ERR_NONE, GSM_CAL_BIRTHDAY, GSM_CAL_MEMO, GSM_EncodeVCAL_RRULE(), GSM_Translate_Category_To_VCal(), GSM_DateTime::Hour, GSM_CalendarEntry::Location, GSM_DateTime::Minute, Mozilla_iCalendar, GSM_SubCalendarEntry::Number, Siemens_VCalendar, GSM_SubCalendarEntry::Text, GSM_CalendarEntry::Type, VC_StoreDate(), VC_StoreDateTime(), VC_StoreLine(), VC_StoreText(), and VCALTimeDiff().

Referenced by GSM_EncodeMultiPartSMS().

815 {
816  GSM_DateTime deltatime;
817  char dtstr[20];
818  char category[100];
819  int i, alarm_pos = -1, date_pos = -1;
820  GSM_Error error;
821 
822  /* Write header */
823  if (header) {
824  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VCALENDAR");
825  if (error != ERR_NONE) return error;
826  error = VC_StoreLine(Buffer, buff_len, Length, "VERSION:%s", Version == Mozilla_iCalendar ? "2.0" : "1.0");
827  if (error != ERR_NONE) return error;
828  }
829  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VEVENT");
830  if (error != ERR_NONE) return error;
831 
832  if (Version == Mozilla_iCalendar) {
833  /* Mozilla Calendar needs UIDs. http://www.innerjoin.org/iCalendar/events-and-uids.html */
834  error = VC_StoreLine(Buffer, buff_len, Length, "UID:calendar-%i",note->Location);
835  if (error != ERR_NONE) return error;
836  error = VC_StoreLine(Buffer, buff_len, Length, "STATUS:CONFIRMED");
837  if (error != ERR_NONE) return error;
838  }
839 
840  /* Store category */
841  GSM_Translate_Category_To_VCal(category, note->Type);
842  error = VC_StoreLine(Buffer, buff_len, Length, "CATEGORIES:%s", category);
843  if (error != ERR_NONE) return error;
844 
845  /* Loop over entries */
846  for (i=0; i < note->EntriesNum; i++) {
847  switch (note->Entries[i].EntryType) {
848  case CAL_START_DATETIME :
849  date_pos = i;
850  if (Version == Mozilla_iCalendar && (note->Type == GSM_CAL_MEMO || note->Type == GSM_CAL_BIRTHDAY)) {
851  error = VC_StoreDate(Buffer, buff_len, Length, &note->Entries[i].Date, "DTSTART;VALUE=DATE");
852  if (error != ERR_NONE) return error;
853  } else {
854  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DTSTART");
855  if (error != ERR_NONE) return error;
856  }
857  break;
858  case CAL_END_DATETIME :
859  if (Version == Mozilla_iCalendar && (note->Type == GSM_CAL_MEMO || note->Type == GSM_CAL_BIRTHDAY)) {
860  error = VC_StoreDate(Buffer, buff_len, Length, &note->Entries[i].Date, "DTEND;VALUE=DATE");
861  if (error != ERR_NONE) return error;
862  } else {
863  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DTEND");
864  if (error != ERR_NONE) return error;
865  }
866  break;
868  alarm_pos = i;
869  /* Disable alarm for birthday entries. Mozilla would generate an alarm before birth! */
870  if (Version != Mozilla_iCalendar || note->Type != GSM_CAL_BIRTHDAY) {
871  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "AALARM");
872  if (error != ERR_NONE) return error;
873  }
874  break;
876  alarm_pos = i;
877  /* Disable alarm for birthday entries. Mozilla would generate an alarm before birth! */
878  if (Version != Mozilla_iCalendar || note->Type != GSM_CAL_BIRTHDAY) {
879  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DALARM");
880  if (error != ERR_NONE) return error;
881  }
882  break;
883  case CAL_LAST_MODIFIED:
884  if (Version == Mozilla_iCalendar && (note->Type == GSM_CAL_MEMO || note->Type == GSM_CAL_BIRTHDAY)) {
885  error = VC_StoreDate(Buffer, buff_len, Length, &note->Entries[i].Date, "LAST-MODIFIED;VALUE=DATE");
886  if (error != ERR_NONE) return error;
887  } else {
888  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "LAST-MODIFIED");
889  if (error != ERR_NONE) return error;
890  }
891  break;
892  case CAL_TEXT:
893  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "SUMMARY", Version == Mozilla_iCalendar);
894  if (error != ERR_NONE) return error;
895  break;
896  case CAL_DESCRIPTION:
897  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "DESCRIPTION", Version == Mozilla_iCalendar);
898  if (error != ERR_NONE) return error;
899  break;
900  case CAL_PHONE:
901  /* There is no specific field for phone number, use description */
902  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "DESCRIPTION", Version == Mozilla_iCalendar);
903  if (error != ERR_NONE) return error;
904  break;
905  case CAL_LOCATION:
906  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "LOCATION", Version == Mozilla_iCalendar);
907  if (error != ERR_NONE) return error;
908  break;
909  case CAL_LUID:
910  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "X-IRMC-LUID", Version == Mozilla_iCalendar);
911  if (error != ERR_NONE) return error;
912  break;
914  case CAL_REPEAT_DAY:
916  case CAL_REPEAT_MONTH:
919  case CAL_REPEAT_STOPDATE:
921  case CAL_REPEAT_COUNT:
922  /* Handled later */
923  break;
924  case CAL_PRIVATE:
925  if (note->Entries[i].Number == 0) {
926  error = VC_StoreLine(Buffer, buff_len, Length, "CLASS:PUBLIC");
927  if (error != ERR_NONE) return error;
928  } else {
929  error = VC_StoreLine(Buffer, buff_len, Length, "CLASS:PRIVATE");
930  if (error != ERR_NONE) return error;
931  }
932  break;
933  case CAL_CONTACTID:
934  /* Not supported */
935  break;
936  }
937  }
938 
939  /* Handle recurrance */
940  if (note->Type == GSM_CAL_BIRTHDAY) {
941  if (Version == Mozilla_iCalendar) {
942  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-RECUR-DEFAULT-UNITS:years");
943  if (error != ERR_NONE) return error;
944  } else if (Version == Siemens_VCalendar) {
945  error = VC_StoreLine(Buffer, buff_len, Length, "RRULE:YD1");
946  if (error != ERR_NONE) return error;
947  } else {
948  error = VC_StoreLine(Buffer, buff_len, Length, "RRULE:YM1");
949  if (error != ERR_NONE) return error;
950  }
951  } else {
952  error = GSM_EncodeVCAL_RRULE(Buffer, buff_len, Length, note, date_pos, Version);
953  if (error != ERR_NONE && error != ERR_EMPTY) return error;
954  }
955 
956  /* Include mozilla specific alarm encoding */
957  if (Version == Mozilla_iCalendar && alarm_pos != -1 && date_pos != -1) {
958  deltatime = VCALTimeDiff(&note->Entries[alarm_pos].Date, &note->Entries[date_pos].Date);
959 
960  dtstr[0]='\0';
961  if (deltatime.Minute !=0) {
962  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-UNITS:minutes");
963  if (error != ERR_NONE) return error;
964  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-LENGTH:%i", deltatime.Minute);
965  if (error != ERR_NONE) return error;
966  sprintf(dtstr,"-PT%iM",deltatime.Minute);
967  } else if (deltatime.Hour !=0) {
968  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-UNITS:hours");
969  if (error != ERR_NONE) return error;
970  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-LENGTH:%i", deltatime.Hour);
971  if (error != ERR_NONE) return error;
972  sprintf(dtstr,"-PT%iH",deltatime.Hour);
973  } else if (deltatime.Day !=0) {
974  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-UNITS:days");
975  if (error != ERR_NONE) return error;
976  error = VC_StoreLine(Buffer, buff_len, Length, "X-MOZILLA-ALARM-DEFAULT-LENGTH:%i", deltatime.Day);
977  if (error != ERR_NONE) return error;
978  sprintf(dtstr,"-P%iD",deltatime.Day);
979  }
980  if (dtstr[0] != '\0') {
981  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VALARM");
982  if (error != ERR_NONE) return error;
983  error = VC_StoreLine(Buffer, buff_len, Length, "TRIGGER;VALUE=DURATION");
984  if (error != ERR_NONE) return error;
988  error = VC_StoreLine(Buffer, buff_len, Length, " :%s",dtstr);
989  if (error != ERR_NONE) return error;
990  error = VC_StoreLine(Buffer, buff_len, Length, "END:VALARM");
991  if (error != ERR_NONE) return error;
992  }
993  }
994 
995  error = VC_StoreLine(Buffer, buff_len, Length, "END:VEVENT");
996  if (error != ERR_NONE) return error;
997  if (header) {
998  error = VC_StoreLine(Buffer, buff_len, Length, "END:VCALENDAR");
999  if (error != ERR_NONE) return error;
1000  }
1001 
1002  return ERR_NONE;
1003 }
GSM_Error VC_StoreDateTime(char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
Definition: gsmmisc.c:224
GSM_Error VC_StoreText(char *Buffer, const size_t buff_len, size_t *Pos, const unsigned char *Text, const char *Start, const gboolean UTF8)
Definition: gsmmisc.c:360
GSM_Error
Definition: gammu-error.h:23
GSM_Error VC_StoreLine(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:187
GSM_Error GSM_EncodeVCAL_RRULE(char *Buffer, const size_t buff_len, size_t *Length, GSM_CalendarEntry *note, int TimePos UNUSED, GSM_VCalendarVersion Version)
Definition: gsmcal.c:441
GSM_CalendarNoteType Type
GSM_DateTime VCALTimeDiff(GSM_DateTime *Alarm, GSM_DateTime *Time)
Definition: gsmcal.c:320
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_Error GSM_Translate_Category_To_VCal(char *string, const GSM_CalendarNoteType Type)
Definition: gsmcal.c:404
GSM_Error VC_StoreDate(char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
Definition: gsmmisc.c:240
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]

§ GSM_EncodeVNTFile()

GSM_Error GSM_EncodeVNTFile ( char *  Buffer,
const size_t  buff_len,
size_t *  Length,
GSM_NoteEntry Note 
)

Encodes vNote to buffer.

Parameters
BufferStorage for data.
[in]buff_lenSize of output buffer.
LengthPointer to current position in data (will be incremented).
NoteNote to encode.
Returns
Error code.

Definition at line 2066 of file gsmcal.c.

References ERR_NONE, FALSE, GSM_NoteEntry::Text, VC_StoreLine(), and VC_StoreText().

2067 {
2068  GSM_Error error;
2069 
2070  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VNOTE");
2071  if (error != ERR_NONE) return error;
2072  error = VC_StoreLine(Buffer, buff_len, Length, "VERSION:1.1");
2073  if (error != ERR_NONE) return error;
2074  error = VC_StoreText(Buffer, buff_len, Length, Note->Text, "BODY", FALSE);
2075  if (error != ERR_NONE) return error;
2076  error = VC_StoreLine(Buffer, buff_len, Length, "END:VNOTE");
2077  if (error != ERR_NONE) return error;
2078 
2079  return ERR_NONE;
2080 }
GSM_Error VC_StoreText(char *Buffer, const size_t buff_len, size_t *Pos, const unsigned char *Text, const char *Start, const gboolean UTF8)
Definition: gsmmisc.c:360
GSM_Error
Definition: gammu-error.h:23
GSM_Error VC_StoreLine(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:187
char Text[(GSM_MAX_NOTE_TEXT_LENGTH+1) *2]
#define FALSE
Definition: gammu-types.h:25

§ GSM_EncodeVTODO()

GSM_Error GSM_EncodeVTODO ( char *  Buffer,
const size_t  buff_len,
size_t *  Length,
const GSM_ToDoEntry note,
const gboolean  header,
const GSM_VToDoVersion  Version 
)

Encodes vTodo to buffer.

Parameters
BufferStorage for data.
[in]buff_lenSize of output buffer.
LengthPointer to current position in data (will be incremented).
noteNote to encode.
headerWhether to include vCalendar header.
VersionFormat of vTodo to create.
Returns
Error code.

Definition at line 1038 of file gsmcal.c.

References GSM_SubToDoEntry::Date, GSM_DateTime::Day, GSM_ToDoEntry::Entries, GSM_ToDoEntry::EntriesNum, GSM_SubToDoEntry::EntryType, ERR_NONE, GSM_CAL_BIRTHDAY, GSM_Priority_High, GSM_Priority_INVALID, GSM_Priority_Low, GSM_Priority_Medium, GSM_Priority_None, GSM_Translate_Category_To_VCal(), GSM_DateTime::Hour, GSM_ToDoEntry::Location, GSM_DateTime::Minute, GSM_DateTime::Month, Mozilla_VToDo, GSM_SubToDoEntry::Number, GSM_ToDoEntry::Priority, GSM_SubToDoEntry::Text, TODO_ALARM_DATETIME, TODO_CATEGORY, TODO_COMPLETED, TODO_COMPLETED_DATETIME, TODO_CONTACTID, TODO_DESCRIPTION, TODO_END_DATETIME, TODO_LAST_MODIFIED, TODO_LOCATION, TODO_LUID, TODO_PHONE, TODO_PRIVATE, TODO_SILENT_ALARM_DATETIME, TODO_START_DATETIME, TODO_TEXT, GSM_ToDoEntry::Type, VC_StoreDateTime(), VC_StoreLine(), VC_StoreText(), and GSM_DateTime::Year.

Referenced by GSM_EncodeMultiPartSMS().

1039 {
1040  char category[100];
1041  int i;
1042  GSM_Error error;
1043 
1044  /* Write header */
1045  if (header) {
1046  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VCALENDAR");
1047  if (error != ERR_NONE) return error;
1048  error = VC_StoreLine(Buffer, buff_len, Length, "VERSION:%s", Version == Mozilla_VToDo ? "2.0" : "1.0");
1049  if (error != ERR_NONE) return error;
1050  }
1051  error = VC_StoreLine(Buffer, buff_len, Length, "BEGIN:VTODO");
1052  if (error != ERR_NONE) return error;
1053 
1054  if (Version == Mozilla_VToDo) {
1055  /* Mozilla Calendar needs UIDs. http://www.innerjoin.org/iCalendar/events-and-uids.html */
1056  error = VC_StoreLine(Buffer, buff_len, Length, "UID:calendar-%i",note->Location);
1057  if (error != ERR_NONE) return error;
1058  error = VC_StoreLine(Buffer, buff_len, Length, "STATUS:CONFIRMED");
1059  if (error != ERR_NONE) return error;
1060  }
1061 
1062  if (Version == Mozilla_VToDo) {
1063  switch (note->Priority) {
1064  case GSM_Priority_None :
1065  case GSM_Priority_INVALID:
1066  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:0");
1067  if (error != ERR_NONE) return error;
1068  break;
1069  case GSM_Priority_Low :
1070  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:1");
1071  if (error != ERR_NONE) return error;
1072  break;
1073  case GSM_Priority_Medium:
1074  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:5");
1075  if (error != ERR_NONE) return error;
1076  break;
1077  case GSM_Priority_High :
1078  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:9");
1079  if (error != ERR_NONE) return error;
1080  break;
1081  }
1082  } else {
1083  switch (note->Priority) {
1084  case GSM_Priority_None :
1085  case GSM_Priority_INVALID:
1086  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:0");
1087  if (error != ERR_NONE) return error;
1088  break;
1089  case GSM_Priority_Low :
1090  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:1");
1091  if (error != ERR_NONE) return error;
1092  break;
1093  case GSM_Priority_Medium:
1094  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:2");
1095  if (error != ERR_NONE) return error;
1096  break;
1097  case GSM_Priority_High :
1098  error = VC_StoreLine(Buffer, buff_len, Length, "PRIORITY:3");
1099  if (error != ERR_NONE) return error;
1100  break;
1101  }
1102  }
1103  /* Store category */
1104  GSM_Translate_Category_To_VCal(category, note->Type);
1105  error = VC_StoreLine(Buffer, buff_len, Length, "CATEGORIES:%s", category);
1106  if (error != ERR_NONE) return error;
1107 
1108  /* Loop over entries */
1109  for (i=0; i < note->EntriesNum; i++) {
1110  switch (note->Entries[i].EntryType) {
1111  case TODO_END_DATETIME :
1112  if (note->Entries[i].Date.Year != 2037 &&
1113  note->Entries[i].Date.Month != 12 &&
1114  note->Entries[i].Date.Day != 31 &&
1115  note->Entries[i].Date.Hour != 23 &&
1116  note->Entries[i].Date.Minute != 59 ) {
1117  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DUE");
1118  if (error != ERR_NONE) return error;
1119  }
1120  break;
1121  case TODO_ALARM_DATETIME :
1122  /* Disable alarm for birthday entries. Mozilla would generate an alarm before birth! */
1123  if (Version != Mozilla_VToDo || note->Type != GSM_CAL_BIRTHDAY) {
1124  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "AALARM");
1125  if (error != ERR_NONE) return error;
1126  }
1127  break;
1129  /* Disable alarm for birthday entries. Mozilla would generate an alarm before birth! */
1130  if (Version != Mozilla_VToDo || note->Type != GSM_CAL_BIRTHDAY) {
1131  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DALARM");
1132  if (error != ERR_NONE) return error;
1133  }
1134  break;
1135  case TODO_START_DATETIME:
1136  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "DTSTART");
1137  if (error != ERR_NONE) return error;
1138  break;
1140  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "COMPLETED");
1141  if (error != ERR_NONE) return error;
1142  break;
1143  case TODO_LAST_MODIFIED:
1144  error = VC_StoreDateTime(Buffer, buff_len, Length, &note->Entries[i].Date, "LAST-MODIFIED");
1145  if (error != ERR_NONE) return error;
1146  break;
1147  case TODO_TEXT:
1148  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "SUMMARY", Version == Mozilla_VToDo);
1149  if (error != ERR_NONE) return error;
1150  break;
1151  case TODO_DESCRIPTION:
1152  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "DESCRIPTION", Version == Mozilla_VToDo);
1153  if (error != ERR_NONE) return error;
1154  break;
1155  case TODO_PHONE:
1156  /* There is no specific field for phone number, use description */
1157  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "DESCRIPTION", Version == Mozilla_VToDo);
1158  if (error != ERR_NONE) return error;
1159  break;
1160  case TODO_LOCATION:
1161  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "LOCATION", Version == Mozilla_VToDo);
1162  if (error != ERR_NONE) return error;
1163  break;
1164  case TODO_LUID:
1165  error = VC_StoreText(Buffer, buff_len, Length, note->Entries[i].Text, "X-IRMC-LUID", Version == Mozilla_VToDo);
1166  if (error != ERR_NONE) return error;
1167  break;
1168  case TODO_PRIVATE:
1169  if (note->Entries[i].Number == 0) {
1170  error = VC_StoreLine(Buffer, buff_len, Length, "CLASS:PUBLIC");
1171  if (error != ERR_NONE) return error;
1172  } else {
1173  error = VC_StoreLine(Buffer, buff_len, Length, "CLASS:PRIVATE");
1174  if (error != ERR_NONE) return error;
1175  }
1176  break;
1177  case TODO_COMPLETED:
1178  if (note->Entries[i].Number == 1) {
1179  error = VC_StoreLine(Buffer, buff_len, Length, "STATUS:COMPLETED");
1180  if (error != ERR_NONE) return error;
1181  error = VC_StoreLine(Buffer, buff_len, Length, "PERCENT-COMPLETE:100");
1182  if (error != ERR_NONE) return error;
1183  } else {
1184  error = VC_StoreLine(Buffer, buff_len, Length, "STATUS:NEEDS ACTION");
1185  if (error != ERR_NONE) return error;
1186  }
1187  break;
1188  case TODO_CONTACTID:
1189  case TODO_CATEGORY:
1190  /* Not supported */
1191  break;
1192  }
1193  }
1194 
1195  error = VC_StoreLine(Buffer, buff_len, Length, "END:VTODO");
1196  if (error != ERR_NONE) return error;
1197  if (header) {
1198  error = VC_StoreLine(Buffer, buff_len, Length, "END:VCALENDAR");
1199  if (error != ERR_NONE) return error;
1200  }
1201 
1202  return ERR_NONE;
1203 }
GSM_ToDo_Priority Priority
unsigned int Number
GSM_Error VC_StoreDateTime(char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
Definition: gsmmisc.c:224
GSM_CalendarNoteType Type
GSM_Error VC_StoreText(char *Buffer, const size_t buff_len, size_t *Pos, const unsigned char *Text, const char *Start, const gboolean UTF8)
Definition: gsmmisc.c:360
GSM_Error
Definition: gammu-error.h:23
GSM_Error VC_StoreLine(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:187
GSM_ToDoType EntryType
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]
GSM_Error GSM_Translate_Category_To_VCal(char *string, const GSM_CalendarNoteType Type)
Definition: gsmcal.c:404
unsigned char Text[(GSM_MAX_TODO_TEXT_LENGTH+1) *2]
GSM_DateTime Date

§ GSM_GetAlarm()

GSM_Error GSM_GetAlarm ( GSM_StateMachine s,
GSM_Alarm Alarm 
)

Reads alarm set in phone.

Parameters
sState machine pointer.
AlarmStorage for alarm.
Returns
Error code

Reads alarm set in phone.

Definition at line 255 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetAlarm, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

256 {
257  GSM_Error err;
258 
260 
261  err = s->Phone.Functions->GetAlarm(s, Alarm);
262  PRINT_LOG_ERROR(err);
263  return err;
264 }
GSM_Error(* GetAlarm)(GSM_StateMachine *s, GSM_Alarm *Alarm)
Definition: gsmstate.h:822
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_GetCalendar()

GSM_Error GSM_GetCalendar ( GSM_StateMachine s,
GSM_CalendarEntry Note 
)

Retrieves calendar entry.

Parameters
sState machine pointer.
NoteStorage for note.
Returns
Error code

Retrieves calendar entry.

Definition at line 1424 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetCalendar, _GSM_StateMachine::Phone, PRINT_CALENDAR_INFO, and PRINT_LOG_ERROR.

1425 {
1426  GSM_Error err;
1427 
1430 
1431  err = s->Phone.Functions->GetCalendar(s, Note);
1432  PRINT_LOG_ERROR(err);
1433  return err;
1434 }
#define PRINT_CALENDAR_INFO()
Definition: api.c:17
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* GetCalendar)(GSM_StateMachine *s, GSM_CalendarEntry *Note)
Definition: gsmstate.h:1171

§ GSM_GetCalendarRecurranceRepeat()

void GSM_GetCalendarRecurranceRepeat ( GSM_Debug_Info di,
unsigned char *  rec,
unsigned char *  endday,
GSM_CalendarEntry entry 
)

Definition at line 137 of file gsmcal.c.

References CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STOPDATE, CAL_START_DATETIME, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, GetDayOfWeek(), GetTimeDifference(), GSM_DateTime::Hour, GSM_DateTime::Minute, GSM_DateTime::Month, GSM_SubCalendarEntry::Number, GSM_DateTime::Second, smfprintf(), TRUE, and GSM_DateTime::Year.

Referenced by NOKIA_EncodeDateTime().

138 {
139  int Recurrance,num=-1,i;
140 
141  Recurrance = rec[0]*256 + rec[1];
142  if (Recurrance == 0) return;
143  /* dct3 and dct4: 65535 (0xffff) is 1 year */
144  if (Recurrance == 0xffff) Recurrance=24*365;
145  /* dct3: unavailable, dct4: 65534 (0xffff-1) is 30 days */
146  if (Recurrance == 0xffff-1) Recurrance=24*30;
147  smfprintf(di, "Recurrance : %i hours\n",Recurrance);
148 
149  for (i=0;i<entry->EntriesNum;i++) {
150  if (entry->Entries[i].EntryType == CAL_START_DATETIME) {
151  num = i;
152  break;
153  }
154  }
155  if (num == -1) return;
156 
157  if (Recurrance == 24 || Recurrance == 24*7 ||
158  Recurrance == 24*30 || Recurrance == 24*365) {
160  entry->Entries[entry->EntriesNum].Number = 1;
161  entry->EntriesNum++;
162  }
163  if (Recurrance == 24*14) {
165  entry->Entries[entry->EntriesNum].Number = 2;
166  entry->EntriesNum++;
167  }
168  if (Recurrance == 24*7 || Recurrance == 24*14) {
170  entry->Entries[entry->EntriesNum].Number = GetDayOfWeek(entry->Entries[num].Date.Year,
171  entry->Entries[num].Date.Month,
172  entry->Entries[num].Date.Day);
173  entry->EntriesNum++;
174  }
175  if (Recurrance == 24*30) {
176  entry->Entries[entry->EntriesNum].EntryType = CAL_REPEAT_DAY;
177  entry->Entries[entry->EntriesNum].Number = entry->Entries[num].Date.Day;
178  entry->EntriesNum++;
179  }
180  if (Recurrance == 24*365) {
181  entry->Entries[entry->EntriesNum].EntryType = CAL_REPEAT_DAY;
182  entry->Entries[entry->EntriesNum].Number = entry->Entries[num].Date.Day;
183  entry->EntriesNum++;
184  entry->Entries[entry->EntriesNum].EntryType = CAL_REPEAT_MONTH;
185  entry->Entries[entry->EntriesNum].Number = entry->Entries[num].Date.Month;
186  entry->EntriesNum++;
187  }
188  if (endday == NULL || endday[0]*256+endday[1] == 0) return;
189  smfprintf(di, "Repeat : %i times\n",endday[0]*256+endday[1]);
190  memcpy(&entry->Entries[entry->EntriesNum].Date,&entry->Entries[num].Date,sizeof(GSM_DateTime));
192  switch (Recurrance) {
193  case 24:
194  case 24*7:
195  case 24*14:
196  GetTimeDifference(60*60*Recurrance*(endday[0]*256+endday[1]-1), &entry->Entries[entry->EntriesNum].Date, TRUE, 1);
197  entry->EntriesNum++;
198  break;
199  case 24*30:
200  for (i=0;i<endday[0]*256+endday[1]-1;i++) {
201  if (entry->Entries[entry->EntriesNum].Date.Month == 12) {
202  entry->Entries[entry->EntriesNum].Date.Month = 1;
203  entry->Entries[entry->EntriesNum].Date.Year++;
204  } else {
205  entry->Entries[entry->EntriesNum].Date.Month++;
206  }
207  }
208  entry->EntriesNum++;
209  break;
210  case 24*365:
211  entry->Entries[entry->EntriesNum].Date.Year += (endday[0]*256+endday[1] - 1);
212  entry->EntriesNum++;
213  break;
214  }
215  smfprintf(di, "End Repeat Time: %04i-%02i-%02i %02i:%02i:%02i\n",
216  entry->Entries[entry->EntriesNum-1].Date.Year,
217  entry->Entries[entry->EntriesNum-1].Date.Month,
218  entry->Entries[entry->EntriesNum-1].Date.Day,
219  entry->Entries[entry->EntriesNum-1].Date.Hour,
220  entry->Entries[entry->EntriesNum-1].Date.Minute,
221  entry->Entries[entry->EntriesNum-1].Date.Second);
222 }
void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, gboolean Plus, int multi)
Definition: misc.c:247
int GetDayOfWeek(unsigned int year, unsigned int month, unsigned int day)
Definition: misc.c:117
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
int smfprintf(GSM_Debug_Info *d, const char *format,...)
Definition: debug.c:240
#define TRUE
Definition: gammu-types.h:28

§ GSM_GetCalendarSettings()

GSM_Error GSM_GetCalendarSettings ( GSM_StateMachine s,
GSM_CalendarSettings settings 
)

Reads calendar settings.

Parameters
sState machine pointer.
settingsStorage for settings.
Returns
Error code

Reads calendar settings.

Definition at line 1509 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetCalendarSettings, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1510 {
1511  GSM_Error err;
1512 
1514 
1515  err = s->Phone.Functions->GetCalendarSettings(s, settings);
1516  PRINT_LOG_ERROR(err);
1517  return err;
1518 }
GSM_Error(* GetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings)
Definition: gsmstate.h:1196
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_GetCalendarStatus()

GSM_Error GSM_GetCalendarStatus ( GSM_StateMachine s,
GSM_CalendarStatus Status 
)

Retrieves calendar status (number of used entries).

Parameters
sState machine pointer.
StatusStorage for status.
Returns
Error code

Retrieves calendar status (number of used entries).

Definition at line 1411 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetCalendarStatus, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1412 {
1413  GSM_Error err;
1414 
1416 
1417  err = s->Phone.Functions->GetCalendarStatus(s, Status);
1418  PRINT_LOG_ERROR(err);
1419  return err;
1420 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Error(* GetCalendarStatus)(GSM_StateMachine *s, GSM_CalendarStatus *Status)
Definition: gsmstate.h:1167
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_GetNextCalendar()

GSM_Error GSM_GetNextCalendar ( GSM_StateMachine s,
GSM_CalendarEntry Note,
gboolean  start 
)

Retrieves calendar entry. This is useful for continuous reading of all calendar entries.

Parameters
sState machine pointer.
NoteStorage for note, if start is FALSE, should contain data from previous read (at least position).
startWhether we're doing initial read or continue in reading.
Returns
Error code

Retrieves calendar entry. This is useful for continuous reading of all calendar entries.

Definition at line 1439 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetNextCalendar, _GSM_StateMachine::Phone, PRINT_CALENDAR_INFO, PRINT_LOG_ERROR, and PRINT_START.

1440 {
1441  GSM_Error err;
1442 
1444  PRINT_START();
1446 
1447  err = s->Phone.Functions->GetNextCalendar(s, Note, start);
1448  PRINT_LOG_ERROR(err);
1449  return err;
1450 }
#define PRINT_CALENDAR_INFO()
Definition: api.c:17
GSM_Error
Definition: gammu-error.h:23
#define PRINT_START()
Definition: api.c:21
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* GetNextCalendar)(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
Definition: gsmstate.h:1176

§ GSM_IsCalendarNoteFromThePast()

gboolean GSM_IsCalendarNoteFromThePast ( GSM_CalendarEntry note)

Detects whether calendar note is in past.

Parameters
noteNote to check.
Returns
Whether entry is in past.

Definition at line 224 of file gsmcal.c.

References CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_DAYOFYEAR, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STOPDATE, CAL_REPEAT_WEEKOFMONTH, CAL_START_DATETIME, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, FALSE, GSM_CAL_BIRTHDAY, GSM_GetCurrentDateTime(), GSM_SetCalendarRecurranceRepeat(), GSM_DateTime::Month, TRUE, GSM_CalendarEntry::Type, and GSM_DateTime::Year.

225 {
226  gboolean Past = TRUE, Repeating = FALSE, RepeatingEnd = FALSE;
227  int i,End=-1;
228  GSM_DateTime DT;
229  char rec[20],endday[20];
230 
232  for (i = 0; i < note->EntriesNum; i++) {
233  switch (note->Entries[i].EntryType) {
234  case CAL_START_DATETIME :
235  if (note->Entries[i].Date.Year > DT.Year) Past = FALSE;
236  if (note->Entries[i].Date.Year == DT.Year &&
237  note->Entries[i].Date.Month > DT.Month) Past = FALSE;
238  if (note->Entries[i].Date.Year == DT.Year &&
239  note->Entries[i].Date.Month == DT.Month &&
240  note->Entries[i].Date.Day >= DT.Day) Past = FALSE;
241  break;
242  case CAL_REPEAT_STOPDATE:
243  End = i;
244  RepeatingEnd = TRUE;
245  break;
247  case CAL_REPEAT_DAY:
250  case CAL_REPEAT_MONTH:
252  Repeating = TRUE;
253  break;
254  default:
255  break;
256  }
257  if (!Past) break;
258  }
259  if (note->Type == GSM_CAL_BIRTHDAY) Past = FALSE;
260  GSM_SetCalendarRecurranceRepeat(NULL, rec, endday, note);
261  if (rec[0] != 0 || rec[1] != 0) {
262  if (End == -1) {
263  Past = FALSE;
264  } else {
265  if (note->Entries[End].Date.Year > DT.Year) Past = FALSE;
266  if (note->Entries[End].Date.Year == DT.Year &&
267  note->Entries[End].Date.Month > DT.Month) Past = FALSE;
268  if (note->Entries[End].Date.Year == DT.Year &&
269  note->Entries[End].Date.Month == DT.Month &&
270  note->Entries[End].Date.Day >= DT.Day) Past = FALSE;
271  }
272  }
273  if (Repeating && ! RepeatingEnd) {
274  return FALSE;
275  }
276  return Past;
277 }
void GSM_SetCalendarRecurranceRepeat(GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
Definition: gsmcal.c:31
int gboolean
Definition: gammu-types.h:23
GSM_CalendarNoteType Type
#define FALSE
Definition: gammu-types.h:25
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
#define TRUE
Definition: gammu-types.h:28

§ GSM_Make_VCAL_Lines()

int GSM_Make_VCAL_Lines ( unsigned char *  Buffer,
int *  lBuffer 
)

Prepare input buffer (notably line continuations).

Definition at line 1239 of file gsmcal.c.

References ERR_NONE, and ERR_UNKNOWN.

Referenced by GSM_DecodeVCALENDAR_VTODO().

1240 {
1241  int src=0;
1242  int dst=0;
1243 
1244  for (src=0; src <= *lBuffer; src++) {
1245  if (Buffer[src] == '\r') src++;
1246  if (Buffer[src] == '\n') {
1247  if (Buffer[src+1] == ' ' && Buffer[src+2] == ':' ) src = src + 2;
1248  if (Buffer[src+1] == ' ' && Buffer[src+2] == ';' ) src = src + 2;
1249  }
1250  if (dst > src) return ERR_UNKNOWN;
1251  Buffer[dst] = Buffer[src];
1252  dst++;
1253  }
1254  *lBuffer = dst-1;
1255  return ERR_NONE;
1256 }

§ GSM_SetAlarm()

GSM_Error GSM_SetAlarm ( GSM_StateMachine s,
GSM_Alarm Alarm 
)

Sets alarm in phone.

Parameters
sState machine pointer.
AlarmAlarm to set.
Returns
Error code

Sets alarm in phone.

Definition at line 268 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_LOG_ERROR, and GSM_Phone_Functions::SetAlarm.

269 {
270  GSM_Error err;
271 
273 
274  err = s->Phone.Functions->SetAlarm(s, Alarm);
275  PRINT_LOG_ERROR(err);
276  return err;
277 }
GSM_Error(* SetAlarm)(GSM_StateMachine *s, GSM_Alarm *Alarm)
Definition: gsmstate.h:826
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_SetCalendar()

GSM_Error GSM_SetCalendar ( GSM_StateMachine s,
GSM_CalendarEntry Note 
)

Sets calendar entry

Parameters
sState machine pointer.
NoteNew note values, needs to contain valid position.
Returns
Error code

Sets calendar entry

Definition at line 1454 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_CALENDAR_INFO, PRINT_LOG_ERROR, and GSM_Phone_Functions::SetCalendar.

1455 {
1456  GSM_Error err;
1457 
1460 
1461  err = s->Phone.Functions->SetCalendar(s, Note);
1462  PRINT_LOG_ERROR(err);
1463  return err;
1464 }
#define PRINT_CALENDAR_INFO()
Definition: api.c:17
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* SetCalendar)(GSM_StateMachine *s, GSM_CalendarEntry *Note)
Definition: gsmstate.h:1180

§ GSM_SetCalendarRecurranceRepeat()

void GSM_SetCalendarRecurranceRepeat ( GSM_Debug_Info di,
unsigned char *  rec,
unsigned char *  endday,
GSM_CalendarEntry entry 
)

Definition at line 31 of file gsmcal.c.

References CAL_REPEAT_DAY, CAL_REPEAT_DAYOFWEEK, CAL_REPEAT_FREQUENCY, CAL_REPEAT_MONTH, CAL_REPEAT_STOPDATE, CAL_START_DATETIME, GSM_SubCalendarEntry::Date, GSM_DateTime::Day, GSM_CalendarEntry::Entries, GSM_CalendarEntry::EntriesNum, GSM_SubCalendarEntry::EntryType, Fill_Time_T(), GetDayOfWeek(), GSM_DateTime::Month, GSM_SubCalendarEntry::Number, smfprintf(), and GSM_DateTime::Year.

Referenced by GSM_IsCalendarNoteFromThePast(), and NOKIA_EncodeDateTime().

32 {
33  int i;
34  int start=-1,frequency=-1,dow=-1,day=-1,month=-1,end=-1,Recurrance = 0, Repeat=0, j;
35  GSM_DateTime DT;
36  time_t t_time1,t_time2;
37 
38  rec[0] = 0;
39  rec[1] = 0;
40 
41  for (j = 0; j < entry->EntriesNum; j++) {
42  if (entry->Entries[j].EntryType == CAL_START_DATETIME) start = j;
43  if (entry->Entries[j].EntryType == CAL_REPEAT_FREQUENCY) frequency = j;
44  if (entry->Entries[j].EntryType == CAL_REPEAT_DAYOFWEEK) dow = j;
45  if (entry->Entries[j].EntryType == CAL_REPEAT_DAY) day = j;
46  if (entry->Entries[j].EntryType == CAL_REPEAT_MONTH) month = j;
47  if (entry->Entries[j].EntryType == CAL_REPEAT_STOPDATE) end = j;
48  }
49  if (start == -1) return;
50 
51  if (frequency != -1 && dow == -1 && day == -1 && month == -1) {
52  if (entry->Entries[frequency].Number == 1) {
53  /* each day */
54  Recurrance = 24;
55  }
56  }
57 
58  i = GetDayOfWeek(entry->Entries[start].Date.Year,
59  entry->Entries[start].Date.Month,
60  entry->Entries[start].Date.Day);
61 
62  if (frequency != -1 && dow != -1 && day == -1 && month == -1) {
63  if (entry->Entries[frequency].Number == 1 &&
64  entry->Entries[dow].Number == i) {
65  /* one week */
66  Recurrance = 24*7;
67  }
68  }
69  if (frequency != -1 && dow != -1 && day == -1 && month == -1) {
70  if (entry->Entries[frequency].Number == 2 &&
71  entry->Entries[dow].Number == i) {
72  /* two weeks */
73  Recurrance = 24*14;
74  }
75  }
76  if (frequency != -1 && dow == -1 && day != -1 && month == -1) {
77  if (entry->Entries[frequency].Number == 1 &&
78  entry->Entries[day].Number == entry->Entries[start].Date.Day) {
79  /* month */
80  Recurrance = 0xffff-1;
81  }
82  }
83  if (frequency != -1 && dow == -1 && day != -1 && month != -1) {
84  if (entry->Entries[frequency].Number == 1 &&
85  entry->Entries[day].Number == entry->Entries[start].Date.Day &&
86  entry->Entries[month].Number == entry->Entries[start].Date.Month) {
87  /* year */
88  Recurrance = 0xffff;
89  }
90  }
91 
92  rec[0] = Recurrance / 256;
93  rec[1] = Recurrance % 256;
94 
95  if (endday == NULL) return;
96 
97  endday[0] = 0;
98  endday[1] = 0;
99 
100  if (end == -1) return;
101 
102  t_time1 = Fill_Time_T(entry->Entries[start].Date);
103  t_time2 = Fill_Time_T(entry->Entries[end].Date);
104  if (t_time2 - t_time1 <= 0) return;
105 
106  switch (Recurrance) {
107  case 24:
108  case 24*7:
109  case 24*14:
110  Repeat = (t_time2 - t_time1) / (60*60*Recurrance) + 1;
111  break;
112  case 0xffff-1:
113  memcpy(&DT,&entry->Entries[start].Date,sizeof(GSM_DateTime));
114  while (1) {
115  if ((DT.Year == entry->Entries[end].Date.Year && DT.Month > entry->Entries[end].Date.Month) ||
116  (DT.Year > entry->Entries[end].Date.Year)) break;
117  if (DT.Month == 12) {
118  DT.Month = 1;
119  DT.Year++;
120  } else {
121  DT.Month++;
122  }
123  Repeat++;
124  }
125  break;
126  case 0xffff:
127  Repeat = entry->Entries[end].Date.Year-entry->Entries[start].Date.Year+1;
128  break;
129  }
130 
131  endday[0] = Repeat/256;
132  endday[1] = Repeat%256;
133 
134  smfprintf(di, "Repeat number: %i\n",Repeat);
135 }
int GetDayOfWeek(unsigned int year, unsigned int month, unsigned int day)
Definition: misc.c:117
GSM_CalendarType EntryType
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
time_t Fill_Time_T(GSM_DateTime DT)
Definition: misc.c:189
int smfprintf(GSM_Debug_Info *d, const char *format,...)
Definition: debug.c:240

§ GSM_SetCalendarSettings()

GSM_Error GSM_SetCalendarSettings ( GSM_StateMachine s,
GSM_CalendarSettings settings 
)

Sets calendar settings.

Parameters
sState machine pointer.
settingsNew calendar settings.
Returns
Error code

Sets calendar settings.

Definition at line 1522 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_LOG_ERROR, and GSM_Phone_Functions::SetCalendarSettings.

1523 {
1524  GSM_Error err;
1525 
1527 
1528  err = s->Phone.Functions->SetCalendarSettings(s, settings);
1529  PRINT_LOG_ERROR(err);
1530  return err;
1531 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
GSM_Error(* SetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings)
Definition: gsmstate.h:1200
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_ToDo_AdjustDate()

void GSM_ToDo_AdjustDate ( GSM_ToDoEntry note,
GSM_DeltaTime delta 
)

Definition at line 784 of file gsmcal.c.

References GSM_SubToDoEntry::Date, GSM_ToDoEntry::Entries, GSM_ToDoEntry::EntriesNum, GSM_SubToDoEntry::EntryType, GSM_AddTime(), TODO_ALARM_DATETIME, TODO_CATEGORY, TODO_COMPLETED, TODO_COMPLETED_DATETIME, TODO_CONTACTID, TODO_DESCRIPTION, TODO_END_DATETIME, TODO_LAST_MODIFIED, TODO_LOCATION, TODO_LUID, TODO_PHONE, TODO_PRIVATE, TODO_SILENT_ALARM_DATETIME, TODO_START_DATETIME, and TODO_TEXT.

Referenced by GSM_DecodeVCALENDAR_VTODO().

785 {
786  int i;
787 
788  /* Loop over entries */
789  for (i=0; i < note->EntriesNum; i++) {
790  switch (note->Entries[i].EntryType) {
791  case TODO_END_DATETIME :
792  case TODO_ALARM_DATETIME :
794  case TODO_LAST_MODIFIED:
795  case TODO_START_DATETIME:
797  note->Entries[i].Date = GSM_AddTime(note->Entries[i].Date, *delta);
798  break;
799  case TODO_TEXT:
800  case TODO_DESCRIPTION:
801  case TODO_PHONE:
802  case TODO_LOCATION:
803  case TODO_LUID:
804  case TODO_PRIVATE:
805  case TODO_COMPLETED:
806  case TODO_CONTACTID:
807  case TODO_CATEGORY:
808  /* No need to care */
809  break;
810  }
811  }
812 }
GSM_ToDoType EntryType
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]
GSM_DateTime GSM_AddTime(GSM_DateTime DT, GSM_DeltaTime delta)
Definition: misc.c:223
GSM_DateTime Date

§ GSM_ToDoFindDefaultTextTimeAlarmCompleted()

void GSM_ToDoFindDefaultTextTimeAlarmCompleted ( GSM_ToDoEntry entry,
int *  Text,
int *  Alarm,
int *  Completed,
int *  EndTime,
int *  Phone 
)

Definition at line 1005 of file gsmcal.c.

References GSM_ToDoEntry::Entries, GSM_ToDoEntry::EntriesNum, GSM_SubToDoEntry::EntryType, TODO_ALARM_DATETIME, TODO_COMPLETED, TODO_END_DATETIME, TODO_PHONE, TODO_SILENT_ALARM_DATETIME, and TODO_TEXT.

1006 {
1007  int i;
1008 
1009  *Text = -1;
1010  *EndTime = -1;
1011  *Alarm = -1;
1012  *Completed = -1;
1013  *Phone = -1;
1014  for (i = 0; i < entry->EntriesNum; i++) {
1015  switch (entry->Entries[i].EntryType) {
1016  case TODO_END_DATETIME :
1017  if (*EndTime == -1) *EndTime = i;
1018  break;
1019  case TODO_ALARM_DATETIME :
1021  if (*Alarm == -1) *Alarm = i;
1022  break;
1023  case TODO_TEXT:
1024  if (*Text == -1) *Text = i;
1025  break;
1026  case TODO_COMPLETED:
1027  if (*Completed == -1) *Completed = i;
1028  break;
1029  case TODO_PHONE:
1030  if (*Phone == -1) *Phone = i;
1031  break;
1032  default:
1033  break;
1034  }
1035  }
1036 }
GSM_ToDoType EntryType
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]

§ GSM_Translate_Category_From_VCal()

GSM_Error GSM_Translate_Category_From_VCal ( const char *  string,
GSM_CalendarNoteType Type 
)

Definition at line 370 of file gsmcal.c.

References ERR_NONE, GSM_CAL_BIRTHDAY, GSM_CAL_CALL, GSM_CAL_MEETING, GSM_CAL_MEMO, GSM_CAL_REMINDER, GSM_CAL_SHOPPING, GSM_CAL_TRAVEL, and GSM_CAL_VACATION.

Referenced by GSM_DecodeVCALENDAR_VTODO().

371 {
372  /* Mozilla has user defined categories. These must be converted to GSM_CAL_xxx types.
373  TODO: For now we use hardcoded conversions. Should be user configurable. */
374 
375  if (strstr(string,"MEETING")) *Type = GSM_CAL_MEETING;
376  else if (strstr(string,"REMINDER")) *Type = GSM_CAL_REMINDER;
377  else if (strstr(string,"DATE")) *Type = GSM_CAL_REMINDER; /* SE */
378  else if (strstr(string,"TRAVEL")) *Type = GSM_CAL_TRAVEL; /* SE */
379  else if (strstr(string,"VACATION")) *Type = GSM_CAL_VACATION; /* SE */
380  else if (strstr(string,"MISCELLANEOUS")) *Type = GSM_CAL_MEMO;
381  else if (strstr(string,"PHONE CALL")) *Type = GSM_CAL_CALL;
382  else if (strstr(string,"SPECIAL OCCASION")) *Type = GSM_CAL_BIRTHDAY;
383  else if (strstr(string,"ANNIVERSARY")) *Type = GSM_CAL_BIRTHDAY;
384  else if (strstr(string,"APPOINTMENT")) *Type = GSM_CAL_MEETING;
385  else if (strstr(string,"SHOPPING LIST")) *Type = GSM_CAL_SHOPPING;
386  /* These are the Nokia 6230i categories in local language. */
387  else if (strstr(string,"Erinnerung")) *Type = GSM_CAL_REMINDER;
388  else if (strstr(string,"Besprechung")) *Type = GSM_CAL_MEETING;
389  else if (strstr(string,"Anrufen")) *Type = GSM_CAL_CALL;
390  else if (strstr(string,"Geburtstag")) *Type = GSM_CAL_BIRTHDAY;
391  else if (strstr(string,"Notiz")) *Type = GSM_CAL_MEMO;
392 
393  else if (strstr(string,"Reminder")) *Type = GSM_CAL_REMINDER;
394  else if (strstr(string,"Meeting")) *Type = GSM_CAL_MEETING;
395  else if (strstr(string,"Call")) *Type = GSM_CAL_CALL;
396  else if (strstr(string,"Birthday")) *Type = GSM_CAL_BIRTHDAY;
397  else if (strstr(string,"Memo")) *Type = GSM_CAL_MEMO;
398  /* default */
399  else *Type = GSM_CAL_MEETING;
400 
401  return ERR_NONE;
402 }

§ GSM_Translate_Category_To_VCal()

GSM_Error GSM_Translate_Category_To_VCal ( char *  string,
const GSM_CalendarNoteType  Type 
)

Definition at line 404 of file gsmcal.c.

References ERR_NONE, GSM_CAL_BIRTHDAY, GSM_CAL_CALL, GSM_CAL_MEETING, GSM_CAL_MEMO, GSM_CAL_REMINDER, GSM_CAL_SHOPPING, GSM_CAL_TRAVEL, and GSM_CAL_VACATION.

Referenced by GSM_EncodeVCALENDAR(), and GSM_EncodeVTODO().

405 {
406  switch (Type) {
407  case GSM_CAL_CALL:
408  strcpy(string, "PHONE CALL");
409  break;
410  case GSM_CAL_MEETING:
411  strcpy(string, "MEETING");
412  break;
413  case GSM_CAL_REMINDER:
414  strcpy(string, "DATE");
415  break;
416  case GSM_CAL_TRAVEL:
417  strcpy(string, "TRAVEL");
418  break;
419  case GSM_CAL_VACATION:
420  strcpy(string, "VACATION");
421  break;
422  case GSM_CAL_BIRTHDAY:
423  strcpy(string, "ANNIVERSARY");
424  break;
425  case GSM_CAL_SHOPPING:
426  strcpy(string, "SHOPPING LIST");
427  break;
428  case GSM_CAL_MEMO:
429  default:
430  strcpy(string, "MISCELLANEOUS");
431  break;
432  }
433 
434  return ERR_NONE;
435 }

§ ReadVCALTriggerTime()

GSM_DeltaTime ReadVCALTriggerTime ( unsigned char *  Buffer)

Definition at line 1205 of file gsmcal.c.

References GSM_DeltaTime::Day, GSM_DeltaTime::Hour, GSM_DeltaTime::Minute, GSM_DeltaTime::Month, GSM_DeltaTime::Second, GSM_DeltaTime::Timezone, and GSM_DeltaTime::Year.

Referenced by GSM_DecodeVCALENDAR_VTODO().

1206 {
1207  GSM_DeltaTime dt;
1208  int sign = 1;
1209  int pos = 0;
1210  int val;
1211  char unit;
1212 
1213  dt.Timezone = 0;
1214  dt.Year = 0 ; dt.Day = 0; dt.Month = 0; dt.Hour = 0; dt.Minute = 0; dt.Second = 0;
1215 
1216  if (Buffer[pos] == '+') {
1217  sign = 1; pos++;
1218  } else if (Buffer[pos] == '-') {
1219  sign = -1; pos++;
1220  }
1221  if (Buffer[pos] == 'P') pos++;
1222  if (Buffer[pos] == 'T') pos++;
1223 
1224  if ( !sscanf(Buffer+pos,"%i%c",&val,&unit) ) return dt;
1225 
1226  switch (unit) {
1227  case 'D': dt.Day = sign * val ; break;
1228  case 'H': dt.Hour = sign * val ; break;
1229  case 'M': dt.Minute = sign * val ; break;
1230  case 'S': dt.Second = sign * val ; break;
1231  }
1232 
1233  return dt;
1234 }

§ VCALTimeDiff()

GSM_DateTime VCALTimeDiff ( GSM_DateTime Alarm,
GSM_DateTime Time 
)

Function to compute time difference between alarm and event time.

Definition at line 320 of file gsmcal.c.

References GSM_DateTime::Day, GSM_DateTime::Hour, GSM_DateTime::Minute, GSM_DateTime::Month, GSM_DateTime::Second, and GSM_DateTime::Year.

Referenced by GSM_EncodeVCALENDAR().

321 {
322  int dt;
323  struct tm talarm, ttime;
324  GSM_DateTime delta;
325 
326  talarm.tm_mday = Alarm->Day;
327  talarm.tm_mon = Alarm->Month-1;
328  talarm.tm_year = Alarm->Year - 1900;
329  talarm.tm_hour = Alarm->Hour;
330  talarm.tm_min = Alarm->Minute;
331  talarm.tm_sec = Alarm->Second;
332  talarm.tm_isdst = 0;
333 
334  ttime.tm_mday = Time->Day;
335  ttime.tm_mon = Time->Month-1;
336  ttime.tm_year = Time->Year - 1900;
337  ttime.tm_hour = Time->Hour;
338  ttime.tm_min = Time->Minute;
339  ttime.tm_sec = Time->Second;
340  ttime.tm_isdst = 0;
341 
342  dt = mktime(&ttime) - mktime(&talarm);
343 
344  if (dt <= 0) dt = 0;
345 
346  /* Mozilla Calendar only accepts relative times for alarm.
347  Maximum representation of time differences is in days.*/
348  delta.Year = 0;
349  delta.Month = 0;
350  delta.Day = dt / 86400 ; dt = dt - delta.Day * 86400;
351  delta.Hour = dt / 3600 ; dt = dt - delta.Hour * 3600;
352  delta.Minute = dt / 60 ; dt = dt - delta.Minute * 60;
353  delta.Second = dt;
354 
355  /* Use only one representation. If delta has minutes convert all to minutes etc.*/
356  if (delta.Minute !=0) {
357  delta.Minute = delta.Day * 24*60 + delta.Hour * 60 + delta.Minute;
358  delta.Day=0; delta.Hour=0;
359  } else if (delta.Hour !=0) {
360  delta.Hour = delta.Day * 24 + delta.Hour;
361  delta.Day=0;
362  }
363 
364  delta.Timezone = 0;
365 
366  return delta;
367 }