Gammu internals  1.38.0
coding.c File Reference
#include <gammu-config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#include <limits.h>
#include "../../debug.h"
#include "coding.h"
Include dependency graph for coding.c:

Go to the source code of this file.

Macros

#define ByteMask   ((1 << Bits) - 1)
 
#define tolowerwchar(x)   (towlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) )))
 

Functions

unsigned char * EncodeUnicodeSpecialChars (unsigned char *dest, const unsigned char *buffer)
 
char * EncodeSpecialChars (char *dest, const char *buffer)
 
unsigned char * DecodeUnicodeSpecialChars (unsigned char *dest, const unsigned char *buffer)
 
char * DecodeSpecialChars (char *dest, const char *buffer)
 
size_t UnicodeLength (const unsigned char *str)
 
int EncodeWithUnicodeAlphabet (const unsigned char *src, wchar_t *dest)
 
int DecodeWithUnicodeAlphabet (wchar_t src, unsigned char *dest)
 
void DecodeUnicode (const unsigned char *src, char *dest)
 
char * DecodeUnicodeString (const unsigned char *src)
 
char * DecodeUnicodeConsole (const unsigned char *src)
 
void DecodeISO88591 (unsigned char *dest, const char *src, size_t len)
 
void EncodeUnicode (unsigned char *dest, const char *src, size_t len)
 
unsigned char EncodeWithBCDAlphabet (int value)
 
int DecodeWithBCDAlphabet (unsigned char value)
 
void DecodeBCD (unsigned char *dest, const unsigned char *src, size_t len)
 
void EncodeBCD (unsigned char *dest, const unsigned char *src, size_t len, gboolean fill)
 
int DecodeWithHexBinAlphabet (unsigned char mychar)
 
char EncodeWithHexBinAlphabet (int digit)
 
gboolean DecodeHexUnicode (unsigned char *dest, const char *src, size_t len)
 
void EncodeHexUnicode (char *dest, const unsigned char *src, size_t len)
 
gboolean DecodeHexBin (unsigned char *dest, const unsigned char *src, size_t len)
 
void EncodeHexBin (char *dest, const unsigned char *src, size_t len)
 
void DecodeDefault (unsigned char *dest, const unsigned char *src, size_t len, gboolean UseExtensions, unsigned char *ExtraAlphabet)
 
void EncodeDefault (unsigned char *dest, const unsigned char *src, size_t *len, gboolean UseExtensions, unsigned char *ExtraAlphabet)
 
void FindDefaultAlphabetLen (const unsigned char *src, size_t *srclen, size_t *smslen, size_t maxlen)
 
int GSM_UnpackEightBitsToSeven (size_t offset, size_t in_length, size_t out_length, const unsigned char *input, unsigned char *output)
 
int GSM_PackSevenBitsToEight (size_t offset, const unsigned char *input, unsigned char *output, size_t length)
 
GSM_Error GSM_UnpackSemiOctetNumber (GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, size_t *pos, size_t bufferlength, gboolean semioctet)
 
int GSM_PackSemiOctetNumber (const unsigned char *Number, unsigned char *Output, gboolean semioctet)
 
void CopyUnicodeString (unsigned char *Dest, const unsigned char *Source)
 
void ReverseUnicodeString (unsigned char *String)
 
void ReadUnicodeFile (unsigned char *Dest, const unsigned char *Source)
 
int GetBit (unsigned char *Buffer, size_t BitNum)
 
int SetBit (unsigned char *Buffer, size_t BitNum)
 
int ClearBit (unsigned char *Buffer, size_t BitNum)
 
void BufferAlign (unsigned char *Destination, size_t *CurrentBit)
 
void BufferAlignNumber (size_t *CurrentBit)
 
void AddBuffer (unsigned char *Destination, size_t *CurrentBit, unsigned char *Source, size_t BitsToProcess)
 
void AddBufferByte (unsigned char *Destination, size_t *CurrentBit, unsigned char Source, size_t BitsToProcess)
 
void GetBuffer (unsigned char *Source, size_t *CurrentBit, unsigned char *Destination, size_t BitsToProcess)
 
void GetBufferInt (unsigned char *Source, size_t *CurrentBit, int *integer, size_t BitsToProcess)
 
void GetBufferI (unsigned char *Source, size_t *CurrentBit, int *result, size_t BitsToProcess)
 
void EncodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, size_t len)
 
void DecodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, size_t len)
 
gboolean mywstrncasecmp (unsigned const char *a, unsigned const char *b, int num)
 
gboolean mywstrncmp (unsigned const char *a, unsigned const char *b, int num)
 
gboolean myiswspace (unsigned const char *src)
 
unsigned char * mywstrstr (const unsigned char *haystack, const unsigned char *needle)
 
GSM_Error MyGetLine (char *Buffer, size_t *Pos, char *OutBuffer, size_t MaxLen, size_t MaxOutLen, gboolean MergeLines)
 
GSM_Error GSM_GetVCSLine (char **OutBuffer, char *Buffer, size_t *Pos, size_t MaxLen, gboolean MergeLines)
 
void StringToDouble (char *text, double *d)
 
int EncodeWithUTF8Alphabet (unsigned long src, unsigned char *ret)
 
gboolean EncodeUTF8QuotedPrintable (char *dest, const unsigned char *src)
 
gboolean EncodeUTF8 (char *dest, const unsigned char *src)
 
int DecodeWithUTF8Alphabet (const unsigned char *src, wchar_t *dest, size_t len)
 
void DecodeISO88591QuotedPrintable (unsigned char *dest, const unsigned char *src, size_t len)
 
void DecodeUTF8QuotedPrintable (unsigned char *dest, const char *src, size_t len)
 
void DecodeUTF8 (unsigned char *dest, const char *src, size_t len)
 
void DecodeXMLUTF8 (unsigned char *dest, const char *src, size_t len)
 
void DecodeUTF7 (unsigned char *dest, const unsigned char *src, size_t len)
 
static void EncodeBASE64Block (const unsigned char in[3], char out[4], const size_t len)
 
void EncodeBASE64 (const unsigned char *Input, char *Output, const size_t Length)
 
static void DecodeBASE64Block (const char in[4], unsigned char out[3])
 
int DecodeBASE64 (const char *Input, unsigned char *Output, const size_t Length)
 

Variables

static unsigned char GSM_DefaultAlphabetUnicode [128+1][2]
 
static unsigned char GSM_DefaultAlphabetCharsExtension [][3]
 
static unsigned char ConvertTable []
 

Macro Definition Documentation

§ ByteMask

#define ByteMask   ((1 << Bits) - 1)

Definition at line 951 of file coding.c.

Referenced by GSM_UnpackEightBitsToSeven().

§ tolowerwchar

#define tolowerwchar (   x)    (towlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) )))

Referenced by mywstrstr().

Function Documentation

§ AddBuffer()

void AddBuffer ( unsigned char *  Destination,
size_t *  CurrentBit,
unsigned char *  Source,
size_t  BitsToProcess 
)

Definition at line 1286 of file coding.c.

References ClearBit(), GetBit(), and SetBit().

Referenced by AddBufferByte(), and GSM_EncodeNokiaRTTLRingtone().

1290 {
1291  size_t i;
1292 
1293  for (i = 0; i < BitsToProcess; i++) {
1294  if (GetBit(Source, i)) {
1295  SetBit(Destination, (*CurrentBit)+i);
1296  } else {
1297  ClearBit(Destination, (*CurrentBit)+i);
1298  }
1299  }
1300  (*CurrentBit) = (*CurrentBit) + BitsToProcess;
1301 }
int ClearBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1258
int SetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1253
int GetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1248

§ AddBufferByte()

void AddBufferByte ( unsigned char *  Destination,
size_t *  CurrentBit,
unsigned char  Source,
size_t  BitsToProcess 
)

Definition at line 1303 of file coding.c.

References AddBuffer().

Referenced by GSM_EncodeNokiaRTTLRingtone().

1307 {
1308  AddBuffer(Destination, CurrentBit, &Source, BitsToProcess);
1309 }
void AddBuffer(unsigned char *Destination, size_t *CurrentBit, unsigned char *Source, size_t BitsToProcess)
Definition: coding.c:1286

