+++ /dev/null
-/*
-
- G N O K I I
-
- A Linux/Unix toolset and driver for Nokia mobile phones.
-
- Released under the terms of the GNU GPL, see file COPYING for more details.
-
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "gsm-common.h"
-#include "gsm-coding.h"
-
-#ifdef WIN32
- #include <windows.h>\r
-#else
- #include "devices/device.h"
-#endif\r
-
-/* Coding functions */
-#define NUMBER_OF_7_BIT_ALPHABET_ELEMENTS 128
-
-#ifndef USE_NLS
- static unsigned char GSM_DefaultAlphabet[NUMBER_OF_7_BIT_ALPHABET_ELEMENTS] = {
-
- /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
- /* Generally table shows chars in Latin 1, but not only - Greek
- chars are visible correctly in ... */
-
- '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec, // 0x08
- 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
-
-/* from v13@priest.com codes for Greek chars. Not confirmed and commented */
-// 0xc4, '_' , 0xd6, 0xc3, 0xcb, 0xd9, 0xd0, 0xd8,
-// 0xd3, 0xc8, 0xce, 0xcb, 0xc6, 0xe6, 0xdf, 0xc9, // 0x20
-
- '?', '_', '?', '?', '?', '?', '?', '?',
- '?', '?', '?', '?', 0xc6, 0xe6, 0xdf, 0xc9, // 0x20
- ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/', // 0x30
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', ':', ';', '<', '=', '>', '?', // 0x40
- 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
- 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
- };
-
- #ifndef WIN32
- /*Simple UNICODE decoding and encoding from/to iso-8859-2
- First version prepared by Martin Kacer <M.Kacer@sh.cvut.cz>
-
- Following table contains triplets:
- first unicode byte, second unicode byte, iso-8859-2 character*/
- unsigned char unicode_table[][3] =
- {
- /* C< D< E< N< R< S< T< Uo Z< */
- {0x01, 0x0C, 0xC8}, {0x01, 0x0E, 0xCF}, {0x01, 0x1A, 0xCC},
- {0x01, 0x47, 0xD2}, {0x01, 0x58, 0xD8}, {0x01, 0x60, 0xA9},
- {0x01, 0x64, 0xAB}, {0x01, 0x6E, 0xD9}, {0x01, 0x7D, 0xAE},
- /* c< d< e< n< r< s< t< uo z< */
- {0x01, 0x0D, 0xE8}, {0x01, 0x0F, 0xEF}, {0x01, 0x1B, 0xEC},
- {0x01, 0x48, 0xF2}, {0x01, 0x59, 0xF8}, {0x01, 0x61, 0xB9},
- {0x01, 0x65, 0xBB}, {0x01, 0x6F, 0xF9}, {0x01, 0x7E, 0xBE},
- /* A< A, C' D/ E, L< L' L/ */
- {0x01, 0x02, 0xC3}, {0x01, 0x04, 0xA1}, {0x01, 0x06, 0xC6},
- {0x01, 0x10, 0xD0}, {0x01, 0x18, 0xCA}, {0x01, 0x3D, 0xA5},
- {0x01, 0x39, 0xC5}, {0x01, 0x41, 0xA3},
- /* N' O" R' S' S, T, U" Z' Z. */
- {0x01, 0x43, 0xD1}, {0x01, 0x50, 0xD5}, {0x01, 0x54, 0xC0},
- {0x01, 0x5A, 0xA6}, {0x01, 0x5E, 0xAA}, {0x01, 0x62, 0xDE},
- {0x01, 0x70, 0xDB}, {0x01, 0x79, 0xAC}, {0x01, 0x7B, 0xAF},
- /* a< a, c' d/ e, l< l' l/ */
- {0x01, 0x03, 0xE3}, {0x01, 0x05, 0xB1}, {0x01, 0x07, 0xE6},
- {0x01, 0x11, 0xF0}, {0x01, 0x19, 0xEA}, {0x01, 0x3E, 0xB5},
- {0x01, 0x3A, 0xE5}, {0x01, 0x42, 0xB3},
- /* n' o" r' s' s, t, u" z' z. */
- {0x01, 0x44, 0xF1}, {0x01, 0x51, 0xF5}, {0x01, 0x55, 0xE0},
- {0x01, 0x5B, 0xB6}, {0x01, 0x5F, 0xBA}, {0x01, 0x63, 0xFE},
- {0x01, 0x71, 0xFB}, {0x01, 0x7A, 0xBC}, {0x01, 0x7C, 0xBF},
-
- {0x00, 0x00, 0x00}
- };
- #else
- unsigned char unicode_table[][3] =
- {
-
- /* o' */
- {0x00, 0xF3, 0xA2},
-
- /* O' */
- {0x00, 0xD3, 0xE0},
-
- /* A, C' E, L/ */
- {0x01, 0x04, 0xA4}, {0x01, 0x06, 0x8F},
- {0x01, 0x18, 0xA8},
- {0x01, 0x41, 0x9D},
- /* N' S' Z' Z. */
- {0x01, 0x43, 0xE3},
- {0x01, 0x5A, 0x97},
- {0x01, 0x79, 0x8D}, {0x01, 0x7B, 0xBD},
- /* a, c' e, l/ */
- {0x01, 0x05, 0xA5}, {0x01, 0x07, 0x86},
- {0x01, 0x19, 0xA9},
- {0x01, 0x42, 0x88},
- /* n' s' z' z. */
- {0x01, 0x44, 0xE4},
- {0x01, 0x5B, 0x98},
- {0x01, 0x7A, 0xAB}, {0x01, 0x7C, 0xBE},
-
- {0x00, 0x00, 0x00}
- };
- #endif
-
-unsigned char EncodeWithDefaultAlphabet(unsigned char value)
-{
- unsigned char i;
-
- if (value == '?') return 0x3f;
-
- for (i = 0; i < NUMBER_OF_7_BIT_ALPHABET_ELEMENTS; i++)
- if (GSM_DefaultAlphabet[i] == value)
- return i;
-
- return '?';
-}
-
-unsigned char DecodeWithDefaultAlphabet(unsigned char value)
-{
- return GSM_DefaultAlphabet[value];
-}
-
-wchar_t EncodeWithUnicodeAlphabet(unsigned char value)
-{
- wchar_t retval;
-
- int j;
-
- /*If character is not found, first unicode byte is set to zero
- and second one is the same as iso-8859-2 character*/
- retval = value | (0x00 << 8);
-
- for ( j = 0; unicode_table[j][2] != 0x00; ++j )
- if ( value == unicode_table[j][2] )
- {
- retval = unicode_table[j][1] | (unicode_table[j][0] << 8);
- break;
- }
-
- return retval;
-}
-
-unsigned char DecodeWithUnicodeAlphabet(wchar_t value)
-{
- unsigned char retval;
-
- int j;
-
- retval=value & 0xff; /* default is to cut off the first byte */
-
- for ( j = 0; unicode_table[j][2] != 0x00; ++j )
- if (((value >> 8) & 0xff) == unicode_table[j][0] &&
- (value & 0xff) == unicode_table[j][1] ) {
- retval = unicode_table[j][2];
- break;
- }
-
- return retval;
-}
-
-#else
-
- /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
- unsigned char GSM_DefaultAlphabetUnicode[NUMBER_OF_7_BIT_ALPHABET_ELEMENTS+1][2] =
- {
- {0x00,0x40},{0x00,0xa3},{0x00,0x24},{0x00,0xA5},
- {0x00,0xE8},{0x00,0xE9},{0x00,0xF9},{0x00,0xEC},//0x08
- {0x00,0xF2},{0x00,0xC7},{0x00,'\n'},{0x00,0xD8},
- {0x00,0xD9},{0x00,'\r'},{0x00,0xC5},{0x00,0xE5},
- {0x03,0x94},{0x00,0xb9}/*not exactly, but*/,{0x03,0xA6},{0x03,0x93},
- {0x03,0x9B},{0x03,0xA9},{0x03,0xA0},{0x03,0xA8},
- {0x03,0xA3},{0x03,0x98},{0x03,0x9E},{0x00,0xb9},/*not exactly, but*/
- {0x00,0xC6},{0x00,0xE6},{0x00,0xDF},{0x00,0xC9},//0x20
- {0x00,' ' },{0x00,'!' },{0x00,'\"'},{0x00,'#' },
- {0x00,0xA4},{0x00,'%' },{0x00,'&' },{0x00,'\''},
- {0x00,'(' },{0x00,')' },{0x00,'*' },{0x00,'+' },
- {0x00,',' },{0x00,'-' },{0x00,'.' },{0x00,'/' }, //0x30
- {0x00,'0' },{0x00,'1' },{0x00,'2' },{0x00,'3' },
- {0x00,'4' },{0x00,'5' },{0x00,'6' },{0x00,'7' },
- {0x00,'8' },{0x00,'9' },{0x00,':' },{0x00,';' },
- {0x00,'<' },{0x00,'=' },{0x00,'>' },{0x00,'?' }, //0x40
- {0x00,0xA1},{0x00,'A' },{0x00,'B' },{0x00,'C' },
- {0x00,'D' },{0x00,'E' },{0x00,'F' },{0x00,'G' },
- {0x00,'H' },{0x00,'I' },{0x00,'J' },{0x00,'K' },
- {0x00,'L' },{0x00,'M' },{0x00,'N' },{0x00,'O' },
- {0x00,'P' },{0x00,'Q' },{0x00,'R' },{0x00,'S' },
- {0x00,'T' },{0x00,'U' },{0x00,'V' },{0x00,'W' },
- {0x00,'X' },{0x00,'Y' },{0x00,'Z' },{0x00,0xC4},
- {0x00,0xD6},{0x00,0xD1},{0x00,0xDC},{0x00,0xA7},
- {0x00,0xBF},{0x00,'a' },{0x00,'b' },{0x00,'c' },
- {0x00,'d' },{0x00,'e' },{0x00,'f' },{0x00,'g' },
- {0x00,'h' },{0x00,'i' },{0x00,'j' },{0x00,'k' },
- {0x00,'l' },{0x00,'m' },{0x00,'n' },{0x00,'o' },
- {0x00,'p' },{0x00,'q' },{0x00,'r' },{0x00,'s' },
- {0x00,'t' },{0x00,'u' },{0x00,'v' },{0x00,'w' },
- {0x00,'x' },{0x00,'y' },{0x00,'z' },{0x00,0xE4},
- {0x00,0xF6},{0x00,0xF1},{0x00,0xFC},{0x00,0xE0},
- {0x00,0x00}
- };
-
-unsigned char EncodeWithDefaultAlphabet(unsigned char value)
-{
- unsigned char i;
-
- wchar_t value2;
-
- if (value == '?') return 0x3f;
-
- for (i = 0; i < NUMBER_OF_7_BIT_ALPHABET_ELEMENTS; i++) {
-
- value2 = GSM_DefaultAlphabetUnicode[i][1] | ( GSM_DefaultAlphabetUnicode[i][0] << 8);
-
- if (EncodeWithUnicodeAlphabet(value) == value2)
- return i;
- }
-
- return '?';
-}
-
-unsigned char DecodeWithDefaultAlphabet(unsigned char value)
-{
- wchar_t value2;
-
- value2 = GSM_DefaultAlphabetUnicode[value][1] | ( GSM_DefaultAlphabetUnicode[value][0] << 8);
-
- return DecodeWithUnicodeAlphabet(value2);
-}
-
-wchar_t EncodeWithUnicodeAlphabet(unsigned char value)
-{
- wchar_t retval;
-
- if (mbtowc(&retval, &value, 1) == -1) return '?';
- else return retval;
-}
-
-unsigned char DecodeWithUnicodeAlphabet(wchar_t value)
-{
- unsigned char retval;
-
- if (wctomb(&retval, value) == -1) return '?';
- else return retval;
-}
-
-#endif
-
-void DecodeDefault (unsigned char* dest, const unsigned char* src, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- dest[i] = DecodeWithDefaultAlphabet(src[i]);
- dest[len]=0;
-}
-
-void EncodeDefault (unsigned char* dest, const unsigned char* src, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- dest[i] = EncodeWithDefaultAlphabet(src[i]);
- return;
-}
-
-void DecodeUnicode (unsigned char* dest, const unsigned char* src, int len)
-{
- int i;
- wchar_t wc;
-
- for (i = 0; i < len; i++) {
- wc = src[(2*i)+1] | (src[2*i] << 8);
- dest[i] = DecodeWithUnicodeAlphabet(wc);
- }
- dest[len]=0;
- return;
-}
-
-void EncodeUnicode (unsigned char* dest, const unsigned char* src, int len)
-{
- int i;
- wchar_t wc;
-
- for (i = 0; i < len; i++) {
- wc = EncodeWithUnicodeAlphabet(src[i]);
- dest[i*2] = (wc >> 8) &0xff;
- dest[(i*2)+1] = wc & 0xff;
- }
-}
-
-bool EncodeWithUTF8Alphabet(u8 mychar, u8 *ret1, u8 *ret2)
-{
- u8 mychar1,mychar2,mychar3,mychar4;
- int j=0;\r
-
- mychar1=((EncodeWithUnicodeAlphabet(mychar)>>8)&0xff);
- mychar2=EncodeWithUnicodeAlphabet(mychar)&0xff;
- if (mychar1>0x00 || mychar2>128) {
- mychar3=0x00;
- mychar4=128;
- while (true) {
- if (mychar3==mychar1) {
- if (mychar4+64>=mychar2) {
- *ret1=j+0xc2;\r
- *ret2=0x80+(mychar2-mychar4);\r
- return true;\r
- }
- }
- if (mychar4==192) {
- mychar3++;
- mychar4=0;
- } else {
- mychar4=mychar4+64;
- }
- j++;
- }
- }
- return false;
-}
-
-void DecodeWithUTF8Alphabet(u8 mychar3, u8 mychar4, u8 *ret)
-{
- u8 mychar1, mychar2;
- int j;
- wchar_t wc;
-
- mychar1=0x00;
- mychar2=128;
- for(j=0;j<mychar3-0xc2;j++) {
- if (mychar2==192) {
- mychar1++;
- mychar2=0;
- } else {
- mychar2=mychar2+64;
- }
- }
- mychar2=mychar2+(mychar4-0x80);
- wc = mychar2 | (mychar1 << 8);
- *ret=DecodeWithUnicodeAlphabet(wc);\r
- j=-1;
-}
-
-void EncodeUTF8 (unsigned char* dest, const unsigned char* src, int len)
-{
- int i,j=0,z;
- u8 mychar1, mychar2;
- u8 buf[7];
-
- for (i = 0; i < len; i++) {
- if (EncodeWithUTF8Alphabet(src[i],&mychar1,&mychar2)) {
- sprintf(buf, "=%02X=%02X",mychar1,mychar2);
- for (z=0;z<6;z++) dest[j++]=buf[z];
- } else {
- dest[j++]=src[i];
- }
- }
- dest[j++]=0;
-}
-
-void DecodeUTF8 (unsigned char* dest, const unsigned char* src, int len)
-{
- int i=0,j=0;
- u8 mychar1, mychar2,ret;
-
- while (i<=len) {
- if (len-6>=i) {
- /* Need to have correct chars */
- if (src[i] =='=' && DecodeWithHexBinAlphabet(src[i+1])!=-1
- && DecodeWithHexBinAlphabet(src[i+2])!=-1 &&
- src[i+3]=='=' && DecodeWithHexBinAlphabet(src[i+4])!=-1 &&
- DecodeWithHexBinAlphabet(src[i+5])!=-1) {
- mychar1=16*DecodeWithHexBinAlphabet(src[i+1])+DecodeWithHexBinAlphabet(src[i+2]);
- mychar2=16*DecodeWithHexBinAlphabet(src[i+4])+DecodeWithHexBinAlphabet(src[i+5]);
- DecodeWithUTF8Alphabet(mychar1,mychar2,&ret);
- i=i+5;
- dest[j++]=ret;
- } else {
- dest[j++]=src[i];
- }
- } else {
- dest[j++]=src[i];
- }
- i++;
- }
- dest[j++]=0;
-}
-
-int DecodeWithHexBinAlphabet (unsigned char mychar) {
- if (mychar>='A' && mychar<='F') return mychar-'A'+10;
- if (mychar>='a' && mychar<='f') return mychar-'a'+10;
- if (mychar>='0' && mychar<='9') return mychar-'0';
- return -1;
-}
-
-unsigned char EncodeWithHexBinAlphabet (int digit) {
- if (digit >= 0 && digit <= 9) return '0'+(digit);
- if (digit >=10 && digit <=15) return 'A'+(digit-10);
- return 0;
-}
-
-void DecodeHexBin (unsigned char* dest, const unsigned char* src, int len)
-{
- int i,current=0;
-
- for (i = 0; i < len/2 ; i++) {
- dest[current++]=DecodeWithHexBinAlphabet(src[i*2])*16+
- DecodeWithHexBinAlphabet(src[i*2+1]);
- }
- dest[current++]=0;
-}
-
-void EncodeHexBin (unsigned char* dest, const unsigned char* src, int len)
-{
- int i,current=0;
-
- for (i = 0; i < len; i++) {
- dest[current++]=EncodeWithHexBinAlphabet(src[i] >> 0x04);
- dest[current++]=EncodeWithHexBinAlphabet(src[i] & 0x0f);
- }
-}
-
-void DecodeBCD (unsigned char* dest, const unsigned char* src, int len)
-{
- int i,current=0,digit;
-
- for (i = 0; i < len; i++) {
- digit=src[i] & 0x0f;
- if (digit<10) dest[current++]=digit + '0';
- digit=src[i] >> 4;
- if (digit<10) dest[current++]=digit + '0';
- }
- dest[current++]=0;
-}
-
-void EncodeBCD (unsigned char* dest, const unsigned char* src, int len, bool fill)
-{
- int i,current=0;
-
- for (i = 0; i < len; i++) {
- if (i & 0x01) {
- dest[current]=dest[current] | ((src[i]-'0') << 4);
- current++;
- } else {
- dest[current]=src[i]-'0';
- }
- }
-
- /* When fill is set: we fill in the most significant bits of the
- last byte with 0x0f (1111 binary) if the number is represented
- with odd number of digits. */
- if (fill && (len & 0x01)) {
- dest[current]=dest[current] | 0xf0;
- }
-}
-
-unsigned char EncodeWithBCDAlphabet(int value)
-{
- div_t division;
-
- division=div(value,10);
- return ( ( (value-division.quot*10) & 0x0f) << 4) | (division.quot & 0xf);
-}
-
-int DecodeWithBCDAlphabet(unsigned char value)
-{
- return 10*(value & 0x0f)+(value >> 4);
-}