summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/misc
authorzautrix <zautrix>2004-10-05 11:13:51 (UTC)
committer zautrix <zautrix>2004-10-05 11:13:51 (UTC)
commit50ab40e1e02ad7c65c17a78d08116a808b1257aa (patch) (side-by-side diff)
tree0d1939e2297fa7bbd8e1f2030f154463854164c6 /gammu/emb/common/misc
parentcf8616f64f20e5448d4ff644f7cc15750cf3f85f (diff)
downloadkdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.zip
kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.gz
kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.bz2
updated to latest gammu version
Diffstat (limited to 'gammu/emb/common/misc') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/misc/coding/coding.c177
-rw-r--r--gammu/emb/common/misc/coding/coding.h27
-rw-r--r--gammu/emb/common/misc/coding/md5.c2
-rw-r--r--gammu/emb/common/misc/misc.c19
-rw-r--r--gammu/emb/common/misc/misc.h8
5 files changed, 209 insertions, 24 deletions
diff --git a/gammu/emb/common/misc/coding/coding.c b/gammu/emb/common/misc/coding/coding.c
index 62543ac..b30b645 100644
--- a/gammu/emb/common/misc/coding/coding.c
+++ b/gammu/emb/common/misc/coding/coding.c
@@ -1,66 +1,219 @@
/* (c) 2002-2004 by Marcin Wiacek, Michal Cihar and others */
-/* based on some work from MyGnokii and Gnokii */
+/* based on some work from MyGnokii (www.mwiacek.com) */
+/* based on some work from Gnokii (www.gnokii.org)
+ * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
+ * GNU GPL version 2 or later
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#ifndef __OpenBSD__
# include <wctype.h>
#endif
#ifdef WIN32
# include "windows.h"
#endif
#include "../misc.h"
#include "coding.h"
+/* function changes #10 #13 chars to \n \r */
+char *EncodeUnicodeSpecialChars(unsigned char *buffer)
+{
+ int Pos=0, Pos2=0;
+ static unsigned char Buf[20000];
+
+ while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) {
+ if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 10) {
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = '\\';
+ Pos2++;
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = 'n';
+ Pos2++;
+ } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 13) {
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = '\\';
+ Pos2++;
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = 'r';
+ Pos2++;
+ } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = '\\';
+ Pos2++;
+ Buf[Pos2*2] = 0x00;
+ Buf[Pos2*2+1] = '\\';
+ Pos2++;
+ } else {
+ Buf[Pos2*2] = buffer[Pos*2];
+ Buf[Pos2*2+1] = buffer[Pos*2+1];
+ Pos2++;
+ }
+ Pos++;
+ }
+ Buf[Pos2*2] = 0;
+ Buf[Pos2*2+1] = 0;
+ return Buf;
+}
+
+/* function changes #10 #13 chars to \n \r */
+char *EncodeSpecialChars(unsigned char *buffer)
+{
+ int Pos=0, Pos2=0;
+ static unsigned char Buf[10000];
+
+ while (buffer[Pos]!=0x00) {
+ switch (buffer[Pos]) {
+ case 10:
+ Buf[Pos2++] = '\\';
+ Buf[Pos2++] = 'n';
+ break;
+ case 13:
+ Buf[Pos2++] = '\\';
+ Buf[Pos2++] = 'r';
+ break;
+ case '\\':
+ Buf[Pos2++] = '\\';
+ Buf[Pos2++] = '\\';
+ break;
+ default:
+ Buf[Pos2++] = buffer[Pos];
+ }
+ Pos++;
+ }
+ Buf[Pos2] = 0;
+ return Buf;
+}
+
+char *DecodeUnicodeSpecialChars(unsigned char *buffer)
+{
+ int Pos=0, Pos2=0, level=0;
+ static unsigned char Buf[10000];
+
+ while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) {
+ Buf[Pos2*2] = buffer[Pos*2];
+ Buf[Pos2*2+1] = buffer[Pos*2+1];
+ switch (level) {
+ case 0:
+ if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
+ level = 1;
+ } else {
+ Pos2++;
+ }
+ break;
+ case 1:
+ if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'n') {
+ Buf[Pos2*2] = 0;
+ Buf[Pos2*2+1] = 10;
+ }
+ if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'r') {
+ Buf[Pos2*2] = 0;
+ Buf[Pos2*2+1] = 13;
+ }
+ if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') {
+ Buf[Pos2*2] = 0;
+ Buf[Pos2*2+1] = '\\';
+ }
+ Pos2++;
+ level = 0;
+ }
+ Pos++;
+ }
+ Buf[Pos2*2] = 0;
+ Buf[Pos2*2+1] = 0;
+ return Buf;
+}
+
+char *DecodeSpecialChars(unsigned char *buffer)
+{
+ int Pos=0, Pos2=0, level=0;
+ static unsigned char Buf[10000];
+
+ while (buffer[Pos]!=0x00) {
+ Buf[Pos2] = buffer[Pos];
+ switch (level) {
+ case 0:
+ if (buffer[Pos] == '\\') {
+ level = 1;
+ } else {
+ Pos2++;
+ }
+ break;
+ case 1:
+ if (buffer[Pos] == 'n') Buf[Pos2] = 10;
+ if (buffer[Pos] == 'r') Buf[Pos2] = 13;
+ if (buffer[Pos] == '\\') Buf[Pos2] = '\\';
+ Pos2++;
+ level = 0;
+ }
+ Pos++;
+ }
+ Buf[Pos2] = 0;
+ return Buf;
+}
+
+char *mystrcasestr(unsigned const char *a, unsigned const char *b)
+{
+ unsigned char A[2000], B[200];
+ int i;
+
+ memset(A,0,sizeof(A));
+ memset(B,0,sizeof(B));
+ for (i=0;i<(int)strlen(a);i++) A[i] = tolower(a[i]);
+ for (i=0;i<(int)strlen(b);i++) B[i] = tolower(b[i]);
+
+ return strstr(A,B);
+}
+
unsigned int UnicodeLength(const unsigned char *str)
{
unsigned int len = 0;
if (str == NULL) return 0;
while(str[len*2] != 0 || str[len*2+1] != 0) len++;
return len;
}
/* Convert Unicode char saved in src to dest */
unsigned int EncodeWithUnicodeAlphabet(const unsigned char *src, wchar_t *dest)
{
char retval;
switch (retval = mbtowc(dest, src, MB_CUR_MAX)) {
case -1 :
case 0 : return 1;
default : return retval;
}
}
/* Convert Unicode char saved in src to dest */
unsigned int DecodeWithUnicodeAlphabet(wchar_t src, unsigned char *dest)
{
int retval;
switch (retval = wctomb(dest, src)) {
case -1:
*dest = '?';
return 1;
default:
return retval;
}
}
void DecodeUnicode (const unsigned char *src, unsigned char *dest)
{
int i=0,o=0;
wchar_t wc;
while (src[(2*i)+1]!=0x00 || src[2*i]!=0x00) {
wc = src[(2*i)+1] | (src[2*i] << 8);
o += DecodeWithUnicodeAlphabet(wc, dest + o);
i++;
}
dest[o]=0;
@@ -541,165 +694,165 @@ int GSM_PackSevenBitsToEight(int offset, unsigned char *input, unsigned char *ou
unsigned char *OUTPUT = output; /* Current pointer to the output buffer */
unsigned char *INPUT = input; /* Current pointer to the input buffer */
int Bits; /* Number of bits directly copied to
* the output buffer */
Bits = (7 + offset) % 8;
/* If we don't begin with 0th bit, we will write only a part of the
first octet */
if (offset) {
*OUTPUT = 0x00;
OUTPUT++;
}
while ((INPUT - input) < length) {
unsigned char Byte = *INPUT;
*OUTPUT = Byte >> (7 - Bits);
/* If we don't write at 0th bit of the octet, we should write
a second part of the previous octet */
if (Bits != 7)
*(OUTPUT-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1);
Bits--;
if (Bits == -1) Bits = 7; else OUTPUT++;
INPUT++;
}
return (OUTPUT - output);
#else
return 0;
#endif
}
void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, bool semioctet)
{
unsigned char Buffer[50] = "";
int length = Number[0];
if (semioctet) {
/* Convert number of semioctets to number of chars */
if (length % 2) length++;
length=length / 2 + 1;
}
/*without leading byte with format of number*/
length--;
- switch (Number[1]) {
- case NUMBER_ALPHANUMERIC:
+ switch ((Number[1] & 112)) {
+ case (NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN & 112):
if (length > 6) length++;
dbgprintf("Alphanumeric number, length %i\n",length);
GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer);
Buffer[length]=0;
break;
- case NUMBER_INTERNATIONAL:
+ case (NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN & 112):
dbgprintf("International number\n");
Buffer[0]='+';
DecodeBCD(Buffer+1,Number+2, length);
break;
default:
dbgprintf("Default number %02x\n",Number[1]);
DecodeBCD (Buffer, Number+2, length);
break;
}
EncodeUnicode(retval,Buffer,strlen(Buffer));
}
/**
* 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
*/
int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool semioctet)
{
unsigned char format, buffer[50];
int length, i;
length=UnicodeLength(Number);
memcpy(buffer,DecodeUnicodeString(Number),length+1);
/* Checking for format number */
- format = NUMBER_UNKNOWN;
+ format = NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN;
for (i=0;i<length;i++) {
/* first byte is '+'. Number can be international */
if (i==0 && buffer[i]=='+') {
- format=NUMBER_INTERNATIONAL;
+ format=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN;
} else {
/*char is not number. It must be alphanumeric*/
- if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC;
+ if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN;
}
}
/**
* First byte is used for saving type of number. See GSM 03.40
* section 9.1.2.5
*/
Output[0]=format;
/* After number type we will have number. GSM 03.40 section 9.1.2 */
switch (format) {
- case NUMBER_ALPHANUMERIC:
+ case NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN:
length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2;
if (strlen(buffer)==7) length--;
break;
- case NUMBER_INTERNATIONAL:
+ case NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN:
length--;
EncodeBCD (Output+1, buffer+1, length, true);
break;
default:
EncodeBCD (Output+1, buffer, length, true);
break;
}
if (semioctet) return length;
/* Convert number of semioctets to number of chars */
if (length % 2) length++;
return length / 2 + 1;
}
void CopyUnicodeString(unsigned char *Dest, unsigned char *Source)
{
int j = 0;
while (Source[j]!=0x00 || Source[j+1]!=0x00) {
Dest[j] = Source[j];
Dest[j+1] = Source[j+1];
j=j+2;
}
Dest[j] = 0;
Dest[j+1] = 0;
}
/* Changes minor/major order in Unicode string */
void ReverseUnicodeString(unsigned char *String)
{
int j = 0;
unsigned char byte1, byte2;
while (String[j]!=0x00 || String[j+1]!=0x00) {
byte1 = String[j];
byte2 = String[j+1];
String[j+1] = byte1;
String[j] = byte2;
j=j+2;
}
String[j] = 0;
String[j+1] = 0;
}
/* All input is in Unicode. First char can show Unicode minor/major order.
Output is Unicode string in Gammu minor/major order */
void ReadUnicodeFile(unsigned char *Dest, unsigned char *Source)
@@ -874,193 +1027,193 @@ void EncodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *sr
}
}
if (special) {
dest[current++] = 0x00;
dest[current++] = 0x01;
}
dest[current++] = 0x00;
dest[current++] = 0x00;
}
void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, int len)
{
int i=0,current=0;
for (i=0;i<len;i++) {
switch (src[2*i]) {
case 0x00:
switch (src[2*i+1]) {
case 0x01:
dest[current++] = 0x00;
dest[current++] = '~';
break;
case '~':
dest[current++] = 0x00;
dest[current++] = '~';
dest[current++] = 0x00;
dest[current++] = '~';
break;
default:
dest[current++] = src[i*2];
dest[current++] = src[i*2+1];
}
break;
default:
dest[current++] = src[i*2];
dest[current++] = src[i*2+1];
}
}
dest[current++] = 0x00;
dest[current++] = 0x00;
}
bool mystrncasecmp(unsigned const char *a, unsigned const char *b, int num)
{
int i;
if (a == NULL || b == NULL) return false;
- num--;
+ if (num == 0) num = -1;
for (i = 0; i != num; i++) {
if (a[i] == 0x00 && b[i] == 0x00) return true;
if (a[i] == 0x00 || b[i] == 0x00) return false;
if (tolower(a[i]) != tolower(b[i])) return false;
}
return true;
}
/* Compares two Unicode strings without regarding to case.
* Return true, when they're equal
*/
bool mywstrncasecmp(unsigned const char *a, unsigned const char *b, int num)
{
int i;
wchar_t wc,wc2;
if (a == NULL || b == NULL) return false;
- num--;
+ if (num == 0) num = -1;
for (i = 0; i != num; i++) {
if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) && (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return true;
if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) || (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return false;
wc = a[i*2+1] | (a[i*2] << 8);
wc2 = b[i*2+1] | (b[i*2] << 8);
if (mytowlower(wc) != mytowlower(wc2)) return false;
}
return true;
}
/* wcscmp in Mandrake 9.0 is wrong */
bool mywstrncmp(unsigned const char *a, unsigned const char *b, int num)
{
int i=0;
while (1) {
if (a[i*2] != b[i*2] || a[i*2+1] != b[i*2+1]) return false;
if (a[i*2] == 0x00 && a[i*2+1] == 0x00) return true;
i++;
if (num == i) return true;
}
}
/* FreeBSD boxes 4.7-STABLE does't have it, although it's ANSI standard */
bool myiswspace(unsigned const char *src)
{
#ifndef HAVE_ISWSPACE
int o;
unsigned char dest[10];
#endif
wchar_t wc;
wc = src[1] | (src[0] << 8);
#ifndef HAVE_ISWSPACE
o = DecodeWithUnicodeAlphabet(wc, dest);
if (o == 1) {
if (isspace(((int)dest[0]))!=0) return true;
return false;
}
return false;
#else
return iswspace(wc);
#endif
}
/* FreeBSD boxes 4.7-STABLE does't have it, although it's ANSI standard */
int mytowlower(wchar_t c)
{
#ifndef HAVE_TOWLOWER
unsigned char dest[10];
DecodeWithUnicodeAlphabet(c, dest);
return tolower(dest[0]);
#else
return towlower(c);
#endif
}
/*
* Following code is based on wcsstr from the GNU C Library, original
* comment follows:
*/
/*
* The original strstr() file contains the following comment:
*
* My personal strstr() implementation that beats most other algorithms.
* Until someone tells me otherwise, I assume that this is the
* fastest implementation of strstr() in C.
* I deliberately chose not to comment it. You should have at least
* as much fun trying to understand it, as I had to write it :-).
*
* Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
-unsigned char *mystrstr (const unsigned char *haystack, const unsigned char *needle)
+unsigned char *mywstrstr (const unsigned char *haystack, const unsigned char *needle)
{
/* One crazy define to convert unicode used in Gammu to standard wchar_t */
#define tolowerwchar(x) (mytowlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) )))
register wchar_t b, c;
if ((b = tolowerwchar(*needle)) != L'\0') {
haystack -= 2; /* possible ANSI violation */
do {
haystack += 2;
if ((c = tolowerwchar(*haystack)) == L'\0')
goto ret0;
} while (c != b);
needle += 2;
if ((c = tolowerwchar(*needle)) == L'\0')
goto foundneedle;
needle += 2;
goto jin;
for (;;) {
register wchar_t a;
register const unsigned char *rhaystack, *rneedle;
do {
haystack += 2;
if ((a = tolowerwchar(*haystack)) == L'\0')
goto ret0;
if (a == b)
break;
haystack += 2;
if ((a = tolowerwchar(*haystack)) == L'\0')
goto ret0;
shloop: ;
} while (a != b);
jin: haystack += 2;
if ((a = tolowerwchar(*haystack)) == L'\0')
goto ret0;
if (a != c)
goto shloop;
rhaystack = haystack + 2;
haystack -= 2;
rneedle = needle;
if (tolowerwchar(*rhaystack) == (a = tolowerwchar(*rneedle)))
do {
if (a == L'\0')
diff --git a/gammu/emb/common/misc/coding/coding.h b/gammu/emb/common/misc/coding/coding.h
index d0c334d..4cf0038 100644
--- a/gammu/emb/common/misc/coding/coding.h
+++ b/gammu/emb/common/misc/coding/coding.h
@@ -1,133 +1,148 @@
/* (c) 2002-2004 by Marcin Wiacek and others */
#ifndef __coding_h
#define __coding_h
+#if defined(_MSC_VER) && defined(__cplusplus)
+ extern "C" {
+#endif
+
#include <stdlib.h>
#include "../misc.h"
#ifdef __OpenBSD__
typedef int wint_t;
#endif
/* ---------------------------- Unicode ------------------------------------ */
bool mywstrncasecmp (unsigned const char *a, unsigned const char *b, int num);
-unsigned char *mystrstr (unsigned const char *haystack, unsigned const char *needle);
+unsigned char *mywstrstr (unsigned const char *haystack, unsigned const char *needle);
bool mywstrncmp (unsigned const char *a, unsigned const char *b, int num);
bool myiswspace (unsigned const char *src);
int mytowlower (wchar_t c);
unsigned int EncodeWithUnicodeAlphabet (const unsigned char *value, wchar_t *dest);
unsigned int DecodeWithUnicodeAlphabet (wchar_t value, unsigned char *dest);
unsigned int UnicodeLength (const unsigned char *str);
unsigned char *DecodeUnicodeString (const unsigned char *src);
unsigned char *DecodeUnicodeConsole (const unsigned char *src);
void DecodeUnicode (const unsigned char *src, unsigned char *dest);
void EncodeUnicode (unsigned char *dest, const unsigned char *src, int len);
void CopyUnicodeString (unsigned char *Dest, unsigned char *Source);
void ReverseUnicodeString (unsigned char *String);
void ReadUnicodeFile (unsigned char *Dest, unsigned char *Source);
void DecodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len);
void EncodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len);
+char *EncodeUnicodeSpecialChars (unsigned char *buffer);
+char *DecodeUnicodeSpecialChars (unsigned char *buffer);
+
/* ------------------------------- BCD ------------------------------------- */
unsigned char EncodeWithBCDAlphabet (int value);
int DecodeWithBCDAlphabet (unsigned char value);
void DecodeBCD (unsigned char *dest, const unsigned char *src, int len);
void EncodeBCD (unsigned char *dest, const unsigned char *src, int len, bool fill);
/* ------------------------------ UTF7 ------------------------------------- */
void DecodeUTF7 (unsigned char *dest, const unsigned char *src, int len);
/* ------------------------------ UTF8 ------------------------------------- */
wchar_t DecodeWithUTF8Alphabet (unsigned char mychar3, unsigned char mychar4);
bool EncodeWithUTF8Alphabet (unsigned char mychar1, unsigned char mychar2, unsigned char *ret1, unsigned char *ret2);
bool EncodeUTF8QuotedPrintable (unsigned char *dest, const unsigned char *src);
void DecodeUTF8QuotedPrintable (unsigned char *dest, const unsigned char *src, int len);
bool EncodeUTF8 (unsigned char *dest, const unsigned char *src);
void DecodeUTF8 (unsigned char *dest, const unsigned char *src, int len);
/* ------------------------------- BASE64 ---------------------------------- */
void EncodeBASE64 (const unsigned char *Input, unsigned char *Output, int Length);
int DecodeBASE64 (const unsigned char *Input, unsigned char *Output, int Length);
/* ----------------------------- HexBin ------------------------------------ */
void DecodeHexBin (unsigned char *dest, const unsigned char *src, int len);
void EncodeHexBin (unsigned char *dest, const unsigned char *src, int len);
/* ----------------------------- HexUnicode -------------------------------- */
void DecodeHexUnicode (unsigned char *dest, const unsigned char *src, int len);
void EncodeHexUnicode (unsigned char *dest, const unsigned char *src, int len);
/* ---------------------- DefaultAlphabet for SMS -------------------------- */
void EncodeDefault (unsigned char *dest, const unsigned char *src, int *len, bool UseExtensions, unsigned char *ExtraAlphabet);
void DecodeDefault (unsigned char *dest, const unsigned char *src, int len, bool UseExtensions, unsigned char *ExtraAlphabet);
void FindDefaultAlphabetLen (const unsigned char *src, int *srclen, int *smslen, int maxlen);
int GSM_PackSevenBitsToEight (int offset, unsigned char *input, unsigned char *output, int length);
int GSM_UnpackEightBitsToSeven (int offset, int in_length, int out_length,
unsigned char *input, unsigned char *output);
/* ----------------- Phone numbers according to GSM specs ------------------ */
/**
* Enum to handle types of phones numbers like
* specified in GSM 03.40 section 9.1.2.5
*/
typedef enum {
/**
* Unknown number type
*/
- NUMBER_UNKNOWN = 0x81,
+ NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN = 0x81,
/**
* International number (full number with code of country)
*/
- NUMBER_INTERNATIONAL = 0x91,
+ NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN = 0x91,
/**
* Alphanumeric number (with chars too)
*/
- NUMBER_ALPHANUMERIC = 0xD0
+ NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN = 0xD0
/* specification give also other values */
} GSM_NumberType;
void GSM_UnpackSemiOctetNumber (unsigned char *retval, unsigned char *Number, bool semioctet);
int GSM_PackSemiOctetNumber (unsigned char *Number, unsigned char *Output, bool semioctet);
/* ---------------------------- Bits --------------------------------------- */
void BufferAlign (unsigned char *Destination, int *CurrentBit);
void BufferAlignNumber(int *CurrentBit);
void AddBuffer (unsigned char *Destination, int *CurrentBit, unsigned char *Source, int BitsToProcess);
void AddBufferByte(unsigned char *Destination, int *CurrentBit, unsigned char Source, int BitsToProcess);
void GetBuffer (unsigned char *Source, int *CurrentBit, unsigned char *Destination, int BitsToProcess);
void GetBufferInt (unsigned char *Source, int *CurrentBit, int *integer, int BitsToProcess);
void GetBufferI (unsigned char *Source, int *CurrentBit, int *result, int BitsToProcess);
int GetBit (unsigned char *Buffer, int BitNum);
int SetBit (unsigned char *Buffer, int BitNum);
int ClearBit (unsigned char *Buffer, int BitNum);
/* ---------------------------- Other -------------------------------------- */
void StringToDouble (char *text, double *d);
-bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num);
+bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num);
+char *mystrcasestr (unsigned const char *a, unsigned const char *b);
-void MyGetLine(unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen);
+void MyGetLine (unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen);
+
+char *EncodeSpecialChars(unsigned char *buffer);
+char *DecodeSpecialChars(unsigned char *buffer);
+
+#if defined(_MSC_VER) && defined(__cplusplus)
+ }
+#endif
#endif
/* How should editor hadle tabs in this file? Add editor commands here.
* vim: noexpandtab sw=8 ts=8 sts=8:
*/
diff --git a/gammu/emb/common/misc/coding/md5.c b/gammu/emb/common/misc/coding/md5.c
index 30fe33f..abb61be 100644
--- a/gammu/emb/common/misc/coding/md5.c
+++ b/gammu/emb/common/misc/coding/md5.c
@@ -1,49 +1,49 @@
-/* Taken from ReHash (see http://www.reichlsoft.de.vu/) and released
+/* Taken from ReHash (www.reichlsoft.de.vu) and released
* under GPL/LGPL with permission from ReHash author
* Dominik Reichl <dominik.reichl@t-online.de>, Germany
*/
/*
**********************************************************************
** MD5.cpp **
** **
** - Style modified by Tony Ray, January 2001 **
** Added support for randomizing initialization constants **
** - Style modified by Dominik Reichl, April 2003 **
** Optimized code **
** **
** MD5.c **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
**********************************************************************
*/
/*
**********************************************************************
** MD5.h -- Header file for implementation of MD5 **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
** Revised (for MD5): RLR 4/27/91 **
** -- G modified to have y&~z instead of y&z **
** -- FF, GG, HH modified to add in last register done **
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
** -- distinct additive constant for each step **
** -- round 4 added, working mod 7 **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** License to copy and use this software is granted provided that **
** it is identified as the "RSA Data Security, Inc. MD5 Message **
** Digest Algorithm" in all material mentioning or referencing this **
** software or this function. **
** **
** License is also granted to make and use derivative works **
** provided that such works are identified as "derived from the RSA **
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
** material mentioning or referencing the derived work. **
diff --git a/gammu/emb/common/misc/misc.c b/gammu/emb/common/misc/misc.c
index c2f09e4..7227e7b 100644
--- a/gammu/emb/common/misc/misc.c
+++ b/gammu/emb/common/misc/misc.c
@@ -1,61 +1,64 @@
/* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */
/* Checking used compiler (c) 2002 by Michal Cihar */
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#include <stdio.h>
#include <locale.h>
#include <sys/timeb.h>
#ifdef WIN32
# include "windows.h"
#endif
+#if defined(linux) || defined(__linux) || defined(__linux__)
+# include <sys/utsname.h>
+#endif
#include "../gsmstate.h"
#include "misc.h"
/* Based on article in Polish PC-Kurier 8/1998 page 104
* Archive on http://www.pckurier.pl
*/
char *DayOfWeek (int year, int month, int day)
{
int p,q,r,w;
static char DayOfWeekChar[10];
p=(14-month) / 12;
q=month+12*p-2;
r=year-p;
w=(day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
strcpy(DayOfWeekChar,"");
switch (w) {
case 0: strcpy(DayOfWeekChar,"Sun"); break;
case 1: strcpy(DayOfWeekChar,"Mon"); break;
case 2: strcpy(DayOfWeekChar,"Tue"); break;
case 3: strcpy(DayOfWeekChar,"Wed"); break;
case 4: strcpy(DayOfWeekChar,"Thu"); break;
case 5: strcpy(DayOfWeekChar,"Fri"); break;
case 6: strcpy(DayOfWeekChar,"Sat"); break;
}
return DayOfWeekChar;
}
void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet)
{
struct tm *now;
now = localtime(&timet);
Date->Year = now->tm_year;
Date->Month = now->tm_mon+1;
Date->Day = now->tm_mday;
Date->Hour = now->tm_hour;
Date->Minute = now->tm_min;
Date->Second = now->tm_sec;
}
void GSM_GetCurrentDateTime (GSM_DateTime *Date)
{
Fill_GSM_DateTime(Date, time(NULL));
if (Date->Year<1900) {
if (Date->Year>90) Date->Year = Date->Year+1900;
else Date->Year = Date->Year+2000;
@@ -185,101 +188,103 @@ char *OSDate (GSM_DateTime dt)
#endif
/* Based on article in Polish PC-Kurier 8/1998 page 104
* Archive on http://www.pckurier.pl
*/
p=(14-dt.Month) / 12;
q=dt.Month+12*p-2;
r=dt.Year-p;
w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
timeptr.tm_yday = 0; /* FIXME */
timeptr.tm_isdst = -1; /* FIXME */
timeptr.tm_year = dt.Year - 1900;
timeptr.tm_mon = dt.Month - 1;
timeptr.tm_mday = dt.Day;
timeptr.tm_hour = dt.Hour;
timeptr.tm_min = dt.Minute;
timeptr.tm_sec = dt.Second;
timeptr.tm_wday = w;
#ifdef _BSD_SOURCE
timeptr.tm_zone = NULL;
#endif
#ifdef WIN32
strftime(retval2, 200, "%#x", &timeptr);
#else
strftime(retval2, 200, "%x", &timeptr);
#endif
/* If don't have weekday name, include it */
strftime(retval, 200, "%A", &timeptr);
if (strstr(retval2,retval)==NULL) {
/* Check also for short name */
strftime(retval, 200, "%a", &timeptr);
if (strstr(retval2,retval)==NULL) {
strcat(retval2," (");
strcat(retval2,retval);
strcat(retval2,")");
}
}
#ifdef WIN32
setlocale(LC_ALL, ".ACP");
#endif
return retval2;
}
bool CheckDate(GSM_DateTime *date)
-{
- /* FIXME: This could also check if day is correct for selected month */
+{
+ const unsigned int days[]={31,29,31,30,31,30,31,31,30,31,30,31};
+
+ /* FIXME: This could also check for leap years */
return date->Year != 0 &&
- date->Month >= 1 && date->Month <= 12 &&
- date->Day >= 1 && date->Day <= 31;
+ date->Month >= 1 && date->Month <= 12 &&
+ date->Day >= 1 && date->Day <= days[date->Month];
}
bool CheckTime(GSM_DateTime *date)
{
return date->Hour <= 23 && date->Hour >= 0 &&
date->Minute <= 59 && date->Minute >= 0 &&
date->Second <= 59 && date->Second >= 0;
}
int GetLine(FILE *File, char *Line, int count)
{
int num;
if (fgets(Line, count, File) != NULL) {
num = strlen(Line) - 1;
while(1) {
if (Line[num] != '\n' && Line[num] != '\r') break;
if (num == 0) break;
Line[num--] = 0;
}
return strlen(Line);
}
return -1;
}
void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot)
{
int i,number=0,j;
bool whitespace=true, nowwhite;
for (i=0;i<MAX_LINES*2;i++) lines->numbers[i]=0;
for (i=0;i<messagesize;i++) {
nowwhite = false;
for (j=0;j<spaceslen;j++) {
if (whitespaces[j] == message[i]) {
nowwhite = true;
break;
}
}
if (whitespace) {
if (!nowwhite) {
lines->numbers[number]=i;
number++;
whitespace=false;
}
} else {
if (nowwhite) {
@@ -406,166 +411,170 @@ bool GSM_SetDebugLevel(char *info, Debug_Info *di)
if (!strcmp(info,"errors")) {di->dl = DL_TEXTERROR; return true;}
if (!strcmp(info,"textdate")) {di->dl = DL_TEXTDATE; return true;}
if (!strcmp(info,"textalldate")) {di->dl = DL_TEXTALLDATE; return true;}
if (!strcmp(info,"errorsdate")) {di->dl = DL_TEXTERRORDATE; return true;}
return false;
}
/* Dumps a message */
void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int messagesize)
{
int i,j=0,len=16;
unsigned char buffer[200];
if (df==NULL || messagesize == 0) return;
smfprintf(df, dl, "\n");
memset(buffer,0x20,sizeof(buffer));
buffer[len*5-1]=0;
for (i = 0; i < messagesize; i++) {
sprintf(buffer+j*4,"%02X",message[i]);
buffer[j*4+2] = 0x20;
if (isprint(message[i]) && message[i]!=0x09) {
if (j != len-1) buffer[j*4+2] = message[i];
buffer[(len-1)*4+j+3] = message[i];
} else {
buffer[(len-1)*4+j+3] = '.';
}
if (j != len-1 && i != messagesize-1) buffer[j*4+3] = '|';
if (j == len-1) {
smfprintf(df, dl, "%s\n", buffer);
memset(buffer,0x20,sizeof(buffer));
buffer[len*5-1]=0;
j = 0;
} else {
j++;
}
}
if (j != 0) smfprintf(df, dl, "%s\n", buffer);
}
char *GetOS(void)
{
#ifdef WIN32
OSVERSIONINFOEX Ver;
bool Extended = true;
#endif
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ struct utsname Ver;
+#endif
static char Buffer[100] = {0x00};
#ifdef WIN32
memset(&Ver,sizeof(OSVERSIONINFOEX),0);
Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
Extended = false;
Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
//#ifdef _MSC_VER
// Ver.dwMajorVersion = _winmajor;
// Ver.dwMinorVersion = _winminor;
// Ver.dwBuildNumber = _osver;
//#else
sprintf(Buffer, "Windows");
return Buffer;
//#endif
}
}
/* ----------------- 9x family ------------------ */
/* no info about Win95 SP1, Win95 OSR2.1, Win95 OSR2.5.... */
if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 950) {
sprintf(Buffer,"Win 95");
} else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1111) {
sprintf(Buffer,"Win 95 OSR2.x");
/* no info about Win98 SP1.... */
} else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 1998) {
sprintf(Buffer,"Win 98");
} else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 2222) {
sprintf(Buffer,"Win 98 SE");
} else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 90 && Ver.dwBuildNumber == 3000) {
sprintf(Buffer,"Win ME");
/* ---------------- NT family ------------------- */
} else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1381) {
sprintf(Buffer,"Win NT 4.0");
} else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 2195) {
sprintf(Buffer,"Win 2000");
} else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 1 && Ver.dwBuildNumber == 2600) {
sprintf(Buffer,"Win XP");
#if _MSC_VER > 1200 //6.0 has it undeclared
if (Extended) {
if (Ver.wSuiteMask & VER_SUITE_PERSONAL) {
sprintf(Buffer+strlen(Buffer)," Home");
} else {
sprintf(Buffer+strlen(Buffer)," Pro");
}
}
#endif
} else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 2) {
sprintf(Buffer,"Win 2003");
} else {
sprintf(Buffer, "Windows %i.%i.%i",Ver.dwMajorVersion,Ver.dwMinorVersion,Ver.dwBuildNumber);
}
if (Extended && Ver.wServicePackMajor != 0) {
sprintf(Buffer+strlen(Buffer)," SP%i",Ver.wServicePackMajor);
}
#elif defined(linux) || defined(__linux) || defined(__linux__)
- sprintf(Buffer, "Linux");
+ uname(&Ver);
+ sprintf(Buffer, "Linux, kernel %s",Ver.release);
#elif defined(__FreeBSD__)
sprintf(Buffer, "FreeBSD");
#elif defined(__NetBSD__)
sprintf(Buffer, "NetBSD");
#elif defined(__OpenBSD__)
sprintf(Buffer, "OpenBSD");
#elif defined(__GNU__)
sprintf(Buffer, "GNU/Hurd");
#elif defined(sun) || defined(__sun) || defined(__sun__)
# ifdef __SVR4
sprintf(Buffer, "Sun Solaris");
# else
sprintf(Buffer, "SunOS");
# endif
#elif defined(hpux) || defined(__hpux) || defined(__hpux__)
sprintf(Buffer, "HP-UX");
#elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__)
sprintf(Buffer, "DEC Ultrix");
#elif defined(sgi) || defined(__sgi)
sprintf(Buffer, "SGI Irix");
#elif defined(__osf__)
sprintf(Buffer, "OSF Unix");
#elif defined(bsdi) || defined(__bsdi__)
sprintf(Buffer, "BSDI Unix");
#elif defined(_AIX)
sprintf(Buffer, "AIX Unix");
#elif defined(_UNIXWARE)
sprintf(Buffer, "SCO Unixware");
#elif defined(DGUX)
sprintf(Buffer, "DG Unix");
#elif defined(__QNX__)
sprintf(Buffer, "QNX");
#endif
return Buffer;
}
char *GetCompiler(void)
{
static char Buffer[100] = {0x00};
#ifdef WIN32
# ifdef _MSC_VER
if (_MSC_VER == 1200) { //?
sprintf(Buffer, "MS VC 6.0");
} else if (_MSC_VER == 1300) {
sprintf(Buffer, "MS VC .NET 2002");
} else if (_MSC_VER == 1310) {
sprintf(Buffer, "MS VC .NET 2003");
diff --git a/gammu/emb/common/misc/misc.h b/gammu/emb/common/misc/misc.h
index 8b46170..c461001 100644
--- a/gammu/emb/common/misc/misc.h
+++ b/gammu/emb/common/misc/misc.h
@@ -1,53 +1,57 @@
/* (c) 2002-2004 by Marcin Wiacek */
#ifndef __misc_h
#define __misc_h
+#if defined(_MSC_VER) && defined(__cplusplus)
+ extern "C" {
+#endif
+
#include <stdio.h>
#include <time.h>
#ifdef WIN32
# include <windows.h>
#endif
#include "../config.h"
#ifndef __cplusplus
#ifndef false
# define false 0
#endif
#ifndef true
# define true !0
#endif
#ifndef bool
# define bool char
#endif
#endif /* __cplusplus */
#ifdef WIN32
# define my_sleep(x) ((x)<1000 ? Sleep(1) : Sleep((x)/1000))
#else
# define my_sleep(x) usleep(x)
#endif
#undef MAX
#define MAX(a,b) ((a)>(b) ? (a) : (b))
#undef MIN
#define MIN(a,b) ((a)<(b) ? (a) : (b))
/* ------------------------------------------------------------------------- */
#define MAX_LINES 50
int GetLine(FILE *File, char *Line, int count);
typedef struct {
int numbers[MAX_LINES*2];
} GSM_Lines;
void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot);
char *GetLineString(unsigned char *message, GSM_Lines lines, int start);
void CopyLineString(unsigned char *dest, unsigned char *src, GSM_Lines lines, int start);
/* ------------------------------------------------------------------------- */
typedef enum {
@@ -85,53 +89,57 @@ int dbgprintf(const char *format, ...);
#ifdef __GNUC__
__attribute__((format(printf, 3, 4)))
#endif
int smfprintf(FILE *f, Debug_Level dl, const char *format, ...);
void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int messagesize);
bool GSM_SetDebugLevel(char *info, Debug_Info *di);
/* ------------------------------------------------------------------------- */
/**
* Structure used for saving date and time
*/
typedef struct {
/**
* The difference between local time and GMT in hours
*/
int Timezone;
unsigned int Second;
unsigned int Minute;
unsigned int Hour;
unsigned int Day;
/**
* January = 1, February = 2, etc.
*/
unsigned int Month;
/**
* Complete year number. Not 03, but 2003
*/
unsigned int Year;
} GSM_DateTime;
void GSM_GetCurrentDateTime (GSM_DateTime *Date);
char *OSDateTime (GSM_DateTime dt, bool TimeZone);
char *OSDate (GSM_DateTime dt);
char *DayOfWeek (int year, int month, int day);
time_t Fill_Time_T (GSM_DateTime DT, int TZ);
void GetTimeDifference (unsigned long diff, GSM_DateTime *DT, bool Plus, int multi);
void Fill_GSM_DateTime (GSM_DateTime *Date, time_t timet);
bool CheckDate (GSM_DateTime *date);
bool CheckTime (GSM_DateTime *date);
char *GetCompiler(void);
char *GetOS(void);
+#if defined(_MSC_VER) && defined(__cplusplus)
+ }
+#endif
+
#endif
/* How should editor hadle tabs in this file? Add editor commands here.
* vim: noexpandtab sw=8 ts=8 sts=8:
*/