§ BufferAlign()

void BufferAlign ( unsigned char *  Destination,
size_t *  CurrentBit 
)

Definition at line 1263 of file coding.c.

References ClearBit().

Referenced by GSM_EncodeNokiaRTTLRingtone().

1264 {
1265  int i=0;
1266 
1267  while(((*CurrentBit) + i) % 8 != 0) {
1268  ClearBit(Destination, (*CurrentBit)+i);
1269  i++;
1270  }
1271 
1272  (*CurrentBit) = (*CurrentBit) + i;
1273 }
int ClearBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1258

§ BufferAlignNumber()

void BufferAlignNumber ( size_t *  CurrentBit)

Definition at line 1275 of file coding.c.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

1276 {
1277  int i=0;
1278 
1279  while(((*CurrentBit) + i) % 8 != 0) {
1280  i++;
1281  }
1282 
1283  (*CurrentBit) = (*CurrentBit) + i;
1284 }

§ ClearBit()

int ClearBit ( unsigned char *  Buffer,
size_t  BitNum 
)

Definition at line 1258 of file coding.c.

Referenced by AddBuffer(), BufferAlign(), GetBuffer(), and GSM_ClearPointBitmap().

1259 {
1260  return Buffer[BitNum / 8] &= 255 - (1 << (7 - (BitNum % 8)));
1261 }

§ DecodeBASE64()

int DecodeBASE64 ( const char *  Input,
unsigned char *  Output,
const size_t  Length 
)

Definition at line 2149 of file coding.c.

References DecodeBASE64Block(), and FALSE.

Referenced by DecodeUTF7(), and GSM_DecodeVCARD().

2150 {
2151  unsigned char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
2152  unsigned char in[4], out[3], v;
2153  size_t i, len, pos = 0, outpos = 0;
2154 
2155  while (pos < Length) {
2156  len = 0;
2157  for(i = 0; i < 4; i++) {
2158  v = 0;
2159  while(v == 0) {
2160  if (pos >= Length) break;
2161  v = (unsigned char) Input[pos++];
2162  v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
2163  if (v) v = (unsigned char) ((v == '$') ? 0 : v - 61);
2164  }
2165  if(pos<=Length) {
2166  if (v) {
2167  len++;
2168  in[i] = (unsigned char) (v - 1);
2169  }
2170  }
2171  }
2172  if (len) {
2173  DecodeBASE64Block(in, out);
2174  for(i = 0; i < len - 1; i++) Output[outpos++] = out[i];
2175  }
2176  }
2177  Output[outpos] = 0;
2178  return outpos;
2179 }
static void DecodeBASE64Block(const char in[4], unsigned char out[3])
Definition: coding.c:2142

§ DecodeBASE64Block()

static void DecodeBASE64Block ( const char  in[4],
unsigned char  out[3] 
)
static

Definition at line 2142 of file coding.c.

Referenced by DecodeBASE64().

2143 {
2144  out[0] = (unsigned char) ((in[0] << 2) | (in[1] >> 4));
2145  out[1] = (unsigned char) ((in[1] << 4) | (in[2] >> 2));
2146  out[2] = (unsigned char) (((in[2] << 6) & 0xc0) | in[3]);
2147 }

§ DecodeBCD()

void DecodeBCD ( unsigned char *  dest,
const unsigned char *  src,
size_t  len 
)

Definition at line 328 of file coding.c.

Referenced by GSM_UnpackSemiOctetNumber(), and NOKIA_DecodeNetworkCode().

329 {
330  size_t i,current=0;
331  int digit;
332 
333  for (i = 0; i < len; i++) {
334  digit=src[i] & 0x0f;
335  if (digit<10) dest[current++]=digit + '0';
336  digit=src[i] >> 4;
337  if (digit<10) dest[current++]=digit + '0';
338  }
339  dest[current]=0;
340 }

§ DecodeDefault()

void DecodeDefault ( unsigned char *  dest,
const unsigned char *  src,
size_t  len,
gboolean  UseExtensions,
unsigned char *  ExtraAlphabet 
)

Definition at line 498 of file coding.c.

References DumpMessageText(), GSM_DefaultAlphabetCharsExtension, GSM_DefaultAlphabetUnicode, GSM_global_debug, and UnicodeLength().

Referenced by GSM_DecodePDUFrame(), GSM_DecodeSMSFrameText(), and GSM_EncodeMultiPartSMS().

499 {
500  size_t pos, current = 0, i;
501 
502 #ifdef DEBUG
503  DumpMessageText(&GSM_global_debug, src, len);
504 #endif
505 
506  for (pos = 0; pos < len; pos++) {
507  if ((pos < (len - 1)) && UseExtensions && src[pos] == 0x1b) {
508  for (i = 0; GSM_DefaultAlphabetCharsExtension[i][0] != 0x00; i++) {
509  if (GSM_DefaultAlphabetCharsExtension[i][0] == src[pos + 1]) {
510  dest[current++] = GSM_DefaultAlphabetCharsExtension[i][1];
511  dest[current++] = GSM_DefaultAlphabetCharsExtension[i][2];
512  pos++;
513  break;
514  }
515  }
516  /* Skip rest if we've found something */
517  if (GSM_DefaultAlphabetCharsExtension[i][0] != 0x00) {
518  continue;
519  }
520  }
521  if (ExtraAlphabet != NULL) {
522  for (i = 0; ExtraAlphabet[i] != 0x00; i += 3) {
523  if (ExtraAlphabet[i] == src[pos]) {
524  dest[current++] = ExtraAlphabet[i + 1];
525  dest[current++] = ExtraAlphabet[i + 2];
526  break;
527  }
528  }
529  /* Skip rest if we've found something */
530  if (ExtraAlphabet[i] != 0x00) {
531  continue;
532  }
533  }
534  dest[current++] = GSM_DefaultAlphabetUnicode[src[pos]][0];
535  dest[current++] = GSM_DefaultAlphabetUnicode[src[pos]][1];
536  }
537  dest[current++]=0;
538  dest[current]=0;
539 #ifdef DEBUG
541 #endif
542 }
static unsigned char GSM_DefaultAlphabetUnicode[128+1][2]
Definition: coding.c:438
void DumpMessageText(GSM_Debug_Info *d, const unsigned char *message, const size_t messagesize)
Definition: debug.c:371
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
GSM_Debug_Info GSM_global_debug
Definition: debug.c:33
static unsigned char GSM_DefaultAlphabetCharsExtension[][3]
Definition: coding.c:483

§ DecodeISO88591()

void DecodeISO88591 ( unsigned char *  dest,
const char *  src,
size_t  len 
)

Definition at line 282 of file coding.c.

Referenced by ReadVCALText().

283 {
284  size_t i;
285 
286  for (i = 0; i < len; i++) {
287  /* Hack for Euro sign */
288  if ((unsigned char)src[i] == 0x80) {
289  dest[2 * i] = 0x20;
290  dest[(2 * i) + 1] = 0xac;
291  } else {
292  dest[2 * i] = 0;
293  dest[(2 * i) + 1] = src[i];
294  }
295  }
296  dest[2 * i] = 0;
297  dest[(2 * i) + 1] = 0;
298 }

§ DecodeISO88591QuotedPrintable()

void DecodeISO88591QuotedPrintable ( unsigned char *  dest,
const unsigned char *  src,
size_t  len 
)

Definition at line 1889 of file coding.c.

References DecodeWithHexBinAlphabet().

Referenced by ReadVCALText().

1890 {
1891  size_t i = 0, j = 0;
1892 
1893  while (i < len) {
1894  if (src[i] == '=' && i + 2 < len
1895  && DecodeWithHexBinAlphabet(src[i + 1]) != -1
1896  && DecodeWithHexBinAlphabet(src[i + 2]) != -1) {
1897  dest[j++] = 0;
1898  dest[j++] = 16 * DecodeWithHexBinAlphabet(src[i + 1]) + DecodeWithHexBinAlphabet(src[i + 2]);
1899  i += 2;
1900  } else {
1901  dest[j++] = 0;
1902  dest[j++] = src[i];
1903  }
1904  i++;
1905  }
1906  dest[j++] = 0;
1907  dest[j] = 0;
1908 }
int DecodeWithHexBinAlphabet(unsigned char mychar)
Definition: coding.c:361

