10 #include "sat_manager.h"
13 #define tabGsmUniMax2 9
14 #define tabGsmUniMax 42
16 static void _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len, unsigned char *src, unsigned int src_len);
18 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len);
19 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len);
21 static char* _convert_ucs_to_utf8(unsigned char *src, int src_len);
22 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len);
24 static unsigned short* _convert_process_unicode(unsigned short *dest, int dest_buf_len, unsigned char *src, unsigned long src_len);
26 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len);
27 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len);
29 static gboolean _find_gsm_code_exception_table(unsigned short src);
30 static int _get_gsm_code_size(unsigned short* src, int src_len);
31 static unsigned short* _swap_byte_order(unsigned short *dest, unsigned short *src, int len);
35 unsigned short unicode;
38 const GsmUniTable gsm_unicode2_table[] = {
39 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
40 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
43 const GsmUniTable gsm_unicode_table[] = {
44 { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 },
45 { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 },
46 { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 },
47 { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B },
48 { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 },
49 { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 },
50 { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 },
51 { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 },
52 { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, };
54 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
56 unsigned short* org = NULL;
58 unsigned char mid = 0;
59 unsigned char low = 0;
61 if ((NULL == dest) || (NULL == src)) {
62 dbg( "[SAT] INPUT PARAM NULL");
68 while (src_len > 0 && (*src != '\0')) {
70 *dest = (*src & 0x7F);
74 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
76 low = *(src+1) & 0x3F;
77 *dest = (hi << 6) | low;
81 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
83 mid = *(src+1) & 0x3F;
84 low = *(src+2) & 0x3F;
85 *dest = (hi << 12) | (mid << 6) | low;
90 *dest = (*src & 0x7F);
94 dbg( "[SAT] utf8 incorrect range");
101 static gboolean _find_gsm_code_exception_table(unsigned short src)
103 if ((src >= 0x0020 && src <= 0x0023)
104 || (src >= 0x0025 && src <= 0x003F)
105 || (src >= 0x0041 && src <= 0x005A)
106 || (src >= 0x0061 && src <= 0x007A)
107 || src == 0x000A || src == 0x000D)
112 static int _get_gsm_code_size(unsigned short* src, int src_len)
114 gboolean in_table = FALSE;
115 gboolean in_sec_table = FALSE;
119 dbg( "INPUT PARAM was NULL");
123 for (; src_len > 0 && src; src_len--) {
124 if (_find_gsm_code_exception_table(*src) == TRUE) {
130 for (i = 0; i < tabGsmUniMax; i++) {
131 if (*src == gsm_unicode_table[i].unicode) {
138 if (in_table == FALSE) {
139 in_sec_table = FALSE;
140 for (i = 0; i < tabGsmUniMax2; i++) {/* second table */
141 if (*src == gsm_unicode2_table[i].unicode) {
149 if (in_sec_table == FALSE) {/* second*/
150 if (_find_gsm_code_exception_table(*src) == FALSE) {
151 dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len);
162 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
164 unsigned char* rear = NULL;
167 gboolean in_table = FALSE;
168 gboolean in_sec_table = FALSE;
171 if ((!dest) || (!src) || (0x00 == src_len)) {
172 dbg( "Warning: Wrong Input");
179 for (; src_len > 0 && p; src_len--) {
181 for (i = 0; i < tabGsmUniMax; i++) { /* is in table */
182 if (*p == gsm_unicode_table[i].unicode) {
183 temp = (unsigned char) (gsm_unicode_table[i].gsm);
192 if (in_table == FALSE) {
193 in_sec_table = FALSE;
194 for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/
195 if (*p == gsm_unicode2_table[i].unicode) {
198 temp = (unsigned char) (gsm_unicode2_table[i].gsm);
208 if (in_sec_table == FALSE) { /* second */
209 if (_find_gsm_code_exception_table(*p) == FALSE)
211 temp = (unsigned char) (*p); /* isn't in table */
223 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
228 if ((NULL == dest) || (NULL == src)) {
229 dbg( "INPUT PARAM was NULL");
236 gc_len = _get_gsm_code_size(src, src_len);
238 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
242 if (dest_len < gc_len) {
243 if (dest_len == sizeof(void*)) {
244 dbg( "Out buffer size seems to be small (%s)", dest);
246 dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
251 tmp_str = calloc(1, (unsigned short) gc_len);
252 if (tmp_str == NULL) {
253 dbg( "Memory Allocation Failed!");
257 gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
259 memcpy((char*) dest, (char*) tmp_str, gc_len);
268 void sat_mgr_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, unsigned int src_len)
270 unsigned short *uc = NULL;
273 gboolean ret = FALSE;
275 if (src == NULL || src_len == 0) {
276 dbg( "WARNING: Invalid Parameter");
280 uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
282 dbg( "WARNING: calloc Failed");
286 /*Converting from UTF8 => UNICODE*/
287 uc_len = _convert_utf8_to_unicode(uc, src, src_len);
288 dbg( "uc_len:[%d]", uc_len);
290 dbg( "_convert_utf8_to_unicode returns false!");
295 /*Finding the GSMCode Size*/
296 gc_len = _get_gsm_code_size(uc, uc_len);
297 dbg( "gc_len:[%d]", gc_len);
299 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]", gc_len);
305 /*Converting from UNICODE ==> GSM CODE */
306 ret = _convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len);
308 dbg( "_convert_unicode_to_gsm Failed");
318 void sat_mgr_convert_utf8_to_ucs2(unsigned char* dest, int* dest_len, unsigned char* src, int src_len)
320 gsize byte_converted = 0;
322 gchar* str_converted = NULL;
323 GError *error = NULL;
327 if (dest == NULL || dest_len == NULL || src == NULL) {
328 dbg( "Invalid Input Parameter");
332 /*Converting from UTF8 => UCS-2 using the g_convert*/
333 str_converted = (gchar*) g_convert((gchar*) src, (gsize) src_len,
334 (gchar*) "UCS-2", (gchar*) "UTF8",
335 (gsize*) &byte_read, (gsize*) &byte_converted,
337 if (str_converted == NULL) {
338 dbg( "str_converted is NULL");
340 dbg( "Problem while conversion UTF8 => UCS2, ErrorCode[%d]", error->code);
345 dbg( "src_len[%u], byte_read[%u], byte_converted[%u]", src_len, byte_read, byte_converted);
346 *dest_len = (int) byte_converted;
348 if (byte_converted % 2 != 0) {
349 dbg( "string length is wrong!");
351 for (i = 0; i < (int)byte_converted; i++) {
353 tmp_char = str_converted[i];
354 str_converted[i] = str_converted[i + 1];
355 str_converted[i + 1] = tmp_char;
359 memcpy((unsigned char*) dest, (unsigned char*) str_converted, byte_converted);
360 g_free(str_converted);
364 static int _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
367 size_t src_len = in_len;
368 size_t dest_len = in_len*3;
373 iconv_t cd = iconv_open("UTF-8", "UCS2");
374 if (cd == (iconv_t) (-1)) {
375 perror("iconv_open");
378 //For byte swap - start
379 src = (short*)malloc(in_len);
380 memcpy(src, in, in_len);
381 dest = (short*)malloc(in_len);
382 memset(dest, 0, in_len);
383 for(i=0; i<in_len/2; i++){
384 dest[i] = ((src[i] << 8) + (src[i] >> 8));
386 memcpy(in, dest, in_len);
389 //For byte swap - end
393 dbg("expected input bytes:%d dest_len:%d\n", src_len, dest_len);
395 if (iconv(cd, &in, &src_len, &p_o, &dest_len) == (size_t)(-1)) {
396 dbg("failed to iconv errno:%d", errno);
398 dbg("remained input bytes:%d processed bytes:%d", src_len, in_len*3-dest_len);
399 out[in_len*3-dest_len] = '\0';
401 *out_len = in_len*3-dest_len;
402 dbg("out_len[%d], output[%s]", *out_len, out);
407 void sat_mgr_convert_string(unsigned char *dest, unsigned short *dest_len,
408 enum alphabet_format dcs, unsigned char *src, unsigned short src_len)
411 unsigned char* tmp_dest_str = dest;
412 unsigned short* in_buf = NULL;
414 /*get string length*/
415 /* 0xFF is the end of string */
416 while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
419 /* last space character must be deleted */
420 while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
424 dbg( "[SAT] alphabetFormat : [0x%x]", dcs);
425 dbg( "[SAT] tmp_str_len[%d] src_len[%d]", tmp_str_len, src_len);
428 case ALPHABET_FROMAT_SMS_DEFAULT:
429 tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len);
430 _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
433 case ALPHABET_FROMAT_8BIT_DATA:
434 _convert_gsm_to_utf8(dest, dest_len, src, tmp_str_len);
437 case ALPHABET_FROMAT_UCS2:{
438 if (src[0] == 0x80) {
439 dbg("UCS2:[0x%2x] prefix case", src[0]);
440 _convert_ucs2_to_utf8((char*) dest, dest_len, (char*) (src + 1), src_len - 1);
441 } else if (src[0] == 0x81 || src[0] == 0x82) {
442 dbg("UCS2:[0x%2x] prefix case", src[0]);
443 *dest_len = tmp_str_len;
444 in_buf = (unsigned short*) malloc(tmp_str_len * sizeof(unsigned short) + 1);
446 dbg( "[SAT] Error:malloc failed");
449 _convert_process_unicode(in_buf, (tmp_str_len * sizeof(unsigned short) + 1), src,
451 dest = (unsigned char*) _convert_ucs_to_utf8((unsigned char *) in_buf, tmp_str_len);
452 if (in_buf) free(in_buf);
455 dbg( "[SAT] WARNING: dest str is NULL");
458 memcpy(tmp_dest_str, dest, SAT_TEXT_STRING_LEN_MAX);
460 if (tmp_dest_str != dest) {
461 dbg( "[SAT] destination string address changed hence freeing");
465 dbg( "[SAT] string[%s]", dest);
466 dbg( "[SAT] out put string[%s]", tmp_dest_str);
467 dbg( "[SAT] string pointer after parsing dcs[0x%x]", dest);
468 dbg( "[SAT] string length[%d]", *dest_len);
470 dbg("UCS2: no prefix case");
471 _convert_ucs2_to_utf8((char*) dest, dest_len, (char*) src, src_len);
477 dbg("not handled alpha format[%d]", dcs);
483 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
490 for(index=0; index < (int)src_len; index++){
492 gboolean b_tabled = FALSE;
495 * if the first byte is 0x1B, it is the escape character.
496 * The byte value shoulbe be changed to unicode.
499 src++; index++;//move to next byte
500 for(table_index=0; table_index < tabGsmUniMax2; table_index++){
501 if(*src == gsm_unicode2_table[table_index].gsm){
502 *dest = gsm_unicode2_table[table_index].unicode;
508 //if matched data is not in table, it should be changed to NULL;
514 for(table_index=0; table_index < tabGsmUniMax; table_index++){
515 if(*src == gsm_unicode_table[table_index].gsm){
516 *dest = gsm_unicode_table[table_index].unicode;
522 //if matched data is not in table, it is using original value;
528 //move to next position
532 dbg("[SAT] cvt sr(%s), the size of data (%d) ", org, dest - org);
536 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
541 dbg( "[SAT] dest(%p) or src(%p) is null",dest, src);
550 dbg("[SAT] source string (%s) len(%d)", src, src_len);
552 for(index = 0; index < (int)src_len; index++){
553 if(src[index] == 0x1B)
556 dbg("[SAT] strlen excluding escape character (%d)", src_len);
558 tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
559 dest[tmp_len] = '\0';
564 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
566 char* utf_str = NULL;
574 char* out_buf = NULL;
581 ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes
582 oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes
583 pIn = in_buf = (char*) malloc(ileft + 2);
584 utf_str = out_buf = (char *) malloc(oleft + 1);
586 memset(in_buf, 0x00, ileft + 2);
587 memset(out_buf, 0x00, oleft + 1);
588 memcpy(in_buf, src, ileft);
590 in_buf[ileft] = '\0';
592 cd = iconv_open("UTF-8", "UCS-2");
593 err = iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft);
595 utf_str[src_len * 2 - ileft] = '\0';
601 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
604 char *target_tmp = NULL;
605 unsigned char *raw_unicode = NULL;
606 unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
608 memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
610 _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
611 while(tmp_dest[tmp_len] != '\0')
613 tmp_len++; // add null character
615 tmp_len = tmp_len*2; //for byte align
616 raw_unicode = (unsigned char*)malloc(tmp_len);
617 memset(raw_unicode, 0, tmp_len);
619 memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
622 target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
628 memcpy(dest, target_tmp, strlen((const char*)target_tmp));
629 dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
634 * UCS2 character decoding for SIM alpha identifier as defined ETSI 102 221.
636 static unsigned short* _convert_process_unicode(unsigned short* dest, int dest_buf_len, unsigned char* src, unsigned long src_len)
638 int i, j, base = 0, str_len = 0, shift =0;
639 unsigned short tmp_str[255 + 1];
643 str_len = (src_len - 1) / 2;
644 memcpy(tmp_str, &src[1], src_len - 1);
645 tmp_str[str_len] = '\0';
646 _swap_byte_order(dest, tmp_str, str_len);
647 dest[str_len] = '\0';
652 str_len = (int) src[1];
660 str_len = (int) src[1];
661 base = (int) (src[2] << 8 | src[3]);
668 for (i = 0; i < (int) src_len; i++) {
669 if (src[i] == 0xFF) {
674 str_len = (src_len) / 2;
675 memcpy(tmp_str, &src[0], src_len);
676 tmp_str[str_len] = '\0';
677 _swap_byte_order(dest, tmp_str, str_len);
678 dest[str_len] = '\0';
684 dbg( "[SAT] str_len[%d], dest_buf_len[%d]", str_len, dest_buf_len);
686 for (i = 0; i < str_len && i < dest_buf_len; i++, j++) {
687 if (src[j] <= 0x7F) {/* GSM Code */
688 if (src[j] == 0x1B) {/* 2Byte GSM Code */
689 _convert_gsm_to_unicode(&dest[i], 2, &src[j], 2);
692 _convert_gsm_to_unicode(&dest[i], 2, &src[j], 1);
695 dest[i] = (unsigned short) ((base << shift) + (src[j] & 0x7F));
696 dbg( "[SAT] converted0x%x\n", src[j]);
697 dbg( "[SAT] converted0x%x\n", dest[i]);
704 static unsigned short* _swap_byte_order(unsigned short* dest, unsigned short* src, int src_len)
707 for (i = 0; i < src_len; i++) {
710 dest[i] = ((src[i] << 8) + (src[i] >> 8));