4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
33 #include <glib-object.h>
40 #define tabGsmUniMax2 9
41 #define tabGsmUniMax 42
44 gboolean tcore_debug = TRUE;
46 static gboolean _find_gsm_code_exception_table(unsigned short src);
47 static int _get_gsm_code_size(unsigned short* src, int src_len);
48 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len);
49 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len);
50 static void _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len, unsigned char *src, unsigned int src_len);
51 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len);
52 static char* _convert_ucs_to_utf8(unsigned char *src, int src_len);
53 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len);
54 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len);
55 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len);
59 unsigned short unicode;
62 const GsmUniTable gsm_unicode2_table[] = {
63 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
64 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
67 const GsmUniTable gsm_unicode_table[] = {
68 { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 },
69 { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 },
70 { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 },
71 { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B },
72 { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 },
73 { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 },
74 { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 },
75 { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 },
76 { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, };
81 static gboolean _find_gsm_code_exception_table(unsigned short src)
83 if ((src >= 0x0020 && src <= 0x0023)
84 || (src >= 0x0025 && src <= 0x003F)
85 || (src >= 0x0041 && src <= 0x005A)
86 || (src >= 0x0061 && src <= 0x007A)
87 || src == 0x000A || src == 0x000D)
92 static int _get_gsm_code_size(unsigned short* src, int src_len)
94 gboolean in_table = FALSE;
95 gboolean in_sec_table = FALSE;
99 dbg( "INPUT PARAM was NULL");
103 for (; src_len > 0 && src; src_len--) {
104 if (_find_gsm_code_exception_table(*src) == TRUE) {
110 for (i = 0; i < tabGsmUniMax; i++) {
111 if (*src == gsm_unicode_table[i].unicode) {
118 if (in_table == FALSE) {
119 in_sec_table = FALSE;
120 for (i = 0; i < tabGsmUniMax2; i++) {/* second table */
121 if (*src == gsm_unicode2_table[i].unicode) {
129 if (in_sec_table == FALSE) {/* second*/
130 if (_find_gsm_code_exception_table(*src) == FALSE) {
131 dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len);
142 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
147 dbg( "dest(%p) or src(%p) is null",dest, src);
156 dbg("source string (%s) len(%d)", src, src_len);
158 for(count = 0; count < (int)src_len; count++){
159 if(src[count] == 0x1B)
162 dbg("strlen excluding escape character (%d)", src_len);
164 tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
165 dest[tmp_len] = '\0';
170 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
177 for(count=0; count < (int)src_len; count++){
179 gboolean b_tabled = FALSE;
182 * if the first byte is 0x1B, it is the escape character.
183 * The byte value shoulbe be changed to unicode.
186 src++; count++;//move to next byte
187 for(table_index=0; table_index < tabGsmUniMax2; table_index++){
188 if(*src == gsm_unicode2_table[table_index].gsm){
189 *dest = gsm_unicode2_table[table_index].unicode;
195 //if matched data is not in table, it should be changed to NULL;
201 for(table_index=0; table_index < tabGsmUniMax; table_index++){
202 if(*src == gsm_unicode_table[table_index].gsm){
203 *dest = gsm_unicode_table[table_index].unicode;
209 //if matched data is not in table, it is using original value;
215 //move to next position
219 dbg("cvt sr(%s), the size of data (%d) ", org, dest - org);
223 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
225 unsigned short tmp_len = 0;
226 char *target_tmp = NULL;
227 unsigned char *raw_unicode = NULL;
228 unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
230 memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
232 _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
233 while(tmp_dest[tmp_len] != '\0'){
236 tmp_len++; // add null character
238 tmp_len = tmp_len*2; //for byte align
239 raw_unicode = (unsigned char*)malloc(tmp_len);
243 memset(raw_unicode, 0, tmp_len);
245 memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
247 target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
254 *dest_len = strlen((const char*)target_tmp);
255 dbg("utf8 (%s), len(%d)", (const char*)target_tmp, strlen((const char*)target_tmp));
256 memcpy(dest, target_tmp, strlen((const char*)target_tmp));
257 dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
264 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
269 if ((NULL == dest) || (NULL == src)) {
270 dbg( "INPUT PARAM was NULL");
277 gc_len = _get_gsm_code_size(src, src_len);
279 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
283 if (dest_len < gc_len) {
284 if (dest_len == sizeof(void*)) {
285 dbg( "Out buffer size seems to be small (%s)", dest);
287 dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
292 tmp_str = calloc(1, (unsigned short) gc_len);
293 if (tmp_str == NULL) {
294 dbg( "Memory Allocation Failed!");
298 gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
300 memcpy((char*) dest, (char*) tmp_str, gc_len);
309 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
311 char* utf_str = NULL;
318 char* out_buf = NULL;
325 ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes
326 oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes
327 pIn = in_buf = (char*) malloc(ileft + 2);
328 if (in_buf == NULL) {
329 dbg("in_buf allocation failed");
332 utf_str = out_buf = (char *) malloc(oleft + 1);
333 if (utf_str == NULL) {
334 dbg("in_buf allocation failed");
339 memset(in_buf, 0x00, ileft + 2);
340 memset(out_buf, 0x00, oleft + 1);
341 memcpy(in_buf, src, ileft);
343 in_buf[ileft] = '\0';
345 cd = iconv_open("UTF-8", "UCS-2");
347 if (iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft) == (size_t)(-1)) {
348 dbg("failed to iconv errno:%d", errno);
350 utf_str[src_len * 2 - ileft] = '\0';
359 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
361 unsigned char* rear = NULL;
364 gboolean in_table = FALSE;
365 gboolean in_sec_table = FALSE;
368 if ((!dest) || (!src) || (0x00 == src_len)) {
369 dbg( "Warning: Wrong Input");
376 for (; src_len > 0 && p; src_len--) {
378 for (i = 0; i < tabGsmUniMax; i++) { /* is in table */
379 if (*p == gsm_unicode_table[i].unicode) {
380 temp = (unsigned char) (gsm_unicode_table[i].gsm);
389 if (in_table == FALSE) {
390 in_sec_table = FALSE;
391 for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/
392 if (*p == gsm_unicode2_table[i].unicode) {
395 temp = (unsigned char) (gsm_unicode2_table[i].gsm);
405 if (in_sec_table == FALSE) { /* second */
406 if (_find_gsm_code_exception_table(*p) == FALSE)
408 temp = (unsigned char) (*p); /* isn't in table. but it's just able to be converted to GSM (0x00?? -> 0x??)*/
420 int tcore_util_convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
422 //input string "char *in" should be BIG-ENDIAN format.
423 gsize byte_converted = 0;
425 gchar *str_converted = NULL;
427 if (NULL == out || NULL == out_len || NULL == in) {
428 dbg( "Invalid Input Parameter");
432 str_converted = (gchar *)g_convert((const gchar *)in, (gssize)in_len, "UTF8", "UCS-2BE", &byte_read, &byte_converted, NULL);
434 dbg("read:[%d] converted:[%d] out:[%s]", byte_read, byte_converted, str_converted);
436 *out_len = byte_converted;
438 memcpy(out, str_converted, byte_converted);
439 g_free(str_converted);
441 warn("Cannot get converted data");
450 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len)
452 //input string "unsigned char *in" should be BIG-ENDIAN format.
457 dbg("[UCS2] prefix case:[0x80]");
458 tcore_util_hex_dump(" [UCS2] ", in_len, in);
459 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*)in+1, in_len-1);
463 unsigned char num = in[1]; //number of characters
464 unsigned short base = (unsigned short) in[2] << 7; //base pointer for UCS2 type
465 int data_loc = 3; //starting location of data
466 unsigned short* in_buf = NULL;
467 dbg("[UCS2] prefix case:[0x81]");
468 in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
470 dbg("in_buf malloc failed.");
474 for(i=0; i<num; i++,data_loc++) {
475 if(in[data_loc]<0x80) { // if the MSB is zero (0x80 => 1000b), then remaining 7 bits are GSM default character.
476 _convert_gsm_to_ucs2(&in_buf[i], &in[data_loc], 1);
477 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
478 } else { // if the MSB is 1 then the remaining 7 bits are offset value added to Base Pointer which the result defines the UCS2 character.
479 in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
480 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
484 unsigned char *dest = NULL;
485 dest = (unsigned char*)malloc(num*2);
487 dbg("dest malloc failed.");
492 tcore_util_swap_byte_order(dest, (unsigned char*)in_buf, num*2);
493 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*) dest, num*2);
501 unsigned char num = in[1]; //number of characters
502 unsigned short base = ((unsigned short) in[2] << 8) | (unsigned short) in[3]; //base pointer for UCS2 type
503 int data_loc = 4; //starting location of data
504 unsigned short* in_buf = NULL;
505 dbg("[UCS2] prefix case:[0x82]");
506 in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
508 dbg("in_buf malloc failed.");
512 for(i=0; i<num; i++,data_loc++) {
513 if(in[data_loc]<0x80) {
514 _convert_gsm_to_ucs2(&in_buf[i], &in[data_loc], (unsigned int)1);
515 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
517 in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
518 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
522 unsigned char *dest = NULL;
523 dest = (unsigned char*)malloc(num*2);
525 dbg("dest malloc failed.");
530 tcore_util_swap_byte_order(dest, (unsigned char*)in_buf, num*2);
531 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*) dest, num*2);
539 dbg("[UCS2] non-prefix case.");
540 tcore_util_hex_dump(" [UCS2] ", in_len, in);
541 tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*)in, in_len);
546 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
548 unsigned short* org = NULL;
549 unsigned char hi = 0;
550 unsigned char mid = 0;
551 unsigned char low = 0;
553 if ((NULL == dest) || (NULL == src)) {
554 dbg( "INPUT PARAM NULL");
560 while (src_len > 0 && (*src != '\0')) {
562 *dest = (*src & 0x7F);
566 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
568 low = *(src+1) & 0x3F;
569 *dest = (hi << 6) | low;
573 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
575 mid = *(src+1) & 0x3F;
576 low = *(src+2) & 0x3F;
577 *dest = (hi << 12) | (mid << 6) | low;
582 *dest = (*src & 0x7F);
586 dbg( "utf8 incorrect range");
593 static char _convert_gsm7bit_extension( char c )
617 This code represents the EURO currency symbol. The code value is that used for the character ‘e’. Therefore
618 a receiving entity which is incapable of displaying the EURO currency symbol will display the character ‘e’
624 dbg("this is not extension character : (0x%x)", c);
631 gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len)
633 unsigned short *uc = NULL;
637 if (src == NULL || src_len == 0) {
638 dbg( "WARNING: Invalid Parameter");
642 uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
644 dbg( "WARNING: calloc Failed");
648 /*Converting from UTF8 => UNICODE*/
649 uc_len = _convert_utf8_to_unicode(uc, src, src_len);
650 dbg( "uc_len:[%d]", uc_len);
652 dbg( "_convert_utf8_to_unicode returns false!");
657 /*Finding the GSMCode Size*/
658 gc_len = _get_gsm_code_size(uc, uc_len);
659 dbg( "gc_len:[%d]", gc_len);
661 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]", gc_len);
667 /*Converting from UNICODE ==> GSM CODE */
668 if (_convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len) == FALSE) {
669 dbg( "_convert_unicode_to_gsm Failed");
680 gboolean tcore_util_convert_utf8_to_ucs2(char **dest, int *dest_len, unsigned char *src, int src_len)
682 gsize byte_converted = 0;
684 gchar *str_converted = NULL;
686 if (NULL == src || NULL == dest || NULL == dest_len) {
687 dbg( "Invalid Input Parameter");
691 /*Converting from UTF8 => UCS-2 BIG-ENDIAN FORMAT using the g_convert*/
692 str_converted = (gchar *)g_convert((const gchar *)src, (gssize)src_len, "UCS-2BE", "UTF8", &byte_read, &byte_converted, NULL);
694 dbg("byte_read: [%d] byte_converted: [%d]", byte_read, byte_converted);
696 *dest = str_converted;
697 *dest_len = byte_converted;
699 warn("Cannot get converted string");
708 gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len,
709 enum alphabet_format dcs, const unsigned char *src, unsigned short src_len)
711 dbg("dcs=[0x%02x], src=[%s], src_len=[%d]", dcs, src, src_len );
713 if(src==NULL || src_len==0) {
714 err("src is NULL or src_len is 0");
719 case ALPHABET_FORMAT_SMS_DEFAULT: {
720 unsigned char* tmp_dest_str = NULL;
721 tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len);
724 err("temp_dest_str is NULL");
727 _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
733 case ALPHABET_FORMAT_8BIT_DATA: {//GSM7bit with bit 8 set to 0
735 unsigned char *src_buf = NULL;
737 src_buf = (unsigned char*)malloc(src_len);
738 if(src_buf == NULL) {
739 dbg("src_buf malloc failed.");
743 memset(src_buf, 0, src_len);
744 memcpy(src_buf, src, src_len);
746 /*get string length*/
747 /* 0xFF is the end of string */
748 while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
751 /* last space character must be deleted */
752 while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
755 dbg( "tmp_str_len[%d]", tmp_str_len);
757 _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len);
762 case ALPHABET_FORMAT_UCS2: {
763 unsigned char *src_buf = NULL;
765 src_buf = (unsigned char*)malloc(src_len);
766 if(src_buf == NULL) {
767 dbg("src_buf malloc failed.");
771 memset(src_buf, 0, src_len);
772 memcpy(src_buf, src, src_len);
774 _convert_alpha_field_ucs2_to_utf8(dest, dest_len, src_buf, src_len);
780 dbg("not handled alpha format[0x%02x]", dcs);
787 gboolean tcore_util_convert_ascii_to_utf8( unsigned char **dest, int *dest_len, unsigned char *src, int src_len )
789 int i = 0, j = 0, tmp_len = 0;
790 unsigned char *tmp = 0;
792 if ( (!dest) || (!src) || (!dest_len) )
796 src_len = strlen( (char*)src );
799 tmp_len = (src_len * 2);
800 tmp = g_new0( unsigned char, tmp_len );
802 for ( i=0, j=0; i<src_len; i++, j++ ) {
803 if ( src[i] <= 0x7F ) {
806 } else if ( (src[i] >= 0x80) && (src[i] <= 0xBF) ) {
810 } else { //( (src[i] >= 0xC0) && (src[i] <= 0xFF) )
812 tmp[++j] = (src[i] - 0x40);
819 *dest = g_new0( unsigned char, *dest_len );
820 memcpy( *dest, tmp, j );
827 void tcore_util_swap_byte_order(unsigned char* dest, const unsigned char* src, int src_len)
830 for (i = 0; i+1 < src_len; i=i+2) {
835 dest[i-1] = src[i-1];
836 dbg("swap completed.");
839 static gboolean _tcore_util_marshal_create_gvalue(GValue *value,
840 const void *data, enum tcore_util_marshal_data_type type)
843 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
844 g_value_init(value, type);
845 g_value_set_schar(value, *((gchar *) data));
848 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
849 g_value_init(value, type);
850 g_value_set_boolean(value, *((gboolean *) data));
853 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
854 g_value_init(value, type);
855 g_value_set_int(value, *((gint *) data));
858 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
859 g_value_init(value, type);
860 g_value_set_double(value, *((gdouble *) data));
863 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
864 g_value_init(value, type);
865 g_value_set_string(value, (gchar *) data);
868 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
869 g_value_init(value, G_TYPE_HASH_TABLE);
870 g_value_set_boxed(value, (gpointer) data);
882 static gboolean _tcore_util_return_value(GValue *src, void **dest,
883 enum tcore_util_marshal_data_type type)
886 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
887 *dest = g_new0(gchar, 1);
888 *((gchar *) *dest) = g_value_get_schar(src);
891 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
892 *dest = g_new0(gboolean, 1);
893 *((gboolean *) *dest) = g_value_get_boolean(src);
896 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
897 *dest = g_new0(gint, 1);
898 *((gint *) *dest) = g_value_get_int(src);
901 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
902 *dest = g_new0(gdouble, 1);
903 *((gdouble *) *dest) = g_value_get_double(src);
906 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
907 *dest = g_value_dup_string(src);
910 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
911 *dest = g_value_dup_boxed(src);
923 static void _tcore_util_marshal_remove_value(gpointer value)
925 unsigned int gtype = 0;
926 GHashTable *ht = NULL;
928 gtype = ((GValue *) value)->g_type;
929 if (gtype == G_TYPE_HASH_TABLE) {
930 ht = g_value_get_boxed(value);
931 g_hash_table_destroy(ht);
934 g_value_unset((GValue *) value);
940 static gboolean _tcore_util_marshal_convert_str_to_type(GValue *src,
941 GValue *dest, unsigned int dest_type)
943 if (dest_type == G_TYPE_HASH_TABLE)
944 dest_type = G_TYPE_BOXED;
949 tmp = g_ascii_strtoll(g_value_get_string(src), NULL, 10);
950 g_value_set_int(dest, tmp);
953 case G_TYPE_BOOLEAN: {
954 gboolean tmp = FALSE;
955 tmp = g_ascii_strncasecmp(g_value_get_string(src), "TRUE", 4) == 0
957 g_value_set_boolean(dest, tmp);
960 case G_TYPE_STRING: {
961 const gchar* tmp = NULL;
962 tmp = g_value_get_string(src);
963 g_value_set_string(dest, tmp);
966 case G_TYPE_DOUBLE: {
968 tmp = g_ascii_strtod(g_value_get_string(src), NULL);
969 g_value_set_double(dest, tmp);
974 tmp = tcore_util_marshal_deserialize_string(g_value_get_string(src));
975 g_value_set_boxed(dest, tmp);
987 TReturn tcore_util_netif_up(const char *name)
994 return TCORE_RETURN_EINVAL;
996 if (strlen(name) > IFNAMSIZ)
997 return TCORE_RETURN_EINVAL;
999 fd = socket(AF_INET, SOCK_DGRAM, 0);
1001 return TCORE_RETURN_FAILURE;
1004 memset(&ifr, 0, sizeof(struct ifreq));
1005 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1006 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1008 ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1011 return TCORE_RETURN_FAILURE;
1014 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
1016 ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
1019 return TCORE_RETURN_FAILURE;
1023 return TCORE_RETURN_SUCCESS;
1026 TReturn tcore_util_netif_down(const char *name)
1033 return TCORE_RETURN_EINVAL;
1035 if (strlen(name) > IFNAMSIZ)
1036 return TCORE_RETURN_EINVAL;
1038 fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
1040 return TCORE_RETURN_FAILURE;
1043 memset(&ifr, 0, sizeof(struct ifreq));
1044 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1045 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1048 ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1051 return TCORE_RETURN_FAILURE;
1054 ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
1056 ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
1059 return TCORE_RETURN_FAILURE;
1063 return TCORE_RETURN_SUCCESS;
1066 TReturn tcore_util_netif_set(const char *name, const char *ipaddr,
1067 const char *gateway, const char *netmask)
1072 struct sockaddr_in sai;
1075 return TCORE_RETURN_EINVAL;
1077 if (strlen(name) > IFNAMSIZ)
1078 return TCORE_RETURN_EINVAL;
1080 fd = socket(AF_INET, SOCK_DGRAM, 0);
1082 return TCORE_RETURN_FAILURE;
1085 memset(&sai, 0, sizeof(struct sockaddr_in));
1086 sai.sin_family = AF_INET;
1088 memset(&ifr, 0, sizeof(struct ifreq));
1091 dbg("ip = [%s]", ipaddr);
1092 if (!inet_aton(ipaddr, &sai.sin_addr)) {
1094 return TCORE_RETURN_FAILURE;
1097 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1098 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1099 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
1101 ret = ioctl(fd, SIOCSIFADDR, &ifr);
1104 return TCORE_RETURN_FAILURE;
1109 dbg("gateway = [%s]", gateway);
1110 if (!inet_aton(gateway, &sai.sin_addr)) {
1112 return TCORE_RETURN_FAILURE;
1115 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1116 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1117 memcpy(&ifr.ifr_dstaddr, &sai, sizeof(sai));
1119 ret = ioctl(fd, SIOCSIFDSTADDR, &ifr);
1122 return TCORE_RETURN_FAILURE;
1127 dbg("netmask = [%s]", netmask);
1128 if (!inet_aton(netmask, &sai.sin_addr)) {
1130 return TCORE_RETURN_FAILURE;
1133 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1134 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1135 memcpy(&ifr.ifr_netmask, &sai, sizeof(sai));
1137 ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
1140 return TCORE_RETURN_FAILURE;
1145 return TCORE_RETURN_SUCCESS;
1148 TReturn tcore_util_reset_ipv4_socket(const char *name, const char* ipaddr)
1153 struct sockaddr_in sai;
1156 return TCORE_RETURN_EINVAL;
1158 if (strlen(name) > IFNAMSIZ)
1159 return TCORE_RETURN_EINVAL;
1161 fd = socket(AF_INET, SOCK_DGRAM, 0);
1163 return TCORE_RETURN_FAILURE;
1166 memset(&sai, 0, sizeof(struct sockaddr_in));
1167 sai.sin_family = AF_INET;
1170 if (!inet_aton(ipaddr, &sai.sin_addr)) {
1171 dbg("fail to inet_aton()");
1173 return TCORE_RETURN_FAILURE;
1177 memset(&ifr, 0, sizeof(struct ifreq));
1178 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
1179 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1180 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1183 ret = ioctl(fd, SIOCGIFADDR, &ifr);
1185 dbg("fail to ioctl[SIOCGIFADDR]!!!");
1187 return TCORE_RETURN_FAILURE;
1190 /* SIOCKILLADDR is initially introduced in Android OS. */
1191 #ifndef SIOCKILLADDR
1192 #define SIOCKILLADDR 0x8939
1194 ret = ioctl(fd, SIOCKILLADDR, &ifr);
1196 dbg("fail to ioctl[SIOCKILLADDR]!!!");
1198 return TCORE_RETURN_FAILURE;
1202 dbg("devname: %s, ipaddr: %s", name, ipaddr);
1204 memset(&sai, 0, sizeof(struct sockaddr_in));
1205 memcpy(&sai, &ifr.ifr_addr, sizeof(struct sockaddr_in));
1206 dbg("devname: %s, ipaddr: %s", name, inet_ntoa(sai.sin_addr));
1209 return TCORE_RETURN_SUCCESS;
1212 TReturn tcore_util_netif_set_mtu(const char *name, unsigned int mtu)
1219 return TCORE_RETURN_EINVAL;
1221 if (strlen(name) > IFNAMSIZ)
1222 return TCORE_RETURN_EINVAL;
1224 fd = socket(AF_INET, SOCK_DGRAM, 0);
1226 return TCORE_RETURN_FAILURE;
1229 memset(&ifr, 0, sizeof(struct ifreq));
1230 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1231 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1232 ifr.ifr_data = (void*)mtu;
1234 ret = ioctl(fd, SIOCSIFMTU, &ifr);
1236 dbg("fail to ioctl[SIOCSIFMTU]!!!");
1238 return TCORE_RETURN_FAILURE;
1242 return TCORE_RETURN_SUCCESS;
1245 char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip)
1247 char buf[16]; /* 'nnn'*4 + '.'*3 + '\0' */
1249 snprintf(buf, 16, "%d.%d.%d.%d", ip.s[0], ip.s[1], ip.s[2], ip.s[3]);
1254 enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode)
1256 enum tcore_dcs_type dcs = TCORE_DCS_TYPE_NONE;
1258 switch (encode & 0xf0)
1263 dcs = TCORE_DCS_TYPE_7_BIT;
1267 if ((encode & 0x0f) == 0x00)
1268 dcs = TCORE_DCS_TYPE_7_BIT;
1269 else if ((encode & 0x0f) == 0x01)
1270 dcs = TCORE_DCS_TYPE_8_BIT; //should be re-defined
1272 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1279 if ((encode & 0x0c) == 0x00)
1280 dcs = TCORE_DCS_TYPE_7_BIT;
1281 else if ((encode & 0x0c) == 0x04)
1282 dcs = TCORE_DCS_TYPE_8_BIT;
1283 else if ((encode & 0x0c) == 0x08)
1284 dcs = TCORE_DCS_TYPE_UCS2;
1285 else if ((encode & 0x0c) == 0x0c)
1286 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1290 if ((encode & 0x0c) == 0x00)
1291 dcs = TCORE_DCS_TYPE_7_BIT;
1292 else if ((encode & 0x0c) == 0x04)
1293 dcs = TCORE_DCS_TYPE_8_BIT;
1294 else if ((encode & 0x0c) == 0x08)
1295 dcs = TCORE_DCS_TYPE_UCS2;
1296 else if ((encode & 0x0c) == 0x0c)
1297 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
1304 case 0xD0: // 1010 .. 1101
1305 case 0xE0: // 0x1110
1309 if ((encode & 0x04) == 0x00)
1310 dcs = TCORE_DCS_TYPE_7_BIT;
1311 else if ((encode & 0x04) == 0x04)
1312 dcs = TCORE_DCS_TYPE_8_BIT;
1315 err("invalid encoding type");
1322 #define CONVERT_HEXCHAR_TO_INT(h, i) if ((h) >= '0' && (h) <= '9') (i) = (h) - '0'; \
1323 else if ((h) >= 'A' && (h) <= 'F') (i) = (h) - 'A' + 10; \
1324 else if ((h) >= 'a' && (h) <= 'f') (i) = (h) - 'a' + 10; \
1328 unsigned char *tcore_util_decode_hex(const char *src, int len)
1341 out_len = strlen(src) / 2 + 1;
1347 buf = calloc(1, out_len);
1351 for (; j < out_len; i+= 2, j++) {
1352 CONVERT_HEXCHAR_TO_INT(src[i], value1);
1353 CONVERT_HEXCHAR_TO_INT(src[i+1], value2);
1355 buf[j] = (value1 << 4) + value2;
1361 void tcore_util_hex_dump(const char *pad, int size, const void *data)
1363 char buf[255] = {0, };
1364 char hex[4] = {0, };
1366 unsigned char *p = NULL;
1369 msg("%sno data", pad);
1373 p = (unsigned char *)data;
1375 g_snprintf(buf, 255, "%s%04X: ", pad, 0);
1376 for (i = 0; i<size; i++) {
1377 g_snprintf(hex, 4, "%02X ", p[i]);
1378 memcpy(buf+strlen(buf), hex, 4);
1380 if ((i + 1) % 8 == 0) {
1381 if ((i + 1) % 16 == 0) {
1383 memset(buf, 0, 255);
1384 snprintf(buf, 255, "%s%04X: ", pad, i + 1);
1387 strncat(buf, TAB_SPACE, strlen(TAB_SPACE));
1395 unsigned char *tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len)
1397 unsigned char *dest;
1399 unsigned int pos = 0;
1400 unsigned char shift = 0;
1403 if (!src || src_len == 0) {
1407 outlen = (src_len * 8) / 7;
1409 dest = calloc(1, outlen + 1);
1413 for (i = 0; pos < src_len; i++, pos++) {
1414 dest[i] = (src[pos] << shift) & 0x7F;
1417 /* except the first byte, a character contains some bits from the previous byte.*/
1418 dest[i] |= src[pos - 1] >> (8 - shift);
1426 /* a possible extra complete character is available */
1428 dest[i] = src[pos] >> 1;
1432 /*If a character is '\r'(13), change it to space(32) */
1433 for (i = 0, j=0; i < outlen; i++, j++) {
1434 if (dest[i] == '\r') {
1437 } else if (dest[i] == 0x1B) { /*If a charater is 0x1B (escape), next charater is changed on gsm 7bit extension table */
1438 dest[j] = _convert_gsm7bit_extension( dest[++i] );
1445 outlen -= ( i - j );
1447 dest[outlen] = '\0';
1452 unsigned char *tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len)
1454 unsigned char *dest;
1456 unsigned int pos = 0, shift = 0;
1457 unsigned int outlen = 0;
1459 if (!src || src_len == 0) {
1463 outlen = ((src_len * 7) / 8) + 1;
1465 dest = calloc(1, outlen + 1);
1469 for (pos = 0, i = 0; i < src_len; pos++, i++) {
1470 if (pos >= outlen) {
1475 /* pack the low bits */
1476 dest[pos] = src[i] >> shift;
1478 if (i + 1 < src_len) {
1479 /* pack the high bits using the low bits of the next character */
1480 dest[pos] |= src[i + 1] << (7 - shift);
1498 char* tcore_util_convert_bcd_str_2_ascii_str(const char* src, int src_len)
1506 dest = malloc((src_len+1)*sizeof(char));
1510 memset(dest, 0, (src_len+1)*sizeof(char));
1512 for(count = 0; count < src_len; count++){
1521 dest[count] = 'p'; //Pause
1524 dest[count] = '?'; //Wild Card character
1526 case 0x0E: //ignore, RFU
1528 dest[count] = '\0'; //Null termination
1531 dest[count] = src[count]+'0'; //digits 0~9
1537 dbg("PARSER - number(%s) len(%d)", dest, strlen(dest));
1542 char* tcore_util_convert_bcd2ascii(const char* src, int src_len, int max_len)
1544 int count = 0, len=0;
1545 char l_bcd = 0x00, h_bcd = 0x0F;
1551 if(src_len*2 > max_len){
1552 err("PARSER - number length exceeds the max");
1556 dest = malloc((src_len*2)*sizeof(char)+1);
1560 memset(dest, 0, (src_len*2)*sizeof(char)+1);
1562 for(count = 0; count < src_len; count++){
1563 l_bcd = src[count] & 0x0F;
1564 h_bcd = (src[count] & 0xF0) >> 0x04;
1574 dest[len++] = 'p'; //Pause
1577 dest[len++] = '?'; //Wild Card character
1579 case 0x0E: //ignore, RFU
1580 case 0x0F: //ignore in l_bcd
1583 dest[len++] = l_bcd+'0'; //digits 0~9
1595 dest[len++] = 'p'; //Pause
1598 dest[len++] = '?'; //Wild Card character
1600 case 0x0E: //ignore, RFU
1602 dest[len] = '\0'; //Null termination
1605 dest[len++] = h_bcd+'0'; //digits 0~9
1613 dbg("PARSER - number(%s) len(%d)", dest, len);
1617 char* tcore_util_convert_digit2ascii(const char* src, int src_len)
1625 dest = malloc((src_len+1)*sizeof(char));
1629 memset(dest, 0, (src_len+1)*sizeof(char));
1631 for(count = 0; count < src_len; count++){
1632 dest[count] = src[count] + '0';
1636 dbg("PARSER - number(%s) len(%d)", dest, strlen(dest));
1641 GHashTable *tcore_util_marshal_create()
1643 GHashTable *ht = NULL;
1645 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1646 _tcore_util_marshal_remove_value);
1651 void tcore_util_marshal_destory(GHashTable *ht)
1656 g_hash_table_destroy(ht);
1660 GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string)
1663 gchar **tuple = NULL;
1664 GHashTable *ht = NULL;
1665 GValue src = G_VALUE_INIT;
1667 if (!serialized_string)
1670 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1671 _tcore_util_marshal_remove_value);
1673 if (strlen(serialized_string) == 0) {
1677 g_value_init(&src, G_TYPE_STRING);
1679 tuple = g_strsplit(serialized_string, " ", 0);
1681 while (strlen(tuple[count]) > 3) {
1683 guchar *content = NULL;
1684 gchar **inner_tuple = NULL;
1685 GValue *dest = g_new0(GValue, 1);
1686 unsigned int type = 0;
1688 inner_tuple = g_strsplit(tuple[count], ":", 0);
1689 type = atoi(inner_tuple[1]);
1690 content = g_base64_decode(inner_tuple[2], (gsize *)&tmp);
1692 g_value_init(dest, type);
1694 g_value_set_string(&src, (const gchar *)content);
1695 _tcore_util_marshal_convert_str_to_type(&src, dest, type);
1696 g_hash_table_insert(ht, g_strdup(inner_tuple[0]), dest);
1698 g_value_reset(&src);
1700 g_strfreev(inner_tuple);
1708 gchar *tcore_util_marshal_serialize(GHashTable *ht)
1710 gchar *rv_str = NULL;
1711 GHashTableIter iter;
1712 gpointer key, value;
1713 GString *gstring_tmp = NULL;
1715 gstring_tmp = g_string_new(NULL);
1716 g_hash_table_iter_init(&iter, ht);
1717 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1718 unsigned int gtype = 0;
1719 gchar *tmp = NULL, *encoded_d = NULL;
1720 GValue gval = { 0,{ { 0 } } };
1722 g_value_init(&gval, G_TYPE_STRING);
1724 gtype = ((GValue *) value)->g_type;
1725 if (gtype != G_TYPE_HASH_TABLE) {
1726 g_value_transform((GValue *) value, &gval);
1727 tmp = g_value_dup_string(&gval);
1731 sub_ht = g_value_get_boxed((GValue *) value);
1732 tmp = tcore_util_marshal_serialize(sub_ht);
1735 encoded_d = g_base64_encode((guchar *)tmp, (gsize)strlen(tmp));
1738 g_string_append_printf(gstring_tmp, "%s:%d:%s ", (gchar *)key,
1740 g_free((gpointer)encoded_d);
1741 g_value_unset(&gval);
1744 rv_str = g_strdup(gstring_tmp->str);
1745 g_string_free(gstring_tmp, TRUE);
1750 gboolean tcore_util_marshal_add_data(GHashTable *ht, const gchar *key,
1751 const void *data, enum tcore_util_marshal_data_type type)
1753 gboolean rv = FALSE;
1756 if (!ht || !key || !data)
1762 value = g_new0(GValue, 1);
1764 rv = _tcore_util_marshal_create_gvalue(value, data, type);
1769 g_hash_table_insert(ht, g_strdup(key), value);
1774 gboolean tcore_util_marshal_get_data(GHashTable *ht, const gchar *key,
1775 void **data, enum tcore_util_marshal_data_type type)
1777 gboolean rv = FALSE;
1780 if (!ht || !key || !data)
1783 value = g_hash_table_lookup(ht, key);
1785 rv = _tcore_util_return_value((GValue *) value, data, type);
1792 gint tcore_util_marshal_get_int(GHashTable *ht, const gchar *key)
1794 gboolean rv = FALSE;
1795 gint rvalue, *tmp = NULL;
1800 rv = tcore_util_marshal_get_data(ht, key, (void **) &tmp,
1801 TCORE_UTIL_MARSHAL_DATA_INT_TYPE);
1814 gchar *tcore_util_marshal_get_string(GHashTable *ht, const gchar *key)
1816 gboolean rv = FALSE;
1817 gchar *rvalue = NULL;
1822 rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1823 TCORE_UTIL_MARSHAL_DATA_STRING_TYPE);
1830 GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key)
1832 gboolean rv = FALSE;
1833 GHashTable *rvalue = NULL;
1838 rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1839 TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE);
1846 char *tcore_util_get_version(void)
1848 return strdup(TCORE_VERSION);
1851 void tcore_util_set_log(gboolean enable)
1853 tcore_debug = enable;