§ DecodeSpecialChars()

char* DecodeSpecialChars ( char *  dest,
const char *  buffer 
)

Definition at line 159 of file coding.c.

160 {
161  int Pos=0, Pos2=0, level=0;
162 
163  while (buffer[Pos]!=0x00) {
164  dest[Pos2] = buffer[Pos];
165  switch (level) {
166  case 0:
167  if (buffer[Pos] == '\\') {
168  level = 1;
169  } else {
170  Pos2++;
171  }
172  break;
173  case 1:
174  if (buffer[Pos] == 'n') dest[Pos2] = 10;
175  if (buffer[Pos] == 'r') dest[Pos2] = 13;
176  if (buffer[Pos] == '\\') dest[Pos2] = '\\';
177  Pos2++;
178  level = 0;
179  }
180  Pos++;
181  }
182  dest[Pos2] = 0;
183  return dest;
184 }

§ DecodeUnicodeSpecialChars()

unsigned char* DecodeUnicodeSpecialChars ( unsigned char *  dest,
const unsigned char *  buffer 
)

Definition at line 121 of file coding.c.

122 {
123  int Pos=0, Pos2=0, level=0;
124 
125  while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) {
126  dest[Pos2*2] = buffer[Pos*2];
127  dest[Pos2*2+1] = buffer[Pos*2+1];
128  switch (level) {
129  case 0:
130  if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
131  level = 1;
132  } else {
133  Pos2++;
134  }
135  break;
136  case 1:
137  if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'n') {
138  dest[Pos2*2] = 0;
139  dest[Pos2*2+1] = 10;
140  } else
141  if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'r') {
142  dest[Pos2*2] = 0;
143  dest[Pos2*2+1] = 13;
144  } else
145  if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
146  dest[Pos2*2] = 0;
147  dest[Pos2*2+1] = '\\';
148  }
149  Pos2++;
150  level = 0;
151  }
152  Pos++;
153  }
154  dest[Pos2*2] = 0;
155  dest[Pos2*2+1] = 0;
156  return dest;
157 }

§ DecodeUnicodeSpecialNOKIAChars()

void DecodeUnicodeSpecialNOKIAChars ( unsigned char *  dest,
const unsigned char *  src,
size_t  len 
)

Definition at line 1401 of file coding.c.

Referenced by GSM_DecodeNokiaRTTLRingtone(), GSM_DecodePDUFrame(), and GSM_DecodeSMSFrameText().

1402 {
1403  size_t i=0,current=0;
1404 
1405  for (i=0;i<len;i++) {
1406  switch (src[2*i]) {
1407  case 0x00:
1408  switch (src[2*i+1]) {
1409  case 0x01:
1410  dest[current++] = 0x00;
1411  dest[current++] = '~';
1412  break;
1413  case '~':
1414  dest[current++] = 0x00;
1415  dest[current++] = '~';
1416  dest[current++] = 0x00;
1417  dest[current++] = '~';
1418  break;
1419  default:
1420  dest[current++] = src[i*2];
1421  dest[current++] = src[i*2+1];
1422  }
1423  break;
1424  default:
1425  dest[current++] = src[i*2];
1426  dest[current++] = src[i*2+1];
1427  }
1428  }
1429  dest[current++] = 0x00;
1430  dest[current] = 0x00;
1431 }

§ DecodeUTF7()

void DecodeUTF7 ( unsigned char *  dest,
const unsigned char *  src,
size_t  len 
)

Definition at line 2051 of file coding.c.

References DecodeBASE64(), and EncodeWithUnicodeAlphabet().

Referenced by ReadVCALText().

2052 {
2053  size_t i=0,j=0,z,p;
2054  wchar_t ret;
2055 
2056  while (i<=len) {
2057  if (len-5>=i) {
2058  if (src[i] == '+') {
2059  z=0;
2060  while (src[z+i+1] != '-' && z+i+1<len) z++;
2061  p=DecodeBASE64(src+i+1, dest+j, z);
2062  if (p%2 != 0) p--;
2063  j+=p;
2064  i+=z+2;
2065  } else {
2066  i+=EncodeWithUnicodeAlphabet(&src[i], &ret);
2067  dest[j++] = (ret >> 8) & 0xff;
2068  dest[j++] = ret & 0xff;
2069  }
2070  } else {
2071  i+=EncodeWithUnicodeAlphabet(&src[i], &ret);
2072  dest[j++] = (ret >> 8) & 0xff;
2073  dest[j++] = ret & 0xff;
2074  }
2075  }
2076  dest[j++] = 0;
2077  dest[j] = 0;
2078 }
int EncodeWithUnicodeAlphabet(const unsigned char *src, wchar_t *dest)
Definition: coding.c:198
int DecodeBASE64(const char *Input, unsigned char *Output, const size_t Length)
Definition: coding.c:2149

§ DecodeWithBCDAlphabet()

int DecodeWithBCDAlphabet ( unsigned char  value)

Definition at line 323 of file coding.c.

Referenced by GSM_DecodeSMSDateTime().

324 {
325  return 10*(value & 0x0f)+(value >> 4);
326 }

§ DecodeWithHexBinAlphabet()

int DecodeWithHexBinAlphabet ( unsigned char  mychar)

Definition at line 361 of file coding.c.

Referenced by DecodeHexBin(), DecodeHexUnicode(), DecodeISO88591QuotedPrintable(), and DecodeUTF8QuotedPrintable().

362 {
363  if (mychar >= 'A' && mychar <= 'F')
364  return mychar - 'A' + 10;
365 
366  if (mychar >= 'a' && mychar <= 'f')
367  return mychar - 'a' + 10;
368 
369  if (mychar >= '0' && mychar <= '9')
370  return mychar - '0';
371 
372  return -1;
373 }

§ DecodeWithUnicodeAlphabet()

int DecodeWithUnicodeAlphabet ( wchar_t  value,
unsigned char *  dest 
)

Converts single character from wchar_t to unicode.

Definition at line 210 of file coding.c.

Referenced by DecodeUnicode(), and myiswspace().

211 {
212  int retval;
213 
214  switch (retval = wctomb(dest, src)) {
215  case -1:
216  *dest = '?';
217  return 1;
218  default:
219  return retval;
220  }
221 }

§ DecodeXMLUTF8()

void DecodeXMLUTF8 ( unsigned char *  dest,
const char *  src,
size_t  len 
)

Decodes UTF-8 text with XML entities to Unicode.

Definition at line 1966 of file coding.c.

References dbgprintf, DecodeUTF8(), and EncodeWithUTF8Alphabet().

