Gammu internals  1.38.0
gsmmisc.c File Reference
#include <gammu-config.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <gammu-keys.h>
#include <gammu-debug.h>
#include "../misc/coding/coding.h"
#include "../debug.h"
#include "gsmmisc.h"
#include "../../helper/string.h"
Include dependency graph for gsmmisc.c:

Go to the source code of this file.

Data Structures

struct  keys_table_position
 

Functions

GSM_Error MakeKeySequence (char *text, GSM_KeyCode *KeyCode, size_t *Length)
 
GSM_Error GSM_ReadFile (const char *FileName, GSM_File *File)
 
static void GSM_JADFindLine (GSM_File *File, const char *Name, char *Value)
 
GSM_Error GSM_JADFindData (GSM_File *File, char *Vendor, char *Name, char *JAR, char *Version, int *Size)
 
void GSM_IdentifyFileFormat (GSM_File *File)
 
GSM_Error VC_StoreLine (char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
 
GSM_Error VC_Store (char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
 
GSM_Error VC_StoreDateTime (char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
 
GSM_Error VC_StoreDate (char *Buffer, const size_t buff_len, size_t *Pos, const GSM_DateTime *Date, const char *Start)
 
gboolean ReadVCALDateTime (const char *Buffer, GSM_DateTime *dt)
 
gboolean ReadVCALInt (char *Buffer, const char *Start, int *Value)
 
gboolean ReadVCALDate (char *Buffer, const char *Start, GSM_DateTime *Date, gboolean *is_date_only)
 
GSM_Error VC_StoreText (char *Buffer, const size_t buff_len, size_t *Pos, const unsigned char *Text, const char *Start, const gboolean UTF8)
 
GSM_Error VC_StoreBase64 (char *Buffer, const size_t buff_len, size_t *Pos, const unsigned char *data, const size_t length)
 
unsigned char * VCALGetTextPart (unsigned char *Buff, int *pos)
 
gboolean ReadVCALText (char *Buffer, const char *Start, unsigned char *Value, const gboolean UTF8, GSM_EntryLocation *location)
 
void GSM_ClearBatteryCharge (GSM_BatteryCharge *bat)
 

Variables

static struct keys_table_position Keys []
 

Function Documentation

§ GSM_ClearBatteryCharge()

void GSM_ClearBatteryCharge ( GSM_BatteryCharge bat)

Resets all members of GSM_BatteryCharge structure.

Definition at line 784 of file gsmmisc.c.

References GSM_BatteryCharge::BatteryCapacity, GSM_BatteryCharge::BatteryPercent, GSM_BatteryCharge::BatteryTemperature, GSM_BatteryCharge::BatteryType, GSM_BatteryCharge::BatteryVoltage, GSM_BatteryCharge::ChargeCurrent, GSM_BatteryCharge::ChargeState, GSM_BatteryCharge::ChargeVoltage, GSM_BatteryCharge::PhoneCurrent, and GSM_BatteryCharge::PhoneTemperature.

785 {
786  bat->BatteryPercent = -1;
787  bat->ChargeState = 0;
788  bat->BatteryType = 0;
789  bat->BatteryVoltage = -1;
790  bat->ChargeVoltage = -1;
791  bat->ChargeCurrent = -1;
792  bat->PhoneCurrent = -1;
793  bat->BatteryTemperature = -1;
794  bat->PhoneTemperature = -1;
795  bat->BatteryCapacity = -1;
796 }
GSM_ChargeState ChargeState
Definition: gammu-info.h:244
GSM_BatteryType BatteryType
Definition: gammu-info.h:276

§ GSM_JADFindLine()

static void GSM_JADFindLine ( GSM_File File,
const char *  Name,
char *  Value 
)
static

Definition at line 117 of file gsmmisc.c.

References GSM_File::Buffer, ERR_NONE, FALSE, MyGetLine(), and GSM_File::Used.

Referenced by GSM_JADFindData().

118 {
119  unsigned char Line[2000];
120  size_t Pos = 0;
121 
122  Value[0] = 0;
123 
124  while (1) {
125  if (MyGetLine(File->Buffer, &Pos, Line, File->Used, sizeof(Line), FALSE) != ERR_NONE) break;
126  if (strlen(Line) == 0) break;
127  if (!strncmp(Line,Name,strlen(Name))) {
128  Pos = strlen(Name);
129  while (Line[Pos] == 0x20) Pos++;
130  strcpy(Value,Line+Pos);
131  return;
132  }
133  }
134 }
unsigned char * Buffer
Definition: gammu-file.h:94
size_t Used
Definition: gammu-file.h:70
#define FALSE
Definition: gammu-types.h:25
GSM_Error MyGetLine(char *Buffer, size_t *Pos, char *OutBuffer, size_t MaxLen, size_t MaxOutLen, gboolean MergeLines)
Definition: coding.c:1580

§ ReadVCALDate()

gboolean ReadVCALDate ( char *  Buffer,
const char *  Start,
GSM_DateTime Date,
gboolean is_date_only 
)

Definition at line 335 of file gsmmisc.c.

References dbgprintf, DecodeUnicodeString(), FALSE, OSDate(), ReadVCALDateTime(), ReadVCALText(), and TRUE.

Referenced by GSM_DecodeVCALENDAR_VTODO().

336 {
337  char fullstart[200];
338  unsigned char datestring[200];
339 
340  if (!ReadVCALText(Buffer, Start, datestring, FALSE, NULL)) {
341  fullstart[0] = 0;
342  strcat(fullstart, Start);
343  strcat(fullstart, ";VALUE=DATE");
344  if (!ReadVCALText(Buffer, fullstart, datestring, FALSE, NULL)) {
345  return FALSE;
346  }
347  *is_date_only = TRUE;
348  }
349 
350  if (ReadVCALDateTime(DecodeUnicodeString(datestring), Date)) {
351  dbgprintf(NULL, "ReadVCALDateTime is %s\n", OSDate(*Date));
352  *is_date_only = FALSE;
353  return TRUE;
354  }
355 
356  return FALSE;
357 }
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
char * OSDate(GSM_DateTime dt)
Definition: misc.c:305
gboolean ReadVCALDateTime(const char *Buffer, GSM_DateTime *dt)
Definition: gsmmisc.c:254
#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 dbgprintf
Definition: debug.h:72
#define TRUE
Definition: gammu-types.h:28

§ ReadVCALDateTime()

gboolean ReadVCALDateTime ( const char *  Buffer,
GSM_DateTime dt 
)
Todo:
Handle properly timezone information

Definition at line 254 of file gsmmisc.c.

References CheckDate(), CheckTime(), GSM_DateTime::Day, dbgprintf, FALSE, Fill_GSM_DateTime(), Fill_Time_T(), GSM_DateTime::Hour, GSM_DateTime::Minute, GSM_DateTime::Month, GSM_DateTime::Second, GSM_DateTime::Timezone, TRUE, and GSM_DateTime::Year.

Referenced by GSM_DecodeVCAL_RRULE(), GSM_DecodeVCARD(), and ReadVCALDate().

255 {
256  time_t timestamp;
257  char year[5]="", month[3]="", day[3]="", hour[3]="", minute[3]="", second[3]="";
258 
259  memset(dt,0,sizeof(GSM_DateTime));
260 
261  /* YYYY-MM-DD is invalid, though used */
262  if (sscanf(Buffer, "%d-%d-%d", &dt->Year, &dt->Month, &dt->Day) == 3) {
263  goto checkdt;
264  }
265 
266  if (strlen(Buffer) < 8) {
267  return FALSE;
268  }
269 
270  strncpy(year, Buffer, 4);
271  strncpy(month, Buffer+4, 2);
272  strncpy(day, Buffer+6, 2);
273  dt->Year = atoi(year);
274  dt->Month = atoi(month);
275  dt->Day = atoi(day);
276 
277  if (Buffer[8] == 'T') {
278  if (strlen(Buffer + 9) < 6) return FALSE;
279 
280  strncpy(hour, Buffer+9, 2);
281  strncpy(minute, Buffer+11, 2);
282  strncpy(second, Buffer+13, 2);
283  dt->Hour = atoi(hour);
284  dt->Minute = atoi(minute);
285  dt->Second = atoi(second);
286 
290  if (Buffer[15] == 'Z') dt->Timezone = 0; /* Z = ZULU = GMT */
291  }
292 checkdt:
293 
294  if (!CheckTime(dt)) {
295  dbgprintf(NULL, "incorrect date %d-%d-%d %d:%d:%d\n",dt->Day,dt->Month,dt->Year,dt->Hour,dt->Minute,dt->Second);
296  return FALSE;
297  }
298  if (dt->Year!=0) {
299  if (!CheckDate(dt)) {
300  dbgprintf(NULL, "incorrect date %d-%d-%d %d:%d:%d\n",dt->Day,dt->Month,dt->Year,dt->Hour,dt->Minute,dt->Second);
301  return FALSE;
302  }
303  }
304 
305  if (dt->Timezone != 0) {
306  timestamp = Fill_Time_T(*dt) + dt->Timezone;
307  Fill_GSM_DateTime(dt, timestamp);
308  }
309 
310  return TRUE;
311 }
void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet)
Definition: misc.c:170
#define FALSE
Definition: gammu-types.h:25
gboolean CheckTime(GSM_DateTime *date)
Definition: misc.c:363
#define dbgprintf
Definition: debug.h:72
time_t Fill_Time_T(GSM_DateTime DT)
Definition: misc.c:189
#define TRUE
Definition: gammu-types.h:28
gboolean CheckDate(GSM_DateTime *date)
Definition: misc.c:349

§ ReadVCALInt()

gboolean ReadVCALInt ( char *  Buffer,
const char *  Start,
int *  Value 
)

Definition at line 313 of file gsmmisc.c.

References dbgprintf, FALSE, and TRUE.

Referenced by GSM_DecodeVCALENDAR_VTODO().

314 {
315  unsigned char buff[200];
316 
317  *Value = 0;
318 
319  strcpy(buff,Start);
320  strcat(buff,":");
321  if (!strncmp(Buffer,buff,strlen(buff))) {
322  int lstart = strlen(Start);
323  int lvalue = strlen(Buffer)-(lstart+1);
324  strncpy(buff,Buffer+lstart+1,lvalue);
325  strncpy(buff+lvalue,"\0",1);
326  if (sscanf(buff,"%i",Value)) {
327  dbgprintf(NULL, "ReadVCalInt is \"%i\"\n",*Value);
328  return TRUE;
329  }
330  }
331  return FALSE;
332 }
#define FALSE
Definition: gammu-types.h:25
#define dbgprintf
Definition: debug.h:72
#define TRUE
Definition: gammu-types.h:28

§ ReadVCALText()

gboolean ReadVCALText ( char *  Buffer,
const char *  Start,
unsigned char *  Value,
const gboolean  UTF8,
GSM_EntryLocation location 
)

We separate matching text (Start) to tokens and then try to find all tokens in Buffer. We also accept tokens like PREF, CHARSET or ENCODING.

Also it parses TYPE=* tokens, matching it to text types passed in Start parameter. For example Start "TEL;FAX;VOICE" matches "TEL;TYPE=FAX,VOICE" or "TEL;FAX;TYPE=VOICE" or "TEL;TYPE=FAX;TYPE=VOICE" and of course "TEL;FAX;VOICE".

When all tokens are matched we found matching line.

Definition at line 468 of file gsmmisc.c.

References dbgprintf, DecodeISO88591(), DecodeISO88591QuotedPrintable(), DecodeUnicodeConsole(), DecodeUTF7(), DecodeUTF8(), DecodeUTF8QuotedPrintable(), FALSE, PBK_Location_Home, PBK_Location_Unknown, PBK_Location_Work, TRUE, and UnicodeLength().

Referenced by GSM_DecodeVCALENDAR_VTODO(), GSM_DecodeVCARD(), GSM_DecodeVNOTE(), and ReadVCALDate().

469 {
470  char *line = NULL;
471  char **tokens = NULL;
472  char *charset = NULL;
473  char *begin, *pos, *end, *end2;
474  gboolean quoted_printable = FALSE;
475  size_t numtokens, token;
476  size_t i, j, len;
477  gboolean found;
478  gboolean ret = FALSE;
479 
480  /* Initialize output */
481  Value[0] = 0x00;
482  Value[1] = 0x00;
483 
484  /* Count number of tokens */
485  len = strlen(Start);
486  numtokens = 1;
487  for (i = 0; i < len; i++) {
488  if (Start[i] == ';') {
489  numtokens++;
490  }
491  }
492 
493  /* Allocate memory */
494  line = strdup(Start);
495  if (line == NULL) {
496  dbgprintf(NULL, "Could not alloc!\n");
497  goto fail;
498  }
499  tokens = (char **)malloc(sizeof(char *) * numtokens);
500  if (tokens == NULL) {
501  dbgprintf(NULL, "Could not alloc!\n");
502  goto fail;
503  }
504 
505  /* Parse Start to vCard tokens (separated by ;) */
506  token = 0;
507  begin = line;
508  for (i = 0; i < len; i++) {
509  if (line[i] == ';') {
510  tokens[token++] = begin;
511  begin = line + i + 1;
512  line[i] = 0;
513  }
514  }
515  /* Store last token */
516  tokens[token] = begin;
517 
518  /* Compare first token, it must be in place */
519  pos = Buffer;
520  len = strlen(tokens[0]);
521  if (strncasecmp(pos, tokens[0], len) != 0) {
522  goto fail;
523  }
524  /* Advance position */
525  pos += len;
526  /* No need to check this token anymore */
527  tokens[0][0] = 0;
528  /* Initialize location */
529  if (location != NULL) {
530  *location = PBK_Location_Unknown;
531  }
532 
533  /* Check remaining tokens */
534  while (*pos != ':') {
535  if (*pos == ';') {
536  pos++;
537  } else {
538  dbgprintf(NULL, "Could not parse! (stopped at string: %s)\n", pos);
539  goto fail;
540  }
541  found = FALSE;
542  for (token = 0; token < numtokens; token++) {
543  len = strlen(tokens[token]);
544  /* Skip already matched tokens */
545  if (len == 0) {
546  continue;
547  }
548  if (strncasecmp(pos, tokens[token], len) == 0) {
549  dbgprintf(NULL, "Found %s\n", tokens[token]);
550  /* Advance position */
551  pos += len;
552  /* We need to check one token less */
553  tokens[token][0] = 0;
554  found = TRUE;
555  break;
556  }
557  }
558  if (!found) {
559  if (strncasecmp(pos, "ENCODING=QUOTED-PRINTABLE", 25) == 0) {
560  quoted_printable = TRUE;
561  /* Advance position */
562  pos += 25;
563  found = TRUE;
564  } else if (strncasecmp(pos, "CHARSET=", 8) == 0) {
565  /* Advance position */
566  pos += 8;
567  /* Grab charset */
568  end = strchr(pos, ':');
569  end2 = strchr(pos, ';');
570  if (end == NULL && end2 == NULL) {
571  dbgprintf(NULL, "Could not read charset!\n");
572  goto fail;
573  } else if (end == NULL) {
574  end = end2;
575  } else if (end2 != NULL && end2 < end) {
576  end = end2;
577  }
578  /* We basically want strndup, but it is not portable */
579  charset = strdup(pos);
580  if (charset == NULL) {
581  dbgprintf(NULL, "Could not alloc!\n");
582  goto fail;
583  }
584  charset[end - pos] = 0;
585 
586  pos = end;
587  found = TRUE;
588  } else if (strncasecmp(pos, "TZID=", 5) == 0) {
589  /* @todo: We ignore time zone for now */
590  /* Advance position */
591  pos += 5;
592  /* Go behind value */
593  end = strchr(pos, ':');
594  end2 = strchr(pos, ';');
595  if (end == NULL && end2 == NULL) {
596  dbgprintf(NULL, "Could not read timezone!\n");
597  goto fail;
598  } else if (end == NULL) {
599  end = end2;
600  } else if (end2 != NULL && end2 < end) {
601  end = end2;
602  }
603  pos = end;
604  found = TRUE;
605  } else if (strncasecmp(pos, "TYPE=", 5) == 0) {
606  /* We ignore TYPE= prefix */
607  pos += 5;
608 
609  /* Now process types, which should be comma separated */
610  while (*pos != ':' && *pos != ';') {
611  found = FALSE;
612 
613  /* Go through tokens to match */
614  for (token = 0; token < numtokens; token++) {
615  len = strlen(tokens[token]);
616  /* Skip already matched tokens */
617  if (len == 0) {
618  continue;
619  }
620  if (strncasecmp(pos, tokens[token], len) == 0) {
621  dbgprintf(NULL, "Found %s\n", tokens[token]);
622  /* Advance position */
623  pos += len;
624  /* We need to check one token less */
625  tokens[token][0] = 0;
626  found = TRUE;
627  break;
628  }
629  }
630 
631  if (!found) {
632  if (strncasecmp(pos, "PREF", 4) == 0) {
633  /* We ignore pref token */
634  pos += 4;
635  found = TRUE;
636  } else if (strncasecmp(pos, "WORK", 4) == 0) {
637  /* We ignore work token */
638  pos += 4;
639  found = TRUE;
640  if (location != NULL) {
641  *location = PBK_Location_Work;
642  }
643  } else if (strncasecmp(pos, "HOME", 4) == 0) {
644  /* We ignore home token */
645  pos += 4;
646  found = TRUE;
647  if (location != NULL) {
648  *location = PBK_Location_Home;
649  }
650  } else {
651  dbgprintf(NULL, "%s not found! (%s)\n", Start, pos);
652  goto fail;
653  }
654  }
655 
656  if (*pos == ';' || *pos == ':') {
657  dbgprintf(NULL, "End of TYPE= string\n");
658  break;
659  } else if (*pos == ',') {
660  /* Advance past separator */
661  pos++;
662  } else {
663  dbgprintf(NULL, "Could not parse TYPE=! (stopped at string: %s)\n", pos);
664  goto fail;
665  }
666 
667  }
668  } else if (strncasecmp(pos, "PREF", 4) == 0) {
669  /* We ignore pref token */
670  pos += 4;
671  found = TRUE;
672  } else if (location && strncasecmp(pos, "WORK", 4) == 0) {
673  /* We ignore pref token */
674  pos += 4;
675  found = TRUE;
676  *location = PBK_Location_Work;
677  } else if (location && strncasecmp(pos, "HOME", 4) == 0) {
678  /* We ignore pref token */
679  pos += 4;
680  found = TRUE;
681  *location = PBK_Location_Home;
682  }
683  if (!found) {
684  dbgprintf(NULL, "%s not found!\n", Start);
685  goto fail;
686  }
687  }
688  }
689  /* Skip : */
690  pos++;
691  /* Length of rest */
692  len = strlen(pos);
693 
694  /* Did we match all our tokens? */
695  for (token = 0; token < numtokens; token++) {
696  if (strlen(tokens[token]) > 0) {
697  dbgprintf(NULL, "All tokens did not match!\n");
698  goto fail;
699  }
700  }
701 
702  /* Decode the text */
703  if (charset == NULL) {
704  if (quoted_printable) {
705  if (UTF8) {
706  DecodeUTF8QuotedPrintable(Value, pos, len);
707  } else {
708  DecodeISO88591QuotedPrintable(Value, pos, len);
709  }
710  } else {
711  if (UTF8) {
712  DecodeUTF8(Value, pos, len);
713  } else {
714  DecodeISO88591(Value, pos, len);
715  }
716  }
717  } else {
718  if (strcasecmp(charset, "UTF-8") == 0||
719  strcasecmp(charset, "\"UTF-8\"") == 0
720  ) {
721  if (quoted_printable) {
722  DecodeUTF8QuotedPrintable(Value, pos, len);
723  } else {
724  DecodeUTF8(Value, pos, len);
725  }
726  } else if (strcasecmp(charset, "UTF-7") == 0||
727  strcasecmp(charset, "\"UTF-7\"") == 0
728  ) {
729  if (quoted_printable) {
730  dbgprintf(NULL, "Unsupported charset: %s\n", charset);
731  goto fail;
732  } else {
733  DecodeUTF7(Value, pos, len);
734  }
735  } else {
736  dbgprintf(NULL, "Unsupported charset: %s\n", charset);
737  goto fail;
738  }
739  }
740 
741  /* Postprocess escaped chars */
742  len = UnicodeLength(Value);
743  for (i = 0; i < len; i++) {
744  if (Value[(2 * i)] == 0 && Value[(2 * i) + 1] == '\\') {
745  j = i + 1;
746  if (Value[(2 * j)] == 0 && (
747  Value[(2 * j) + 1] == 'n' ||
748  Value[(2 * j) + 1] == 'N')
749  ) {
750  Value[(2 * i) + 1] = '\n';
751  } else if (Value[(2 * j)] == 0 && (
752  Value[(2 * j) + 1] == 'r' ||
753  Value[(2 * j) + 1] == 'R')
754  ) {
755  Value[(2 * i) + 1] = '\r';
756  } else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == '\\') {
757  Value[(2 * i) + 1] = '\\';
758  } else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == ';') {
759  Value[(2 * i) + 1] = ';';
760  } else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == ',') {
761  Value[(2 * i) + 1] = ',';
762  } else {
763  /* We ignore unknown for now */
764  continue;
765  }
766  /* Shift the string */
767  memmove(Value + (2 * j), Value + (2 * j) + 2, 2 * (len + 1 - j));
768  len--;
769  }
770  }
771 
772  ret = TRUE;
773  dbgprintf(NULL, "ReadVCalText(%s) is \"%s\"\n", Start, DecodeUnicodeConsole(Value));
774 fail:
775  free(line);
776  line=NULL;
777  free(tokens);
778  tokens=NULL;
779  free(charset);
780  charset=NULL;
781  return ret;
782 }
char * DecodeUnicodeConsole(const unsigned char *src)
Definition: coding.c:256
void DecodeISO88591QuotedPrintable(unsigned char *dest, const unsigned char *src, size_t len)
Definition: coding.c:1889
void DecodeUTF7(unsigned char *dest, const unsigned char *src, size_t len)
Definition: coding.c:2051
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
void DecodeISO88591(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:282
int gboolean
Definition: gammu-types.h:23
void DecodeUTF8QuotedPrintable(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:1911
#define FALSE
Definition: gammu-types.h:25
void DecodeUTF8(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:1947
#define dbgprintf
Definition: debug.h:72
#define TRUE
Definition: gammu-types.h:28

§ VC_Store()

GSM_Error VC_Store ( char *  Buffer,
const size_t  buff_len,
size_t *  Pos,
const char *  format,
  ... 
)

Prints a string to a buffer with error checking.

Definition at line 208 of file gsmmisc.c.

References ERR_MOREMEMORY, and ERR_NONE.

Referenced by GSM_EncodeVCAL_RRULE(), GSM_EncodeVCARD(), VC_StoreDate(), and VC_StoreDateTime().

209 {
210  va_list argp;
211  int result;
212 
213  va_start(argp, format);
214  result = vsnprintf(Buffer + (*Pos), buff_len - *Pos - 1, format, argp);
215  va_end(argp);
216 
217  *Pos += result;
218  if (*Pos >= buff_len - 1) return ERR_MOREMEMORY;
219 
220  return ERR_NONE;
221 }

§ VC_StoreBase64()

GSM_Error VC_StoreBase64 ( char *  Buffer,
const size_t  buff_len,
size_t *  Pos,
const unsigned char *  data,
const size_t  length 
)

Store base64 encoded string to buffer.

Definition at line 392 of file gsmmisc.c.

References EncodeBASE64(), ERR_MOREMEMORY, ERR_NONE, MIN, and VC_StoreLine().

Referenced by GSM_EncodeVCARD().

393 {
394  char *buffer=NULL, *pos=NULL, linebuffer[80]={0};
395  size_t len=0, current=0;
396  char spacer[2]={0};
397  GSM_Error error;
398 
399  /*
400  * Need to be big enough to store base64 (what is *4/3, but *2 is safer
401  * and we don't have to care about rounding and padding).
402  */
403  buffer = (char *)malloc(length * 2);
404  if (buffer == NULL) return ERR_MOREMEMORY;
405 
406  spacer[0] = 0;
407  spacer[1] = 0;
408 
409 
410  EncodeBASE64(data, buffer, length);
411 
412  len = strlen(buffer);
413  pos = buffer;
414 
415  /* Write at most 76 chars per line */
416  while (len > 0) {
417  current = MIN(len, 76);
418  strncpy(linebuffer, pos, current);
419  linebuffer[current] = 0;
420  error = VC_StoreLine(Buffer, buff_len, Pos, "%s%s", spacer, linebuffer);
421  if (error != ERR_NONE) {
422  free(buffer);
423  buffer=NULL;
424  return error;
425  }
426  spacer[0] = ' ';
427  len -= current;
428  pos += current;
429  }
430 
431  free(buffer);
432  buffer=NULL;
433  return ERR_NONE;
434 }
void EncodeBASE64(const unsigned char *Input, char *Output, const size_t Length)
Definition: coding.c:2118
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
#define MIN(a, b)
Definition: gammu-misc.h:70

§ VC_StoreDate()

GSM_Error VC_StoreDate ( char *  Buffer,
const size_t  buff_len,
size_t *  Pos,
const GSM_DateTime Date,
const char *  Start 
)

Definition at line 240 of file gsmmisc.c.

References GSM_DateTime::Day, ERR_NONE, GSM_DateTime::Month, VC_Store(), VC_StoreLine(), and GSM_DateTime::Year.

Referenced by GSM_EncodeVCAL_RRULE(), GSM_EncodeVCALENDAR(), and GSM_EncodeVCARD().

241 {
242  GSM_Error error;
243 
244  if (Start != NULL) {
245  error = VC_Store(Buffer, buff_len, Pos, "%s:", Start);
246  if (error != ERR_NONE) return error;
247  }
248  error = VC_StoreLine(Buffer, buff_len, Pos,
249  "%04d%02d%02d",
250  Date->Year, Date->Month, Date->Day);
251  return error;
252 }
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

§ VC_StoreDateTime()

GSM_Error VC_StoreDateTime ( char *  Buffer,
const size_t  buff_len,
size_t *  Pos,
const GSM_DateTime Date,
const char *  Start 
)

Definition at line 224 of file gsmmisc.c.

References GSM_DateTime::Day, ERR_NONE, GSM_DateTime::Hour, GSM_DateTime::Minute, GSM_DateTime::Month, GSM_DateTime::Second, GSM_DateTime::Timezone, VC_Store(), VC_StoreLine(), and GSM_DateTime::Year.

Referenced by GSM_EncodeVCALENDAR(), GSM_EncodeVCARD(), and GSM_EncodeVTODO().

225 {
226  GSM_Error error;
227 
228  if (Start != NULL) {
229  error = VC_Store(Buffer, buff_len, Pos, "%s:", Start);
230  if (error != ERR_NONE) return error;
231  }
232  error = VC_StoreLine(Buffer, buff_len, Pos,
233  "%04d%02d%02dT%02d%02d%02d%s",
234  Date->Year, Date->Month, Date->Day,
235  Date->Hour, Date->Minute, Date->Second,
236  Date->Timezone == 0 ? "Z" : "");
237  return error;
238 }
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

§ VC_StoreLine()

GSM_Error VC_StoreLine ( char *  Buffer,
const size_t  buff_len,
size_t *  Pos,
const char *  format,
  ... 
)

Prints a line (terminated with CRLF) to a buffer with error checking.

Definition at line 187 of file gsmmisc.c.

References ERR_MOREMEMORY, ERR_NONE, and PRINTF_STYLE.

Referenced by GSM_EncodeVCAL_RRULE(), GSM_EncodeVCALENDAR(), GSM_EncodeVCARD(), GSM_EncodeVNTFile(), GSM_EncodeVTODO(), VC_StoreBase64(), VC_StoreDate(), VC_StoreDateTime(), and VC_StoreText().

188 {
189  va_list argp;
190  int result;
191 
192  va_start(argp, format);
193  result = vsnprintf(Buffer + (*Pos), buff_len - *Pos - 1, format, argp);
194  va_end(argp);
195 
196  *Pos += result;
197  if (*Pos >= buff_len - 1) return ERR_MOREMEMORY;
198 
199  result = snprintf(Buffer + (*Pos), buff_len - *Pos - 1, "%c%c", 13, 10);
200 
201  *Pos += result;
202  if (*Pos >= buff_len - 1) return ERR_MOREMEMORY;
203 
204  return ERR_NONE;
205 }

§ VC_StoreText()

GSM_Error VC_StoreText ( char *  Buffer,
const size_t  buff_len,
size_t *  Length,
const unsigned char *  Text,
const char *  Start,
const gboolean  UTF8 
)

Stores text in vCalendar/vCard formatted buffer.

Parameters
[out]BufferBuffer where output will be stored.
[in]buff_lenSize of Buffer.
[in,out]LengthCurrent position in output buffer (will be updated).
[in]TextValue to be stored.
[in]StartName of field which is being stored.
[in]UTF8Whether text should be stored in UTF-8 without prefix.

Definition at line 360 of file gsmmisc.c.

References EncodeUTF8QuotedPrintable(), ERR_MOREMEMORY, ERR_NONE, UnicodeLength(), and VC_StoreLine().

Referenced by GSM_EncodeVCALENDAR(), GSM_EncodeVCARD(), GSM_EncodeVNTFile(), and GSM_EncodeVTODO().

361 {
362  char *buffer=NULL;
363  size_t len=0;
364  GSM_Error error;
365 
366  len = UnicodeLength(Text);
367 
368  if (len == 0) return ERR_NONE;
369 
370  /* Need to be big enough to store quoted printable */
371  buffer = (char *)malloc(len * 8);
372  if (buffer == NULL) return ERR_MOREMEMORY;
373 
374  if (UTF8) {
375  EncodeUTF8QuotedPrintable(buffer, Text);
376  error = VC_StoreLine(Buffer, buff_len, Pos, "%s:%s", Start, buffer);
377  } else {
378  EncodeUTF8QuotedPrintable(buffer, Text);
379  if (UnicodeLength(Text) == strlen(buffer)) {
380  /* Text is plain ASCII */
381  error = VC_StoreLine(Buffer, buff_len, Pos, "%s:%s", Start, buffer);
382  } else {
383  error = VC_StoreLine(Buffer, buff_len, Pos, "%s;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:%s", Start, buffer);
384  }
385  }
386 
387  free(buffer);
388  buffer=NULL;
389  return error;
390 }
gboolean EncodeUTF8QuotedPrintable(char *dest, const unsigned char *src)
Definition: coding.c:1794
GSM_Error
Definition: gammu-error.h:23
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
GSM_Error VC_StoreLine(char *Buffer, const size_t buff_len, size_t *Pos, const char *format,...)
Definition: gsmmisc.c:187

§ VCALGetTextPart()

unsigned char* VCALGetTextPart ( unsigned char *  Buff,
int *  pos 
)

Definition at line 436 of file gsmmisc.c.

References CopyUnicodeString().

Referenced by GSM_DecodeVCARD().

437 {
438  static unsigned char tmp[1000];
439  unsigned char *start;
440 
441  start = Buff + *pos;
442  while (Buff[*pos] != 0 || Buff[*pos + 1] != 0) {
443  if (Buff[*pos] == 0 && Buff[*pos + 1] == ';') {
444  Buff[*pos + 1] = 0;
445  CopyUnicodeString(tmp, start);
446  Buff[*pos + 1] = ';';
447  *pos += 2;
448  return tmp;
449  }
450  *pos += 2;
451  }
452  if (start == Buff || (start[0] == 0 && start[1] == 0)) return NULL;
453  CopyUnicodeString(tmp, start);
454  return tmp;
455 }
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192

Variable Documentation

§ Keys

struct keys_table_position Keys[]
static
Initial value:
= {
{'m',GSM_KEY_MENU}, {'M',GSM_KEY_MENU},
{'u',GSM_KEY_UP}, {'U',GSM_KEY_UP},
{'d',GSM_KEY_DOWN}, {'D',GSM_KEY_DOWN},
{'1',GSM_KEY_1}, {'2',GSM_KEY_2}, {'3',GSM_KEY_3},
{'4',GSM_KEY_4}, {'5',GSM_KEY_5}, {'6',GSM_KEY_6},
{'7',GSM_KEY_7}, {'8',GSM_KEY_8}, {'9',GSM_KEY_9},
{'r',GSM_KEY_RED}, {'R',GSM_KEY_RED},
{' ',0}
}

Definition at line 23 of file gsmmisc.c.