7 A Linux/Unix toolset and driver for Nokia mobile phones.
9 Copyright (C) 2001 Pawe³ Kot <pkot@linuxnews.pl>
11 Released under the terms of the GNU GPL, see file COPYING for more details.
13 Functions for encoding SMS, calendar and other things.
16 Revision 1.1.1.2 2002/04/03 00:08:03 short
17 Found in "gnokii-working" directory, some November-patches version
19 Revision 1.2 2001/11/08 16:34:19 pkot
20 Updates to work with new libsms
22 Revision 1.1 2001/10/24 22:37:25 pkot
23 Moved encoding functions to a separate file
31 #define NUMBER_OF_7_BIT_ALPHABET_ELEMENTS 128
33 static unsigned char GSM_DefaultAlphabet[NUMBER_OF_7_BIT_ALPHABET_ELEMENTS] = {
35 /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
36 /* Characters in hex position 10, [12 to 1a] and 24 are not present on
37 latin1 charset, so we cannot reproduce on the screen, however they are
38 greek symbol not present even on my Nokia */
40 '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
41 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
42 '?', '_', '?', '?', '?', '?', '?', '?',
43 '?', '?', '?', '?', 0xc6, 0xe6, 0xdf, 0xc9,
44 ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
45 '(', ')', '*', '+', ',', '-', '.', '/',
46 '0', '1', '2', '3', '4', '5', '6', '7',
47 '8', '9', ':', ';', '<', '=', '>', '?',
48 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
49 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
51 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
52 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
53 'H', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
54 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
55 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
58 static unsigned char EncodeWithDefaultAlphabet(unsigned char value)
62 if (value == '?') return 0x3f;
64 for (i = 0; i < NUMBER_OF_7_BIT_ALPHABET_ELEMENTS; i++)
65 if (GSM_DefaultAlphabet[i] == value)
71 static wchar_t EncodeWithUnicodeAlphabet(unsigned char value)
75 if (mbtowc(&retval, &value, 1) == -1) return '?';
79 static unsigned char DecodeWithDefaultAlphabet(unsigned char value)
81 return GSM_DefaultAlphabet[value];
84 static unsigned char DecodeWithUnicodeAlphabet(wchar_t value)
88 if (wctomb(&retval, value) == -1) return '?';
93 #define ByteMask ((1 << Bits) - 1)
95 int Unpack7BitCharacters(int offset, int in_length, int out_length,
96 unsigned char *input, unsigned char *output)
98 unsigned char *OUT = output; /* Current pointer to the output buffer */
99 unsigned char *IN = input; /* Current pointer to the input buffer */
100 unsigned char Rest = 0x00;
103 Bits = offset ? offset : 7;
105 while ((IN - input) < in_length) {
107 *OUT = ((*IN & ByteMask) << (7 - Bits)) | Rest;
110 /* If we don't start from 0th bit, we shouldn't go to the
111 next char. Under *OUT we have now 0 and under Rest -
112 _first_ part of the char. */
113 if ((IN != input) || (Bits == 7)) OUT++;
116 if ((OUT - output) >= out_length) break;
118 /* After reading 7 octets we have read 7 full characters but
119 we have 7 bits as well. This is the next character */
133 int Pack7BitCharacters(int offset, unsigned char *input, unsigned char *output)
136 unsigned char *OUT = output; /* Current pointer to the output buffer */
137 unsigned char *IN = input; /* Current pointer to the input buffer */
138 int Bits; /* Number of bits directly copied to
141 Bits = (7 + offset) % 8;
143 /* If we don't begin with 0th bit, we will write only a part of the
150 while ((IN - input) < strlen(input)) {
152 unsigned char Byte = EncodeWithDefaultAlphabet(*IN);
154 *OUT = Byte >> (7 - Bits);
155 /* If we don't write at 0th bit of the octet, we should write
156 a second part of the previous octet */
158 *(OUT-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1);
162 if (Bits == -1) Bits = 7;
168 return (OUT - output);
171 void DecodeAscii (unsigned char* dest, const unsigned char* src, int len)
175 for (i = 0; i < len; i++)
176 dest[i] = DecodeWithDefaultAlphabet(src[i]);
180 void EncodeAscii (unsigned char* dest, const unsigned char* src, int len)
184 for (i = 0; i < len; i++)
185 dest[i] = EncodeWithDefaultAlphabet(src[i]);
189 void DecodeUnicode (unsigned char* dest, const unsigned char* src, int len)
194 for (i = 0; i < len; i++) {
195 wc = src[(2*i)+1] | (src[2*i] << 8);
196 dest[i] = DecodeWithUnicodeAlphabet(wc);
202 void EncodeUnicode (unsigned char* dest, const unsigned char* src, int len)
207 for (i = 0; i < len; i++) {
208 wc = EncodeWithUnicodeAlphabet(src[i]);
209 dest[i*2] = (wc >> 8) &0xff;
210 dest[(i*2)+1] = wc & 0xff;