1967 {
1968  char *tmp;
1969  char *pos, *pos_end;
1970  const char *lastpos;
1971  char *entity;
1972  unsigned long long int c;
1973  int tmplen;
1974 
1975  /* Allocate buffer */
1976  tmp = (char *)calloc(2 * len, sizeof(char));
1977  if (tmp == NULL) {
1978  /* We have no memory for XML decoding */
1979  DecodeUTF8(dest, src, len);
1980  return;
1981  }
1982  if (src == NULL) {
1983  *dest = 0;
1984  free(tmp);
1985  return;
1986  }
1987 
1988  /* Find ampersand and decode the */
1989  lastpos = src;
1990  while ((*lastpos != 0) && ((pos = strchr(lastpos, '&')) != NULL)) {
1991  /* Store current string */
1992  strncat(tmp, lastpos, pos - lastpos);
1993  lastpos = pos;
1994  /* Skip ampersand */
1995  pos++;
1996  /* Detect end of string */
1997  if (*pos == 0) break;
1998  /* Find entity length */
1999  pos_end = strchr(pos, ';');
2000  if (pos_end - pos > 6 || pos_end == NULL) {
2001  if (pos_end == NULL) {
2002  dbgprintf(NULL, "No entity end found, ignoring!\n");
2003  } else {
2004  dbgprintf(NULL, "Too long html entity, ignoring!\n");
2005  }
2006  strncat(tmp, lastpos, 1);
2007  lastpos++;
2008  continue;
2009  }
2010  /* Create entity */
2011  /* strndup would be better, but not portable */
2012  entity = strdup(pos);
2013  if (entity == NULL) break;
2014  entity[pos_end - pos] = 0;
2015  dbgprintf(NULL, "Found XML entity: %s\n", entity);
2016  if (entity[0] == '#') {
2017  if (entity[1] == 'x' || entity[1] == 'X') {
2018  c = strtoull(entity + 2, NULL, 16);
2019  } else {
2020  c = strtoull(entity + 1, NULL, 10);
2021  }
2022  dbgprintf(NULL, "Unicode char 0x%04llx\n", c);
2023  tmplen = strlen(tmp);
2024  tmplen += EncodeWithUTF8Alphabet(c, tmp + tmplen);
2025  tmp[tmplen] = 0;
2026  } else if (strcmp(entity, "amp") == 0) {
2027  strcat(tmp, "&");
2028  } else if (strcmp(entity, "apos") == 0) {
2029  strcat(tmp, "'");
2030  } else if (strcmp(entity, "gt") == 0) {
2031  strcat(tmp, ">");
2032  } else if (strcmp(entity, "lt") == 0) {
2033  strcat(tmp, "<");
2034  } else if (strcmp(entity, "quot") == 0) {
2035  strcat(tmp, "\"");
2036  } else {
2037  dbgprintf(NULL, "Could not decode XML entity!\n");
2038  strncat(tmp, lastpos, pos_end - pos + 1);
2039  }
2040  free(entity);
2041  entity=NULL;
2042  lastpos = pos_end + 1;
2043  }
2044  /* Copy rest of string */
2045  strcat(tmp, lastpos);
2046  DecodeUTF8(dest, tmp, strlen(tmp));
2047  free(tmp);
2048  tmp=NULL;
2049 }
void DecodeUTF8(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:1947
#define dbgprintf
Definition: debug.h:72
int EncodeWithUTF8Alphabet(unsigned long src, unsigned char *ret)
Definition: coding.c:1752

§ EncodeBASE64()

void EncodeBASE64 ( const unsigned char *  Input,
char *  Output,
const size_t  Length 
)

Definition at line 2118 of file coding.c.

References EncodeBASE64Block().

Referenced by VC_StoreBase64().

2119 {
2120  unsigned char in[3], out[4];
2121  size_t i, pos = 0, len, outpos = 0;
2122 
2123  while (pos < Length) {
2124  len = 0;
2125  for (i = 0; i < 3; i++) {
2126  in[i] = 0;
2127  if (pos < Length) {
2128  in[i] = Input[pos];
2129  len++;
2130  pos++;
2131  }
2132  }
2133  if(len) {
2134  EncodeBASE64Block(in, out, len);
2135  for (i = 0; i < 4; i++) Output[outpos++] = out[i];
2136  }
2137  }
2138 
2139  Output[outpos] = 0;
2140 }
static void EncodeBASE64Block(const unsigned char in[3], char out[4], const size_t len)
Definition: coding.c:2107

§ EncodeBASE64Block()

static void EncodeBASE64Block ( const unsigned char  in[3],
char  out[4],
const size_t  len 
)
static

Definition at line 2107 of file coding.c.

Referenced by EncodeBASE64().

2108 {
2109  /* BASE64 translation Table as described in RFC1113 */
2110  unsigned char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2111 
2112  out[0] = cb64[ in[0] >> 2 ];
2113  out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
2114  out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
2115  out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
2116 }

§ EncodeBCD()

void EncodeBCD ( unsigned char *  dest,
const unsigned char *  src,
size_t  len,
gboolean  fill 
)

Definition at line 342 of file coding.c.

Referenced by GSM_PackSemiOctetNumber(), and NOKIA_EncodeNetworkCode().

343 {
344  size_t i,current=0;
345 
346  for (i = 0; i < len; i++) {
347  if (i & 0x01) {
348  dest[current]=dest[current] | ((src[i]-'0') << 4);
349  current++;
350  } else {
351  dest[current]=src[i]-'0';
352  }
353  }
354 
355  /* When fill is set: if number consist of odd number of digits,
356  we fill last bits in last byte with 0x0f
357  */
358  if (fill && (len & 0x01)) dest[current]=dest[current] | 0xf0;
359 }

§ EncodeDefault()

void EncodeDefault ( unsigned char *  dest,
const unsigned char *  src,
size_t *  len,
gboolean  UseExtensions,
unsigned char *  ExtraAlphabet 
)

Definition at line 831 of file coding.c.

References ConvertTable, DumpMessageText(), FALSE, GSM_DefaultAlphabetCharsExtension, GSM_DefaultAlphabetUnicode, GSM_global_debug, and TRUE.

Referenced by GSM_EncodeAlcatelMultiPartSMS(), GSM_EncodeMultiPartSMS(), and GSM_EncodeSMSFrameText().

832 {
833  size_t i,current=0;
834  int j,z;
835  char ret;
836  gboolean FoundSpecial,FoundNormal;
837 
838 #ifdef DEBUG
839  DumpMessageText(&GSM_global_debug, src, (*len)*2);
840 #endif
841 
842  for (i = 0; i < *len; i++) {
843  FoundSpecial = FALSE;
844  j = 0;
845  while (GSM_DefaultAlphabetCharsExtension[j][0]!=0x00 && UseExtensions) {
846  if (src[i*2] == GSM_DefaultAlphabetCharsExtension[j][1] &&
847  src[i*2+1] == GSM_DefaultAlphabetCharsExtension[j][2]) {
848  dest[current++] = 0x1b;
849  dest[current++] = GSM_DefaultAlphabetCharsExtension[j][0];
850  FoundSpecial = TRUE;
851  break;
852  }
853  j++;
854  }
855  if (!FoundSpecial) {
856  ret = '?';
857  FoundNormal = FALSE;
858  j = 0;
859  while (GSM_DefaultAlphabetUnicode[j][1]!=0x00) {
860  if (src[i*2] == GSM_DefaultAlphabetUnicode[j][0] &&
861  src[i*2+1] == GSM_DefaultAlphabetUnicode[j][1]) {
862  ret = j;
863  FoundNormal = TRUE;
864  break;
865  }
866  j++;
867  }
868  if (ExtraAlphabet!=NULL && !FoundNormal) {
869  j = 0;
870  while (ExtraAlphabet[j] != 0x00 || ExtraAlphabet[j+1] != 0x00 || ExtraAlphabet[j+2] != 0x00) {
871  if (ExtraAlphabet[j+1] == src[i*2] &&
872  ExtraAlphabet[j+2] == src[i*2 + 1]) {
873  ret = ExtraAlphabet[j];
874  FoundSpecial = TRUE;
875  break;
876  }
877  j=j+3;
878  }
879  }
880  if (!FoundNormal && !FoundSpecial) {
881  j = 0;
882  FoundNormal = FALSE;
883  while (ConvertTable[j*4] != 0x00 ||
884  ConvertTable[j*4+1] != 0x00) {
885  if (src[i*2] == ConvertTable[j*4] &&
886  src[i*2+1] == ConvertTable[j*4+1]) {
887  z = 0;
888  while (GSM_DefaultAlphabetUnicode[z][1]!=0x00) {
889  if (ConvertTable[j*4+2] == GSM_DefaultAlphabetUnicode[z][0] &&
890  ConvertTable[j*4+3] == GSM_DefaultAlphabetUnicode[z][1]) {
891  ret = z;
892  FoundNormal = TRUE;
893  break;
894  }
895  z++;
896  }
897  if (FoundNormal) break;
898  }
899  j++;
900  }
901  }
902  dest[current++]=ret;
903  }
904  }
905  dest[current]=0;
906 #ifdef DEBUG
907  DumpMessageText(&GSM_global_debug, dest, current);
908 #endif
909 
910  *len = current;
911 }
static unsigned char ConvertTable[]
Definition: coding.c:551
static unsigned char GSM_DefaultAlphabetUnicode[128+1][2]
Definition: coding.c:438
void DumpMessageText(GSM_Debug_Info *d, const unsigned char *message, const size_t messagesize)
Definition: debug.c:371
int gboolean
Definition: gammu-types.h:23
GSM_Debug_Info GSM_global_debug
Definition: debug.c:33
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28
static unsigned char GSM_DefaultAlphabetCharsExtension[][3]
Definition: coding.c:483

§ EncodeHexBin()

void EncodeHexBin ( char *  dest,
const unsigned char *  src,
size_t  len 
)

Encodes text to hexadecimal binary representation.

Definition at line 426 of file coding.c.

References EncodeWithHexBinAlphabet().

Referenced by EncodeHexUnicode().

427 {
428  size_t i, outpos = 0;
429 
430  for (i = 0; i < len; i++) {
431  dest[outpos++] = EncodeWithHexBinAlphabet(src[i] >> 4);
432  dest[outpos++] = EncodeWithHexBinAlphabet(src[i] & 0xF);
433  }
434  dest[outpos] = 0;
435 }
char EncodeWithHexBinAlphabet(int digit)
Definition: coding.c:375

§ EncodeSpecialChars()

char* EncodeSpecialChars ( char *  dest,
const char *  buffer 
)

Definition at line 94 of file coding.c.

95 {
96  int Pos=0, Pos2=0;
97 
98  while (buffer[Pos]!=0x00) {
99  switch (buffer[Pos]) {
100  case 10:
101  dest[Pos2++] = '\\';
102  dest[Pos2++] = 'n';
103  break;
104  case 13:
105  dest[Pos2++] = '\\';
106  dest[Pos2++] = 'r';
107  break;
108  case '\\':
109  dest[Pos2++] = '\\';
110  dest[Pos2++] = '\\';
111  break;
112  default:
113  dest[Pos2++] = buffer[Pos];
114  }
115  Pos++;
116  }
117  dest[Pos2] = 0;
118  return dest;
119 }

§ EncodeUnicodeSpecialChars()

unsigned char* EncodeUnicodeSpecialChars ( unsigned char *  dest,
const unsigned char *  buffer 
)

Definition at line 41 of file coding.c.

42 {
43  int Pos=0, Pos2=0;
44 
45  while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) {
46  if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 10) {
47  dest[Pos2*2] = 0x00;
48  dest[Pos2*2+1] = '\\';
49  Pos2++;
50  dest[Pos2*2] = 0x00;
51  dest[Pos2*2+1] = 'n';
52  Pos2++;
53  } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 13) {
54  dest[Pos2*2] = 0x00;
55  dest[Pos2*2+1] = '\\';
56  Pos2++;
57  dest[Pos2*2] = 0x00;
58  dest[Pos2*2+1] = 'r';
59  Pos2++;
60  } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
61  dest[Pos2*2] = 0x00;
62  dest[Pos2*2+1] = '\\';
63  Pos2++;
64  dest[Pos2*2] = 0x00;
65  dest[Pos2*2+1] = '\\';
66  Pos2++;
67  } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == ';') {
68  dest[Pos2*2] = 0x00;
69  dest[Pos2*2+1] = '\\';
70  Pos2++;
71  dest[Pos2*2] = 0x00;
72  dest[Pos2*2+1] = ';';
73  Pos2++;
74  } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == ',') {
75  dest[Pos2*2] = 0x00;
76  dest[Pos2*2+1] = '\\';
77  Pos2++;
78  dest[Pos2*2] = 0x00;
79  dest[Pos2*2+1] = ',';
80  Pos2++;
81  } else {
82  dest[Pos2*2] = buffer[Pos*2];
83  dest[Pos2*2+1] = buffer[Pos*2+1];
84  Pos2++;
85  }
86  Pos++;
87  }
88  dest[Pos2*2] = 0;
89  dest[Pos2*2+1] = 0;
90  return dest;
91 }

