2 * This file is part of samsung-ril.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
6 * samsung-ril is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * samsung-ril is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
24 #define LOG_TAG "RIL-UTIL"
25 #include <utils/Log.h>
28 #include "samsung-ril.h"
31 * Converts a hexidecimal string to binary
33 void hex2bin(const char *data, int length, unsigned char *buf)
37 unsigned char *p = buf;
44 if(data[i] - '0' < 10)
46 else if(data[i] - 'a' < 7)
47 b = data[i] - 'a' + 10;
48 else if(data[i] - 'A' < 7)
49 b = data[i] - 'A' + 10;
54 if(data[i] - '0' < 10)
56 else if(data[i] - 'a' < 7)
57 b |= data[i] - 'a' + 10;
58 else if(data[i] - 'A' < 7)
59 b |= data[i] - 'A' + 10;
67 * Converts binary data to a hexidecimal string
69 void bin2hex(const unsigned char *data, int length, char *buf)
75 for(i = 0; i < length; i++) {
78 b = (data[i] >> 4 & 0x0f);
79 b += (b < 10) ? '0' : ('a' - 10);
83 b += (b < 10) ? '0' : ('a' - 10);
91 * Converts GSM7 (8 bits) data to ASCII (7 bits)
93 int gsm72ascii(unsigned char *data, char **data_dec, int length)
101 dec_length = ((length * 8) - ((length * 8) % 7) ) / 7;
102 dec = malloc(dec_length);
104 memset(dec, 0, dec_length);
106 for(i=0 ; i < length ; i++)
112 t = (data[i] - (((data[i] >> d) & 0xff) << d));
113 u = (data[i] >> d) & 0xff;
115 dec[i+o]+=t << (i + o) % 8;
127 * Converts ASCII (7 bits) data to GSM7 (8 bits)
129 int ascii2gsm7(char *data, unsigned char **data_enc, int length)
131 int d_off, d_pos, a_off, a_pos = 0;
137 enc_length = ((length * 7) - (length * 7) % 8) / 8;
138 enc_length += (length * 7) % 8 > 0 ? 1 : 0;
140 //FIXME: why does samsung does that?
143 enc = malloc(enc_length);
144 memset(enc, 0, enc_length);
146 for(i=0 ; i < length ; i++)
148 // offset from the right of data to keep
151 // position of the data we keep
152 d_pos = ((i * 7) - (i * 7) % 8) / 8;
153 d_pos += (i * 7) % 8 > 0 ? 1 : 0;
155 // adding the data with correct offset
156 enc[d_pos] |= data[i] >> d_off;
158 // numbers of bits to omit to get data to add another place
160 // position (on the encoded feed) of the data to add
163 // adding the data to add at the correct position
164 enc[a_pos] |= data[i] << a_off;
169 //FIXME: what is going on here?
170 enc[enc_length - 2] |= 0x30;
171 enc[enc_length - 1] = 0x02;
176 void hex_dump(void *data, int size)
178 /* dumps size bytes of *data to stdout. Looks like:
179 * [0000] 75 6E 6B 6E 6F 77 6E 20
180 * 30 FF 00 00 00 00 39 00 unknown 0.....9.
181 * (in a single line of course)
184 unsigned char *p = data;
187 char bytestr[4] = {0};
188 char addrstr[10] = {0};
189 char hexstr[ 16*3 + 5] = {0};
190 char charstr[16*1 + 5] = {0};
191 for(n=1;n<=size;n++) {
193 /* store address for this line */
194 snprintf(addrstr, sizeof(addrstr), "%.4x",
195 ((unsigned int)p-(unsigned int)data) );
199 if (isalnum(c) == 0) {
203 /* store hex str (for left side) */
204 snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
205 strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
207 /* store char str (for right side) */
208 snprintf(bytestr, sizeof(bytestr), "%c", c);
209 strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
213 LOGD("[%4.4s] %-50.50s %s", addrstr, hexstr, charstr);
216 } else if(n%8 == 0) {
217 /* half line: add whitespaces */
218 strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
219 strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
224 if (strlen(hexstr) > 0) {
225 /* print rest of buffer if not empty */
226 LOGD("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
230 /* writes the utf8 character encoded in v
231 * to the buffer utf8 at the specified offset
233 int utf8_write(char *utf8, int offset, int v)
241 utf8[offset] = (char)v;
242 } else if (v < 0x800) {
245 utf8[offset + 0] = (char)(0xc0 | (v >> 6));
246 utf8[offset + 1] = (char)(0x80 | (v & 0x3f));
248 } else if (v < 0x10000) {
251 utf8[offset + 0] = (char)(0xe0 | (v >> 12));
252 utf8[offset + 1] = (char)(0x80 | ((v >> 6) & 0x3f));
253 utf8[offset + 2] = (char)(0x80 | (v & 0x3f));
258 utf8[offset + 0] = (char)(0xf0 | ((v >> 18) & 0x7));
259 utf8[offset + 1] = (char)(0x80 | ((v >> 12) & 0x3f));
260 utf8[offset + 2] = (char)(0x80 | ((v >> 6) & 0x3f));
261 utf8[offset + 3] = (char)(0x80 | (v & 0x3f));
267 SmsCodingScheme sms_get_coding_scheme(int dataCoding)
269 switch (dataCoding >> 4) {
273 return SMS_CODING_SCHEME_GSM7;
275 if (dataCoding == 0x10)
276 return SMS_CODING_SCHEME_GSM7;
277 if (dataCoding == 0x11)
278 return SMS_CODING_SCHEME_UCS2;
284 if (dataCoding & 0x20)
285 return SMS_CODING_SCHEME_UNKNOWN;
286 if (((dataCoding >> 2) & 3) == 0)
287 return SMS_CODING_SCHEME_GSM7;
288 if (((dataCoding >> 2) & 3) == 2)
289 return SMS_CODING_SCHEME_UCS2;
292 if (!(dataCoding & 4))
293 return SMS_CODING_SCHEME_GSM7;
296 return SMS_CODING_SCHEME_UNKNOWN;