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