§ EncodeUnicodeSpecialNOKIAChars()

void EncodeUnicodeSpecialNOKIAChars ( unsigned char *  dest,
const unsigned char *  src,
size_t  len 
)

Definition at line 1367 of file coding.c.

References FALSE, and TRUE.

Referenced by GSM_EncodeNokiaRTTLRingtone(), and GSM_EncodeSMSFrameText().

1368 {
1369  size_t i,current = 0;
1370  gboolean special=FALSE;
1371 
1372  for (i = 0; i < len; i++) {
1373  if (special) {
1374  if (src[i*2] == 0x00 && src[i*2+1] == '~') {
1375  dest[current++] = 0x00;
1376  dest[current++] = '~';
1377  } else {
1378  dest[current++] = 0x00;
1379  dest[current++] = 0x01;
1380  dest[current++] = src[i*2];
1381  dest[current++] = src[i*2+1];
1382  }
1383  special = FALSE;
1384  } else {
1385  if (src[i*2] == 0x00 && src[i*2+1] == '~') {
1386  special = TRUE;
1387  } else {
1388  dest[current++] = src[i*2];
1389  dest[current++] = src[i*2+1];
1390  }
1391  }
1392  }
1393  if (special) {
1394  dest[current++] = 0x00;
1395  dest[current++] = 0x01;
1396  }
1397  dest[current++] = 0x00;
1398  dest[current] = 0x00;
1399 }
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28

§ EncodeWithBCDAlphabet()

unsigned char EncodeWithBCDAlphabet ( int  value)

Definition at line 315 of file coding.c.

Referenced by GSM_EncodeSMSDateTime().

316 {
317  div_t division;
318 
319  division=div(value,10);
320  return ( ( (value-division.quot*10) & 0x0f) << 4) | (division.quot & 0xf);
321 }

§ EncodeWithHexBinAlphabet()

char EncodeWithHexBinAlphabet ( int  digit)

Definition at line 375 of file coding.c.

Referenced by EncodeHexBin().

376 {
377  if (digit >= 0 && digit <= 9) return '0'+(digit);
378  if (digit >=10 && digit <=15) return 'A'+(digit-10);
379  return 0;
380 }

§ EncodeWithUnicodeAlphabet()

int EncodeWithUnicodeAlphabet ( const unsigned char *  value,
wchar_t dest 
)

Converts single character from unicode to wchar_t.

Definition at line 198 of file coding.c.

Referenced by DecodeUTF7(), DecodeUTF8(), DecodeUTF8QuotedPrintable(), and EncodeUnicode().

199 {
200  int retval;
201 
202  switch (retval = mbtowc(dest, src, MB_CUR_MAX)) {
203  case -1 :
204  case 0 : return 1;
205  default : return retval;
206  }
207 }

§ FindDefaultAlphabetLen()

void FindDefaultAlphabetLen ( const unsigned char *  src,
size_t *  srclen,
size_t *  smslen,
size_t  maxlen 
)

Definition at line 914 of file coding.c.

References FALSE, GSM_DefaultAlphabetCharsExtension, and TRUE.

Referenced by GSM_AddSMS_Text_UDH(), GSM_EncodeMultiPartSMS(), and GSM_Find_Free_Used_SMS2().

915 {
916  size_t current=0,j,i;
917  gboolean FoundSpecial;
918 
919  i = 0;
920  while (src[i*2] != 0x00 || src[i*2+1] != 0x00) {
921  FoundSpecial = FALSE;
922  j = 0;
923  while (GSM_DefaultAlphabetCharsExtension[j][0]!=0x00) {
924  if (src[i*2] == GSM_DefaultAlphabetCharsExtension[j][1] &&
925  src[i*2+1] == GSM_DefaultAlphabetCharsExtension[j][2]) {
926  FoundSpecial = TRUE;
927  if (current+2 > maxlen) {
928  *srclen = i;
929  *smslen = current;
930  return;
931  }
932  current+=2;
933  break;
934  }
935  j++;
936  }
937  if (!FoundSpecial) {
938  if (current+1 > maxlen) {
939  *srclen = i;
940  *smslen = current;
941  return;
942  }
943  current++;
944  }
945  i++;
946  }
947  *srclen = i;
948  *smslen = current;
949 }
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28
static unsigned char GSM_DefaultAlphabetCharsExtension[][3]
Definition: coding.c:483

§ GetBit()

int GetBit ( unsigned char *  Buffer,
size_t  BitNum 
)

