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.1 2001/11/25 21:59:06 short
17 :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
19 Revision 1.4 2001/11/22 17:56:53 pkot
20 smslib update. sms sending
22 Revision 1.3 2001/11/17 20:15:31 pkot
23 Typo in default alphabet
25 Revision 1.2 2001/11/08 16:34:19 pkot
26 Updates to work with new libsms
28 Revision 1.1 2001/10/24 22:37:25 pkot
29 Moved encoding functions to a separate file
36 #define NUMBER_OF_7_BIT_ALPHABET_ELEMENTS 128
38 static unsigned char GSM_DefaultAlphabet[NUMBER_OF_7_BIT_ALPHABET_ELEMENTS] = {
40 /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
41 /* Characters in hex position 10, [12 to 1a] and 24 are not present on
42 latin1 charset, so we cannot reproduce on the screen, however they are
43 greek symbol not present even on my Nokia */
45 '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
46 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
47 '?', '_', '?', '?', '?', '?', '?', '?',
48 '?', '?', '?', '?', 0xc6, 0xe6, 0xdf, 0xc9,
49 ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
50 '(', ')', '*', '+', ',', '-', '.', '/',
51 '0', '1', '2', '3', '4', '5', '6', '7',
52 '8', '9', ':', ';', '<', '=', '>', '?',
53 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
54 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
55 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
56 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
57 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
58 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
59 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
60 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
63 static unsigned char EncodeWithDefaultAlphabet(unsigned char value)
67 if (value == '?') return 0x3f;
69 for (i = 0; i < NUMBER_OF_7_BIT_ALPHABET_ELEMENTS; i++)
70 if (GSM_DefaultAlphabet[i] == value)
76 static wchar_t EncodeWithUnicodeAlphabet(unsigned char value)
80 if (mbtowc(&retval, &value, 1) == -1) return '?';
84 static unsigned char DecodeWithDefaultAlphabet(unsigned char value)
86 return GSM_DefaultAlphabet[value];
89 static unsigned char DecodeWithUnicodeAlphabet(wchar_t value)
93 if (wctomb(&retval, value) == -1) return '?';
98 #define ByteMask ((1 << Bits) - 1)
100 int Unpack7BitCharacters(int offset, int in_length, int out_length,
101 unsigned char *input, unsigned char *output)
103 unsigned char *OUT = output; /* Current pointer to the output buffer */
104 unsigned char *IN = input; /* Current pointer to the input buffer */
105 unsigned char Rest = 0x00;
108 Bits = offset ? offset : 7;
110 while ((IN - input) < in_length) {
112 *OUT = ((*IN & ByteMask) << (7 - Bits)) | Rest;
115 /* If we don't start from 0th bit, we shouldn't go to the
116 next char. Under *OUT we have now 0 and under Rest -
117 _first_ part of the char. */
118 if ((IN != input) || (Bits == 7)) OUT++;
121 if ((OUT - output) >= out_length) break;
123 /* After reading 7 octets we have read 7 full characters but
124 we have 7 bits as well. This is the next character */
138 int Pack7BitCharacters(int offset, unsigned char *input, unsigned char *output)
141 unsigned char *OUT = output; /* Current pointer to the output buffer */
142 unsigned char *IN = input; /* Current pointer to the input buffer */
143 int Bits; /* Number of bits directly copied to
146 Bits = (7 + offset) % 8;
148 /* If we don't begin with 0th bit, we will write only a part of the
155 while ((IN - input) < strlen(input)) {
157 unsigned char Byte = EncodeWithDefaultAlphabet(*IN);
158 *OUT = Byte >> (7 - Bits);
159 /* If we don't write at 0th bit of the octet, we should write
160 a second part of the previous octet */
162 *(OUT-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1);
166 if (Bits == -1) Bits = 7;
172 return (OUT - output);
175 void DecodeAscii (unsigned char* dest, const unsigned char* src, int len)
179 for (i = 0; i < len; i++)
180 dest[i] = DecodeWithDefaultAlphabet(src[i]);
184 void EncodeAscii (unsigned char* dest, const unsigned char* src, int len)
188 for (i = 0; i < len; i++)
189 dest[i] = EncodeWithDefaultAlphabet(src[i]);
193 void DecodeUnicode (unsigned char* dest, const unsigned char* src, int len)
198 for (i = 0; i < len; i++) {
199 wc = src[(2*i)+1] | (src[2*i] << 8);
200 dest[i] = DecodeWithUnicodeAlphabet(wc);
206 void EncodeUnicode (unsigned char* dest, const unsigned char* src, int len)
211 for (i = 0; i < len; i++) {
212 wc = EncodeWithUnicodeAlphabet(src[i]);
213 dest[i*2] = (wc >> 8) &0xff;
214 dest[(i*2)+1] = wc & 0xff;