Always use semi-colons at the end of MACROs
[platform/core/telephony/tel-plugin-dbus_tapi.git] / src / sat_util.c
1 /*
2  * tel-plugin-dbus_tapi
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 <stdlib.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include <iconv.h>
28 #include <glib.h>
29
30 #include "sat_manager.h"
31 #include "util.h"
32
33 #define tabGsmUniMax2 9
34 #define tabGsmUniMax 42
35
36 static gboolean _find_gsm_code_exception_table(unsigned short src);
37 static int              _get_gsm_code_size(unsigned short* src, int src_len);
38 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len);
39 static int                      _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len);
40 static void             _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len,     unsigned char *src, unsigned int src_len);
41 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len);
42 static char*            _convert_ucs_to_utf8(unsigned char *src, int src_len);
43 static int                      _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len);
44 static int                      _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len);
45 static void             _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len);
46 static int                      _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len);
47
48 typedef struct {
49         char gsm;
50         unsigned short unicode;
51 } GsmUniTable;
52
53 const GsmUniTable gsm_unicode2_table[] = {
54                 { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C },
55                 { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C },
56                 { 0x65, 0x20AC } };
57
58 const GsmUniTable gsm_unicode_table[] = {
59                 { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 },
60                 { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 },
61                 { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 },
62                 { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B },
63                 { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 },
64                 { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 },
65                 { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 },
66                 { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 },
67                 { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, };
68
69
70
71 static gboolean _find_gsm_code_exception_table(unsigned short src)
72 {
73         if ((src >= 0x0020 && src <= 0x0023)
74                         || (src >= 0x0025 && src <= 0x003F)
75                         || (src >= 0x0041 && src <= 0x005A)
76                         || (src >= 0x0061 && src <= 0x007A)
77                         || src == 0x000A || src == 0x000D)
78                 return TRUE;
79         return FALSE;
80 }
81
82 static int _get_gsm_code_size(unsigned short* src, int src_len)
83 {
84         gboolean in_table = FALSE;
85         gboolean in_sec_table = FALSE;
86         int i, gsm_len = 0;
87
88         if (NULL == src) {
89                 dbg( "INPUT PARAM was NULL");
90                 return -1;
91         }
92
93         for (; src_len > 0 && src; src_len--) {
94                 if (_find_gsm_code_exception_table(*src) == TRUE) {
95                         src++;
96                         gsm_len++;
97                         continue;
98                 }
99                 in_table = FALSE;
100                 for (i = 0; i < tabGsmUniMax; i++) {
101                         if (*src == gsm_unicode_table[i].unicode) {
102                                 src++;
103                                 in_table = TRUE;
104                                 gsm_len++;
105                                 break;
106                         }
107                 }
108                 if (in_table == FALSE) {
109                         in_sec_table = FALSE;
110                         for (i = 0; i < tabGsmUniMax2; i++) {/* second table */
111                                 if (*src == gsm_unicode2_table[i].unicode) {
112                                         src++;
113                                         in_table = TRUE;
114                                         in_sec_table = TRUE;
115                                         gsm_len += 2;
116                                         break;
117                                 }
118                         }
119                         if (in_sec_table == FALSE) {/* second*/
120                                 if (_find_gsm_code_exception_table(*src) == FALSE) {
121                                         dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len);
122                                         return -1;
123                                 }
124                                 src++;
125                                 gsm_len++;
126                         }
127                 }
128         }
129         return gsm_len;
130 }
131
132 static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len)
133 {
134         int index, tmp_len;
135
136         if(!dest || !src) {
137                 dbg( "[SAT] dest(%p) or src(%p) is null",dest, src);
138                 return FALSE;
139         }
140
141         if(!src_len){
142                 dest[0] = '\0';
143                 return TRUE;
144         }
145
146         dbg("[SAT] source string (%s) len(%d)", src, src_len);
147
148         for(index = 0; index < (int)src_len; index++){
149                 if(src[index] == 0x1B)
150                         src_len--;
151         }
152         dbg("[SAT] strlen excluding escape character (%d)", src_len);
153
154         tmp_len = _convert_gsm_to_ucs2(dest, src, src_len);
155         dest[tmp_len] = '\0';
156
157         return TRUE;
158 }
159
160 static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len)
161 {
162         int index;
163         unsigned short* org;
164
165         org = dest;
166
167         for(index=0; index < (int)src_len; index++){
168                 int table_index=0;
169                 gboolean b_tabled = FALSE;
170
171                 /*
172                  * if the first byte is 0x1B, it is the escape character.
173                  * The byte value shoulbe be changed to unicode.
174                  */
175                 if(*src == 0x1B){
176                         src++; index++;//move to next byte
177                         for(table_index=0; table_index < tabGsmUniMax2; table_index++){
178                                 if(*src == gsm_unicode2_table[table_index].gsm){
179                                         *dest = gsm_unicode2_table[table_index].unicode;
180                                         b_tabled = TRUE;
181                                         break;
182                                 }
183                         }
184
185                         //if matched data is not in table, it should be changed to NULL;
186                         if(!b_tabled){
187                                 *dest = 0x0020;
188                         }
189                 }
190                 else{
191                         for(table_index=0; table_index < tabGsmUniMax; table_index++){
192                                 if(*src == gsm_unicode_table[table_index].gsm){
193                                         *dest = gsm_unicode_table[table_index].unicode;
194                                         b_tabled = TRUE;
195                                         break;
196                                 }
197                         }
198
199                         //if matched data is not in table, it is using original value;
200                         if(!b_tabled){
201                                 *dest = *src;
202                         }
203                 }
204
205                 //move to next position
206                 src++; dest++;
207         }
208
209         dbg("[SAT] cvt sr(%s), the size of data (%d) ", org, dest - org);
210         return (dest - org);
211 }
212
213 static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len)
214 {
215         int tmp_len = 0;
216         char *target_tmp = NULL;
217         unsigned char *raw_unicode = NULL;
218         unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX];
219
220         memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX);
221
222         _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len);
223         while(tmp_dest[tmp_len] != '\0')
224                 tmp_len++;
225         tmp_len++; // add null character
226
227         tmp_len = tmp_len*2; //for byte align
228         raw_unicode = (unsigned char*)malloc(tmp_len);
229         memset(raw_unicode, 0, tmp_len);
230
231         memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len);
232
233         *dest_len = tmp_len;
234         target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len);
235         if(!target_tmp){
236                 dbg( "str is NULL");
237                 g_free(raw_unicode);
238                 return;
239         }
240
241         memcpy(dest, target_tmp, strlen((const char*)target_tmp));
242         dbg("final utf8 str (%s), length (%d)", dest, tmp_len);
243
244         g_free(raw_unicode);
245         g_free(target_tmp);
246         return;
247 }
248
249 static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len)
250 {
251         char* tmp_str;
252         int gc_len = 0;
253
254         if ((NULL == dest) || (NULL == src)) {
255                 dbg( "INPUT PARAM was NULL");
256                 return FALSE;
257         }
258
259         if (src_len == 0)
260                 return FALSE;
261
262         gc_len = _get_gsm_code_size(src, src_len);
263         if (0 >= gc_len) {
264                 dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len);
265                 return FALSE;
266         }
267
268         if (dest_len < gc_len) {
269                 if (dest_len == sizeof(void*)) {
270                         dbg( "Out buffer size seems to be small (%s)", dest);
271                 } else {
272                         dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len);
273                 }
274                 return FALSE;
275         }
276
277         tmp_str = calloc(1, (unsigned short) gc_len);
278         if (tmp_str == NULL) {
279                 dbg( "Memory Allocation Failed!");
280                 return FALSE;
281         }
282
283         gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len);
284         if (gc_len != -1) {
285                 memcpy((char*) dest, (char*) tmp_str, gc_len);
286                 free(tmp_str);
287                 return TRUE;
288         }
289
290         free(tmp_str);
291         return FALSE;
292 }
293
294 static char* _convert_ucs_to_utf8(unsigned char* src, int src_len)
295 {
296         char* utf_str = NULL;
297         iconv_t cd = NULL;
298         size_t ileft = 0;
299         size_t oleft = 0;
300         int err = 0;
301
302         char* pIn = NULL;
303         char* in_buf = NULL;
304         char* out_buf = NULL;
305
306         if (!src) {
307                 dbg("src is null");
308                 return NULL;
309         }
310
311         ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes
312         oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes
313         pIn = in_buf = (char*) malloc(ileft + 2);
314         utf_str = out_buf = (char *) malloc(oleft + 1);
315
316         memset(in_buf, 0x00, ileft + 2);
317         memset(out_buf, 0x00, oleft + 1);
318         memcpy(in_buf, src, ileft);
319
320         in_buf[ileft] = '\0';
321
322         cd = iconv_open("UTF-8", "UCS-2");
323         err = iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft);
324
325         utf_str[src_len * 2 - ileft] = '\0';
326         iconv_close(cd);
327         free(pIn);
328         return utf_str;
329 }
330
331 static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len)
332 {
333         unsigned char* rear = NULL;
334         unsigned short* p;
335         unsigned char temp;
336         gboolean in_table = FALSE;
337         gboolean in_sec_table = FALSE;
338         int i, gc_len = 0;
339
340         if ((!dest) || (!src) || (0x00 == src_len)) {
341                 dbg( "Warning: Wrong Input");
342                 return -1;
343         }
344
345         rear = dest;
346         p = src;
347
348         for (; src_len > 0 && p; src_len--) {
349                 in_table = FALSE;
350                 for (i = 0; i < tabGsmUniMax; i++) { /* is in table  */
351                         if (*p == gsm_unicode_table[i].unicode) {
352                                 temp = (unsigned char) (gsm_unicode_table[i].gsm);
353                                 *rear = temp;
354                                 rear++;
355                                 p++;
356                                 in_table = TRUE;
357                                 gc_len++;
358                                 break;
359                         }
360                 }
361                 if (in_table == FALSE) {
362                         in_sec_table = FALSE;
363                         for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/
364                                 if (*p == gsm_unicode2_table[i].unicode) {
365                                         *rear = 0x1B;
366                                         rear++;
367                                         temp = (unsigned char) (gsm_unicode2_table[i].gsm);
368                                         *rear = temp;
369                                         rear++;
370                                         p++;
371                                         in_table = TRUE;
372                                         in_sec_table = TRUE;
373                                         gc_len += 2;
374                                         break;
375                                 }
376                         }
377                         if (in_sec_table == FALSE) { /* second */
378                                 if (_find_gsm_code_exception_table(*p) == FALSE)
379                                         return -1;
380                                 temp = (unsigned char) (*p); /* isn't in table */
381                                 *rear = temp;
382                                 rear++;
383                                 p++;
384                                 gc_len++;
385                         }
386                 }
387         }
388         src = p;
389         return gc_len;
390 }
391
392 static int _convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len)
393 {
394         char *p_o = NULL;
395         size_t src_len = in_len;
396         size_t dest_len = in_len*3;
397
398         iconv_t cd = iconv_open("UTF-8", "UCS2");
399         if (cd == (iconv_t) (-1)) {
400                 perror("iconv_open");
401                 return 0;
402         }
403
404         p_o = out;
405
406         dbg("expected input bytes:%d dest_len:%d\n", src_len, dest_len);
407
408         if (iconv(cd, &in, &src_len, &p_o, &dest_len) == (size_t)(-1)) {
409                 dbg("failed to iconv errno:%d", errno);
410         } else {
411                 dbg("remained input bytes:%d processed bytes:%d", src_len, in_len*3-dest_len);
412                 out[in_len*3-dest_len] = '\0';
413         }
414         *out_len = in_len*3-dest_len;
415         dbg("out_len[%d], output[%s]", *out_len, out);
416         iconv_close(cd);
417         return 0;
418 }
419
420 static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len)
421 {
422
423         dbg("[UCS2] prefix case:[0x%02x]", in[0]);
424
425         switch(in[0]) {
426                 case 0x80: {
427                         unsigned char num = in_len/2;           //number of characters
428                         int i = 0;
429                         int data_loc = 1;               //starting location of data
430                         unsigned short* in_buf = NULL;
431
432                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
433
434                         for(i=0; i<num; i++,data_loc++) {
435                                 in_buf[i] = ((unsigned short)in[data_loc]<<8) + (unsigned short)in[data_loc+1];
436                                 data_loc++;
437                                 dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
438                         }
439                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
440                         if(in_buf!=NULL)        free(in_buf);
441                 } break;
442
443                 case 0x81: {
444                         unsigned char num = in[1];              //number of characters
445                         unsigned short base = (unsigned short) in[2] << 7;      //base pointer for UCS2 type
446                         int i = 0;
447                         int data_loc = 3;               //starting location of data
448                         unsigned short* in_buf = NULL;
449
450                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
451
452                         for(i=0; i<num; i++,data_loc++) {
453                                 if(in[data_loc]<0x80) { // if the MSB is zero (0x80 => 1000b), then remaining 7 bits are GSM default character.
454                                         _convert_gsm_to_ucs2(&in_buf[i], (unsigned char *)&in[data_loc], 1);
455                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
456                                 } 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.
457                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
458                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
459                                 }
460                         }
461                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
462                         if(in_buf!=NULL)        free(in_buf);
463
464                 } break;
465
466                 case 0x82: {
467                         unsigned char num = in[1];              //number of characters
468                         unsigned short base = ((unsigned short) in[2] << 8) | (unsigned short) in[3];   //base pointer for UCS2 type
469                         int i = 0;
470                         int data_loc = 4;               //starting location of data
471                         unsigned short* in_buf = NULL;
472
473                         in_buf = (unsigned short*)malloc(num * sizeof(unsigned short));
474
475                         for(i=0; i<num; i++,data_loc++) {
476                                 if(in[data_loc]<0x80) {
477                                         _convert_gsm_to_ucs2(&in_buf[i], (unsigned char *)&in[data_loc], (unsigned int)1);
478                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
479                                 } else {
480                                         in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F);
481                                         dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]);
482                                 }
483                         }
484                         _convert_ucs2_to_utf8((char*)out, out_len, (char*) in_buf, num*2);
485                         if(in_buf!=NULL)        free(in_buf);
486                 } break;
487
488                 default: {
489                         int i = 0;
490                         for(i=0; i<in_len; i++) {
491                                 dbg("[UCS2]in[%d]=0x%02x", i, in[i]);
492                         }
493                         _convert_ucs2_to_utf8((char*)out, out_len, (char*)in, in_len);
494                 } break;
495         }
496 }
497
498 static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len)
499 {
500         unsigned short* org = NULL;
501         unsigned char hi = 0;
502         unsigned char mid = 0;
503         unsigned char low = 0;
504
505         if ((NULL == dest) || (NULL == src)) {
506                 dbg( "[SAT] INPUT PARAM NULL");
507                 return -1;
508         }
509
510         org = dest;
511
512         while (src_len > 0 && (*src != '\0')) {
513                 if (*src < 0x80) {
514                         *dest = (*src & 0x7F);
515                         dest++;
516                         src++;
517                         src_len--;
518                 } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) {
519                         hi = *src & 0x1F;
520                         low = *(src+1) & 0x3F;
521                         *dest = (hi << 6) | low;
522                         dest++;
523                         src += 2;
524                         src_len -= 2;
525                 } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) {
526                         hi = *src & 0x0F;
527                         mid = *(src+1) & 0x3F;
528                         low = *(src+2) & 0x3F;
529                         *dest = (hi << 12) | (mid << 6) | low;
530                         dest++;
531                         src += 3;
532                         src_len -= 3;
533                 } else {
534                         *dest = (*src & 0x7F);
535                         dest++;
536                         src++;
537                         src_len--;
538                         dbg( "[SAT] utf8 incorrect range");
539                 }
540         }
541         *dest = 0;
542         return (dest - org);
543 }
544
545 void sat_mgr_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, unsigned int src_len)
546 {
547         unsigned short *uc = NULL;
548         int gc_len = 0;
549         int uc_len = 0;
550         gboolean ret = FALSE;
551
552         if (src == NULL || src_len == 0) {
553                 dbg( "WARNING: Invalid Parameter");
554                 return;
555         }
556
557         uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short));
558         if (!uc) {
559                 dbg( "WARNING: calloc Failed");
560                 return;
561         }
562
563         /*Converting from UTF8 => UNICODE*/
564         uc_len = _convert_utf8_to_unicode(uc, src, src_len);
565         dbg( "uc_len:[%d]", uc_len);
566         if(uc_len == -1) {
567                 dbg( "_convert_utf8_to_unicode returns false!");
568                 free(uc);
569                 return;
570         }
571
572         /*Finding the GSMCode Size*/
573         gc_len = _get_gsm_code_size(uc, uc_len);
574         dbg( "gc_len:[%d]", gc_len);
575         if ( gc_len == -1) {
576                 dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]",   gc_len);
577                 free(uc);
578                 return;
579         }
580
581         *dest_len = gc_len;
582         /*Converting from UNICODE ==> GSM CODE */
583         ret = _convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len);
584         if (ret == FALSE) {
585                 dbg( "_convert_unicode_to_gsm Failed");
586                 *dest_len = 0x00;
587                 free(uc);
588                 return;
589         }
590
591         if(uc)
592                 free(uc);
593 }
594
595 void sat_mgr_convert_utf8_to_ucs2(unsigned char* dest, int* dest_len,   unsigned char* src, int src_len)
596 {
597         gsize byte_converted = 0;
598         gsize byte_read = 0;
599         gchar* str_converted = NULL;
600         GError *error = NULL;
601         int i;
602         char tmp_char;
603
604         if (dest == NULL || dest_len == NULL || src == NULL) {
605                 dbg( "Invalid Input Parameter");
606                 return;
607         }
608
609         /*Converting from UTF8 => UCS-2 using the g_convert*/
610         str_converted = (gchar*) g_convert((gchar*) src, (gsize) src_len,
611                                                                                                                                                 (gchar*) "UCS-2", (gchar*) "UTF8",
612                                                                                                                                                 (gsize*) &byte_read, (gsize*) &byte_converted,
613                                                                                                                                                 &error);
614         if (str_converted == NULL) {
615                 dbg( "str_converted is NULL");
616                 if (error != NULL) {
617                         dbg( "Problem while conversion UTF8 => UCS2, ErrorCode[%d]", error->code);
618                 }
619                 return;
620         }
621
622         dbg( "src_len[%u], byte_read[%u], byte_converted[%u]", src_len, byte_read, byte_converted);
623         *dest_len = (int) byte_converted;
624
625         if (byte_converted % 2 != 0) {
626                 dbg( "string length is wrong!");
627         } else {
628                 for (i = 0; i < (int)byte_converted; i++) {
629                         if (i % 2 == 0) {
630                                 tmp_char = str_converted[i];
631                                 str_converted[i] = str_converted[i + 1];
632                                 str_converted[i + 1] = tmp_char;
633                         }
634                 }
635         }
636         memcpy((unsigned char*) dest, (unsigned char*) str_converted, byte_converted);
637         g_free(str_converted);
638         return;
639 }
640
641 gboolean sat_mgr_convert_string(unsigned char *dest, unsigned short *dest_len,
642                 enum alphabet_format dcs, const unsigned char *src, unsigned short src_len)
643 {
644         dbg("[SAT] dcs=[0x%02x]", dcs );
645         dbg("[SAT] src=[%s], src_len=[%d]", src, src_len);
646
647         if(src==NULL || src_len==0) {
648                 err("[SAT] src is NULL or src_len is 0");
649                 return FALSE;
650         }
651
652         switch (dcs) {
653                 case ALPHABET_FORMAT_SMS_DEFAULT: {
654                         unsigned char* tmp_dest_str = NULL;
655                         dbg( "[SAT] alphabetFormat : [ALPHABET_FORMAT_SMS_DEFAULT]");
656                         tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len);
657
658                         if(!tmp_dest_str) {
659                                 err("temp_dest_str is NULL");
660                                 return FALSE;
661                         }
662                         _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str));
663                         if(tmp_dest_str) {
664                                 free(tmp_dest_str);
665                         }
666                 }       break;
667
668                 case ALPHABET_FORMAT_8BIT_DATA: {       //GSM7bit with bit 8 set to 0
669                         int tmp_str_len = 0;
670                         unsigned char *src_buf = NULL;
671                         src_buf = (unsigned char*)malloc(src_len);
672                         memcpy(src_buf, src, src_len);
673
674                         /*get string length*/
675                         /* 0xFF is the end of string */
676                         while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) {
677                                 tmp_str_len++;
678                         }
679                         /* last space character must be deleted */
680                         while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) {
681                                 tmp_str_len--;
682                         }
683                         dbg( "[SAT] alphabetFormat : [ALPHABET_FORMAT_8BIT_DATA]");
684                         dbg( "[SAT] tmp_str_len[%d]", tmp_str_len);
685
686                         _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len);
687                         if(src_buf != NULL)             free(src_buf);
688                 }       break;
689
690                 case ALPHABET_FORMAT_UCS2: {
691                         unsigned char *src_buf = NULL;
692                         src_buf = (unsigned char*)malloc(src_len);
693                         memcpy(src_buf, src, src_len);
694                         dbg( "[SAT] alphabetFormat : [ALPHABET_FORMAT_UCS2]");
695                         _convert_alpha_field_ucs2_to_utf8(dest, dest_len, src_buf, src_len);
696                         if(src_buf != NULL)             free(src_buf);
697                 }       break;
698
699                 default: {
700                         dbg("[SAT] not handled alpha format[0x%02x]", dcs);
701                         return FALSE;
702                 }       break;
703         }
704         return TRUE;
705 }
706
707 void swap_byte_order(unsigned short* dest, const unsigned short* src, int src_len)
708 {
709         int i = 0;
710
711         for (i = 0; i < src_len; i++) {
712                 dest[i] = (src[i] << 8) + (src[i] >> 8);
713         }
714 }