Definition at line 1248 of file coding.c.

Referenced by AddBuffer(), GetBuffer(), GetBufferI(), GetBufferInt(), and GSM_IsPointBitmap().

1249 {
1250  return Buffer[BitNum / 8] & (1 << (7 - (BitNum % 8)));
1251 }

§ GetBuffer()

void GetBuffer ( unsigned char *  Source,
size_t *  CurrentBit,
unsigned char *  Destination,
size_t  BitsToProcess 
)

Definition at line 1311 of file coding.c.

References ClearBit(), GetBit(), and SetBit().

Referenced by GSM_DecodeNokiaRTTLRingtone().

1315 {
1316  size_t i=0;
1317 
1318  while (i!=BitsToProcess) {
1319  if (GetBit(Source, (*CurrentBit)+i)) {
1320  SetBit(Destination, i);
1321  } else {
1322  ClearBit(Destination, i);
1323  }
1324  i++;
1325  }
1326  (*CurrentBit) = (*CurrentBit) + BitsToProcess;
1327 }
int ClearBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1258
int SetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1253
int GetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1248

§ GetBufferI()

void GetBufferI ( unsigned char *  Source,
size_t *  CurrentBit,
int *  result,
size_t  BitsToProcess 
)

Definition at line 1345 of file coding.c.

References GetBit().

1349 {
1350  size_t l=0,z,i=0;
1351 
1352  z = 1<<(BitsToProcess-1);
1353 
1354  while (i!=BitsToProcess) {
1355  if (GetBit(Source, (*CurrentBit)+i)) l=l+z;
1356  z=z>>1;
1357  i++;
1358  }
1359  *result=l;
1360  (*CurrentBit) = (*CurrentBit) + i;
1361 }
int GetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1248

§ GetBufferInt()

void GetBufferInt ( unsigned char *  Source,
size_t *  CurrentBit,
int *  integer,
size_t  BitsToProcess 
)

Definition at line 1329 of file coding.c.

References GetBit().

Referenced by GSM_DecodeNokiaRTTLRingtone().

1333 {
1334  size_t l=0,z=128,i=0;
1335 
1336  while (i!=BitsToProcess) {
1337  if (GetBit(Source, (*CurrentBit)+i)) l=l+z;
1338  z=z/2;
1339  i++;
1340  }
1341  *integer=l;
1342  (*CurrentBit) = (*CurrentBit) + i;
1343 }
int GetBit(unsigned char *Buffer, size_t BitNum)
Definition: coding.c:1248

§ GSM_GetVCSLine()

GSM_Error GSM_GetVCSLine ( char **  OutBuffer,
char *  Buffer,
size_t *  Pos,
size_t  MaxLen,
gboolean  MergeLines 
)

Gets VCS line from buffer.

Parameters
MergeLinesDetermine whether merge lines as vCard style continuation or quoted printable continutaion.
BufferData source to parse.
PosCurrent position in data.
OutBufferPointer to buffer pointer, which will be allocated.
MaxLenMaximal length of data to process.
Returns
ERR_NONE on success, ERR_MOREMEMORY if buffer is too small.

Definition at line 1656 of file coding.c.

References ERR_MOREMEMORY, ERR_NONE, FALSE, and TRUE.

Referenced by GSM_DecodeVCARD().

1657 {
1658  gboolean skip = FALSE;
1659  gboolean quoted_printable = FALSE;
1660  gboolean was_cr = FALSE, was_lf = FALSE;
1661  size_t pos=0;
1662  int tmp=0;
1663  size_t OutLen = 200;
1664 
1665  *OutBuffer = (char *)malloc(OutLen);
1666  if (*OutBuffer == NULL) return ERR_MOREMEMORY;
1667  (*OutBuffer)[0] = 0;
1668  pos = 0;
1669  if (Buffer == NULL) return ERR_NONE;
1670  while ((*Pos) < MaxLen) {
1671  switch (Buffer[*Pos]) {
1672  case 0x00:
1673  return ERR_NONE;
1674  case 0x0A:
1675  case 0x0D:
1676  if (skip) {
1677  if (Buffer[*Pos] == 0x0d) {
1678  if (was_cr && skip) return ERR_NONE;
1679  was_cr = TRUE;
1680  } else {
1681  if (was_lf && skip) return ERR_NONE;
1682  was_lf = TRUE;
1683  }
1684  }
1685  if (pos != 0 && !skip) {
1686  if (MergeLines) {
1687  /* (Quote printable new line) Does string end with = ? */
1688  if ((*OutBuffer)[pos - 1] == '=' && quoted_printable) {
1689  pos--;
1690  (*OutBuffer)[pos] = 0;
1691  skip = TRUE;
1692  was_cr = (Buffer[*Pos] == 0x0d);
1693  was_lf = (Buffer[*Pos] == 0x0a);
1694  break;
1695  }
1696  /* (vCard continuation) Next line start with space? */
1697  tmp = *Pos + 1;
1698  if (Buffer[*Pos + 1] == 0x0a || Buffer[*Pos + 1] == 0x0d) {
1699  tmp += 1;
1700  }
1701  if (Buffer[tmp] == ' ') {
1702  *Pos = tmp;
1703  break;
1704  }
1705  }
1706  return ERR_NONE;
1707  }
1708  break;
1709  default:
1710  /* Detect quoted printable for possible escaping */
1711  if (Buffer[*Pos] == ':' &&
1712  strstr(*OutBuffer, ";ENCODING=QUOTED-PRINTABLE") != NULL) {
1713  quoted_printable = TRUE;
1714  }
1715  skip = FALSE;
1716  (*OutBuffer)[pos] = Buffer[*Pos];
1717  pos++;
1718  (*OutBuffer)[pos] = 0;
1719  if (pos + 2 >= OutLen) {
1720  OutLen += 100;
1721  *OutBuffer = (char *)realloc(*OutBuffer, OutLen);
1722  if (*OutBuffer == NULL) return ERR_MOREMEMORY;
1723  }
1724  }
1725  (*Pos)++;
1726  }
1727  return ERR_NONE;
1728 }
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28

§ GSM_PackSemiOctetNumber()

int GSM_PackSemiOctetNumber ( const unsigned char *  Number,
unsigned char *  Output,
gboolean  semioctet 
)

Packing some phone numbers (SMSC, SMS destination and others)

See GSM 03.40 9.1.1: 1 byte - length of number given in semioctets or bytes (when given in bytes, includes one byte for byte with number format). Returned by function (set semioctet to TRUE, if want result in semioctets). 1 byte - format of number (see GSM_NumberType in coding.h). Returned in unsigned char *Output. n bytes - 2n or 2n-1 semioctets with number. Returned in unsigned char *Output.

1 semioctet = 4 bits = half of byte

First byte is used for saving type of number. See GSM 03.40 section 9.1.2.5

Definition at line 1125 of file coding.c.

References DecodeUnicode(), EncodeBCD(), GSM_PackSevenBitsToEight(), NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN, NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN, TRUE, and UnicodeLength().

Referenced by GSM_EncodeSMSFrame(), and NOKIA_EncodeDateTime().

