tizen 2.3.1 release
[framework/telephony/libtcore.git] / src / util.c
1 /*
2  * libtcore
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #include <net/if.h>
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
31
32 #include <glib.h>
33 #include <glib-object.h>
34 #include <iconv.h>
35
36 #include "tcore.h"
37 #include "util.h"
38
39
40 #define tabGsmUniMax2 9
41 #define tabGsmUniMax 42
42 #define TAB_SPACE     "  "
43
44 gboolean tcore_debug = TRUE;
45
46 static gboolean         _find_gsm_code_exception_table(unsigned short src);
47 static int              _get_gsm_code_size(unsigned short* src, int src_len);
48 static gboolean         _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len);
49 static int                      _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len);
50 static void             _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len,     unsigned char *src, unsigned int src_len);
51 static gboolean         _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len);
52 static char*            _convert_ucs_to_utf8(unsigned char *src, int src_len);
53 static int                      _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len);
54 static void             _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len);
55 static int                      _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len);
56
57 typedef struct {
58         char gsm;
59         unsigned short unicode;
60 } GsmUniTable;
61
62 const GsmUniTable gsm_unicode2_table[] = {
63                 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
64                 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
65                 { 0x65, 0x20AC } };
66
67 const GsmUniTable gsm_unicode_table[] = {
68                 { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 },
69                 { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 },
70                 { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 },
71                 { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B },
72                 { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 },
73                 { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 },
74                 { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 },
75                 { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 },
76                 { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, };
77
78
79
80
81 static gboolean _find_gsm_code_exception_table(unsigned short src)
82 {
83         if ((src >= 0x0020 && src <= 0x0023)
84                         || (src >= 0x0025 && src <= 0x003F)
85                         || (src >= 0x0041 && src <= 0x005A)
86                         || (src >= 0x0061 && src <= 0x007A)
87                         || src == 0x000A || src == 0x000D)
88                 return TRUE;
89         return FALSE;
90 }
91
92 static int _get_gsm_code_size(unsigned short* src, int src_len)
93 {
94         gboolean in_table = FALSE;
95         gboolean in_sec_table = FALSE;
96         int i, gsm_len = 0;
97
98         if (NULL == src) {
99                 dbg( "INPUT PARAM was NULL");
100                 return -1;
101         }
102
103         for (; src_len > 0 && src; src_len--) {
104                 if (_find_gsm_code_exception_table(*src) == TRUE) {
105                         src++;
106                         gsm_len++;
107                         continue;
108                 }
109                 in_table = FALSE;
110                 for (i = 0; i < tabGsmUniMax; i++) {
111                         if (*src == gsm_unicode_table[i].unicode) {
112                                 src++;
113                                 in_table = TRUE;
114                                 gsm_len++;
115                                 break;
116                         }
117                 }
118                 if (in_table == FALSE) {
119                         in_sec_table = FALSE;
120                         for (i = 0; i < tabGsmUniMax2; i++) {/* second table */
121                                 if (*src == gsm_unicode2_table[i].unicode) {
122                                         src++;
123                                         in_table = TRUE;
124                                         in_sec_table = TRUE;
125                                         gsm_len += 2;
126                                         break;
127                                 }
128                         }
129                         if (in_sec_table == FALSE) {/* second*/
130                                 if (_find_gsm_code_exception_table(*src) == FALSE) {
131                                         dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len);
132                                         return -1;
133                                 }
134                                 src++;
135                                 gsm_len++;
136                         }
137                 }
138         }
139         return gsm_len;
140 }
141
142 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
143 {
144         int count, tmp_len;
145
146         if(!dest || !src) {
147                 dbg( "dest(%p) or src(%p) is null",dest, src);
148                 return FALSE;
149         }
150
151         if(!src_len){
152                 dest[0] = '\0';
153                 return TRUE;
154         }
155
156         dbg("source string (%s) len(%d)", src, src_len);
157
158         for(count = 0; count < (int)src_len; count++){
159                 if(src[count] == 0x1B)
160                         src_len--;
161         }
162         dbg("strlen excluding escape character (%d)", src_len);
163
164         tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
165         dest[tmp_len] = '\0';
166
167         return TRUE;
168 }
169
170 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
171 {
172         int count;
173         unsigned short* org;
174
175         org = dest;
176
177         for(count=0; count < (int)src_len; count++){
178                 int table_index=0;
179                 gboolean b_tabled = FALSE;
180
181                 /*
182                  * if the first byte is 0x1B, it is the escape character.
183                  * The byte value shoulbe be changed to unicode.
184                  */
185                 if(*src == 0x1B){
186                         src++; count++;//move to next byte
187                         for(table_index=0; table_index < tabGsmUniMax2; table_index++){
188                                 if(*src == gsm_unicode2_table[table_index].gsm){
189                                         *dest = gsm_unicode2_table[table_index].unicode;
190                                         b_tabled = TRUE;
191                                         break;
192                                 }
193                         }
194
195                         //if matched data is not in table, it should be changed to NULL;
196                         if(!b_tabled){
197                                 *dest = 0x0020;
198                         }
199                 }
200                 else{
201                         for(table_index=0; table_index < tabGsmUniMax; table_index++){
202                                 if(*src == gsm_unicode_table[table_index].gsm){
203                                         *dest = gsm_unicode_table[table_index].unicode;
204                                         b_tabled = TRUE;
205                                         break;
206                                 }
207                         }
208
209                         //if matched data is not in table, it is using original value;
210                         if(!b_tabled){
211                                 *dest = *src;
212                         }
213                 }
214
215                 //move to next position
216                 src++; dest++;
217         }
218
219         dbg("cvt sr(%s), the size of data (%d) ", org, dest - org);
220         return (dest - org);
221 }
222
223 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
224 {
225         unsigned short tmp_len = 0;
226         char *target_tmp = NULL;
227         unsigned char *raw_unicode = NULL;
228         unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
229
230         memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
231
232         _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
233         while(tmp_dest[tmp_len] != '\0'){
234                 tmp_len++;
235         }
236         tmp_len++; // add null character
237
238         tmp_len = tmp_len*2; //for byte align
239         raw_unicode = (unsigned char*)malloc(tmp_len);
240         if(!raw_unicode)
241                 return;
242
243         memset(raw_unicode, 0, tmp_len);
244
245         memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
246
247         target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
248         if(!target_tmp){
249                 dbg( "str is NULL");
250                 g_free(raw_unicode);
251                 return;
252         }
253
254         *dest_len = strlen((const char*)target_tmp);
255         dbg("utf8 (%s), len(%d)", (const char*)target_tmp, strlen((const char*)target_tmp));
256         memcpy(dest, target_tmp, strlen((const char*)target_tmp));
257         dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
258
259         g_free(raw_unicode);
260         g_free(target_tmp);
261         return;
262 }
263
264 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
265 {
266         char* tmp_str;
267         int gc_len = 0;
268
269         if ((NULL == dest) || (NULL == src)) {
270                 dbg( "INPUT PARAM was NULL");
271                 return FALSE;
272         }
273
274         if (src_len == 0)
275                 return FALSE;
276
277         gc_len = _get_gsm_code_size(src, src_len);
278         if (0 >= gc_len) {
279                 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
280                 return FALSE;
281         }
282
283         if (dest_len < gc_len) {
284                 if (dest_len == sizeof(void*)) {
285                         dbg( "Out buffer size seems to be small (%s)", dest);
286                 } else {
287                         dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
288                 }
289                 return FALSE;
290         }
291
292         tmp_str = calloc(1, (unsigned short) gc_len);
293         if (tmp_str == NULL) {
294                 dbg( "Memory Allocation Failed!");
295                 return FALSE;
296         }
297
298         gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
299         if (gc_len != -1) {
300                 memcpy((char*) dest, (char*) tmp_str, gc_len);
301                 free(tmp_str);
302                 return TRUE;
303         }
304
305         free(tmp_str);
306         return FALSE;
307 }
308
309 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
310 {
311         char* utf_str = NULL;
312         iconv_t cd = NULL;
313         size_t ileft = 0;
314         size_t oleft = 0;
315
316         char* pIn = NULL;
317         char* in_buf = NULL;
318         char* out_buf = NULL;
319
320         if (!src) {
321                 dbg("src is null");
322                 return NULL;
323         }
324
325         ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes
326         oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes
327         pIn = in_buf = (char*) malloc(ileft + 2);
328         if (in_buf == NULL) {
329                 dbg("in_buf allocation failed");
330                 return NULL;
331         }
332         utf_str = out_buf = (char *) malloc(oleft + 1);
333         if (utf_str == NULL) {
334                 dbg("in_buf allocation failed");
335                 free(in_buf);
336                 return NULL;
337         }
338
339         memset(in_buf, 0x00, ileft + 2);
340         memset(out_buf, 0x00, oleft + 1);
341         memcpy(in_buf, src, ileft);
342
343         in_buf[ileft] = '\0';
344
345         cd = iconv_open("UTF-8", "UCS-2");
346
347         if (iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft) == (size_t)(-1)) {
348                 dbg("failed to iconv errno:%d", errno);
349         } else {
350                 utf_str[src_len * 2 - ileft] = '\0';
351         }
352
353         iconv_close(cd);
354         free(pIn);
355
356         return utf_str;
357 }
358
359 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
360 {
361         unsigned char* rear = NULL;
362         unsigned short* p;
363         unsigned char temp;
364         gboolean in_table = FALSE;
365         gboolean in_sec_table = FALSE;
366         int i, gc_len = 0;
367
368         if ((!dest) || (!src) || (0x00 == src_len)) {
369                 dbg( "Warning: Wrong Input");
370                 return -1;
371         }
372
373         rear = dest;
374         p = src;
375
376         for (; src_len > 0 && p; src_len--) {
377                 in_table = FALSE;
378                 for (i = 0; i < tabGsmUniMax; i++) { /* is in table  */
379                         if (*p == gsm_unicode_table[i].unicode) {
380                                 temp = (unsigned char) (gsm_unicode_table[i].gsm);
381                                 *rear = temp;
382                                 rear++;
383                                 p++;
384                                 in_table = TRUE;
385                                 gc_len++;
386                                 break;
387                         }
388                 }
389                 if (in_table == FALSE) {
390                         in_sec_table = FALSE;
391                         for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/
392                                 if (*p == gsm_unicode2_table[i].unicode) {
393                                         *rear = 0x1B;
394                                         rear++;
395                                         temp = (unsigned char) (gsm_unicode2_table[i].gsm);
396                                         *rear = temp;
397                                         rear++;
398                                         p++;
399                                         in_table = TRUE;
400                                         in_sec_table = TRUE;
401                                         gc_len += 2;
402                                         break;
403                                 }
404                         }
405                         if (in_sec_table == FALSE) { /* second */
406                                 if (_find_gsm_code_exception_table(*p) == FALSE)
407                                         return -1;
408                                 temp = (unsigned char) (*p); /* isn't in table. but it's just able to be converted to GSM (0x00?? -> 0x??)*/
409                                 *rear = temp;
410                                 rear++;
411                                 p++;
412                                 gc_len++;
413                         }
414                 }
415         }
416         src = p;
417         return gc_len;
418 }
419
420 int tcore_util_convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
421 {
422         //input string "char *in" should be BIG-ENDIAN format.
423         gsize byte_converted = 0;
424         gsize byte_read = 0;
425         gchar *str_converted = NULL;
426
427         if (NULL == out || NULL == out_len || NULL == in) {
428                 dbg( "Invalid Input Parameter");
429                 return 0;
430         }
431 try_again:
432         str_converted = (gchar *)g_convert((const gchar *)in, (gssize)in_len, "UTF8", "UCS-2BE", &byte_read, &byte_converted, NULL);
433
434         dbg("read:[%d] converted:[%d] out:[%s]", byte_read, byte_converted, str_converted);
435
436         *out_len = byte_converted;
437         if (str_converted) {
438                 memcpy(out, str_converted, byte_converted);
439                 g_free(str_converted);
440         } else {
441                 warn("Cannot get converted data");
442                 if (byte_read > 0) {
443                         in_len = byte_read;
444                         goto try_again;
445                 }
446         }
447         return 0;
448 }
449
450 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len)
451 {
452         //input string "unsigned char *in" should be BIG-ENDIAN format.
453         int i = 0;
454
455         switch(in[0]) {
456                 case 0x80: {
457                         dbg("[UCS2] prefix case:[0x80]");
458                         tcore_util_hex_dump(" [UCS2] ", in_len, in);
459                         tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*)in+1, in_len-1);
460                 } break;
461
462                 case 0x81: {
463                         unsigned char num = in[1];      //number of characters
464                         unsigned short base = (unsigned short) in[2] << 7;      //base pointer for UCS2 type
465                         int data_loc = 3;       //starting location of data
466                         unsigned short* in_buf = NULL;
467                         dbg("[UCS2] prefix case:[0x81]");
468                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
469                         if(in_buf == NULL) {
470                                 dbg("in_buf malloc failed.");
471                                 return;
472                         }
473
474                         for(i=0; i<num; i++,data_loc++) {
475                                 if(in[data_loc]<0x80) { // if the MSB is zero (0x80 => 1000b), then remaining 7 bits are GSM default character.
476                                         _convert_gsm_to_ucs2(&in_buf[i], &in[data_loc], 1);
477                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
478                                 } else {        // if the MSB is 1 then the remaining 7 bits are offset value added to Base Pointer which the result defines the UCS2 character.
479                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
480                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
481                                 }
482                         }
483                         {
484                                 unsigned char *dest = NULL;
485                                 dest = (unsigned char*)malloc(num*2);
486                                 if(dest == NULL) {
487                                         dbg("dest malloc failed.");
488                                         free(in_buf);
489                                         return;
490                                 }
491
492                                 tcore_util_swap_byte_order(dest, (unsigned char*)in_buf, num*2);
493                                 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*) dest, num*2);
494
495                                 free(in_buf);
496                                 free(dest);
497                         }
498                 } break;
499
500                 case 0x82: {
501                         unsigned char num = in[1];      //number of characters
502                         unsigned short base = ((unsigned short) in[2] << 8) | (unsigned short) in[3];   //base pointer for UCS2 type
503                         int data_loc = 4;       //starting location of data
504                         unsigned short* in_buf = NULL;
505                         dbg("[UCS2] prefix case:[0x82]");
506                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
507                         if(in_buf == NULL) {
508                                 dbg("in_buf malloc failed.");
509                                 return;
510                         }
511
512                         for(i=0; i<num; i++,data_loc++) {
513                                 if(in[data_loc]<0x80) {
514                                         _convert_gsm_to_ucs2(&in_buf[i], &in[data_loc], (unsigned int)1);
515                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
516                                 } else {
517                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
518                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
519                                 }
520                         }
521                         {
522                                 unsigned char *dest = NULL;
523                                 dest = (unsigned char*)malloc(num*2);
524                                 if(dest == NULL) {
525                                         dbg("dest malloc failed.");
526                                         free(in_buf);
527                                         return;
528                                 }
529
530                                 tcore_util_swap_byte_order(dest, (unsigned char*)in_buf, num*2);
531                                 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*) dest, num*2);
532
533                                 free(in_buf);
534                                 free(dest);
535                         }
536                 } break;
537
538                 default: {
539                         dbg("[UCS2] non-prefix case.");
540                         tcore_util_hex_dump(" [UCS2] ", in_len, in);
541                         tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*)in, in_len);
542                 } break;
543         }
544 }
545
546 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
547 {
548         unsigned short* org = NULL;
549         unsigned char hi = 0;
550         unsigned char mid = 0;
551         unsigned char low = 0;
552
553         if ((NULL == dest) || (NULL == src)) {
554                 dbg( "INPUT PARAM NULL");
555                 return -1;
556         }
557
558         org = dest;
559
560         while (src_len > 0 && (*src != '\0')) {
561                 if (*src < 0x80) {
562                         *dest = (*src & 0x7F);
563                         dest++;
564                         src++;
565                         src_len--;
566                 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
567                         hi = *src & 0x1F;
568                         low = *(src+1) & 0x3F;
569                         *dest = (hi << 6) | low;
570                         dest++;
571                         src += 2;
572                         src_len -= 2;
573                 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
574                         hi = *src & 0x0F;
575                         mid = *(src+1) & 0x3F;
576                         low = *(src+2) & 0x3F;
577                         *dest = (hi << 12) | (mid << 6) | low;
578                         dest++;
579                         src += 3;
580                         src_len -= 3;
581                 } else {
582                         *dest = (*src & 0x7F);
583                         dest++;
584                         src++;
585                         src_len--;
586                         dbg( "utf8 incorrect range");
587                 }
588         }
589         *dest = 0;
590         return (dest - org);
591 }
592
593 static char _convert_gsm7bit_extension( char c )
594 {
595         switch ( c ) {
596                 case 0x0A:
597                 case 0x1B:
598                         return ' ';
599                 case 0x14:
600                         return '^';
601                 case 0x28:
602                         return '{';
603                 case 0x29:
604                         return '}';
605                 case 0x2F:
606                         return '\\';
607                 case 0x3C:
608                         return '[';
609                 case 0x3D:
610                         return '~';
611                 case 0x3E:
612                         return ']';
613                 case 0x40:
614                         return '|';
615                 /*
616                    case 0x65:
617                    This code represents the EURO currency symbol. The code value is that used for the character â€˜e’. Therefore
618                    a receiving entity which is incapable of displaying the EURO currency symbol will display the character â€˜e’
619                    instead. GSM 03.38
620                 */
621                 case 0x65:
622                         return 'e';
623                 default:
624                         dbg("this is not extension character : (0x%x)", c);
625                         break;
626         }
627
628         return c;
629 }
630
631 gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len)
632 {
633         unsigned short *uc = NULL;
634         int gc_len = 0;
635         int uc_len = 0;
636
637         if (src == NULL || src_len == 0) {
638                 dbg( "WARNING: Invalid Parameter");
639                 return FALSE;
640         }
641
642         uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
643         if (!uc) {
644                 dbg( "WARNING: calloc Failed");
645                 return FALSE;
646         }
647
648         /*Converting from UTF8 => UNICODE*/
649         uc_len = _convert_utf8_to_unicode(uc, src, src_len);
650         dbg( "uc_len:[%d]", uc_len);
651         if(uc_len == -1) {
652                 dbg( "_convert_utf8_to_unicode returns false!");
653                 free(uc);
654                 return FALSE;
655         }
656
657         /*Finding the GSMCode Size*/
658         gc_len = _get_gsm_code_size(uc, uc_len);
659         dbg( "gc_len:[%d]", gc_len);
660         if ( gc_len == -1) {
661                 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]",   gc_len);
662                 free(uc);
663                 return FALSE;
664         }
665
666         *dest_len = gc_len;
667         /*Converting from UNICODE ==> GSM CODE */
668         if (_convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len) == FALSE) {
669                 dbg( "_convert_unicode_to_gsm Failed");
670                 *dest_len = 0x00;
671                 free(uc);
672                 return FALSE;
673         }
674
675         if(uc)
676                 free(uc);
677         return TRUE;
678 }
679
680 gboolean tcore_util_convert_utf8_to_ucs2(char **dest, int *dest_len, unsigned char *src, int src_len)
681 {
682         gsize byte_converted = 0;
683         gsize byte_read = 0;
684         gchar *str_converted = NULL;
685
686         if (NULL == src || NULL == dest || NULL == dest_len) {
687                 dbg( "Invalid Input Parameter");
688                 return FALSE;
689         }
690 try_again:
691         /*Converting from UTF8 => UCS-2 BIG-ENDIAN FORMAT using the g_convert*/
692         str_converted = (gchar *)g_convert((const gchar *)src, (gssize)src_len, "UCS-2BE", "UTF8", &byte_read, &byte_converted, NULL);
693
694         dbg("byte_read: [%d] byte_converted: [%d]", byte_read, byte_converted);
695         if (str_converted) {
696                 *dest = str_converted;
697                 *dest_len = byte_converted;
698         } else {
699                 warn("Cannot get converted string");
700                 if (byte_read > 0) {
701                         src_len = byte_read;
702                         goto try_again;
703                 }
704         }
705         return TRUE;
706 }
707
708 gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len,
709                 enum alphabet_format dcs, const unsigned char *src, unsigned short src_len)
710 {
711         dbg("dcs=[0x%02x], src=[%s], src_len=[%d]", dcs, src, src_len );
712
713         if(src==NULL || src_len==0) {
714                 err("src is NULL or src_len is 0");
715                 return FALSE;
716         }
717
718         switch (dcs) {
719                 case ALPHABET_FORMAT_SMS_DEFAULT: {
720                         unsigned char* tmp_dest_str = NULL;
721                         tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len);
722
723                         if(!tmp_dest_str) {
724                                 err("temp_dest_str is NULL");
725                                 return FALSE;
726                         }
727                         _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
728                         if(tmp_dest_str) {
729                                 free(tmp_dest_str);
730                         }
731                 }       break;
732
733                 case ALPHABET_FORMAT_8BIT_DATA: {//GSM7bit with bit 8 set to 0
734                         int tmp_str_len = 0;
735                         unsigned char *src_buf = NULL;
736
737                         src_buf = (unsigned char*)malloc(src_len);
738                         if(src_buf == NULL) {
739                                 dbg("src_buf malloc failed.");
740                                 return FALSE;
741                         }
742
743                         memset(src_buf, 0, src_len);
744                         memcpy(src_buf, src, src_len);
745
746                         /*get string length*/
747                         /* 0xFF is the end of string */
748                         while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
749                                 tmp_str_len++;
750                         }
751                         /* last space character must be deleted */
752                         while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
753                                 tmp_str_len--;
754                         }
755                         dbg( "tmp_str_len[%d]", tmp_str_len);
756
757                         _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len);
758                         if(src_buf != NULL)
759                                 free(src_buf);
760                 }       break;
761
762                 case ALPHABET_FORMAT_UCS2: {
763                         unsigned char *src_buf = NULL;
764
765                         src_buf = (unsigned char*)malloc(src_len);
766                         if(src_buf == NULL) {
767                                 dbg("src_buf malloc failed.");
768                                 return FALSE;
769                         }
770
771                         memset(src_buf, 0, src_len);
772                         memcpy(src_buf, src, src_len);
773
774                         _convert_alpha_field_ucs2_to_utf8(dest, dest_len, src_buf, src_len);
775                         if(src_buf != NULL)
776                                 free(src_buf);
777                 }       break;
778
779                 default: {
780                         dbg("not handled alpha format[0x%02x]", dcs);
781                         return FALSE;
782                 }       break;
783         }
784         return TRUE;
785 }
786
787 gboolean tcore_util_convert_ascii_to_utf8( unsigned char **dest, int *dest_len, unsigned char *src, int src_len )
788 {
789         int i = 0, j = 0, tmp_len = 0;
790         unsigned char *tmp = 0;
791
792         if ( (!dest) || (!src) || (!dest_len) )
793                 return FALSE;
794
795         if ( !src_len ) {
796                 src_len = strlen( (char*)src );
797         }
798
799         tmp_len = (src_len * 2);
800         tmp = g_new0( unsigned char, tmp_len );
801
802         for ( i=0, j=0; i<src_len; i++, j++ ) {
803                 if ( src[i] <= 0x7F ) {
804                         tmp[j] = src[i];
805
806                 } else if ( (src[i] >= 0x80) && (src[i] <= 0xBF) ) {
807                         tmp[j] = 0xC2;
808                         tmp[++j] = src[i];
809
810                 } else { //( (src[i] >= 0xC0) && (src[i] <= 0xFF) )
811                         tmp[j] = 0xC3;
812                         tmp[++j] = (src[i] - 0x40);
813
814                 }
815         }
816
817         *dest_len = (j+1);
818
819         *dest = g_new0( unsigned char, *dest_len );
820         memcpy( *dest, tmp, j );
821
822         g_free( tmp );
823
824         return TRUE;
825 }
826
827 void tcore_util_swap_byte_order(unsigned char* dest, const unsigned char* src, int src_len)
828 {
829         int i = 0;
830         for (i = 0; i+1 < src_len; i=i+2) {
831                 dest[i] = src[i+1];
832                 dest[i+1] = src[i];
833         }
834         if(src_len%2==1)
835                 dest[i-1] = src[i-1];
836         dbg("swap completed.");
837 }
838
839 static gboolean _tcore_util_marshal_create_gvalue(GValue *value,
840                 const void *data, enum tcore_util_marshal_data_type type)
841 {
842         switch (type) {
843                 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
844                         g_value_init(value, type);
845                         g_value_set_schar(value, *((gchar *) data));
846                         break;
847
848                 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
849                         g_value_init(value, type);
850                         g_value_set_boolean(value, *((gboolean *) data));
851                         break;
852
853                 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
854                         g_value_init(value, type);
855                         g_value_set_int(value, *((gint *) data));
856                         break;
857
858                 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
859                         g_value_init(value, type);
860                         g_value_set_double(value, *((gdouble *) data));
861                         break;
862
863                 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
864                         g_value_init(value, type);
865                         g_value_set_string(value, (gchar *) data);
866                         break;
867
868                 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
869                         g_value_init(value, G_TYPE_HASH_TABLE);
870                         g_value_set_boxed(value, (gpointer) data);
871                         break;
872
873                 default:
874                         return FALSE;
875                         break;
876         }
877
878         return TRUE;
879 }
880
881
882 static gboolean _tcore_util_return_value(GValue *src, void **dest,
883                 enum tcore_util_marshal_data_type type)
884 {
885         switch (type) {
886                 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
887                         *dest = g_new0(gchar, 1);
888                         *((gchar *) *dest) = g_value_get_schar(src);
889                         break;
890
891                 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
892                         *dest = g_new0(gboolean, 1);
893                         *((gboolean *) *dest) = g_value_get_boolean(src);
894                         break;
895
896                 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
897                         *dest = g_new0(gint, 1);
898                         *((gint *) *dest) = g_value_get_int(src);
899                         break;
900
901                 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
902                         *dest = g_new0(gdouble, 1);
903                         *((gdouble *) *dest) = g_value_get_double(src);
904                         break;
905
906                 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
907                         *dest = g_value_dup_string(src);
908                         break;
909
910                 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
911                         *dest = g_value_dup_boxed(src);
912                         break;
913
914                 default:
915                         return FALSE;
916                         break;
917         }
918
919         return TRUE;
920 }
921
922
923 static void _tcore_util_marshal_remove_value(gpointer value)
924 {
925         unsigned int gtype = 0;
926         GHashTable *ht = NULL;
927
928         gtype = ((GValue *) value)->g_type;
929         if (gtype == G_TYPE_HASH_TABLE) {
930                 ht = g_value_get_boxed(value);
931                 g_hash_table_destroy(ht);
932         }
933
934         g_value_unset((GValue *) value);
935         g_free(value);
936
937         return;
938 }
939
940 static gboolean _tcore_util_marshal_convert_str_to_type(GValue *src,
941                 GValue *dest, unsigned int dest_type)
942 {
943         if (dest_type == G_TYPE_HASH_TABLE)
944                 dest_type = G_TYPE_BOXED;
945
946         switch (dest_type) {
947                 case G_TYPE_INT: {
948                         gint64 tmp = 0;
949                         tmp = g_ascii_strtoll(g_value_get_string(src), NULL, 10);
950                         g_value_set_int(dest, tmp);
951                 }
952                         break;
953                 case G_TYPE_BOOLEAN: {
954                         gboolean tmp = FALSE;
955                         tmp = g_ascii_strncasecmp(g_value_get_string(src), "TRUE", 4) == 0
956                                         ? TRUE : FALSE;
957                         g_value_set_boolean(dest, tmp);
958                 }
959                         break;
960                 case G_TYPE_STRING: {
961                         const gchar* tmp = NULL;
962                         tmp = g_value_get_string(src);
963                         g_value_set_string(dest, tmp);
964                 }
965                         break;
966                 case G_TYPE_DOUBLE: {
967                         gdouble tmp = 0;
968                         tmp = g_ascii_strtod(g_value_get_string(src), NULL);
969                         g_value_set_double(dest, tmp);
970                 }
971                         break;
972                 case G_TYPE_BOXED: {
973                         GHashTable* tmp;
974                         tmp = tcore_util_marshal_deserialize_string(g_value_get_string(src));
975                         g_value_set_boxed(dest, tmp);
976                 }
977                         break;
978                 default: {
979                         return FALSE;
980                 }
981                         break;
982         }
983
984         return TRUE;
985 }
986
987 TReturn tcore_util_netif_up(const char *name)
988 {
989         int ret;
990         int fd;
991         struct ifreq ifr;
992
993         if (!name)
994                 return TCORE_RETURN_EINVAL;
995
996         if (strlen(name) > IFNAMSIZ)
997                 return TCORE_RETURN_EINVAL;
998
999         fd = socket(AF_INET, SOCK_DGRAM, 0);
1000         if (fd < 0) {
1001                 return TCORE_RETURN_FAILURE;
1002         }
1003
1004         memset(&ifr, 0, sizeof(struct ifreq));
1005         strncpy(ifr.ifr_name, name, IFNAMSIZ);
1006         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1007
1008         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1009         if (ret < 0) {
1010                 close(fd);
1011                 return TCORE_RETURN_FAILURE;
1012         }
1013
1014         ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
1015
1016         ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
1017         if (ret < 0) {
1018                 close(fd);
1019                 return TCORE_RETURN_FAILURE;
1020         }
1021
1022         close(fd);
1023         return TCORE_RETURN_SUCCESS;
1024 }
1025
1026 TReturn tcore_util_netif_down(const char *name)
1027 {
1028         int ret;
1029         int fd;
1030         struct ifreq ifr;
1031
1032         if (!name)
1033                 return TCORE_RETURN_EINVAL;
1034
1035         if (strlen(name) > IFNAMSIZ)
1036                 return TCORE_RETURN_EINVAL;
1037
1038         fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
1039         if (fd < 0) {
1040                 return TCORE_RETURN_FAILURE;
1041         }
1042
1043         memset(&ifr, 0, sizeof(struct ifreq));
1044         strncpy(ifr.ifr_name, name, IFNAMSIZ);
1045         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1046
1047
1048         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1049         if (ret < 0) {
1050                 close(fd);
1051                 return TCORE_RETURN_FAILURE;
1052         }
1053
1054         ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
1055
1056         ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
1057         if (ret < 0) {
1058                 close(fd);
1059                 return TCORE_RETURN_FAILURE;
1060         }
1061
1062         close(fd);
1063         return TCORE_RETURN_SUCCESS;
1064 }
1065
1066 TReturn tcore_util_netif_set(const char *name, const char *ipaddr,
1067                 const char *gateway, const char *netmask)
1068 {
1069         int ret;
1070         int fd;
1071         struct ifreq ifr;
1072         struct sockaddr_in sai;
1073
1074         if (!name)
1075                 return TCORE_RETURN_EINVAL;
1076
1077         if (strlen(name) > IFNAMSIZ)
1078                 return TCORE_RETURN_EINVAL;
1079
1080         fd = socket(AF_INET, SOCK_DGRAM, 0);
1081         if (fd < 0) {
1082                 return TCORE_RETURN_FAILURE;
1083         }
1084
1085         memset(&sai, 0, sizeof(struct sockaddr_in));
1086         sai.sin_family = AF_INET;
1087         sai.sin_port = 0;
1088         memset(&ifr, 0, sizeof(struct ifreq));
1089
1090         if (ipaddr) {
1091                 dbg("ip = [%s]", ipaddr);
1092                 if (!inet_aton(ipaddr, &sai.sin_addr)) {
1093                         close(fd);
1094                         return TCORE_RETURN_FAILURE;
1095                 }
1096
1097                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1098                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1099                 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
1100
1101                 ret = ioctl(fd, SIOCSIFADDR, &ifr);
1102                 if (ret < 0) {
1103                         close(fd);
1104                         return TCORE_RETURN_FAILURE;
1105                 }
1106         }
1107
1108         if (gateway) {
1109                 dbg("gateway = [%s]", gateway);
1110                 if (!inet_aton(gateway, &sai.sin_addr)) {
1111                         close(fd);
1112                         return TCORE_RETURN_FAILURE;
1113                 }
1114
1115                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1116                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1117                 memcpy(&ifr.ifr_dstaddr, &sai, sizeof(sai));
1118
1119                 ret = ioctl(fd, SIOCSIFDSTADDR, &ifr);
1120                 if (ret < 0) {
1121                         close(fd);
1122                         return TCORE_RETURN_FAILURE;
1123                 }
1124         }
1125
1126         if (netmask) {
1127                 dbg("netmask = [%s]", netmask);
1128                 if (!inet_aton(netmask, &sai.sin_addr)) {
1129                         close(fd);
1130                         return TCORE_RETURN_FAILURE;
1131                 }
1132
1133                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1134                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1135                 memcpy(&ifr.ifr_netmask, &sai, sizeof(sai));
1136
1137                 ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
1138                 if (ret < 0) {
1139                         close(fd);
1140                         return TCORE_RETURN_FAILURE;
1141                 }
1142         }
1143
1144         close(fd);
1145         return TCORE_RETURN_SUCCESS;
1146 }
1147
1148 TReturn tcore_util_reset_ipv4_socket(const char *name, const char* ipaddr)
1149 {
1150         int ret;
1151         int fd;
1152         struct ifreq ifr;
1153         struct sockaddr_in sai;
1154
1155         if (!name)
1156                 return TCORE_RETURN_EINVAL;
1157
1158         if (strlen(name) > IFNAMSIZ)
1159                 return TCORE_RETURN_EINVAL;
1160
1161         fd = socket(AF_INET, SOCK_DGRAM, 0);
1162         if (fd < 0) {
1163                 return TCORE_RETURN_FAILURE;
1164         }
1165
1166         memset(&sai, 0, sizeof(struct sockaddr_in));
1167         sai.sin_family = AF_INET;
1168         sai.sin_port = 0;
1169         if (ipaddr) {
1170                 if (!inet_aton(ipaddr, &sai.sin_addr)) {
1171                         dbg("fail to inet_aton()");
1172                         close(fd);
1173                         return TCORE_RETURN_FAILURE;
1174                 }
1175         }
1176
1177         memset(&ifr, 0, sizeof(struct ifreq));
1178         memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
1179         strncpy(ifr.ifr_name, name, IFNAMSIZ);
1180         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1181
1182         if(!ipaddr) {
1183                 ret = ioctl(fd, SIOCGIFADDR, &ifr);
1184                 if (ret < 0) {
1185                         dbg("fail to ioctl[SIOCGIFADDR]!!!");
1186                         close(fd);
1187                         return TCORE_RETURN_FAILURE;
1188                 }
1189         }
1190         /* SIOCKILLADDR is initially introduced in Android OS. */
1191 #ifndef SIOCKILLADDR
1192 #define SIOCKILLADDR    0x8939
1193 #endif
1194         ret = ioctl(fd, SIOCKILLADDR, &ifr);
1195         if (ret < 0) {
1196                 dbg("fail to ioctl[SIOCKILLADDR]!!!");
1197                 close(fd);
1198                 return TCORE_RETURN_FAILURE;
1199         }
1200
1201         if(ipaddr) {
1202                 dbg("devname: %s, ipaddr: %s", name, ipaddr);
1203         } else {
1204                 memset(&sai, 0, sizeof(struct sockaddr_in));
1205                 memcpy(&sai, &ifr.ifr_addr, sizeof(struct sockaddr_in));
1206                 dbg("devname: %s, ipaddr: %s", name, inet_ntoa(sai.sin_addr));
1207         }
1208         close(fd);
1209         return TCORE_RETURN_SUCCESS;
1210 }
1211
1212 TReturn tcore_util_netif_set_mtu(const char *name, unsigned int mtu)
1213 {
1214         int ret;
1215         int fd;
1216         struct ifreq ifr;
1217
1218         if (!name)
1219                 return TCORE_RETURN_EINVAL;
1220
1221         if (strlen(name) > IFNAMSIZ)
1222                 return TCORE_RETURN_EINVAL;
1223
1224         fd = socket(AF_INET, SOCK_DGRAM, 0);
1225         if (fd < 0) {
1226                 return TCORE_RETURN_FAILURE;
1227         }
1228
1229         memset(&ifr, 0, sizeof(struct ifreq));
1230         strncpy(ifr.ifr_name, name, IFNAMSIZ);
1231         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1232         ifr.ifr_data = (void*)mtu;
1233
1234         ret = ioctl(fd, SIOCSIFMTU, &ifr);
1235         if (ret < 0) {
1236                 dbg("fail to ioctl[SIOCSIFMTU]!!!");
1237                 close(fd);
1238                 return TCORE_RETURN_FAILURE;
1239         }
1240
1241         close(fd);
1242         return TCORE_RETURN_SUCCESS;
1243 }
1244
1245 char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip)
1246 {
1247         char buf[16]; /* 'nnn'*4 + '.'*3 + '\0' */
1248
1249         snprintf(buf, 16, "%d.%d.%d.%d", ip.s[0], ip.s[1], ip.s[2], ip.s[3]);
1250
1251         return strdup(buf);
1252 }
1253
1254 enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode)
1255 {
1256         enum tcore_dcs_type dcs = TCORE_DCS_TYPE_NONE;
1257
1258         switch (encode & 0xf0)
1259         {
1260                 case 0x00:
1261                 case 0x20:
1262                 case 0x30:
1263                         dcs = TCORE_DCS_TYPE_7_BIT;
1264                         break;
1265
1266                 case 0x10:
1267                         if ((encode & 0x0f) == 0x00)
1268                                 dcs = TCORE_DCS_TYPE_7_BIT;
1269                         else if ((encode & 0x0f) == 0x01)
1270                                 dcs = TCORE_DCS_TYPE_8_BIT; //should be re-defined
1271                         else
1272                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1273                         break;
1274
1275                 case 0x40:
1276                 case 0x50:
1277                 case 0x60:
1278                 case 0x70: // 01xx
1279                         if ((encode & 0x0c) == 0x00)
1280                                 dcs = TCORE_DCS_TYPE_7_BIT;
1281                         else if ((encode & 0x0c) == 0x04)
1282                                 dcs = TCORE_DCS_TYPE_8_BIT;
1283                         else if ((encode & 0x0c) == 0x08)
1284                                 dcs = TCORE_DCS_TYPE_UCS2;
1285                         else if ((encode & 0x0c) == 0x0c)
1286                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1287                         break;
1288
1289                 case 0x90: // 1001
1290                         if ((encode & 0x0c) == 0x00)
1291                                 dcs = TCORE_DCS_TYPE_7_BIT;
1292                         else if ((encode & 0x0c) == 0x04)
1293                                 dcs = TCORE_DCS_TYPE_8_BIT;
1294                         else if ((encode & 0x0c) == 0x08)
1295                                 dcs = TCORE_DCS_TYPE_UCS2;
1296                         else if ((encode & 0x0c) == 0x0c)
1297                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1298                         break;
1299
1300                 case 0x80: // 1000
1301                 case 0xA0:
1302                 case 0xB0:
1303                 case 0xC0:
1304                 case 0xD0: // 1010 .. 1101
1305                 case 0xE0: // 0x1110
1306                         break;
1307
1308                 case 0xF0:
1309                         if ((encode & 0x04) == 0x00)
1310                                 dcs = TCORE_DCS_TYPE_7_BIT;
1311                         else if ((encode & 0x04) == 0x04)
1312                                 dcs = TCORE_DCS_TYPE_8_BIT;
1313                         break;
1314                 default:
1315                         err("invalid encoding type");
1316                         break;
1317         }
1318
1319         return dcs;
1320 }
1321
1322 #define CONVERT_HEXCHAR_TO_INT(h, i) if ((h) >= '0' && (h) <= '9') (i) = (h) - '0'; \
1323         else if ((h) >= 'A' && (h) <= 'F') (i) = (h) - 'A' + 10; \
1324         else if ((h) >= 'a' && (h) <= 'f') (i) = (h) - 'a' + 10; \
1325         else (i) = 0;
1326
1327
1328 unsigned char *tcore_util_decode_hex(const char *src, int len)
1329 {
1330         unsigned char *buf;
1331         int i = 0;
1332         int j = 0;
1333         int out_len = 0;
1334         int value1 = 0;
1335         int value2 = 0;
1336
1337         if (!src)
1338                 return NULL;
1339
1340         if (len == -1) {
1341                 out_len = strlen(src) / 2 + 1;
1342         }
1343         else {
1344                 out_len = len;
1345         }
1346
1347         buf = calloc(1, out_len);
1348         if (!buf)
1349                 return NULL;
1350
1351         for (; j < out_len; i+= 2, j++) {
1352                 CONVERT_HEXCHAR_TO_INT(src[i], value1);
1353                 CONVERT_HEXCHAR_TO_INT(src[i+1], value2);
1354
1355                 buf[j] = (value1 << 4) + value2;
1356         }
1357
1358         return buf;
1359 }
1360
1361 void tcore_util_hex_dump(const char *pad, int size, const void *data)
1362 {
1363         char buf[255] = {0, };
1364         char hex[4] = {0, };
1365         int i = 0;
1366         unsigned char *p = NULL;
1367
1368         if (0 >= size) {
1369                 msg("%sno data", pad);
1370                 return;
1371         }
1372
1373         p = (unsigned char *)data;
1374
1375         g_snprintf(buf, 255, "%s%04X: ", pad, 0);
1376         for (i = 0; i<size; i++) {
1377                 g_snprintf(hex, 4, "%02X ", p[i]);
1378                 memcpy(buf+strlen(buf), hex, 4);
1379
1380                 if ((i + 1) % 8 == 0) {
1381                         if ((i + 1) % 16 == 0) {
1382                                 msg("%s", buf);
1383                                 memset(buf, 0, 255);
1384                                 snprintf(buf, 255, "%s%04X: ", pad, i + 1);
1385                         }
1386                         else {
1387                                 strncat(buf, TAB_SPACE, strlen(TAB_SPACE));
1388                         }
1389                 }
1390         }
1391
1392         msg("%s", buf);
1393 }
1394
1395 unsigned char *tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len)
1396 {
1397         unsigned char *dest;
1398         int i = 0, j = 0;
1399         unsigned int pos = 0;
1400         unsigned char shift = 0;
1401         int outlen = 0;
1402
1403         if (!src || src_len == 0) {
1404                 return NULL;
1405         }
1406
1407         outlen = (src_len * 8) / 7;
1408
1409         dest = calloc(1, outlen + 1);
1410         if (!dest)
1411                 return NULL;
1412
1413         for (i = 0; pos < src_len; i++, pos++) {
1414                 dest[i] = (src[pos] << shift) & 0x7F;
1415
1416                 if (pos != 0) {
1417                         /* except the first byte, a character contains some bits from the previous byte.*/
1418                         dest[i] |= src[pos - 1] >> (8 - shift);
1419                 }
1420
1421                 shift++;
1422
1423                 if (shift == 7) {
1424                         shift = 0;
1425
1426                         /* a possible extra complete character is available */
1427                         i++;
1428                         dest[i] = src[pos] >> 1;
1429                 }
1430         }
1431
1432         /*If a character is '\r'(13), change it to space(32) */
1433         for (i = 0, j=0; i < outlen; i++, j++) {
1434                 if (dest[i] == '\r') {
1435                         dest[j] = ' ';
1436
1437                 } else if (dest[i] == 0x1B) { /*If a charater is 0x1B (escape), next charater is changed on gsm 7bit extension table */
1438                         dest[j] = _convert_gsm7bit_extension( dest[++i] );
1439
1440                 } else {
1441                         dest[j] = dest[i];
1442                 }
1443         }
1444
1445         outlen -= ( i - j );
1446
1447         dest[outlen] = '\0';
1448
1449         return dest;
1450 }
1451
1452 unsigned char *tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len)
1453 {
1454         unsigned char *dest;
1455         unsigned int i = 0;
1456         unsigned int pos = 0, shift = 0;
1457         unsigned int outlen = 0;
1458
1459         if (!src || src_len == 0) {
1460                 return NULL;
1461         }
1462
1463         outlen = ((src_len * 7) / 8) + 1;
1464
1465         dest = calloc(1, outlen + 1);
1466         if (!dest)
1467                 return NULL;
1468
1469         for (pos = 0, i = 0; i < src_len; pos++, i++) {
1470                 if (pos >= outlen) {
1471                         free(dest);
1472                         return NULL;
1473                 }
1474
1475                 /* pack the low bits */
1476                 dest[pos] = src[i] >> shift;
1477
1478                 if (i + 1 < src_len) {
1479                         /* pack the high bits using the low bits of the next character */
1480                         dest[pos] |= src[i + 1] << (7 - shift);
1481
1482                         shift++;
1483
1484                         if (shift == 7) {
1485                                 shift = 0;
1486                                 i++;
1487                         }
1488                 }
1489                 else {
1490                         if (shift == 6)
1491                                 dest[pos] |= 0x1a;
1492                 }
1493         }
1494
1495         return dest;
1496 }
1497
1498 char* tcore_util_convert_bcd_str_2_ascii_str(const char* src, int src_len)
1499 {
1500         int count = 0;
1501         char *dest = NULL;
1502
1503         if(!src)
1504                 return NULL;
1505
1506         dest = malloc((src_len+1)*sizeof(char));
1507         if (!dest)
1508                 return NULL;
1509
1510         memset(dest, 0, (src_len+1)*sizeof(char));
1511
1512         for(count = 0; count < src_len; count++){
1513                 switch(src[count]){
1514                         case 0x0A:
1515                                 dest[count] = '*';
1516                                 break;
1517                         case 0x0B:
1518                                 dest[count] = '#';
1519                                 break;
1520                         case 0x0C:
1521                                 dest[count] = 'p'; //Pause
1522                                 break;
1523                         case 0x0D:
1524                                 dest[count] = '?'; //Wild Card character
1525                                 break;
1526                         case 0x0E: //ignore, RFU
1527                         case 0x0F:
1528                                 dest[count] = '\0'; //Null termination
1529                                 break;
1530                         default:
1531                                 dest[count] = src[count]+'0'; //digits 0~9
1532                                 break;
1533                 }
1534         }
1535
1536         dest[count] = '\0';
1537         dbg("PARSER - number(%s) len(%d)", dest, strlen(dest));
1538
1539         return dest;
1540 }
1541
1542 char* tcore_util_convert_bcd2ascii(const char* src, int src_len, int max_len)
1543 {
1544         int count = 0, len=0;
1545         char l_bcd = 0x00, h_bcd = 0x0F;
1546         char *dest = NULL;
1547
1548         if(!src)
1549                 return NULL;
1550
1551         if(src_len*2 > max_len){
1552                 err("PARSER - number length exceeds the max");
1553                 return NULL;
1554         }
1555
1556         dest = malloc((src_len*2)*sizeof(char)+1);
1557         if (!dest)
1558                 return NULL;
1559
1560         memset(dest, 0, (src_len*2)*sizeof(char)+1);
1561
1562         for(count = 0; count < src_len; count++){
1563                 l_bcd = src[count] & 0x0F;
1564                 h_bcd = (src[count] & 0xF0) >> 0x04;
1565
1566                 switch(l_bcd){
1567                         case 0x0A:
1568                                 dest[len++] = '*';
1569                                 break;
1570                         case 0x0B:
1571                                 dest[len++] = '#';
1572                                 break;
1573                         case 0x0C:
1574                                 dest[len++] = 'p'; //Pause
1575                                 break;
1576                         case 0x0D:
1577                                 dest[len++] = '?'; //Wild Card character
1578                                 break;
1579                         case 0x0E: //ignore, RFU
1580                         case 0x0F: //ignore in l_bcd
1581                                 break;
1582                         default:
1583                                 dest[len++] = l_bcd+'0'; //digits 0~9
1584                                 break;
1585                 }//l_lbcd switch
1586
1587                 switch(h_bcd){
1588                         case 0x0A:
1589                                 dest[len++] = '*';
1590                                 break;
1591                         case 0x0B:
1592                                 dest[len++] = '#';
1593                                 break;
1594                         case 0x0C:
1595                                 dest[len++] = 'p'; //Pause
1596                                 break;
1597                         case 0x0D:
1598                                 dest[len++] = '?'; //Wild Card character
1599                                 break;
1600                         case 0x0E: //ignore, RFU
1601                         case 0x0F:
1602                                 dest[len] = '\0'; //Null termination
1603                                 break;
1604                         default:
1605                                 dest[len++] = h_bcd+'0'; //digits 0~9
1606                                 break;
1607                 }//h_bcd switch
1608         }
1609
1610         if(h_bcd != 0x0F)
1611                 dest[len] = '\0';
1612
1613         dbg("PARSER - number(%s) len(%d)", dest, len);
1614         return dest;
1615 }
1616
1617 char* tcore_util_convert_digit2ascii(const char* src, int src_len)
1618 {
1619         int count = 0;
1620         char *dest = NULL;
1621
1622         if(!src)
1623                 return NULL;
1624
1625         dest = malloc((src_len+1)*sizeof(char));
1626         if(!dest)
1627                 return NULL;
1628
1629         memset(dest, 0, (src_len+1)*sizeof(char));
1630
1631         for(count = 0; count < src_len; count++){
1632                 dest[count] = src[count] + '0';
1633         }
1634         dest[count] = '\0';
1635
1636         dbg("PARSER - number(%s) len(%d)", dest, strlen(dest));
1637         return dest;
1638 }
1639
1640
1641 GHashTable *tcore_util_marshal_create()
1642 {
1643         GHashTable *ht = NULL;
1644
1645         ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1646                         _tcore_util_marshal_remove_value);
1647
1648         return ht;
1649 }
1650
1651 void tcore_util_marshal_destory(GHashTable *ht)
1652 {
1653         if (!ht)
1654                 return;
1655
1656         g_hash_table_destroy(ht);
1657 }
1658
1659
1660 GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string)
1661 {
1662         int count = 0;
1663         gchar **tuple = NULL;
1664         GHashTable *ht = NULL;
1665         GValue src = G_VALUE_INIT;
1666
1667         if (!serialized_string)
1668                 return NULL;
1669
1670         ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1671                         _tcore_util_marshal_remove_value);
1672
1673         if (strlen(serialized_string) == 0) {
1674                 return ht;
1675         }
1676
1677         g_value_init(&src, G_TYPE_STRING);
1678
1679         tuple = g_strsplit(serialized_string, " ", 0);
1680
1681         while (strlen(tuple[count]) > 3) {
1682                 int tmp = 0;
1683                 guchar *content = NULL;
1684                 gchar **inner_tuple = NULL;
1685                 GValue *dest = g_new0(GValue, 1);
1686                 unsigned int type = 0;
1687
1688                 inner_tuple = g_strsplit(tuple[count], ":", 0);
1689                 type = atoi(inner_tuple[1]);
1690                 content = g_base64_decode(inner_tuple[2], (gsize *)&tmp);
1691
1692                 g_value_init(dest, type);
1693
1694                 g_value_set_string(&src, (const gchar *)content);
1695                 _tcore_util_marshal_convert_str_to_type(&src, dest, type);
1696                 g_hash_table_insert(ht, g_strdup(inner_tuple[0]), dest);
1697
1698                 g_value_reset(&src);
1699                 g_free(content);
1700                 g_strfreev(inner_tuple);
1701                 count++;
1702         }
1703
1704         g_strfreev(tuple);
1705         return ht;
1706 }
1707
1708 gchar *tcore_util_marshal_serialize(GHashTable *ht)
1709 {
1710         gchar *rv_str = NULL;
1711         GHashTableIter iter;
1712         gpointer key, value;
1713         GString *gstring_tmp = NULL;
1714
1715         gstring_tmp = g_string_new(NULL);
1716         g_hash_table_iter_init(&iter, ht);
1717         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1718                 unsigned int gtype = 0;
1719                 gchar *tmp = NULL, *encoded_d = NULL;
1720                 GValue gval = { 0,{ { 0 } } };
1721
1722                 g_value_init(&gval, G_TYPE_STRING);
1723
1724                 gtype = ((GValue *) value)->g_type;
1725                 if (gtype != G_TYPE_HASH_TABLE) {
1726                         g_value_transform((GValue *) value, &gval);
1727                         tmp = g_value_dup_string(&gval);
1728                 }
1729                 else {
1730                         GHashTable *sub_ht;
1731                         sub_ht = g_value_get_boxed((GValue *) value);
1732                         tmp = tcore_util_marshal_serialize(sub_ht);
1733                 }
1734
1735                 encoded_d = g_base64_encode((guchar *)tmp, (gsize)strlen(tmp));
1736                 g_free(tmp);
1737
1738                 g_string_append_printf(gstring_tmp, "%s:%d:%s ", (gchar *)key,
1739                                 gtype, encoded_d);
1740                 g_free((gpointer)encoded_d);
1741                 g_value_unset(&gval);
1742         }
1743
1744         rv_str = g_strdup(gstring_tmp->str);
1745         g_string_free(gstring_tmp, TRUE);
1746
1747         return rv_str;
1748 }
1749
1750 gboolean tcore_util_marshal_add_data(GHashTable *ht, const gchar *key,
1751                 const void *data, enum tcore_util_marshal_data_type type)
1752 {
1753         gboolean rv = FALSE;
1754         GValue *value;
1755
1756         if (!ht || !key || !data)
1757                 return FALSE;
1758
1759         if (type >= 0xff)
1760                 return FALSE;
1761
1762         value = g_new0(GValue, 1);
1763
1764         rv = _tcore_util_marshal_create_gvalue(value, data, type);
1765
1766         if (!rv)
1767                 return FALSE;
1768
1769         g_hash_table_insert(ht, g_strdup(key), value);
1770
1771         return TRUE;
1772 }
1773
1774 gboolean tcore_util_marshal_get_data(GHashTable *ht, const gchar *key,
1775                 void **data, enum tcore_util_marshal_data_type type)
1776 {
1777         gboolean rv = FALSE;
1778         gpointer value;
1779
1780         if (!ht || !key || !data)
1781                 return FALSE;
1782
1783         value = g_hash_table_lookup(ht, key);
1784
1785         rv = _tcore_util_return_value((GValue *) value, data, type);
1786         if (!rv)
1787                 return FALSE;
1788
1789         return TRUE;
1790 }
1791
1792 gint tcore_util_marshal_get_int(GHashTable *ht, const gchar *key)
1793 {
1794         gboolean rv = FALSE;
1795         gint rvalue, *tmp = NULL;
1796
1797         if (!ht || !key)
1798                 return 0;
1799
1800         rv = tcore_util_marshal_get_data(ht, key, (void **) &tmp,
1801                         TCORE_UTIL_MARSHAL_DATA_INT_TYPE);
1802         if (!rv)
1803                 return 0;
1804
1805         if (!tmp)
1806                 return 0;
1807
1808         rvalue = *tmp;
1809         g_free(tmp);
1810
1811         return rvalue;
1812 }
1813
1814 gchar *tcore_util_marshal_get_string(GHashTable *ht, const gchar *key)
1815 {
1816         gboolean rv = FALSE;
1817         gchar *rvalue = NULL;
1818
1819         if (!ht || !key)
1820                 return 0;
1821
1822         rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1823                         TCORE_UTIL_MARSHAL_DATA_STRING_TYPE);
1824         if (!rv)
1825                 return NULL;
1826
1827         return rvalue;
1828 }
1829
1830 GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key)
1831 {
1832         gboolean rv = FALSE;
1833         GHashTable *rvalue = NULL;
1834
1835         if (!ht || !key)
1836                 return 0;
1837
1838         rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1839                         TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE);
1840         if (!rv)
1841                 return NULL;
1842
1843         return rvalue;
1844 }
1845
1846 char *tcore_util_get_version(void)
1847 {
1848         return strdup(TCORE_VERSION);
1849 }
1850
1851 void tcore_util_set_log(gboolean enable)
1852 {
1853         tcore_debug = enable;
1854 }
1855