0b10ba55edc365a479737548fe3fb6ccb7ce8155
[platform/core/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
43 static gboolean         _find_gsm_code_exception_table(unsigned short src);
44 static int              _get_gsm_code_size(unsigned short* src, int src_len);
45 static gboolean         _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len);
46 static int                      _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len);
47 static void             _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len,     unsigned char *src, unsigned int src_len);
48 static gboolean         _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len);
49 static char*            _convert_ucs_to_utf8(unsigned char *src, int src_len);
50 static int                      _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len);
51 static int                      _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len);
52 static void             _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len);
53 static int                      _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len);
54
55 typedef struct {
56         char gsm;
57         unsigned short unicode;
58 } GsmUniTable;
59
60 const GsmUniTable gsm_unicode2_table[] = {
61                 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
62                 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
63                 { 0x65, 0x20AC } };
64
65 const GsmUniTable gsm_unicode_table[] = {
66                 { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 },
67                 { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 },
68                 { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 },
69                 { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B },
70                 { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 },
71                 { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 },
72                 { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 },
73                 { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 },
74                 { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, };
75
76
77
78
79 static gboolean _find_gsm_code_exception_table(unsigned short src)
80 {
81         if ((src >= 0x0020 && src <= 0x0023)
82                         || (src >= 0x0025 && src <= 0x003F)
83                         || (src >= 0x0041 && src <= 0x005A)
84                         || (src >= 0x0061 && src <= 0x007A)
85                         || src == 0x000A || src == 0x000D)
86                 return TRUE;
87         return FALSE;
88 }
89
90 static int _get_gsm_code_size(unsigned short* src, int src_len)
91 {
92         gboolean in_table = FALSE;
93         gboolean in_sec_table = FALSE;
94         int i, gsm_len = 0;
95
96         if (NULL == src) {
97                 dbg( "INPUT PARAM was NULL");
98                 return -1;
99         }
100
101         for (; src_len > 0 && src; src_len--) {
102                 if (_find_gsm_code_exception_table(*src) == TRUE) {
103                         src++;
104                         gsm_len++;
105                         continue;
106                 }
107                 in_table = FALSE;
108                 for (i = 0; i < tabGsmUniMax; i++) {
109                         if (*src == gsm_unicode_table[i].unicode) {
110                                 src++;
111                                 in_table = TRUE;
112                                 gsm_len++;
113                                 break;
114                         }
115                 }
116                 if (in_table == FALSE) {
117                         in_sec_table = FALSE;
118                         for (i = 0; i < tabGsmUniMax2; i++) {/* second table */
119                                 if (*src == gsm_unicode2_table[i].unicode) {
120                                         src++;
121                                         in_table = TRUE;
122                                         in_sec_table = TRUE;
123                                         gsm_len += 2;
124                                         break;
125                                 }
126                         }
127                         if (in_sec_table == FALSE) {/* second*/
128                                 if (_find_gsm_code_exception_table(*src) == FALSE) {
129                                         dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len);
130                                         return -1;
131                                 }
132                                 src++;
133                                 gsm_len++;
134                         }
135                 }
136         }
137         return gsm_len;
138 }
139
140 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
141 {
142         int index, tmp_len;
143
144         if(!dest || !src) {
145                 dbg( "dest(%p) or src(%p) is null",dest, src);
146                 return FALSE;
147         }
148
149         if(!src_len){
150                 dest[0] = '\0';
151                 return TRUE;
152         }
153
154         dbg("source string (%s) len(%d)", src, src_len);
155
156         for(index = 0; index < (int)src_len; index++){
157                 if(src[index] == 0x1B)
158                         src_len--;
159         }
160         dbg("strlen excluding escape character (%d)", src_len);
161
162         tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
163         dest[tmp_len] = '\0';
164
165         return TRUE;
166 }
167
168 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
169 {
170         int index;
171         unsigned short* org;
172
173         org = dest;
174
175         for(index=0; index < (int)src_len; index++){
176                 int table_index=0;
177                 gboolean b_tabled = FALSE;
178
179                 /*
180                  * if the first byte is 0x1B, it is the escape character.
181                  * The byte value shoulbe be changed to unicode.
182                  */
183                 if(*src == 0x1B){
184                         src++; index++;//move to next byte
185                         for(table_index=0; table_index < tabGsmUniMax2; table_index++){
186                                 if(*src == gsm_unicode2_table[table_index].gsm){
187                                         *dest = gsm_unicode2_table[table_index].unicode;
188                                         b_tabled = TRUE;
189                                         break;
190                                 }
191                         }
192
193                         //if matched data is not in table, it should be changed to NULL;
194                         if(!b_tabled){
195                                 *dest = 0x0020;
196                         }
197                 }
198                 else{
199                         for(table_index=0; table_index < tabGsmUniMax; table_index++){
200                                 if(*src == gsm_unicode_table[table_index].gsm){
201                                         *dest = gsm_unicode_table[table_index].unicode;
202                                         b_tabled = TRUE;
203                                         break;
204                                 }
205                         }
206
207                         //if matched data is not in table, it is using original value;
208                         if(!b_tabled){
209                                 *dest = *src;
210                         }
211                 }
212
213                 //move to next position
214                 src++; dest++;
215         }
216
217         dbg("cvt sr(%s), the size of data (%d) ", org, dest - org);
218         return (dest - org);
219 }
220
221 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
222 {
223         int tmp_len = 0;
224         char *target_tmp = NULL;
225         unsigned char *raw_unicode = NULL;
226         unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
227
228         memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
229
230         _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
231         while(tmp_dest[tmp_len] != '\0')
232                 tmp_len++;
233         tmp_len++; // add null character
234
235         tmp_len = tmp_len*2; //for byte align
236         raw_unicode = (unsigned char*)malloc(tmp_len);
237         memset(raw_unicode, 0, tmp_len);
238
239         memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
240
241         *dest_len = tmp_len;
242         target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
243         if(!target_tmp){
244                 dbg( "str is NULL");
245                 g_free(raw_unicode);
246                 return;
247         }
248
249         memcpy(dest, target_tmp, strlen((const char*)target_tmp));
250         dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
251
252         g_free(raw_unicode);
253         g_free(target_tmp);
254         return;
255 }
256
257 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
258 {
259         char* tmp_str;
260         int gc_len = 0;
261
262         if ((NULL == dest) || (NULL == src)) {
263                 dbg( "INPUT PARAM was NULL");
264                 return FALSE;
265         }
266
267         if (src_len == 0)
268                 return FALSE;
269
270         gc_len = _get_gsm_code_size(src, src_len);
271         if (0 >= gc_len) {
272                 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
273                 return FALSE;
274         }
275
276         if (dest_len < gc_len) {
277                 if (dest_len == sizeof(void*)) {
278                         dbg( "Out buffer size seems to be small (%s)", dest);
279                 } else {
280                         dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
281                 }
282                 return FALSE;
283         }
284
285         tmp_str = calloc(1, (unsigned short) gc_len);
286         if (tmp_str == NULL) {
287                 dbg( "Memory Allocation Failed!");
288                 return FALSE;
289         }
290
291         gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
292         if (gc_len != -1) {
293                 memcpy((char*) dest, (char*) tmp_str, gc_len);
294                 free(tmp_str);
295                 return TRUE;
296         }
297
298         free(tmp_str);
299         return FALSE;
300 }
301
302 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
303 {
304         char* utf_str = NULL;
305         iconv_t cd = NULL;
306         size_t ileft = 0;
307         size_t oleft = 0;
308         int err = 0;
309
310         char* pIn = NULL;
311         char* in_buf = NULL;
312         char* out_buf = NULL;
313
314         if (!src) {
315                 dbg("src is null");
316                 return NULL;
317         }
318
319         ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes
320         oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes
321         pIn = in_buf = (char*) malloc(ileft + 2);
322         utf_str = out_buf = (char *) malloc(oleft + 1);
323
324         memset(in_buf, 0x00, ileft + 2);
325         memset(out_buf, 0x00, oleft + 1);
326         memcpy(in_buf, src, ileft);
327
328         in_buf[ileft] = '\0';
329
330         cd = iconv_open("UTF-8", "UCS-2");
331         err = iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft);
332
333         utf_str[src_len * 2 - ileft] = '\0';
334         iconv_close(cd);
335         free(pIn);
336         return utf_str;
337 }
338
339 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
340 {
341         unsigned char* rear = NULL;
342         unsigned short* p;
343         unsigned char temp;
344         gboolean in_table = FALSE;
345         gboolean in_sec_table = FALSE;
346         int i, gc_len = 0;
347
348         if ((!dest) || (!src) || (0x00 == src_len)) {
349                 dbg( "Warning: Wrong Input");
350                 return -1;
351         }
352
353         rear = dest;
354         p = src;
355
356         for (; src_len > 0 && p; src_len--) {
357                 in_table = FALSE;
358                 for (i = 0; i < tabGsmUniMax; i++) { /* is in table  */
359                         if (*p == gsm_unicode_table[i].unicode) {
360                                 temp = (unsigned char) (gsm_unicode_table[i].gsm);
361                                 *rear = temp;
362                                 rear++;
363                                 p++;
364                                 in_table = TRUE;
365                                 gc_len++;
366                                 break;
367                         }
368                 }
369                 if (in_table == FALSE) {
370                         in_sec_table = FALSE;
371                         for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/
372                                 if (*p == gsm_unicode2_table[i].unicode) {
373                                         *rear = 0x1B;
374                                         rear++;
375                                         temp = (unsigned char) (gsm_unicode2_table[i].gsm);
376                                         *rear = temp;
377                                         rear++;
378                                         p++;
379                                         in_table = TRUE;
380                                         in_sec_table = TRUE;
381                                         gc_len += 2;
382                                         break;
383                                 }
384                         }
385                         if (in_sec_table == FALSE) { /* second */
386                                 if (_find_gsm_code_exception_table(*p) == FALSE)
387                                         return -1;
388                                 temp = (unsigned char) (*p); /* isn't in table. but it's just able to be converted to GSM (0x00?? -> 0x??)*/
389                                 *rear = temp;
390                                 rear++;
391                                 p++;
392                                 gc_len++;
393                         }
394                 }
395         }
396         src = p;
397         return gc_len;
398 }
399
400 static int _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
401 {
402         char *p_o = NULL;
403         size_t src_len = in_len;
404         size_t dest_len = in_len*3;
405
406         iconv_t cd = iconv_open("UTF-8", "UCS2");
407         if (cd == (iconv_t) (-1)) {
408                 perror("iconv_open");
409                 return 0;
410         }
411
412         p_o = out;
413
414         dbg("expected input bytes:%d dest_len:%d\n", src_len, dest_len);
415
416         if (iconv(cd, &in, &src_len, &p_o, &dest_len) == (size_t)(-1)) {
417                 dbg("failed to iconv errno:%d", errno);
418         } else {
419                 dbg("remained input bytes:%d processed bytes:%d", src_len, in_len*3-dest_len);
420                 out[in_len*3-dest_len] = '\0';
421         }
422         *out_len = in_len*3-dest_len;
423         dbg("out_len[%d], output[%s]", *out_len, out);
424         iconv_close(cd);
425         return 0;
426 }
427
428 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len)
429 {
430         //input string UNSIGNED CHAR *IN should be encoded with BIG-ENDIAN
431         switch(in[0]) {
432                 case 0x80: {
433                         unsigned char num = in_len/2;   //number of characters
434                         int i = 0;
435                         int data_loc = 1;       //starting location of data
436                         unsigned short* in_buf = NULL;
437                         dbg("[UCS2] prefix case:[0x80]");
438                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
439                         for(i=0; i<num; i++,data_loc++) {
440                                 in_buf[i] = ((unsigned short)in[data_loc]<<8) + (unsigned short)in[data_loc+1];
441                                 data_loc++;
442                                 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
443                         }
444                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
445                         if(in_buf!=NULL)        free(in_buf);
446                 } break;
447
448                 case 0x81: {
449                         unsigned char num = in[1];      //number of characters
450                         unsigned short base = (unsigned short) in[2] << 7;      //base pointer for UCS2 type
451                         int i = 0;
452                         int data_loc = 3;       //starting location of data
453                         unsigned short* in_buf = NULL;
454                         dbg("[UCS2] prefix case:[0x81]");
455                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
456                         for(i=0; i<num; i++,data_loc++) {
457                                 if(in[data_loc]<0x80) { // if the MSB is zero (0x80 => 1000b), then remaining 7 bits are GSM default character.
458                                         _convert_gsm_to_ucs2(&in_buf[i], (unsigned char *)&in[data_loc], 1);
459                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
460                                 } 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.
461                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
462                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
463                                 }
464                         }
465                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
466                         if(in_buf!=NULL)        free(in_buf);
467
468                 } break;
469
470                 case 0x82: {
471                         unsigned char num = in[1];      //number of characters
472                         unsigned short base = ((unsigned short) in[2] << 8) | (unsigned short) in[3];   //base pointer for UCS2 type
473                         int i = 0;
474                         int data_loc = 4;       //starting location of data
475                         unsigned short* in_buf = NULL;
476                         dbg("[UCS2] prefix case:[0x82]");
477                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
478                         for(i=0; i<num; i++,data_loc++) {
479                                 if(in[data_loc]<0x80) {
480                                         _convert_gsm_to_ucs2(&in_buf[i], (unsigned char *)&in[data_loc], (unsigned int)1);
481                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
482                                 } else {
483                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
484                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
485                                 }
486                         }
487                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
488                         if(in_buf!=NULL)        free(in_buf);
489                 } break;
490
491                 default: {
492                         unsigned char num = in_len/2;   //number of characters
493                         int i = 0;
494                         int data_loc = 0;       //starting location of data
495                         unsigned short* in_buf = NULL;
496                         dbg("[UCS2] non-prefix case.");
497                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
498                         for(i=0; i<num; i++,data_loc++) {
499                                 in_buf[i] = ((unsigned short)in[data_loc]<<8) + (unsigned short)in[data_loc+1];
500                                 data_loc++;
501                                 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
502                         }
503                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
504                         if(in_buf!=NULL)        free(in_buf);
505                 } break;
506         }
507 }
508
509 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
510 {
511         unsigned short* org = NULL;
512         unsigned char hi = 0;
513         unsigned char mid = 0;
514         unsigned char low = 0;
515
516         if ((NULL == dest) || (NULL == src)) {
517                 dbg( "INPUT PARAM NULL");
518                 return -1;
519         }
520
521         org = dest;
522
523         while (src_len > 0 && (*src != '\0')) {
524                 if (*src < 0x80) {
525                         *dest = (*src & 0x7F);
526                         dest++;
527                         src++;
528                         src_len--;
529                 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
530                         hi = *src & 0x1F;
531                         low = *(src+1) & 0x3F;
532                         *dest = (hi << 6) | low;
533                         dest++;
534                         src += 2;
535                         src_len -= 2;
536                 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
537                         hi = *src & 0x0F;
538                         mid = *(src+1) & 0x3F;
539                         low = *(src+2) & 0x3F;
540                         *dest = (hi << 12) | (mid << 6) | low;
541                         dest++;
542                         src += 3;
543                         src_len -= 3;
544                 } else {
545                         *dest = (*src & 0x7F);
546                         dest++;
547                         src++;
548                         src_len--;
549                         dbg( "utf8 incorrect range");
550                 }
551         }
552         *dest = 0;
553         return (dest - org);
554 }
555
556
557
558 gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len)
559 {
560         unsigned short *uc = NULL;
561         int gc_len = 0;
562         int uc_len = 0;
563
564         if (src == NULL || src_len == 0) {
565                 dbg( "WARNING: Invalid Parameter");
566                 return FALSE;
567         }
568
569         uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
570         if (!uc) {
571                 dbg( "WARNING: calloc Failed");
572                 return FALSE;
573         }
574
575         /*Converting from UTF8 => UNICODE*/
576         uc_len = _convert_utf8_to_unicode(uc, src, src_len);
577         dbg( "uc_len:[%d]", uc_len);
578         if(uc_len == -1) {
579                 dbg( "_convert_utf8_to_unicode returns false!");
580                 free(uc);
581                 return FALSE;
582         }
583
584         /*Finding the GSMCode Size*/
585         gc_len = _get_gsm_code_size(uc, uc_len);
586         dbg( "gc_len:[%d]", gc_len);
587         if ( gc_len == -1) {
588                 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]",   gc_len);
589                 free(uc);
590                 return FALSE;
591         }
592
593         *dest_len = gc_len;
594         /*Converting from UNICODE ==> GSM CODE */
595         if (_convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len) == FALSE) {
596                 dbg( "_convert_unicode_to_gsm Failed");
597                 *dest_len = 0x00;
598                 free(uc);
599                 return FALSE;
600         }
601
602         if(uc)
603                 free(uc);
604         return TRUE;
605 }
606
607 gboolean tcore_util_convert_utf8_to_ucs2(unsigned char* dest, int* dest_len,    unsigned char* src, int src_len)
608 {
609         gsize byte_converted = 0;
610         gsize byte_read = 0;
611         gchar* str_converted = NULL;
612         GError *error = NULL;
613         int i;
614         char tmp_char;
615
616         if (dest == NULL || dest_len == NULL || src == NULL) {
617                 dbg( "Invalid Input Parameter");
618                 return FALSE;
619         }
620
621         /*Converting from UTF8 => UCS-2 using the g_convert*/
622         str_converted = (gchar*) g_convert((gchar*) src, (gsize) src_len,
623                                                                                                                                                 (gchar*) "UCS-2", (gchar*) "UTF8",
624                                                                                                                                                 (gsize*) &byte_read, (gsize*) &byte_converted,
625                                                                                                                                                 &error);
626         if (str_converted == NULL) {
627                 dbg( "str_converted is NULL");
628                 if (error != NULL) {
629                         dbg( "Problem while conversion UTF8 => UCS2, ErrorCode[%d]", error->code);
630                 }
631                 return FALSE;
632         }
633
634         dbg( "src_len[%u], byte_read[%u], byte_converted[%u]", src_len, byte_read, byte_converted);
635         *dest_len = (int) byte_converted;
636
637         if (byte_converted % 2 != 0) {
638                 dbg( "string length is wrong!");
639         } else {
640                 for (i = 0; i < (int)byte_converted; i++) {
641                         if (i % 2 == 0) {
642                                 tmp_char = str_converted[i];
643                                 str_converted[i] = str_converted[i + 1];
644                                 str_converted[i + 1] = tmp_char;
645                         }
646                 }
647         }
648         memcpy((unsigned char*) dest, (unsigned char*) str_converted, byte_converted);
649         g_free(str_converted);
650         return TRUE;
651 }
652
653 gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len,
654                 enum alphabet_format dcs, const unsigned char *src, unsigned short src_len)
655 {
656         dbg("dcs=[0x%02x]", dcs );
657         dbg("src=[%s], src_len=[%d]", src, src_len);
658
659         if(src==NULL || src_len==0) {
660                 err("src is NULL or src_len is 0");
661                 return FALSE;
662         }
663
664         switch (dcs) {
665                 case ALPHABET_FORMAT_SMS_DEFAULT: {
666                         unsigned char* tmp_dest_str = NULL;
667                         dbg( "case : [ALPHABET_FORMAT_SMS_DEFAULT]");
668                         tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len);
669
670                         if(!tmp_dest_str) {
671                                 err("temp_dest_str is NULL");
672                                 return FALSE;
673                         }
674                         _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
675                         if(tmp_dest_str) {
676                                 free(tmp_dest_str);
677                         }
678                 }       break;
679
680                 case ALPHABET_FORMAT_8BIT_DATA: {       //GSM7bit with bit 8 set to 0
681                         int tmp_str_len = 0;
682                         unsigned char *src_buf = NULL;
683                         src_buf = (unsigned char*)malloc(src_len);
684                         if(NULL == src_buf){
685                                 err("src_buf is NULL!");
686                                 return FALSE;
687                         }
688                         memcpy(src_buf, src, src_len);
689
690                         /*get string length*/
691                         /* 0xFF is the end of string */
692                         while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
693                                 tmp_str_len++;
694                         }
695                         /* last space character must be deleted */
696                         while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
697                                 tmp_str_len--;
698                         }
699                         dbg( "case : [ALPHABET_FORMAT_8BIT_DATA]");
700                         dbg( "tmp_str_len[%d]", tmp_str_len);
701
702                         _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len);
703                         free(src_buf);
704                 }       break;
705
706                 case ALPHABET_FORMAT_UCS2: {
707                         unsigned char *src_buf = NULL;
708                         src_buf = (unsigned char*)malloc(src_len);
709                         if(NULL == src_buf){
710                                 err("src_buf is NULL");
711                                 return FALSE;
712                         }
713                         memcpy(src_buf, src, src_len);
714                         dbg( "case : [ALPHABET_FORMAT_UCS2]");
715                         _convert_alpha_field_ucs2_to_utf8(dest, dest_len, src_buf, src_len);
716                         free(src_buf);
717                 }       break;
718
719                 default: {
720                         dbg("not handled alpha format[0x%02x]", dcs);
721                         return FALSE;
722                 }       break;
723         }
724         return TRUE;
725 }
726
727 void tcore_util_swap_byte_order(unsigned short* dest, const unsigned short* src, int src_len)
728 {
729         int i = 0;
730
731         for (i = 0; i < src_len; i++) {
732                 dest[i] = (src[i] << 8) + (src[i] >> 8);
733         }
734 }
735
736 static gboolean _tcore_util_marshal_create_gvalue(GValue *value,
737                 const void *data, enum tcore_util_marshal_data_type type)
738 {
739         switch (type) {
740                 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
741                         g_value_init(value, type);
742                         g_value_set_schar(value, *((gchar *) data));
743                         break;
744
745                 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
746                         g_value_init(value, type);
747                         g_value_set_boolean(value, *((gboolean *) data));
748                         break;
749
750                 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
751                         g_value_init(value, type);
752                         g_value_set_int(value, *((gint *) data));
753                         break;
754
755                 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
756                         g_value_init(value, type);
757                         g_value_set_double(value, *((gdouble *) data));
758                         break;
759
760                 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
761                         g_value_init(value, type);
762                         g_value_set_string(value, (gchar *) data);
763                         break;
764
765                 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
766                         g_value_init(value, G_TYPE_HASH_TABLE);
767                         g_value_set_boxed(value, (gpointer) data);
768                         break;
769
770                 default:
771                         return FALSE;
772                         break;
773         }
774
775         return TRUE;
776 }
777
778
779 static gboolean _tcore_util_return_value(GValue *src, void **dest,
780                 enum tcore_util_marshal_data_type type)
781 {
782         switch (type) {
783                 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
784                         *dest = g_new0(gchar, 1);
785                         *((gchar *) *dest) = g_value_get_schar(src);
786                         break;
787
788                 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
789                         *dest = g_new0(gboolean, 1);
790                         *((gboolean *) *dest) = g_value_get_boolean(src);
791                         break;
792
793                 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
794                         *dest = g_new0(gint, 1);
795                         *((gint *) *dest) = g_value_get_int(src);
796                         break;
797
798                 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
799                         *dest = g_new0(gdouble, 1);
800                         *((gdouble *) *dest) = g_value_get_double(src);
801                         break;
802
803                 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
804                         *dest = g_value_dup_string(src);
805                         break;
806
807                 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
808                         *dest = g_value_dup_boxed(src);
809                         break;
810
811                 default:
812                         return FALSE;
813                         break;
814         }
815
816         return TRUE;
817 }
818
819
820 static void _tcore_util_marshal_remove_value(gpointer value)
821 {
822         unsigned int gtype = 0;
823         GHashTable *ht = NULL;
824
825         gtype = ((GValue *) value)->g_type;
826         if (gtype == G_TYPE_HASH_TABLE) {
827                 ht = g_value_get_boxed(value);
828                 g_hash_table_destroy(ht);
829         }
830
831         g_value_unset((GValue *) value);
832         return;
833 }
834
835 static gboolean _tcore_util_marshal_convert_str_to_type(GValue *src,
836                 GValue *dest, unsigned int dest_type)
837 {
838         if (dest_type == G_TYPE_HASH_TABLE)
839                 dest_type = G_TYPE_BOXED;
840
841         switch (dest_type) {
842                 case G_TYPE_INT: {
843                         gint64 tmp = 0;
844                         tmp = g_ascii_strtoll(g_value_get_string(src), NULL, 10);
845                         g_value_set_int(dest, tmp);
846                 }
847                         break;
848                 case G_TYPE_BOOLEAN: {
849                         gboolean tmp = FALSE;
850                         tmp = g_ascii_strncasecmp(g_value_get_string(src), "TRUE", 4) == 0
851                                         ? TRUE : FALSE;
852                         g_value_set_boolean(dest, tmp);
853                 }
854                         break;
855                 case G_TYPE_STRING: {
856                         const gchar* tmp = NULL;
857                         tmp = g_value_get_string(src);
858                         g_value_set_string(dest, tmp);
859                 }
860                         break;
861                 case G_TYPE_DOUBLE: {
862                         gdouble tmp = 0;
863                         tmp = g_ascii_strtod(g_value_get_string(src), NULL);
864                         g_value_set_double(dest, tmp);
865                 }
866                         break;
867                 case G_TYPE_BOXED: {
868                         GHashTable* tmp;
869                         tmp = tcore_util_marshal_deserialize_string(g_value_get_string(src));
870                         g_value_set_boxed(dest, tmp);
871                 }
872                         break;
873                 default: {
874                         return FALSE;
875                 }
876                         break;
877         }
878
879         return TRUE;
880 }
881
882 TReturn tcore_util_netif_up(const char *name)
883 {
884         int ret;
885         int fd;
886         struct ifreq ifr;
887
888         if (!name)
889                 return TCORE_RETURN_EINVAL;
890
891         if (strlen(name) > IFNAMSIZ)
892                 return TCORE_RETURN_EINVAL;
893
894         fd = socket(AF_INET, SOCK_DGRAM, 0);
895         if (fd < 0) {
896                 return TCORE_RETURN_FAILURE;
897         }
898
899         memset(&ifr, 0, sizeof(struct ifreq));
900         strncpy(ifr.ifr_name, name, IFNAMSIZ);
901         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
902
903         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
904         if (ret < 0) {
905                 close(fd);
906                 return TCORE_RETURN_FAILURE;
907         }
908
909         ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
910
911         ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
912         if (ret < 0) {
913                 close(fd);
914                 return TCORE_RETURN_FAILURE;
915         }
916
917         close(fd);
918         return TCORE_RETURN_SUCCESS;
919 }
920
921 TReturn tcore_util_netif_down(const char *name)
922 {
923         int ret;
924         int fd;
925         struct ifreq ifr;
926
927         if (!name)
928                 return TCORE_RETURN_EINVAL;
929
930         if (strlen(name) > IFNAMSIZ)
931                 return TCORE_RETURN_EINVAL;
932
933         fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
934         if (fd < 0) {
935                 return TCORE_RETURN_FAILURE;
936         }
937
938         memset(&ifr, 0, sizeof(struct ifreq));
939         strncpy(ifr.ifr_name, name, IFNAMSIZ);
940         ifr.ifr_name[IFNAMSIZ - 1] = '\0';
941
942
943         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
944         if (ret < 0) {
945                 close(fd);
946                 return TCORE_RETURN_FAILURE;
947         }
948
949         ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
950
951         ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
952         if (ret < 0) {
953                 close(fd);
954                 return TCORE_RETURN_FAILURE;
955         }
956
957         close(fd);
958         return TCORE_RETURN_SUCCESS;
959 }
960
961 TReturn tcore_util_netif_set(const char *name, const char *ipaddr,
962                 const char *gateway, const char *netmask)
963 {
964         int ret;
965         int fd;
966         struct ifreq ifr;
967         struct sockaddr_in sai;
968
969         if (!name)
970                 return TCORE_RETURN_EINVAL;
971
972         if (strlen(name) > IFNAMSIZ)
973                 return TCORE_RETURN_EINVAL;
974
975         fd = socket(AF_INET, SOCK_DGRAM, 0);
976         if (fd < 0) {
977                 return TCORE_RETURN_FAILURE;
978         }
979
980         memset(&sai, 0, sizeof(struct sockaddr_in));
981         sai.sin_family = AF_INET;
982         sai.sin_port = 0;
983         memset(&ifr, 0, sizeof(struct ifreq));
984
985         if (ipaddr) {
986                 dbg("ip = [%s]", ipaddr);
987                 if (!inet_aton(ipaddr, &sai.sin_addr)) {
988                         close(fd);
989                         return TCORE_RETURN_FAILURE;
990                 }
991
992                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
993                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
994                 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
995
996                 ret = ioctl(fd, SIOCSIFADDR, &ifr);
997                 if (ret < 0) {
998                         close(fd);
999                         return TCORE_RETURN_FAILURE;
1000                 }
1001         }
1002
1003         if (gateway) {
1004                 dbg("gateway = [%s]", gateway);
1005                 if (!inet_aton(gateway, &sai.sin_addr)) {
1006                         close(fd);
1007                         return TCORE_RETURN_FAILURE;
1008                 }
1009
1010                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1011                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1012                 memcpy(&ifr.ifr_dstaddr, &sai, sizeof(sai));
1013
1014                 ret = ioctl(fd, SIOCSIFDSTADDR, &ifr);
1015                 if (ret < 0) {
1016                         close(fd);
1017                         return TCORE_RETURN_FAILURE;
1018                 }
1019         }
1020
1021         if (netmask) {
1022                 dbg("netmask = [%s]", netmask);
1023                 if (!inet_aton(netmask, &sai.sin_addr)) {
1024                         close(fd);
1025                         return TCORE_RETURN_FAILURE;
1026                 }
1027
1028                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1029                 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1030                 memcpy(&ifr.ifr_netmask, &sai, sizeof(sai));
1031
1032                 ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
1033                 if (ret < 0) {
1034                         close(fd);
1035                         return TCORE_RETURN_FAILURE;
1036                 }
1037         }
1038
1039         close(fd);
1040         return TCORE_RETURN_SUCCESS;
1041 }
1042
1043 char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip)
1044 {
1045         char buf[16]; /* 'nnn'*4 + '.'*3 + '\0' */
1046
1047         snprintf(buf, 16, "%d.%d.%d.%d", ip.s[0], ip.s[1], ip.s[2], ip.s[3]);
1048
1049         return strdup(buf);
1050 }
1051
1052 enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode)
1053 {
1054         enum tcore_dcs_type dcs = TCORE_DCS_TYPE_NONE;
1055
1056         switch (encode & 0xf0)
1057         {
1058                 case 0x00:
1059                 case 0x20:
1060                 case 0x30:
1061                         dcs = TCORE_DCS_TYPE_7_BIT;
1062                         break;
1063
1064                 case 0x10:
1065                         if ((encode & 0x0f) == 0x00)
1066                                 dcs = TCORE_DCS_TYPE_7_BIT;
1067                         else if ((encode & 0x0f) == 0x01)
1068                                 dcs = TCORE_DCS_TYPE_8_BIT; //should be re-defined
1069                         else
1070                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1071                         break;
1072
1073                 case 0x40:
1074                 case 0x50:
1075                 case 0x60:
1076                 case 0x70: // 01xx
1077                         if ((encode & 0x0c) == 0x00)
1078                                 dcs = TCORE_DCS_TYPE_7_BIT;
1079                         else if ((encode & 0x0c) == 0x04)
1080                                 dcs = TCORE_DCS_TYPE_8_BIT;
1081                         else if ((encode & 0x0c) == 0x08)
1082                                 dcs = TCORE_DCS_TYPE_UCS2;
1083                         else if ((encode & 0x0c) == 0x0c)
1084                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1085                         break;
1086
1087                 case 0x90: // 1001
1088                         if ((encode & 0x0c) == 0x00)
1089                                 dcs = TCORE_DCS_TYPE_7_BIT;
1090                         else if ((encode & 0x0c) == 0x04)
1091                                 dcs = TCORE_DCS_TYPE_8_BIT;
1092                         else if ((encode & 0x0c) == 0x08)
1093                                 dcs = TCORE_DCS_TYPE_UCS2;
1094                         else if ((encode & 0x0c) == 0x0c)
1095                                 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1096                         break;
1097
1098                 case 0x80: // 1000
1099                 case 0xA0:
1100                 case 0xB0:
1101                 case 0xC0:
1102                 case 0xD0: // 1010 .. 1101
1103                 case 0xE0: // 0x1110
1104                         break;
1105
1106                 case 0xF0:
1107                         if ((encode & 0x04) == 0x00)
1108                                 dcs = TCORE_DCS_TYPE_7_BIT;
1109                         else if ((encode & 0x04) == 0x04)
1110                                 dcs = TCORE_DCS_TYPE_8_BIT;
1111                         break;
1112         }
1113
1114         return dcs;
1115 }
1116
1117 #define CONVERT_HEXCHAR_TO_INT(h, i) if ((h) >= '0' && (h) <= '9') (i) = (h) - '0'; \
1118         else if ((h) >= 'A' && (h) <= 'F') (i) = (h) - 'A' + 10; \
1119         else if ((h) >= 'a' && (h) <= 'f') (i) = (h) - 'a' + 10; \
1120         else (i) = 0;
1121
1122
1123 unsigned char *tcore_util_decode_hex(const char *src, int len)
1124 {
1125         unsigned char *buf;
1126         int i = 0;
1127         int j = 0;
1128         int out_len = 0;
1129         int value1 = 0;
1130         int value2 = 0;
1131
1132         if (!src)
1133                 return NULL;
1134
1135         if (len == -1) {
1136                 out_len = strlen(src) / 2 + 1;
1137         }
1138         else {
1139                 out_len = len;
1140         }
1141
1142         buf = calloc(out_len, 1);
1143         if (!buf)
1144                 return NULL;
1145
1146         for (; j < out_len; i+= 2, j++) {
1147                 CONVERT_HEXCHAR_TO_INT(src[i], value1);
1148                 CONVERT_HEXCHAR_TO_INT(src[i+1], value2);
1149
1150                 buf[j] = (value1 << 4) + value2;
1151         }
1152
1153         return buf;
1154 }
1155
1156 unsigned char *tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len)
1157 {
1158         unsigned char *dest;
1159         int i = 0;
1160         unsigned int pos = 0;
1161         unsigned char shift = 0;
1162         int outlen = 0;
1163
1164         if (!src || src_len == 0) {
1165                 return NULL;
1166         }
1167
1168         outlen = (src_len * 8) / 7;
1169
1170         dest = calloc(outlen + 1, 1);
1171         if (!dest)
1172                 return NULL;
1173
1174         for (i = 0; pos < src_len; i++, pos++) {
1175                 dest[i] = (src[pos] << shift) & 0x7F;
1176
1177                 if (pos != 0) {
1178                         /* except the first byte, a character contains some bits from the previous byte.*/
1179                         dest[i] |= src[pos - 1] >> (8 - shift);
1180                 }
1181
1182                 shift++;
1183
1184                 if (shift == 7) {
1185                         shift = 0;
1186
1187                         /* a possible extra complete character is available */
1188                         i++;
1189                         dest[i] = src[pos] >> 1;
1190                 }
1191         }
1192
1193         /*If a character is '\r'(13), change it to space(32) */
1194         for (i = 0; i < outlen; i++)
1195                 if (dest[i] == '\r')
1196                         dest[i] = ' ';
1197
1198         dest[outlen] = '\0';
1199
1200         return dest;
1201 }
1202
1203 unsigned char *tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len)
1204 {
1205         unsigned char *dest;
1206         unsigned int i = 0;
1207         unsigned int pos = 0, shift = 0;
1208         unsigned int outlen = 0;
1209
1210         if (!src || src_len == 0) {
1211                 return NULL;
1212         }
1213
1214         outlen = ((src_len * 7) / 8) + 1;
1215
1216         dest = calloc(outlen + 1, 1);
1217         if (!dest)
1218                 return NULL;
1219
1220         for (pos = 0, i = 0; i < src_len; pos++, i++) {
1221                 if (pos >= outlen) {
1222                         free(dest);
1223                         return NULL;
1224                 }
1225
1226                 /* pack the low bits */
1227                 dest[pos] = src[i] >> shift;
1228
1229                 if (i + 1 < src_len) {
1230                         /* pack the high bits using the low bits of the next character */
1231                         dest[pos] |= src[i + 1] << (7 - shift);
1232
1233                         shift++;
1234
1235                         if (shift == 7) {
1236                                 shift = 0;
1237                                 i++;
1238                         }
1239                 }
1240                 else {
1241                         if (shift == 6)
1242                                 dest[pos] |= 0x1a;
1243                 }
1244         }
1245
1246         return dest;
1247 }
1248
1249 char* tcore_util_convert_bcd2ascii(const char* src, int src_len, int max_len)
1250 {
1251         int index = 0, len=0;
1252         char l_bcd = 0x00, h_bcd = 0x0F;
1253         char *dest = NULL;
1254
1255         if(!src)
1256                 return NULL;
1257
1258         if(src_len*2 > max_len){
1259                 err("PARSER - number length exceeds the max");
1260                 return NULL;
1261         }
1262
1263         dest = malloc((src_len*2)*sizeof(char)+1);
1264         memset(dest, 0, (src_len*2)*sizeof(char)+1);
1265
1266         for(index = 0; index < src_len; index++){
1267                 l_bcd = src[index] & 0x0F;
1268                 h_bcd = (src[index] & 0xF0) >> 0x04;
1269
1270                 switch(l_bcd){
1271                         case 0x0A:
1272                                 dest[len++] = '*';
1273                                 break;
1274                         case 0x0B:
1275                                 dest[len++] = '#';
1276                                 break;
1277                         case 0x0C:
1278                                 dest[len++] = 'p'; //Pause
1279                                 break;
1280                         case 0x0D:
1281                                 dest[len++] = '?'; //Wild Card character
1282                                 break;
1283                         case 0x0E: //ignore, RFU
1284                         case 0x0F: //ignore in l_bcd
1285                                 break;
1286                         default:
1287                                 dest[len++] = l_bcd+'0'; //digits 0~9
1288                                 break;
1289                 }//l_lbcd switch
1290
1291                 switch(h_bcd){
1292                         case 0x0A:
1293                                 dest[len++] = '*';
1294                                 break;
1295                         case 0x0B:
1296                                 dest[len++] = '#';
1297                                 break;
1298                         case 0x0C:
1299                                 dest[len++] = 'p'; //Pause
1300                                 break;
1301                         case 0x0D:
1302                                 dest[len++] = '?'; //Wild Card character
1303                                 break;
1304                         case 0x0E: //ignore, RFU
1305                         case 0x0F:
1306                                 dest[len] = '\0'; //Null termination
1307                                 break;
1308                         default:
1309                                 dest[len++] = h_bcd+'0'; //digits 0~9
1310                                 break;
1311                 }//h_bcd switch
1312         }
1313
1314         if(h_bcd != 0x0F)
1315                 dest[len] = '\0';
1316
1317         dbg("PARSER - number(%s) len(%d)", dest, len);
1318         return dest;
1319 }
1320
1321 GHashTable *tcore_util_marshal_create()
1322 {
1323         GHashTable *ht = NULL;
1324
1325         ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1326                         _tcore_util_marshal_remove_value);
1327
1328         return ht;
1329 }
1330
1331 void tcore_util_marshal_destory(GHashTable *ht)
1332 {
1333         if (!ht)
1334                 return;
1335
1336         g_hash_table_destroy(ht);
1337 }
1338
1339
1340 GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string)
1341 {
1342         int index = 0;
1343         gchar **tuple = NULL;
1344         GHashTable *ht = NULL;
1345
1346         ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1347                         _tcore_util_marshal_remove_value);
1348
1349         if (strlen(serialized_string) == 0) {
1350                 return ht;
1351         }
1352
1353         tuple = g_strsplit((gchar *) serialized_string, " ", 0);
1354
1355         while (strlen(tuple[index]) > 3) {
1356                 int tmp = 0;
1357                 guchar *content = NULL;
1358                 gchar **inner_tuple = NULL;
1359                 GValue *src = g_new0(GValue, 1);
1360                 GValue *dest = g_new0(GValue, 1);
1361                 unsigned int type = 0;
1362
1363                 inner_tuple = g_strsplit(tuple[index], ":", 0);
1364                 type = atoi(inner_tuple[1]);
1365                 content = g_base64_decode(inner_tuple[2], (gsize *)&tmp);
1366
1367                 g_value_init(src, G_TYPE_STRING);
1368                 g_value_init(dest, type);
1369
1370                 g_value_set_string(src, (const gchar *)content);
1371                 _tcore_util_marshal_convert_str_to_type(src, dest, type);
1372                 g_hash_table_insert(ht, g_strdup(inner_tuple[0]), dest);
1373
1374                 g_free(content);
1375                 g_strfreev(inner_tuple);
1376                 index++;
1377         }
1378
1379         g_strfreev(tuple);
1380         return ht;
1381 }
1382
1383 gchar *tcore_util_marshal_serialize(GHashTable *ht)
1384 {
1385         gchar *rv_str = NULL;
1386         GHashTableIter iter;
1387         gpointer key, value;
1388         GString *gstring_tmp = NULL;
1389
1390         gstring_tmp = g_string_new(NULL);
1391         g_hash_table_iter_init(&iter, ht);
1392         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1393                 unsigned int gtype = 0;
1394                 gchar *tmp = NULL, *encoded_d = NULL;
1395                 GValue gval = { 0,{ { 0 } } };
1396
1397                 g_value_init(&gval, G_TYPE_STRING);
1398
1399                 gtype = ((GValue *) value)->g_type;
1400                 if (gtype != G_TYPE_HASH_TABLE) {
1401                         g_value_transform((GValue *) value, &gval);
1402                         tmp = g_value_dup_string(&gval);
1403                 }
1404                 else {
1405                         GHashTable *sub_ht;
1406                         sub_ht = g_value_get_boxed((GValue *) value);
1407                         tmp = tcore_util_marshal_serialize(sub_ht);
1408                 }
1409
1410                 encoded_d = g_base64_encode((guchar *)tmp, (gsize)strlen(tmp));
1411                 g_free(tmp);
1412
1413                 g_string_append_printf(gstring_tmp, "%s:%d:%s ", (gchar *)key,
1414                                 gtype, encoded_d);
1415                 g_free((gpointer)encoded_d);
1416                 g_value_unset(&gval);
1417         }
1418
1419         rv_str = g_strdup(gstring_tmp->str);
1420         g_string_free(gstring_tmp, TRUE);
1421
1422         return rv_str;
1423 }
1424
1425 gboolean tcore_util_marshal_add_data(GHashTable *ht, const gchar *key,
1426                 const void *data, enum tcore_util_marshal_data_type type)
1427 {
1428         gboolean rv = FALSE;
1429         GValue *value;
1430
1431         if (!ht || !key || !data)
1432                 return FALSE;
1433
1434         if (type >= 0xff)
1435                 return FALSE;
1436
1437         value = g_new0(GValue, 1);
1438
1439         rv = _tcore_util_marshal_create_gvalue(value, data, type);
1440
1441         if (!rv)
1442                 return FALSE;
1443
1444         g_hash_table_insert(ht, g_strdup(key), value);
1445
1446         return TRUE;
1447 }
1448
1449 gboolean tcore_util_marshal_get_data(GHashTable *ht, const gchar *key,
1450                 void **data, enum tcore_util_marshal_data_type type)
1451 {
1452         gboolean rv = FALSE;
1453         gpointer value;
1454
1455         if (!ht || !key || !data)
1456                 return FALSE;
1457
1458         value = g_hash_table_lookup(ht, key);
1459
1460         rv = _tcore_util_return_value((GValue *) value, data, type);
1461         if (!rv)
1462                 return FALSE;
1463
1464         return TRUE;
1465 }
1466
1467 gint tcore_util_marshal_get_int(GHashTable *ht, const gchar *key)
1468 {
1469         gboolean rv = FALSE;
1470         gint rvalue, *tmp = NULL;
1471
1472         if (!ht || !key)
1473                 return 0;
1474
1475         rv = tcore_util_marshal_get_data(ht, key, (void **) &tmp,
1476                         TCORE_UTIL_MARSHAL_DATA_INT_TYPE);
1477         if (!rv)
1478                 return 0;
1479
1480         if (!tmp)
1481                 return 0;
1482
1483         rvalue = *tmp;
1484         g_free(tmp);
1485
1486         return rvalue;
1487 }
1488
1489 gchar *tcore_util_marshal_get_string(GHashTable *ht, const gchar *key)
1490 {
1491         gboolean rv = FALSE;
1492         gchar *rvalue = NULL;
1493
1494         if (!ht || !key)
1495                 return 0;
1496
1497         rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1498                         TCORE_UTIL_MARSHAL_DATA_STRING_TYPE);
1499         if (!rv)
1500                 return NULL;
1501
1502         return rvalue;
1503 }
1504
1505 GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key)
1506 {
1507         gboolean rv = FALSE;
1508         GHashTable *rvalue = NULL;
1509
1510         if (!ht || !key)
1511                 return 0;
1512
1513         rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1514                         TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE);
1515         if (!rv)
1516                 return NULL;
1517
1518         return rvalue;
1519 }
1520
1521 char *tcore_util_get_version(void)
1522 {
1523         return strdup(TCORE_VERSION);
1524 }
1525