1126 {
1127  unsigned char format;
1128  int length, i, skip = 0;
1129  unsigned char *buffer;
1130 
1131  length = UnicodeLength(Number);
1132  buffer = (unsigned char*)malloc(length + 2);
1133 
1134  if (buffer == NULL) {
1135  return 0;
1136  }
1137 
1138  DecodeUnicode(Number, buffer);
1139 
1140  /* Checking for format number */
1141  if (buffer[0] == '+') {
1143  skip = 1;
1144  } else if (buffer[0] == '0' && buffer[1] == '0') {
1146  skip = 2;
1147  } else if (buffer[0] == '+' && buffer[1] == '0' && buffer[2] == '0') {
1148  /* This is obviously wrong, but try to cope with that */
1150  skip = 3;
1151  } else {
1153  }
1154  for (i = 0; i < length; i++) {
1155  /* If there is something which can not be in normal
1156  * number, mark it as alphanumberic */
1157  if (strchr("+0123456789*#pP", buffer[i]) == NULL) {
1159  }
1160  }
1161 
1166  Output[0]=format;
1167 
1168  /* After number type we will have number. GSM 03.40 section 9.1.2 */
1169  switch (format) {
1171  length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2;
1172  if (strlen(buffer)==7) length--;
1173  break;
1175  length -= skip;
1176  EncodeBCD (Output+1, buffer + skip, length, TRUE);
1177  break;
1178  default:
1179  EncodeBCD (Output+1, buffer, length, TRUE);
1180  break;
1181  }
1182 
1183  free(buffer);
1184 
1185  if (semioctet) return length;
1186 
1187  /* Convert number of semioctets to number of chars */
1188  if (length % 2) length++;
1189  return length / 2 + 1;
1190 }
void EncodeBCD(unsigned char *dest, const unsigned char *src, size_t len, gboolean fill)
Definition: coding.c:342
int GSM_PackSevenBitsToEight(size_t offset, const unsigned char *input, unsigned char *output, size_t length)
Definition: coding.c:993
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
void DecodeUnicode(const unsigned char *src, char *dest)
Definition: coding.c:223
#define TRUE
Definition: gammu-types.h:28

§ GSM_PackSevenBitsToEight()

int GSM_PackSevenBitsToEight ( size_t  offset,
const unsigned char *  input,
unsigned char *  output,
size_t  length 
)

Definition at line 993 of file coding.c.

Referenced by GSM_EncodeAlcatelMultiPartSMS(), GSM_EncodeMultiPartSMS(), GSM_EncodeSMSFrameText(), and GSM_PackSemiOctetNumber().

994 {
995  /* (c) by Pavel Janik and Pawel Kot */
996 
997  unsigned char *output_pos = output; /* Current pointer to the output buffer */
998  const unsigned char *input_pos = input; /* Current pointer to the input buffer */
999  int Bits; /* Number of bits directly copied to
1000  * the output buffer */
1001  Bits = (7 + offset) % 8;
1002 
1003  /* If we don't begin with 0th bit, we will write only a part of the
1004  first octet */
1005  if (offset) {
1006  *output_pos = 0x00;
1007  output_pos++;
1008  }
1009 
1010  while ((size_t)(input_pos - input) < length) {
1011  unsigned char Byte = *input_pos;
1012 
1013  *output_pos = Byte >> (7 - Bits);
1014  /* If we don't write at 0th bit of the octet, we should write
1015  a second part of the previous octet */
1016  if (Bits != 7)
1017  *(output_pos-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1);
1018 
1019  Bits--;
1020 
1021  if (Bits == -1) Bits = 7; else output_pos++;
1022 
1023  input_pos++;
1024  }
1025  return (output_pos - output);
1026 }

§ GSM_UnpackEightBitsToSeven()

int GSM_UnpackEightBitsToSeven ( size_t  offset,
size_t  in_length,
size_t  out_length,
const unsigned char *  input,
unsigned char *  output 
)

Definition at line 953 of file coding.c.

References ByteMask.

Referenced by GSM_DecodePDUFrame(), GSM_DecodeSMSFrameText(), and GSM_UnpackSemiOctetNumber().

955 {
956  /* (c) by Pavel Janik and Pawel Kot */
957 
958  unsigned char *output_pos = output; /* Current pointer to the output buffer */
959  const unsigned char *input_pos = input; /* Current pointer to the input buffer */
960  unsigned char Rest = 0x00;
961  size_t Bits;
962 
963  Bits = offset ? offset : 7;
964 
965  while ((size_t)(input_pos - input) < in_length) {
966 
967  *output_pos = ((*input_pos & ByteMask) << (7 - Bits)) | Rest;
968  Rest = *input_pos >> Bits;
969 
970  /* If we don't start from 0th bit, we shouldn't go to the
971  next char. Under *output_pos we have now 0 and under Rest -
972  _first_ part of the char. */
973  if ((input_pos != input) || (Bits == 7)) output_pos++;
974  input_pos++;
975 
976  if ((size_t)(output_pos - output) >= out_length) break;
977 
978  /* After reading 7 octets we have read 7 full characters but
979  we have 7 bits as well. This is the next character */
980  if (Bits == 1) {
981  *output_pos = Rest;
982  output_pos++;
983  Bits = 7;
984  Rest = 0x00;
985  } else {
986  Bits--;
987  }
988  }
989 
990  return output_pos - output;
991 }
#define ByteMask
Definition: coding.c:951

§ GSM_UnpackSemiOctetNumber()

GSM_Error GSM_UnpackSemiOctetNumber ( GSM_Debug_Info di,
unsigned char *  retval,
const unsigned char *  Number,
size_t *  pos,
size_t  bufferlength,
gboolean  semioctet 
)

Definition at line 1028 of file coding.c.

References DecodeBCD(), EncodeUnicode(), ERR_NONE, ERR_UNKNOWN, GSM_MAX_NUMBER_LENGTH, GSM_UnpackEightBitsToSeven(), NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN, and smfprintf().

Referenced by GSM_DecodePDUFrame(), GSM_DecodeSMSFrame(), and NOKIA_EncodeDateTime().

1029 {
1030  unsigned char Buffer[GSM_MAX_NUMBER_LENGTH + 1];
1031  size_t length = Number[*pos];
1032  GSM_Error ret = ERR_NONE;
1033 
1034  smfprintf(di, "Number Length=%ld\n", (long)length);
1035 
1036  if (length == 0) {
1037  strcpy(Buffer, "");
1038  goto out;
1039  }
1040 
1041  /* Default ouput on error */
1042  strcpy(Buffer, "<NOT DECODED>");
1043 
1044  if (length > bufferlength) {
1045  smfprintf(di, "Number too long!\n");
1046  return ERR_UNKNOWN;
1047  }
1048 
1049  if (semioctet) {
1050  /* Convert number of semioctets to number of chars */
1051  if (length % 2) length++;
1052  length=length / 2 + 1;
1053  }
1054 
1055  /* Check length */
1056  if (length > GSM_MAX_NUMBER_LENGTH) {
1057  smfprintf(di, "Number too big, not decoding! (Length=%ld, MAX=%d)\n", (long)length, GSM_MAX_NUMBER_LENGTH);
1058  ret = ERR_UNKNOWN;
1059  goto out;
1060  }
1061 
1062  /*without leading byte with format of number*/
1063  length--;
1064 
1065  smfprintf(di, "Number type %02x (%d %d %d %d|%d %d %d %d)\n", Number[*pos + 1],
1066  Number[*pos + 1] & 0x80 ? 1 : 0,
1067  Number[*pos + 1] & 0x40 ? 1 : 0,
1068  Number[*pos + 1] & 0x20 ? 1 : 0,
1069  Number[*pos + 1] & 0x10 ? 1 : 0,
1070  Number[*pos + 1] & 0x08 ? 1 : 0,
1071  Number[*pos + 1] & 0x04 ? 1 : 0,
1072  Number[*pos + 1] & 0x02 ? 1 : 0,
1073  Number[*pos + 1] & 0x01 ? 1 : 0
1074  );
1075 
1076  if ((Number[*pos + 1] & 0x80) == 0) {
1077  smfprintf(di, "Numbering plan not supported!\n");
1078  ret = ERR_UNKNOWN;
1079  goto out;
1080  }
1081 
1082  switch ((Number[*pos + 1] & 0x70)) {
1084  if (length > 6) length++;
1085  smfprintf(di, "Alphanumeric number, length %ld\n", (long)length);
1086  GSM_UnpackEightBitsToSeven(0, length, length, Number+*pos+2, Buffer);
1087  Buffer[length]=0;
1088  break;
1090  smfprintf(di, "International number\n");
1091  Buffer[0]='+';
1092  DecodeBCD(Buffer+1,Number+*pos+2, length);
1093  break;
1094  default:
1095  DecodeBCD (Buffer, Number+*pos+2, length);
1096  break;
1097  }
1098 
1099  smfprintf(di, "Len %ld\n", (long)length);
1100 out:
1101  EncodeUnicode(retval,Buffer,strlen(Buffer));
1102  if (semioctet) {
1103  *pos += 2 + ((Number[*pos] + 1) / 2);
1104  } else {
1105  *pos += 1 + Number[*pos];
1106  }
1107  return ret;
1108 }
void DecodeBCD(unsigned char *dest, const unsigned char *src, size_t len)
Definition: coding.c:328
#define GSM_MAX_NUMBER_LENGTH
Definition: gammu-limits.h:77
GSM_Error
Definition: gammu-error.h:23
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
int GSM_UnpackEightBitsToSeven(size_t offset, size_t in_length, size_t out_length, const unsigned char *input, unsigned char *output)
Definition: coding.c:953
int smfprintf(GSM_Debug_Info *d, const char *format,...)
Definition: debug.c:240

