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>
39 #define tabGsmUniMax2 9
40 #define tabGsmUniMax 42
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);
56 unsigned short unicode;
59 const GsmUniTable gsm_unicode2_table[] = {
60 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
61 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
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 }, };
78 static gboolean _find_gsm_code_exception_table(unsigned short src)
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)
89 static int _get_gsm_code_size(unsigned short* src, int src_len)
91 gboolean in_table = FALSE;
92 gboolean in_sec_table = FALSE;
96 dbg( "INPUT PARAM was NULL");
100 for (; src_len > 0 && src; src_len--) {
101 if (_find_gsm_code_exception_table(*src) == TRUE) {
107 for (i = 0; i < tabGsmUniMax; i++) {
108 if (*src == gsm_unicode_table[i].unicode) {
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) {
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);
139 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
144 dbg( "dest(%p) or src(%p) is null",dest, src);
153 dbg("source string (%s) len(%d)", src, src_len);
155 for(index = 0; index < (int)src_len; index++){
156 if(src[index] == 0x1B)
159 dbg("strlen excluding escape character (%d)", src_len);
161 tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
162 dest[tmp_len] = '\0';
167 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
174 for(index=0; index < (int)src_len; index++){
176 gboolean b_tabled = FALSE;
179 * if the first byte is 0x1B, it is the escape character.
180 * The byte value shoulbe be changed to unicode.
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;
192 //if matched data is not in table, it should be changed to NULL;
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;
206 //if matched data is not in table, it is using original value;
212 //move to next position
216 dbg("cvt sr(%s), the size of data (%d) ", org, dest - org);
220 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
223 char *target_tmp = NULL;
224 unsigned char *raw_unicode = NULL;
225 unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
227 memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
229 _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
230 while(tmp_dest[tmp_len] != '\0')
232 tmp_len++; // add null character
234 tmp_len = tmp_len*2; //for byte align
235 raw_unicode = (unsigned char*)malloc(tmp_len);
236 memset(raw_unicode, 0, tmp_len);
238 memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
241 target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
248 memcpy(dest, target_tmp, strlen((const char*)target_tmp));
249 dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
256 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
261 if ((NULL == dest) || (NULL == src)) {
262 dbg( "INPUT PARAM was NULL");
269 gc_len = _get_gsm_code_size(src, src_len);
271 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
275 if (dest_len < gc_len) {
276 if (dest_len == sizeof(void*)) {
277 dbg( "Out buffer size seems to be small (%s)", dest);
279 dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
284 tmp_str = calloc(1, (unsigned short) gc_len);
285 if (tmp_str == NULL) {
286 dbg( "Memory Allocation Failed!");
290 gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
292 memcpy((char*) dest, (char*) tmp_str, gc_len);
301 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
303 char* utf_str = NULL;
311 char* out_buf = NULL;
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);
323 memset(in_buf, 0x00, ileft + 2);
324 memset(out_buf, 0x00, oleft + 1);
325 memcpy(in_buf, src, ileft);
327 in_buf[ileft] = '\0';
329 cd = iconv_open("UTF-8", "UCS-2");
330 err = iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft);
332 utf_str[src_len * 2 - ileft] = '\0';
338 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
340 unsigned char* rear = NULL;
343 gboolean in_table = FALSE;
344 gboolean in_sec_table = FALSE;
347 if ((!dest) || (!src) || (0x00 == src_len)) {
348 dbg( "Warning: Wrong Input");
355 for (; src_len > 0 && p; src_len--) {
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);
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) {
374 temp = (unsigned char) (gsm_unicode2_table[i].gsm);
384 if (in_sec_table == FALSE) { /* second */
385 if (_find_gsm_code_exception_table(*p) == FALSE)
387 temp = (unsigned char) (*p); /* isn't in table. but it's just able to be converted to GSM (0x00?? -> 0x??)*/
399 static int _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
402 size_t src_len = in_len;
403 size_t dest_len = in_len*3;
405 iconv_t cd = iconv_open("UTF-8", "UCS2");
406 if (cd == (iconv_t) (-1)) {
407 perror("iconv_open");
413 dbg("expected input bytes:%d dest_len:%d\n", src_len, dest_len);
415 if (iconv(cd, &in, &src_len, &p_o, &dest_len) == (size_t)(-1)) {
416 dbg("failed to iconv errno:%d", errno);
418 dbg("remained input bytes:%d processed bytes:%d", src_len, in_len*3-dest_len);
419 out[in_len*3-dest_len] = '\0';
421 *out_len = in_len*3-dest_len;
422 dbg("out_len[%d], output[%s]", *out_len, out);
427 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len)
429 //input string UNSIGNED CHAR *IN should be encoded with BIG-ENDIAN
432 unsigned char num = in_len/2; //number of characters
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];
441 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
443 _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
444 if(in_buf!=NULL) free(in_buf);
448 unsigned char num = in[1]; //number of characters
449 unsigned short base = (unsigned short) in[2] << 7; //base pointer for UCS2 type
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]);
464 _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
465 if(in_buf!=NULL) free(in_buf);
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
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]);
482 in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
483 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
486 _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
487 if(in_buf!=NULL) free(in_buf);
491 unsigned char num = in_len/2; //number of characters
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];
500 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
502 _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
503 if(in_buf!=NULL) free(in_buf);
508 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
510 unsigned short* org = NULL;
511 unsigned char hi = 0;
512 unsigned char mid = 0;
513 unsigned char low = 0;
515 if ((NULL == dest) || (NULL == src)) {
516 dbg( "INPUT PARAM NULL");
522 while (src_len > 0 && (*src != '\0')) {
524 *dest = (*src & 0x7F);
528 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
530 low = *(src+1) & 0x3F;
531 *dest = (hi << 6) | low;
535 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
537 mid = *(src+1) & 0x3F;
538 low = *(src+2) & 0x3F;
539 *dest = (hi << 12) | (mid << 6) | low;
544 *dest = (*src & 0x7F);
548 dbg( "utf8 incorrect range");
557 gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len)
559 unsigned short *uc = NULL;
563 if (src == NULL || src_len == 0) {
564 dbg( "WARNING: Invalid Parameter");
568 uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
570 dbg( "WARNING: calloc Failed");
574 /*Converting from UTF8 => UNICODE*/
575 uc_len = _convert_utf8_to_unicode(uc, src, src_len);
576 dbg( "uc_len:[%d]", uc_len);
578 dbg( "_convert_utf8_to_unicode returns false!");
583 /*Finding the GSMCode Size*/
584 gc_len = _get_gsm_code_size(uc, uc_len);
585 dbg( "gc_len:[%d]", gc_len);
587 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]", 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");
606 gboolean tcore_util_convert_utf8_to_ucs2(unsigned char* dest, int* dest_len, unsigned char* src, int src_len)
608 gsize byte_converted = 0;
610 gchar* str_converted = NULL;
611 GError *error = NULL;
615 if (dest == NULL || dest_len == NULL || src == NULL) {
616 dbg( "Invalid Input Parameter");
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,
625 if (str_converted == NULL) {
626 dbg( "str_converted is NULL");
628 dbg( "Problem while conversion UTF8 => UCS2, ErrorCode[%d]", error->code);
633 dbg( "src_len[%u], byte_read[%u], byte_converted[%u]", src_len, byte_read, byte_converted);
634 *dest_len = (int) byte_converted;
636 if (byte_converted % 2 != 0) {
637 dbg( "string length is wrong!");
639 for (i = 0; i < (int)byte_converted; i++) {
641 tmp_char = str_converted[i];
642 str_converted[i] = str_converted[i + 1];
643 str_converted[i + 1] = tmp_char;
647 memcpy((unsigned char*) dest, (unsigned char*) str_converted, byte_converted);
648 g_free(str_converted);
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)
655 dbg("dcs=[0x%02x]", dcs );
656 dbg("src=[%s], src_len=[%d]", src, src_len);
658 if(src==NULL || src_len==0) {
659 err("src is NULL or src_len is 0");
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);
670 err("temp_dest_str is NULL");
673 _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
679 case ALPHABET_FORMAT_8BIT_DATA: { //GSM7bit with bit 8 set to 0
681 unsigned char *src_buf = NULL;
682 src_buf = (unsigned char*)malloc(src_len);
684 err("src_buf is NULL!");
687 memcpy(src_buf, src, src_len);
689 /*get string length*/
690 /* 0xFF is the end of string */
691 while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
694 /* last space character must be deleted */
695 while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
698 dbg( "case : [ALPHABET_FORMAT_8BIT_DATA]");
699 dbg( "tmp_str_len[%d]", tmp_str_len);
701 _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len);
705 case ALPHABET_FORMAT_UCS2: {
706 unsigned char *src_buf = NULL;
707 src_buf = (unsigned char*)malloc(src_len);
709 err("src_buf is NULL");
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);
719 dbg("not handled alpha format[0x%02x]", dcs);
726 void tcore_util_swap_byte_order(unsigned short* dest, const unsigned short* src, int src_len)
730 for (i = 0; i < src_len; i++) {
731 dest[i] = (src[i] << 8) + (src[i] >> 8);
735 static gboolean _tcore_util_marshal_create_gvalue(GValue *value,
736 const void *data, enum tcore_util_marshal_data_type type)
739 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
740 g_value_init(value, type);
741 g_value_set_schar(value, *((gchar *) data));
744 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
745 g_value_init(value, type);
746 g_value_set_boolean(value, *((gboolean *) data));
749 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
750 g_value_init(value, type);
751 g_value_set_int(value, *((gint *) data));
754 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
755 g_value_init(value, type);
756 g_value_set_double(value, *((gdouble *) data));
759 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
760 g_value_init(value, type);
761 g_value_set_string(value, (gchar *) data);
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);
778 static gboolean _tcore_util_return_value(GValue *src, void **dest,
779 enum tcore_util_marshal_data_type type)
782 case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE:
783 *dest = g_new0(gchar, 1);
784 *((gchar *) *dest) = g_value_get_schar(src);
787 case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE:
788 *dest = g_new0(gboolean, 1);
789 *((gboolean *) *dest) = g_value_get_boolean(src);
792 case TCORE_UTIL_MARSHAL_DATA_INT_TYPE:
793 *dest = g_new0(gint, 1);
794 *((gint *) *dest) = g_value_get_int(src);
797 case TCORE_UTIL_MARSHAL_DATA_DOUBLE_TYPE:
798 *dest = g_new0(gdouble, 1);
799 *((gdouble *) *dest) = g_value_get_double(src);
802 case TCORE_UTIL_MARSHAL_DATA_STRING_TYPE:
803 *dest = g_value_dup_string(src);
806 case TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE:
807 *dest = g_value_dup_boxed(src);
819 static void _tcore_util_marshal_remove_value(gpointer value)
821 unsigned int gtype = 0;
822 GHashTable *ht = NULL;
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);
830 g_value_unset((GValue *) value);
834 static gboolean _tcore_util_marshal_convert_str_to_type(GValue *src,
835 GValue *dest, unsigned int dest_type)
837 if (dest_type == G_TYPE_HASH_TABLE)
838 dest_type = G_TYPE_BOXED;
843 tmp = g_ascii_strtoll(g_value_get_string(src), NULL, 10);
844 g_value_set_int(dest, tmp);
847 case G_TYPE_BOOLEAN: {
848 gboolean tmp = FALSE;
849 tmp = g_ascii_strncasecmp(g_value_get_string(src), "TRUE", 4) == 0
851 g_value_set_boolean(dest, tmp);
854 case G_TYPE_STRING: {
855 const gchar* tmp = NULL;
856 tmp = g_value_get_string(src);
857 g_value_set_string(dest, tmp);
860 case G_TYPE_DOUBLE: {
862 tmp = g_ascii_strtod(g_value_get_string(src), NULL);
863 g_value_set_double(dest, tmp);
868 tmp = tcore_util_marshal_deserialize_string(g_value_get_string(src));
869 g_value_set_boxed(dest, tmp);
881 TReturn tcore_util_netif_up(const char *name)
888 return TCORE_RETURN_EINVAL;
890 if (strlen(name) > IFNAMSIZ)
891 return TCORE_RETURN_EINVAL;
893 fd = socket(AF_INET, SOCK_DGRAM, 0);
895 return TCORE_RETURN_FAILURE;
898 memset(&ifr, 0, sizeof(struct ifreq));
899 strncpy(ifr.ifr_name, name, IFNAMSIZ);
900 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
902 ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
905 return TCORE_RETURN_FAILURE;
908 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
910 ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
913 return TCORE_RETURN_FAILURE;
917 return TCORE_RETURN_SUCCESS;
920 TReturn tcore_util_netif_down(const char *name)
927 return TCORE_RETURN_EINVAL;
929 if (strlen(name) > IFNAMSIZ)
930 return TCORE_RETURN_EINVAL;
932 fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
934 return TCORE_RETURN_FAILURE;
937 memset(&ifr, 0, sizeof(struct ifreq));
938 strncpy(ifr.ifr_name, name, IFNAMSIZ);
939 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
942 ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
945 return TCORE_RETURN_FAILURE;
948 ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
950 ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
953 return TCORE_RETURN_FAILURE;
957 return TCORE_RETURN_SUCCESS;
960 TReturn tcore_util_netif_set(const char *name, const char *ipaddr,
961 const char *gateway, const char *netmask)
966 struct sockaddr_in sai;
969 return TCORE_RETURN_EINVAL;
971 if (strlen(name) > IFNAMSIZ)
972 return TCORE_RETURN_EINVAL;
974 fd = socket(AF_INET, SOCK_DGRAM, 0);
976 return TCORE_RETURN_FAILURE;
979 memset(&sai, 0, sizeof(struct sockaddr_in));
980 sai.sin_family = AF_INET;
982 memset(&ifr, 0, sizeof(struct ifreq));
985 dbg("ip = [%s]", ipaddr);
986 if (!inet_aton(ipaddr, &sai.sin_addr)) {
988 return TCORE_RETURN_FAILURE;
991 strncpy(ifr.ifr_name, name, IFNAMSIZ);
992 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
993 memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
995 ret = ioctl(fd, SIOCSIFADDR, &ifr);
998 return TCORE_RETURN_FAILURE;
1003 dbg("gateway = [%s]", gateway);
1004 if (!inet_aton(gateway, &sai.sin_addr)) {
1006 return TCORE_RETURN_FAILURE;
1009 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1010 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1011 memcpy(&ifr.ifr_dstaddr, &sai, sizeof(sai));
1013 ret = ioctl(fd, SIOCSIFDSTADDR, &ifr);
1016 return TCORE_RETURN_FAILURE;
1021 dbg("netmask = [%s]", netmask);
1022 if (!inet_aton(netmask, &sai.sin_addr)) {
1024 return TCORE_RETURN_FAILURE;
1027 strncpy(ifr.ifr_name, name, IFNAMSIZ);
1028 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1029 memcpy(&ifr.ifr_netmask, &sai, sizeof(sai));
1031 ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
1034 return TCORE_RETURN_FAILURE;
1039 return TCORE_RETURN_SUCCESS;
1042 char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip)
1044 char buf[16]; /* 'nnn'*4 + '.'*3 + '\0' */
1046 snprintf(buf, 16, "%d.%d.%d.%d", ip.s[0], ip.s[1], ip.s[2], ip.s[3]);
1051 enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode)
1053 enum tcore_dcs_type dcs = TCORE_DCS_TYPE_NONE;
1055 switch (encode & 0xf0)
1060 dcs = TCORE_DCS_TYPE_7_BIT;
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
1069 dcs = TCORE_DCS_TYPE_UNSPECIFIED;
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;
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;
1101 case 0xD0: // 1010 .. 1101
1102 case 0xE0: // 0x1110
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;
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; \
1122 unsigned char *tcore_util_decode_hex(const char *src, int len)
1135 out_len = strlen(src) / 2 + 1;
1141 buf = calloc(out_len, 1);
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);
1149 buf[j] = (value1 << 4) + value2;
1155 #define convert_to_hex(in, out) (in <= 9) ? \
1156 (out = '0' + in) : (out = 'A' + in - 10)
1158 long tcore_util_encode_hex(const unsigned char *src, long num_bytes,
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]);
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)
1181 unsigned char converted_sca[SMS_ENCODED_SCA_LEN_MAX];
1184 converted_sca[0] = 0;
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
1196 sca_len = ((sca[0] + 1) / 2) + 1;
1198 converted_sca[0] = (unsigned char)sca_len;
1200 for (i = 1; i <= sca_len; i++)
1201 converted_sca[i] = sca[i];
1204 memcpy(pdu, converted_sca, sca_len);
1205 memcpy(pdu + sca_len, tpdu, tpdu_len);
1207 return sca_len + tpdu_len;
1210 unsigned char *tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len)
1212 unsigned char *dest;
1214 unsigned int pos = 0;
1215 unsigned char shift = 0;
1218 if (!src || src_len == 0) {
1222 outlen = (src_len * 8) / 7;
1224 dest = calloc(outlen + 1, 1);
1228 for (i = 0; pos < src_len; i++, pos++) {
1229 dest[i] = (src[pos] << shift) & 0x7F;
1232 /* except the first byte, a character contains some bits from the previous byte.*/
1233 dest[i] |= src[pos - 1] >> (8 - shift);
1241 /* a possible extra complete character is available */
1243 dest[i] = src[pos] >> 1;
1247 /*If a character is '\r'(13), change it to space(32) */
1248 for (i = 0; i < outlen; i++)
1249 if (dest[i] == '\r')
1252 dest[outlen] = '\0';
1257 unsigned char *tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len)
1259 unsigned char *dest;
1261 unsigned int pos = 0, shift = 0;
1262 unsigned int outlen = 0;
1264 if (!src || src_len == 0) {
1268 outlen = ((src_len * 7) / 8) + 1;
1270 dest = calloc(outlen + 1, 1);
1274 for (pos = 0, i = 0; i < src_len; pos++, i++) {
1275 if (pos >= outlen) {
1280 /* pack the low bits */
1281 dest[pos] = src[i] >> shift;
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);
1303 char* tcore_util_convert_bcd2ascii(const char* src, int src_len, int max_len)
1305 int index = 0, len=0;
1306 char l_bcd = 0x00, h_bcd = 0x0F;
1312 if(src_len*2 > max_len){
1313 err("PARSER - number length exceeds the max");
1317 dest = malloc((src_len*2)*sizeof(char)+1);
1318 memset(dest, 0, (src_len*2)*sizeof(char)+1);
1320 for(index = 0; index < src_len; index++){
1321 l_bcd = src[index] & 0x0F;
1322 h_bcd = (src[index] & 0xF0) >> 0x04;
1332 dest[len++] = 'p'; //Pause
1335 dest[len++] = '?'; //Wild Card character
1337 case 0x0E: //ignore, RFU
1338 case 0x0F: //ignore in l_bcd
1341 dest[len++] = l_bcd+'0'; //digits 0~9
1353 dest[len++] = 'p'; //Pause
1356 dest[len++] = '?'; //Wild Card character
1358 case 0x0E: //ignore, RFU
1360 dest[len] = '\0'; //Null termination
1363 dest[len++] = h_bcd+'0'; //digits 0~9
1371 dbg("PARSER - number(%s) len(%d)", dest, len);
1375 GHashTable *tcore_util_marshal_create()
1377 GHashTable *ht = NULL;
1379 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1380 _tcore_util_marshal_remove_value);
1385 void tcore_util_marshal_destory(GHashTable *ht)
1390 g_hash_table_destroy(ht);
1394 GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string)
1397 gchar **tuple = NULL;
1398 GHashTable *ht = NULL;
1400 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1401 _tcore_util_marshal_remove_value);
1403 if (strlen(serialized_string) == 0) {
1407 tuple = g_strsplit((gchar *) serialized_string, " ", 0);
1409 while (strlen(tuple[index]) > 3) {
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;
1417 inner_tuple = g_strsplit(tuple[index], ":", 0);
1418 type = atoi(inner_tuple[1]);
1419 content = g_base64_decode(inner_tuple[2], (gsize *)&tmp);
1421 g_value_init(src, G_TYPE_STRING);
1422 g_value_init(dest, type);
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);
1429 g_strfreev(inner_tuple);
1437 gchar *tcore_util_marshal_serialize(GHashTable *ht)
1439 gchar *rv_str = NULL;
1440 GHashTableIter iter;
1441 gpointer key, value;
1442 GString *gstring_tmp = NULL;
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 } } };
1451 g_value_init(&gval, G_TYPE_STRING);
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);
1460 sub_ht = g_value_get_boxed((GValue *) value);
1461 tmp = tcore_util_marshal_serialize(sub_ht);
1464 encoded_d = g_base64_encode((guchar *)tmp, (gsize)strlen(tmp));
1467 g_string_append_printf(gstring_tmp, "%s:%d:%s ", (gchar *)key,
1469 g_free((gpointer)encoded_d);
1470 g_value_unset(&gval);
1473 rv_str = g_strdup(gstring_tmp->str);
1474 g_string_free(gstring_tmp, TRUE);
1479 gboolean tcore_util_marshal_add_data(GHashTable *ht, const gchar *key,
1480 const void *data, enum tcore_util_marshal_data_type type)
1482 gboolean rv = FALSE;
1485 if (!ht || !key || !data)
1491 value = g_new0(GValue, 1);
1493 rv = _tcore_util_marshal_create_gvalue(value, data, type);
1498 g_hash_table_insert(ht, g_strdup(key), value);
1503 gboolean tcore_util_marshal_get_data(GHashTable *ht, const gchar *key,
1504 void **data, enum tcore_util_marshal_data_type type)
1506 gboolean rv = FALSE;
1509 if (!ht || !key || !data)
1512 value = g_hash_table_lookup(ht, key);
1514 rv = _tcore_util_return_value((GValue *) value, data, type);
1521 gint tcore_util_marshal_get_int(GHashTable *ht, const gchar *key)
1523 gboolean rv = FALSE;
1524 gint rvalue, *tmp = NULL;
1529 rv = tcore_util_marshal_get_data(ht, key, (void **) &tmp,
1530 TCORE_UTIL_MARSHAL_DATA_INT_TYPE);
1543 gchar *tcore_util_marshal_get_string(GHashTable *ht, const gchar *key)
1545 gboolean rv = FALSE;
1546 gchar *rvalue = NULL;
1551 rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1552 TCORE_UTIL_MARSHAL_DATA_STRING_TYPE);
1559 GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key)
1561 gboolean rv = FALSE;
1562 GHashTable *rvalue = NULL;
1567 rv = tcore_util_marshal_get_data(ht, key, (void **) &rvalue,
1568 TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE);
1575 char *tcore_util_get_version(void)
1577 return strdup(TCORE_VERSION);