§ MyGetLine()

GSM_Error MyGetLine ( char *  Buffer,
size_t *  Pos,
char *  OutBuffer,
size_t  MaxLen,
size_t  MaxOutLen,
gboolean  MergeLines 
)

Gets line from buffer.

Parameters
MergeLinesDetermine whether merge lines as vCard style continuation or quoted printable continutaion.
BufferData source to parse.
PosCurrent position in data.
OutBufferBuffer where line will be written.
MaxLenMaximal length of data to process.
MaxOutLenSize of output buffer.
Returns
ERR_NONE on success, ERR_MOREMEMORY if buffer is too small.

Definition at line 1580 of file coding.c.

References ERR_MOREMEMORY, ERR_NONE, FALSE, and TRUE.

Referenced by GSM_DecodeVCALENDAR_VTODO(), GSM_DecodeVNOTE(), and GSM_JADFindLine().

1581 {
1582  gboolean skip = FALSE;
1583  gboolean quoted_printable = FALSE;
1584  gboolean was_cr = FALSE, was_lf = FALSE;
1585  size_t pos;
1586  int tmp;
1587 
1588  OutBuffer[0] = 0;
1589  pos = 0;
1590  if (Buffer == NULL) return ERR_NONE;
1591  for (; (*Pos) < MaxLen; (*Pos)++) {
1592  switch (Buffer[*Pos]) {
1593  case 0x00:
1594  return ERR_NONE;
1595  case 0x0A:
1596  case 0x0D:
1597  if (skip) {
1598  if (Buffer[*Pos] == 0x0d) {
1599  if (was_cr && skip) return ERR_NONE;
1600  was_cr = TRUE;
1601  } else {
1602  if (was_lf && skip) return ERR_NONE;
1603  was_lf = TRUE;
1604  }
1605  } else {
1606  if (MergeLines) {
1607  /* (Quote printable new line) Does string end with = ? */
1608  if (quoted_printable && pos > 0 && OutBuffer[pos - 1] == '=') {
1609  pos--;
1610  OutBuffer[pos] = 0;
1611  skip = TRUE;
1612  was_cr = (Buffer[*Pos] == 0x0d);
1613  was_lf = (Buffer[*Pos] == 0x0a);
1614  break;
1615  }
1616  /* (vCard continuation) Next line start with space? */
1617  tmp = *Pos + 1;
1618  if (Buffer[*Pos + 1] == 0x0a || Buffer[*Pos + 1] == 0x0d) {
1619  tmp += 1;
1620  }
1621  if (Buffer[tmp] == ' ') {
1622  *Pos = tmp;
1623  break;
1624  }
1625  /* We ignore empty lines in this mode */
1626  if (pos == 0) {
1627  continue;
1628  }
1629  }
1630  if (Buffer[*Pos] == 0x0d && (*Pos)+1 < MaxLen && Buffer[*Pos + 1] == 0x0a) {
1631  /* Skip \r\n */
1632  (*Pos) += 2;
1633  } else {
1634  /* Skip single \r or \n */
1635  (*Pos)++;
1636  }
1637  return ERR_NONE;
1638  }
1639  break;
1640  default:
1641  /* Detect quoted printable for possible escaping */
1642  if (Buffer[*Pos] == ':' &&
1643  strstr(OutBuffer, ";ENCODING=QUOTED-PRINTABLE") != NULL) {
1644  quoted_printable = TRUE;
1645  }
1646  skip = FALSE;
1647  OutBuffer[pos] = Buffer[*Pos];
1648  pos++;
1649  OutBuffer[pos] = 0;
1650  if (pos + 1 >= MaxOutLen) return ERR_MOREMEMORY;
1651  }
1652  }
1653  return ERR_NONE;
1654 }
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28

§ myiswspace()

gboolean myiswspace ( unsigned const char *  src)

Definition at line 1470 of file coding.c.

References DecodeWithUnicodeAlphabet(), FALSE, and TRUE.

Referenced by INI_ReadFile().

1471 {
1472 #ifndef HAVE_ISWSPACE
1473  int o;
1474  unsigned char dest[10];
1475 #endif
1476  wchar_t wc;
1477 
1478  wc = src[1] | (src[0] << 8);
1479 
1480 #ifndef HAVE_ISWSPACE
1481  o = DecodeWithUnicodeAlphabet(wc, dest);
1482  if (o == 1) {
1483  if (isspace(((int)dest[0]))!=0) return TRUE;
1484  return FALSE;
1485  }
1486  return FALSE;
1487 #else
1488  if (iswspace(wc)) return TRUE;
1489  return FALSE;
1490 #endif
1491 }
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28
int DecodeWithUnicodeAlphabet(wchar_t src, unsigned char *dest)
Definition: coding.c:210

§ ReverseUnicodeString()

void ReverseUnicodeString ( unsigned char *  String)

Definition at line 1209 of file coding.c.

1210 {
1211  int j = 0;
1212  unsigned char byte1, byte2;
1213 
1214  while (String[j]!=0x00 || String[j+1]!=0x00) {
1215  byte1 = String[j];
1216  byte2 = String[j+1];
1217  String[j+1] = byte1;
1218  String[j] = byte2;
1219  j=j+2;
1220  }
1221  String[j] = 0;
1222  String[j+1] = 0;
1223 }

§ SetBit()

int SetBit ( unsigned char *  Buffer,
size_t  BitNum 
)

Definition at line 1253 of file coding.c.

Referenced by AddBuffer(), GetBuffer(), and GSM_SetPointBitmap().

1254 {
1255  return Buffer[BitNum / 8] |= 1 << (7 - (BitNum % 8));
1256 }

§ StringToDouble()

void StringToDouble ( char *  text,
double *  d 
)

Definition at line 1731 of file coding.c.

References FALSE, and TRUE.

Referenced by GSM_CreateFirmwareNumber().

1732 {
1733  gboolean before=TRUE;
1734  double multiply = 1;
1735  unsigned int i;
1736 
1737  *d = 0;
1738  for (i=0;i<strlen(text);i++) {
1739  if (isdigit((int)text[i])) {
1740  if (before) {
1741  (*d)=(*d)*10+(text[i]-'0');
1742  } else {
1743  multiply=multiply*0.1;
1744  (*d)=(*d)+(text[i]-'0')*multiply;
1745  }
1746  }
1747  if (text[i]=='.' || text[i]==',') before=FALSE;
1748  }
1749 }
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
#define TRUE
Definition: gammu-types.h:28

Variable Documentation

§ ConvertTable

unsigned char ConvertTable[]
static

Definition at line 551 of file coding.c.

Referenced by EncodeDefault().

§ GSM_DefaultAlphabetCharsExtension

unsigned char GSM_DefaultAlphabetCharsExtension[][3]
static
Initial value:
=
{
{0x0a,0x00,0x0c},
{0x14,0x00,0x5e},
{0x28,0x00,0x7b},
{0x29,0x00,0x7d},
{0x2f,0x00,0x5c},
{0x3c,0x00,0x5b},
{0x3d,0x00,0x7E},
{0x3e,0x00,0x5d},
{0x40,0x00,0x7C},
{0x65,0x20,0xAC},
{0x00,0x00,0x00}
}

Definition at line 483 of file coding.c.

Referenced by DecodeDefault(), EncodeDefault(), and FindDefaultAlphabetLen().

§ GSM_DefaultAlphabetUnicode

unsigned char GSM_DefaultAlphabetUnicode[128+1][2]
static

Definition at line 438 of file coding.c.

Referenced by DecodeDefault(), and EncodeDefault().