c62f89173d11f45e7660e17a362c15c192c60f0c
[platform/adaptation/emulator/vmodem-daemon-emulator.git] / lib / libsms / sms_util.c
1 /*
2  *  telephony-emulator
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: 
7  * Sooyoung Ha <yoosah.ha@samsung.com>
8  * Sungmin Ha <sungmin82.ha@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  * 
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU Lesser General Public License as published by the
13  * Free Software Foundation; either version 2.1 of the License, or (at your option)
14  * any later version.
15  * 
16  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this library; if not, write to the Free Software Foundation, Inc., 51
23  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  * Contributors:
26  * - S-Core Co., Ltd
27  * 
28  */
29
30 #include <assert.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include "sms_header.h"
35 #include "sms_util.h"
36
37
38 void  reverse(char* x, int len)
39 {
40         int i, j = len - 1;
41
42         for (i = 0; i < j; i++)
43         {
44                 int t = x[i];
45                 x[i] = x[j];
46                 x[j--] = t;
47         }
48 }
49
50 char*  AcItoa(int n, char* str, int b)
51 {
52         int i = 0;
53
54         do
55                 str[i++] = "0123456789ABCDEF"[n%b];
56
57         while ((n /= b) > 0);
58         reverse(str, i);
59         str[i] = '\0';
60
61         return str;
62 }
63
64 int  AcToupper(int ch)
65 {
66         return (('a' <= (ch) && (ch) <= 'z')? ((ch) - ('a'-'A')) : (ch));
67 }
68
69 char* SmsUtilUnpackGSM8Code( char* szData, const BYTE* pIn, int in_len )
70 {
71         int i;
72   
73     for (i = 0; i < in_len; i ++) {  
74                 szData [i] = pIn [i];
75         }  
76
77     return szData;      
78 }
79
80
81 int SmsUtilUnpackGSMCode( char* szData, const BYTE* pIn, int in_len )
82 {
83         int i;
84         int pos = 0;
85         int shift = 0;
86
87         /* If the number of fill bits != 0, then it would cause an additional shift */
88         /*
89         if ( shift != 0 )
90                 pos = pos + 1;
91
92         if ( shift ==7 )
93                 shift = 0;
94         */
95
96         for ( i = 0; i < in_len; i++, pos++ )
97         {
98                 szData[i] = ( pIn[pos] << shift ) & 0x7F;
99
100                 if ( pos != 0 )
101                 {
102                         /* except the first byte, a character contains some bits
103                         ** from the previous byte.
104                         */
105                         szData[i] |= pIn[pos-1] >> (8-shift);
106                 }
107
108                 shift ++;
109
110                 if ( shift == 7 )
111                 {
112                         shift = 0;
113
114                         /* a possible extra complete character is available */
115                         i++;
116                         szData[i] = pIn[pos] >> 1;
117
118                         if( szData[i] == 0 )
119                         {
120                                 /* this is the end of the input, quit */
121                 //              break;
122                         }
123                 }
124         }
125
126         return i;
127 }
128
129 int SmsUtilpackGSM8Code( BYTE* pOut, const char* szData, int in_len )
130 {
131         int i;
132         int pos = 0;
133   
134     for (i = 0; i < in_len; i ++) {  
135                 pOut[i] = szData [i];
136                 pos++;
137         }  
138
139     return pos; 
140 }
141
142 int SmsUtilPackGSMCode( BYTE* pOut, const char* szData, int in_len )
143 {
144         int i;
145         int pos;
146         int shift = 0;
147         //shift = fill_bits;
148
149         //  memset( out, 0, out_len_max );
150
151         /* pack the ASCII characters
152         */
153         /*
154         if ( shift == 7 )
155                 shift = 0;
156         */
157
158         for( pos = 0, i = 0; /*pos < out_len_max &&*/ i < in_len; pos++, i++ )
159         {
160                 /* pack the low bits */
161                 pOut[pos] = szData[i] >> shift;
162
163                 if ( i + 1 < in_len )
164                 {
165                         /* pack the high bits using the low bits of the next character */
166                         pOut[pos] |= szData[i+1] << ( 7 - shift );
167
168                         shift++;
169
170                         if( shift == 7 )
171                         {
172                                 shift = 0;
173                                 i++;
174                         }
175                 }
176         }
177
178         /* done */
179         return pos;
180 }
181
182
183 void SmsUtilConvertBCD2Digit( char* pDigits, char* pBCD, int digitLen )
184 {
185         int             i, bcdLen;
186         char    c[2];
187         unsigned char   higher, lower;
188
189         //SysDebug( ( MID_SMS, "__SmsConvertBCD2Digit: start.\n" ) );
190
191         if ( pBCD == NULL || pDigits == NULL )
192         {
193                 printf("__SmsConvertBCD2Digit: pBCD == NULL || pDigits == NULL. return.\n"  );
194                 return;
195         }
196
197         if ( digitLen == 0 )
198         {
199                 //printf("__SmsConvertBCD2Digit: digitLen == 0. return.\n" );
200
201                 pDigits[0] = 0x00;
202
203                 return;
204         }
205
206         if ( digitLen % 2 )
207                 bcdLen = digitLen / 2 + 1;
208         else
209                 bcdLen = digitLen / 2;
210
211         memset( pDigits, 0, bcdLen * 2 );
212
213         for ( i = 0; i < bcdLen; i++ )
214         {
215                 lower = pBCD[i] & 0x0F;                                 // get low nibble
216
217                 if ( lower == 0x0A )
218                         lower = '*';
219                 else if ( lower == 0x0B )
220                         lower = '#';
221                 else if ( lower == 0x0C )
222                         lower = 'p';                    //DTMF Control pDigits seperator
223                 else if ( lower == 0x0F )
224                         lower = 0;
225                 else
226                 {
227                         AcItoa( lower, c, 16 );
228                         lower = (char) AcToupper(c[0]);
229                 }
230
231                 higher = ( pBCD[i] >> 4 ) & 0x0F;                       // get high nibble
232
233                 if ( higher == 0x0A )
234                         higher = '*';           // =0x2A
235                 else if ( higher == 0x0B )
236                         higher = '#';           // =0x23
237                 else if ( higher == 0x0C )
238                         higher = 'p';           // =0x70, DTMF Control pDigits seperator
239                 else if ( higher == 0x0F ) // if higher semi-octet is 0x0F, filled bits.
240                 {
241                         //higher = 0;
242                         sprintf(pDigits + strlen(pDigits), "%c", lower);
243                         pDigits[/*digitLen-1*/bcdLen*2-1] = '\0';
244
245                         //printf("__SmsConvertBCD2Digit: pDigits [%s].\n", pDigits  );
246
247                         return;
248                 }
249                 else
250                 {
251                         AcItoa(higher, c, 16);
252                         higher = (char) AcToupper(c[0]);
253                 }
254
255                 //sprintf(pDigits, "%s%c%c", pDigits, lower, higher);
256                 sprintf(pDigits + strlen(pDigits), "%c%c", lower, higher);
257         }
258
259         pDigits[digitLen] = '\0';
260
261         //printf("__SmsConvertBCD2Digit: pDigits [%s].\n", pDigits  );
262 }
263
264
265 void SmsUtilConvertDigit2BCD( char* pBCD, char* pDigits, int digitLen )
266 {
267         int     i, j, digit;
268
269         unsigned char   higher, lower;
270
271         if ( pBCD == NULL || pDigits == NULL )
272                 return;
273
274         // 0123456789 -> 1032547698
275         for ( i = 0, j = 0; i < digitLen; i = i + 2, j++ )
276         {
277                 if ( pDigits[i] == '*' )
278                         digit = 0x0A;
279                 else if ( pDigits[i] == '#' )
280                         digit = 0x0B;
281                 else if ( AcToupper( pDigits[i] ) == 'P' )
282                         digit = 0x0C;
283                 else
284                         digit = (int) ( pDigits[i] - '0' );
285
286                 lower = digit & 0x0F;
287
288                 if ( digitLen != i + 1 )
289                 {
290                         if ( pDigits[i+1] == '*' )
291                                 digit = 0x0A;
292                         else if ( pDigits[i+1] == '#' )
293                                 digit = 0x0B;
294                         else if ( AcToupper( pDigits[i+1] ) == 'P' )
295                                 digit = 0x0C;
296                         else
297                                 digit = (int) ( pDigits[i+1] - '0' );
298
299                         higher = digit & 0x0F;
300                 }
301                 else
302                 {
303                         higher = 0xFF;
304                 }
305
306                 pBCD[j] = ( higher << 4 ) | lower;
307         }
308 }
309
310
311 TmDateTime* SmsUtilDecodeTimeStamp(unsigned char * pTimeStamp, TmDateTime *tmDateTime )
312 {
313         //TmDateTime tmDateTime;
314         char szBuf[3];
315         //UINT32        time;
316
317         if ( pTimeStamp == NULL )
318                 return NULL;
319
320         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[0], 2 );
321         tmDateTime->year = atoi( szBuf ) + 2000;
322         if ( ( tmDateTime->year >= 1900 + MAX_YEAR )/* && ( tmDateTime->year < 2000 + BASE_YEAR )*/ )
323                 tmDateTime->year -= 100;
324         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[1], 2 );
325         tmDateTime->month = atoi( szBuf );
326         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[2], 2 );
327         tmDateTime->day = atoi( szBuf );
328         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[3], 2 );
329         tmDateTime->hour = atoi( szBuf );
330         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[4], 2 );
331         tmDateTime->minute = atoi( szBuf );
332         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[5], 2 );
333         tmDateTime->second = atoi( szBuf );
334
335         if ( ( tmDateTime->year < 1900 + BASE_YEAR ) || ( tmDateTime->year > 1900 + MAX_YEAR ) )
336                 tmDateTime->year = 1900 + BASE_YEAR;
337
338         /*
339         time = TmDateTimeToSeconds( &tmDateTime );
340         if ( time > MAX_SECONDS )
341                 time = MAX_SECONDS;
342
343         */
344
345         return tmDateTime;
346 }
347
348 unsigned char* SmsUtilEncodeTimeStamp( TmDateTime* tmDateTime, unsigned char* pTimeStamp )
349 {
350         char szBuf[3];
351         int     year;
352
353         if ( pTimeStamp == NULL )
354                 return NULL;
355
356         memset( (void*) pTimeStamp, 0x00, sizeof ( unsigned char ) * 7 );
357
358         year = tmDateTime->year - 2000;
359         if ( year < 0 )
360                 year += 100;
361         
362         sprintf( szBuf, "%02d", year );
363         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[0], szBuf, 2 );
364         sprintf( szBuf, "%02d", tmDateTime->month );
365         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[1], szBuf, 2 );
366         sprintf( szBuf, "%02d", tmDateTime->day );
367         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[2], szBuf, 2 );
368         sprintf( szBuf, "%02d", tmDateTime->hour );
369         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[3], szBuf, 2 );
370         sprintf( szBuf, "%02d", tmDateTime->minute );
371         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[4], szBuf, 2 );
372         sprintf( szBuf, "%02d", tmDateTime->second );
373         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[5], szBuf, 2 );
374
375         sprintf( szBuf, "%02d", 0x00 );
376         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[6], szBuf, 2 );
377
378         return pTimeStamp;
379 }
380
381 void  SmsUtilDecodeAddrField_sca(char *diallingNum, unsigned char* pAddrField, int *result_ton, int *result_npi )
382 {
383         int index = 0;
384         int  ton,npi;
385         int dialnumLen=0;
386         int length = 0;
387
388
389         ton = ( pAddrField[index+1] & 0x70 ) >> 4;
390         npi = pAddrField[index+1] & 0x0F;
391
392         if ( ton != SIM_TON_ALPHA_NUMERIC )
393         {
394                 // Origination/Destination address Çʵ忡¼­ÀÇ length´Â ½ÇÁ¦ address length
395                 // origination/destination address ÇʵåÀΠ°æ¿ì length°¡ 0 ÀÏ ¶§¶óµµ number type/plan Çʵå´Â 0xFF °ªÀ» °®´Â´Ù.
396                 //dialnumLen = pAddrField[index++];
397                 length = pAddrField[index];
398                 // º¸³»Áö ¾ÊÀº ¸Þ½ÃÁöÀÇ °æ¿ì¿¡´Â service center address°¡ ¾øÀ» ¼öµµ ÀÖ´Ù.
399                 // ÀÌ °æ¿ì¿¡ length °¡ 0 À̸é number type, plan µµ ¾ø´Â °æ¿ì
400                 // length °¡ 1 À̸é type, plan ¸¸ Àִ °æ¿ì
401                 if ( length > 1 )
402                 {
403                         dialnumLen = ( pAddrField[index++] - 1 ) * 2; // -1Àº TON/API Çʵå
404                 }
405         }
406         else
407         {
408                 dialnumLen = ( ( ( pAddrField[index++] + 1 ) / 2 ) * 8 ) / 7;
409         }
410
411
412
413
414         // SIM_SMSP_ADDRESS_LEN º¸´Ù address length °¡ Å©¸é SIM_SMSP_ADDRESS_LEN ¸¸Å­¸¸ º¯È¯À» ÇÑ´Ù.
415
416         if ( dialnumLen > SIM_SMSP_ADDRESS_LEN )
417         {
418                 dialnumLen = SIM_SMSP_ADDRESS_LEN;
419         }
420
421         //printf(" dialnumLen = %d\n", dialnumLen  );
422
423         index++; /* ignore Type of Address field */
424
425         if (ton != SIM_TON_ALPHA_NUMERIC )
426         {
427                 SmsUtilConvertBCD2Digit( (char*)diallingNum, (char*) &pAddrField[index],dialnumLen );
428         }
429         else
430         {
431                 SmsUtilUnpackGSMCode( diallingNum, &pAddrField[index],dialnumLen );
432
433         }
434
435
436         //printf(  "__SmsDecodeAddrField: diallingNum [%s].\n", (char*) diallingNum  );
437
438         *result_ton=ton;
439         *result_npi=npi;
440 }
441
442
443 void  SmsUtilDecodeAddrField_dst(char *diallingNum, unsigned char* pAddrField, int *result_ton, int *result_npi )
444 {
445         int index = 0;
446         int  ton,npi;
447         int dialnumLen=0;
448
449         ton = ( pAddrField[index+1] & 0x70 ) >> 4;
450         npi = pAddrField[index+1] & 0x0F;
451
452         if ( ton != SIM_TON_ALPHA_NUMERIC )
453         {
454                 // Origination/Destination address Çʵ忡¼­ÀÇ length´Â ½ÇÁ¦ address length
455                 // origination/destination address ÇʵåÀΠ°æ¿ì length°¡ 0 ÀÏ ¶§¶óµµ number type/plan Çʵå´Â 0xFF °ªÀ» °®´Â´Ù.
456                 dialnumLen = pAddrField[index++];
457                 
458         }
459         else
460         {
461                 dialnumLen = ( ( ( pAddrField[index++] + 1 ) / 2 ) * 8 ) / 7;
462         }
463
464
465
466
467         // SIM_SMSP_ADDRESS_LEN º¸´Ù address length °¡ Å©¸é SIM_SMSP_ADDRESS_LEN ¸¸Å­¸¸ º¯È¯À» ÇÑ´Ù.
468
469         if ( dialnumLen > SIM_SMSP_ADDRESS_LEN )
470         {
471                 dialnumLen = SIM_SMSP_ADDRESS_LEN;
472         }
473
474         //printf(" dialnumLen = %d\n", dialnumLen  );
475
476         index++; /* ignore Type of Address field */
477
478         if (ton != SIM_TON_ALPHA_NUMERIC )
479         {
480                 SmsUtilConvertBCD2Digit( (char*)diallingNum, (char*) &pAddrField[index],dialnumLen );
481         }
482         else
483         {
484                 SmsUtilUnpackGSMCode( diallingNum, &pAddrField[index],dialnumLen );
485
486         }
487
488         *result_ton=ton;
489         *result_npi=npi;
490 }
491
492 int SmsReadSMSCfromSIM(unsigned char* pAddrFiled)
493 {
494         int index = 0;
495         int i;
496         
497         pAddrFiled[index++] = 0x7; //there are 7 octets following
498         pAddrFiled[index++] = 0x91; //internatial format
499         for(i=0; i<6; i++)
500                 pAddrFiled[index++]=0x11; // SMSC number stored in SIM is 111111111111
501                 
502         return index;   
503 }
504
505 int  SmsUtilEncodeAddrField_sca(unsigned char* pAddrField, unsigned char* diallingNum, int dialnumLen, int ton, int npi)
506 {
507         int index = 0;
508
509         if ( diallingNum == NULL || pAddrField == NULL )
510                 return -1;
511
512         if ( ton != SIM_TON_ALPHA_NUMERIC )
513         {
514                 if ( dialnumLen % 2 )
515                 {
516                         pAddrField[index++] = dialnumLen / 2 + 1 + 1; 
517                 }
518                 else
519                 {
520                         pAddrField[index++] = dialnumLen / 2 + 1; 
521                 }
522         }
523         else
524         {
525                 pAddrField[index] = (unsigned char) ( ( ( dialnumLen * 7 + 7 ) / 8 ) * 2 );
526
527                 if ( ( ( dialnumLen * 7 ) % 8 ) <= 4 )
528                         pAddrField[index]--;
529
530                 printf(" addr len packet: %d out of SIM_TON_ALPAHA\n", pAddrField[index]);
531
532                 index++;
533         }
534
535         SET_TON_NPI( pAddrField[index], ton, npi );
536
537         index++; 
538
539         if ( ton != SIM_TON_ALPHA_NUMERIC )
540         {
541                 SmsUtilConvertDigit2BCD( (char*) &pAddrField[index], (char*) diallingNum, dialnumLen );
542
543                 if ( dialnumLen % 2 )
544                         index += dialnumLen / 2 + 1;
545                 else
546                         index += dialnumLen / 2;
547         }
548         else
549         {
550                 index += SmsUtilPackGSMCode( &pAddrField[index], (char *)diallingNum, (int) dialnumLen );
551         }
552
553         return index;
554 }
555
556 int  SmsUtilEncodeAddrField_dst(unsigned char* pAddrField, unsigned char* diallingNum, int dialnumLen, int ton, int npi )
557 {
558         int index = 0;
559
560         if ( diallingNum == NULL || pAddrField == NULL )
561                 return -1;
562
563         if ( ton != SIM_TON_ALPHA_NUMERIC )
564         {
565                 // Origination/Destination address Çʵ忡¼­ÀÇ length´Â ½ÇÁ¦ address length
566                 pAddrField[index++] = (unsigned char)dialnumLen;
567                 //printf(" addr len packet: %d\n", pAddrField[index]);
568         }
569         else
570         {
571                 pAddrField[index] = (unsigned char) ( ( ( dialnumLen * 7 + 7 ) / 8 ) * 2 );
572
573                 // ¸¶Áö¸· ¹ÙÀÌÆ®¿¡¼­ »óÀ§ 4ºñÆ®°¡ »ç¿ëµÇÁö ¾ÊÀ¸¸é length Çʵ尪À» -1À» ÇÑ´Ù.
574                 if ( ( ( dialnumLen * 7 ) % 8 ) <= 4 )
575                         pAddrField[index]--;
576
577                 printf(" addr len packet: %d out of SIM_TON_ALPAHA\n", pAddrField[index]);
578
579                 index++;
580
581
582
583         }
584
585         SET_TON_NPI( pAddrField[index], ton, npi );
586
587         index++; // SET_TON_NPI °¡ MACRO À̹ǷΠ³»ºÎ¿¡¼­ Áõ°¡½ÃÅ°¸é ¹ö±×
588
589         if ( ton != SIM_TON_ALPHA_NUMERIC )
590         {
591                 SmsUtilConvertDigit2BCD( (char*) &pAddrField[index], (char*) diallingNum, dialnumLen );
592
593                 if ( dialnumLen % 2 )
594                         index += dialnumLen / 2 + 1;
595                 else
596                         index += dialnumLen / 2;
597         }
598         else
599         {
600                 index += SmsUtilPackGSMCode( &pAddrField[index], (char *)diallingNum, (int) dialnumLen );
601         }
602
603         return index;
604 }
605
606 int  SmsUtilEncodeAddrField(unsigned char* pAddrField, unsigned char* diallingNum, int dialnumLen, int ton, int npi )
607 {
608         int index = 0;
609
610         if ( diallingNum == NULL || pAddrField == NULL )
611                 return -1;
612
613         if ( ton != SIM_TON_ALPHA_NUMERIC )
614         {
615                 // Origination/Destination address Çʵ忡¼­ÀÇ length´Â ½ÇÁ¦ address length
616                 pAddrField[index++] = (unsigned char)dialnumLen;
617                 //printf(" addr len packet: %d\n", pAddrField[index]);
618         }
619         else
620         {
621                 pAddrField[index] = (unsigned char) ( ( ( dialnumLen * 7 + 7 ) / 8 ) * 2 );
622
623                 // ¸¶Áö¸· ¹ÙÀÌÆ®¿¡¼­ »óÀ§ 4ºñÆ®°¡ »ç¿ëµÇÁö ¾ÊÀ¸¸é length Çʵ尪À» -1À» ÇÑ´Ù.
624                 if ( ( ( dialnumLen * 7 ) % 8 ) <= 4 )
625                         pAddrField[index]--;
626
627                 printf(" addr len packet: %d out of SIM_TON_ALPAHA\n", pAddrField[index]);
628
629                 index++;
630
631
632
633         }
634
635         SET_TON_NPI( pAddrField[index], ton, npi );
636
637         index++; // SET_TON_NPI °¡ MACRO À̹ǷΠ³»ºÎ¿¡¼­ Áõ°¡½ÃÅ°¸é ¹ö±×
638
639         if ( ton != SIM_TON_ALPHA_NUMERIC )
640         {
641                 SmsUtilConvertDigit2BCD( (char*) &pAddrField[index], (char*) diallingNum, dialnumLen );
642
643                 if ( dialnumLen % 2 )
644                         index += dialnumLen / 2 + 1;
645                 else
646                         index += dialnumLen / 2;
647         }
648         else
649         {
650                 index += SmsUtilPackGSMCode( &pAddrField[index], (char *)diallingNum, (int) dialnumLen );
651         }
652
653         return index;
654 }
655 int SmsUtilDecodeScAddrField( SmsAddressInfo* pSmsAddrField, BYTE* pAddrField )
656 {
657         printf("SmsUtilDecodeScAddrField\n");
658         int index = 0;
659         int length = 0;
660
661         //SysDebug( ( MID_SMS, "__SmsDecodeScAddrField: start.\n" ) );
662
663         if ( pSmsAddrField == NULL || pAddrField == NULL )
664         {
665                 printf( "SmsUtilDecodeScAddrField: pSimAddrField or pAddrField is NULL.\n"  );
666
667                 return 0;
668         }
669
670         // Service Center address Çʵ忡¼­ÀÇ length´Â µÚ¿¡ ³ª¿À´Â byteÀÇ ¼ö
671         // -> ½ÇÁ¦ address ±æÀ̴ TON/API ¹ÙÀÌÆ®¸¦ Á¦¿ÜÇÏ°í ³ª¸ÓÁö ¹ÙÀÌÆ®ÀÇ 2¹è or 2¹è - 1(½ÇÁ¦ ±æÀÌ°¡ È¦¼öÀΰæ¿ì)
672         length = pAddrField[index];
673         // º¸³»Áö ¾ÊÀº ¸Þ½ÃÁöÀÇ °æ¿ì¿¡´Â service center address°¡ ¾øÀ» ¼öµµ ÀÖ´Ù.
674         // ÀÌ °æ¿ì¿¡ length °¡ 0 À̸é number type, plan µµ ¾ø´Â °æ¿ì
675         // length °¡ 1 À̸é type, plan ¸¸ Àִ °æ¿ì
676         if ( length > 1 )
677         {
678                 pSmsAddrField->dialnumLen = ( pAddrField[index++] - 1 ) * 2; // -1Àº TON/API Çʵå
679
680                 // SIM_SMSP_ADDRESS_LEN º¸´Ù address length °¡ Å©¸é SIM_SMSP_ADDRESS_LEN ¸¸Å­¸¸ º¯È¯À» ÇÑ´Ù.
681                 if ( pSmsAddrField->dialnumLen > SIM_SMSP_ADDRESS_LEN )
682                 {
683                         pSmsAddrField->dialnumLen = SIM_SMSP_ADDRESS_LEN;
684                 }
685
686                 pSmsAddrField->ton = ( pAddrField[index] & 0x70 ) >> 4;
687                 pSmsAddrField->npi = pAddrField[index] & 0x0F;
688
689                 index++; /* ignore Type of Address field */
690
691                 SmsUtilConvertBCD2Digit( (char*) pSmsAddrField->diallingNum, (char*) &pAddrField[index], pSmsAddrField->dialnumLen );
692
693                 printf( "SmsUtilDecodeScAddrField: diallingNum [%s].\n", (char*) pSmsAddrField->diallingNum  );
694
695                 printf( "length=%d , ton %d, npi =%d\n",pSmsAddrField->dialnumLen, pSmsAddrField->ton,pSmsAddrField->npi );
696         }
697
698         return ++length;
699 }
700
701  int  SmsUtilEncodeScAddrField( BYTE* pAddrField, SmsAddressInfo * pSmsAddrField )
702 {
703         int index = 0;
704
705         if ( pSmsAddrField == NULL || pAddrField == NULL )
706                 return -1;
707
708         // Service Center address Çʵ忡¼­ÀÇ length´Â µÚ¿¡ ³ª¿À´Â byteÀÇ ¼ö
709         // -> ½ÇÁ¦ address ±æÀ̴ TON/API ¹ÙÀÌÆ®¸¦ Á¦¿ÜÇÏ°í ³ª¸ÓÁö ¹ÙÀÌÆ®ÀÇ 2¹è or 2¹è - 1(½ÇÁ¦ ±æÀÌ°¡ È¦¼öÀΰæ¿ì)
710         if ( pSmsAddrField->dialnumLen % 2 )
711         {
712                 pAddrField[index++] = pSmsAddrField->dialnumLen / 2 + 1 + 1; // +1 Àº TON/NPI Çʵå, È¦¼ö°³ÀΠ°æ¿ì´Â °³¼ö¸¦ ¸ÂÃß±â À§ÇØ Çѹø ´õ +1
713         }
714         else
715         {
716                 pAddrField[index++] = pSmsAddrField->dialnumLen / 2 + 1; // +1 Àº TON/NPI Çʵå
717         }
718
719         SET_TON_NPI( pAddrField[index], pSmsAddrField->ton, pSmsAddrField->npi );
720
721         index++; // SET_TON_NPI °¡ MACRO À̹ǷΠ³»ºÎ¿¡¼­ Áõ°¡½ÃÅ°¸é ¹ö±×¹ß»ý
722
723         SmsUtilConvertDigit2BCD( (char*) &pAddrField[index], (char*) pSmsAddrField->diallingNum, pSmsAddrField->dialnumLen );
724
725         if ( pSmsAddrField->dialnumLen % 2 )
726                 index += pSmsAddrField->dialnumLen / 2 + 1;
727         else
728                 index += pSmsAddrField->dialnumLen / 2;
729
730         return index;
731 }
732
733 void SmsUtilDecodeDCS( TapiNetTextCodingScheme* pCodingScheme,   unsigned char dcs )
734 {
735         assert( pCodingScheme != NULL );
736
737         memset( pCodingScheme, 0, sizeof ( TapiNetTextCodingScheme ) );
738
739         if ( dcs < 0x40 ) // bits 7..4 = 00xx : general data coding indication
740         {
741                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_GENERAL_DCS;
742
743                 if ( dcs & 0x20 ) // bit 5 = 1 : indicates the text is compressed
744                         pCodingScheme->bCompressed = TRUE;
745
746                 if ( dcs & 0x10 ) // bit 4 = 1 : indicates that bits  1 to 0 have a message class meaning
747                 {
748                         pCodingScheme->bMsgClassSet = TRUE;
749
750                         switch ( dcs & 0x03 ) // bits 1 to 0 : message class
751                         {
752                                 case 0x00:
753                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_0;
754                                         break;
755                                 case 0x01:
756                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_1;
757                                         break;
758                                 case 0x02:
759                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_2;
760                                         break;
761                                 case 0x03:
762                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_3;
763                                         break;
764                         }
765                 }
766                 else // bit 4 = 0 : indicates that bits 1 to 0 are reserved and have no message class meaning
767                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_NONE;
768
769                 switch ( dcs & 0x0C ) // bits 4 to 3 : character set
770                 {
771                         case 0x00:
772                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_DEFAULT;
773                                 break;
774                         case 0x04:
775                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_8BIT;
776                                 break;
777                         case 0x08:
778                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_UCS2;
779                                 break;
780                         case 0x0C:
781                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_MAX;
782                                 break;
783                 }
784         }
785         else if ( dcs >= 0x40 && dcs < 0x80 ) // bits 7..4 = 01xx : message marked for automatic deletion group. bits 5..0 are coded exactly the same as group 00xx
786         {
787                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_AUTO_DELETION;
788
789                 if ( dcs & 0x20 ) // bit 5 = 1 : indicates the text is compressed
790                         pCodingScheme->bCompressed = TRUE;
791
792                 if ( dcs & 0x10 ) // bit 4 = 1 : indicates that bits  1 to 0 have a message class meaning
793                 {
794                         pCodingScheme->bMsgClassSet = TRUE;
795
796                         switch ( dcs & 0x03 ) // bits 1 to 0 : message class
797                         {
798                                 case 0x00:
799                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_0;
800                                         break;
801                                 case 0x01:
802                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_1;
803                                         break;
804                                 case 0x02:
805                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_2;
806                                         break;
807                                 case 0x03:
808                                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_3;
809                                         break;
810                         }
811                 }
812                 else // bit 4 = 0 : indicates that bits 1 to 0 are reserved and have no message class meaning
813                         pCodingScheme->classType = TAPI_NETTEXT_CLASS_NONE;
814
815                 switch ( dcs & 0x0C ) // bits 4 to 3 : character set
816                 {
817                         case 0x00:
818                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_DEFAULT;
819                                 break;
820                         case 0x04:
821                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_8BIT;
822                                 break;
823                         case 0x08:
824                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_UCS2;
825                                 break;
826                         case 0x0C:
827                                 pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_MAX;
828                                 break;
829                 }
830         }
831         // bits 7..4 = 1000 ~ 1011 : reserved
832         else if ( dcs == 0xC0 ) // bits 7..4 = 1100 : message waiting indication group, discard message
833         {
834                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_WAITING_DISCARD;
835         }
836         else if ( dcs < 0xE0 )
837         {
838                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_WAITING_STORE;
839
840                 if ( dcs & 0x08 )
841                         pCodingScheme->bMsgIndActive = TRUE;
842
843                 switch ( dcs & 0x03 )
844                 {
845                         case 0x00:
846                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_VOICE_MSG;
847                                 break;
848                         case 0x01:
849                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_FAX_MSG;
850                                 break;
851                         case 0x02:
852                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_EMAIL_MSG;
853                                 break;
854                         case 0x03:
855                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_OTHER_MSG;
856                                 break;
857                 }
858         }
859         else if ( dcs < 0xF0 )
860         {
861                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_WAITING_STORE_UCS2;
862
863                 if ( dcs & 0x08 )
864                         pCodingScheme->bMsgIndActive = TRUE;
865
866                 switch ( dcs & 0x03 )
867                 {
868                         case 0x00:
869                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_VOICE_MSG;
870                                 break;
871                         case 0x01:
872                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_FAX_MSG;
873                                 break;
874                         case 0x02:
875                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_EMAIL_MSG;
876                                 break;
877                         case 0x03:
878                                 pCodingScheme->waitingType = TAPI_NETTEXT_WAITING_OTHER_MSG;
879                                 break;
880                 }
881         }
882         else
883         {
884                 pCodingScheme->codingGroupType = TAPI_NETTEXT_CODGRP_SM_CLASS_CODING;
885
886                 if ( dcs & 0x04 )
887                         pCodingScheme->alphabetType = TAPI_NETTEXT_ALPHABET_8BIT;
888
889                 switch ( dcs & 0x03 )
890                 {
891                         case 0x00:
892                                 pCodingScheme->classType = TAPI_NETTEXT_CLASS_0;
893                                 break;
894                         case 0x01:
895                                 pCodingScheme->classType = TAPI_NETTEXT_CLASS_1;
896                                 break;
897                         case 0x02:
898                                 pCodingScheme->classType = TAPI_NETTEXT_CLASS_2;
899                                 break;
900                         case 0x03:
901                                 pCodingScheme->classType = TAPI_NETTEXT_CLASS_3;
902                                 break;
903                 }
904         }
905 }
906
907 void SmsUtilEncodeDCS( BYTE* pDCS, TapiNetTextCodingScheme* pCodingScheme )
908 {
909         BYTE dcs = 0x00;
910
911         assert( pCodingScheme != NULL );
912
913         switch ( pCodingScheme->codingGroupType )
914         {
915                 case TAPI_NETTEXT_CODGRP_SM_GENERAL_DCS: // bit 7..4 is 00xx
916                 {
917                         if ( pCodingScheme->bCompressed )
918                                 dcs |= 0x20; // bit 5 is 1
919
920                         if ( pCodingScheme->bMsgClassSet )
921                         {
922                                 dcs |= 0x10; // bit 4 is 1
923
924                                 switch ( pCodingScheme->classType )
925                                 {
926                                         case TAPI_NETTEXT_CLASS_0: // bit 1..0 is 00
927                                         {
928                                                 dcs |= 0x00;
929                                                 break;
930                                         }
931                                         case TAPI_NETTEXT_CLASS_1: // bit 1..0 is 01
932                                         {
933                                                 dcs |= 0x01;
934                                                 break;
935                                         }
936                                         case TAPI_NETTEXT_CLASS_2: // bit 1..0 is 10
937                                         {
938                                                 dcs |= 0x02;
939                                                 break;
940                                         }
941                                         case TAPI_NETTEXT_CLASS_3: // bit 1..0 is 11
942                                         {
943                                                 dcs |= 0x03;
944                                                 break;
945                                         }
946                                         default:
947                                             break;
948                                 }
949                         }
950
951                         switch ( pCodingScheme->alphabetType )
952                         {
953                                 case TAPI_NETTEXT_ALPHABET_DEFAULT: // bit 3..2 is 00
954                                 {
955                                         dcs |= 0x00;
956                                         break;
957                                 }
958                                 case TAPI_NETTEXT_ALPHABET_8BIT: // bit 3..2 is 01
959                                 {
960                                         dcs |= 0x04;
961                                         break;
962                                 }
963                                 case TAPI_NETTEXT_ALPHABET_UCS2: // bit 3..2 is 10
964                                 {
965                                         dcs |= 0x08;
966                                         break;
967                                 }
968                                 default: // bit 3..2 is 11
969                                 {
970                                         dcs |= 0x0C;
971                                         break;
972                                 }
973                         }
974
975                         break;
976                 }
977                 case TAPI_NETTEXT_CODGRP_SM_WAITING_DISCARD: // bit 7..4 is 1100
978                 {
979                         dcs |= 0xC0;
980
981                         break;
982                 }
983                 case TAPI_NETTEXT_CODGRP_SM_WAITING_STORE: // bit 7..4 is 1101
984                 {
985                         dcs |= 0xD0;
986
987                         if ( pCodingScheme->bMsgIndActive ) // bit 3..2 is 10
988                                 dcs |= 0x08;
989
990                         switch ( pCodingScheme->waitingType )
991                         {
992                                 case TAPI_NETTEXT_WAITING_VOICE_MSG: // bit 1..0 is 00
993                                 {
994                                         dcs |= 0x00;
995                                         break;
996                                 }
997                                 case TAPI_NETTEXT_WAITING_FAX_MSG: // bit 1..0 is 01
998                                 {
999                                         dcs |= 0x01;
1000                                         break;
1001                                 }
1002                                 case TAPI_NETTEXT_WAITING_EMAIL_MSG: // bit 1..0 is 10
1003                                 {
1004                                         dcs |= 0x02;
1005                                         break;
1006                                 }
1007                                 case TAPI_NETTEXT_WAITING_OTHER_MSG: // bit 1..0 is 11
1008                                 {
1009                                         dcs |= 0x03;
1010                                         break;
1011                                 }
1012                                 default:
1013                                     break;
1014                         }
1015
1016                         break;
1017                 }
1018                 case TAPI_NETTEXT_CODGRP_SM_WAITING_STORE_UCS2: // bit 7..4 is 1110
1019                 {
1020                         dcs |= 0xE0;
1021
1022                         if ( pCodingScheme->bMsgIndActive ) // bit 3..2 is 10
1023                                 dcs |= 0x08;
1024
1025                         switch ( pCodingScheme->waitingType )
1026                         {
1027                                 case TAPI_NETTEXT_WAITING_VOICE_MSG: // bit 1..0 is 00
1028                                 {
1029                                         dcs |= 0x00;
1030                                         break;
1031                                 }
1032                                 case TAPI_NETTEXT_WAITING_FAX_MSG: // bit 1..0 is 01
1033                                 {
1034                                         dcs |= 0x01;
1035                                         break;
1036                                 }
1037                                 case TAPI_NETTEXT_WAITING_EMAIL_MSG: // bit 1..0 is 10
1038                                 {
1039                                         dcs |= 0x02;
1040                                         break;
1041                                 }
1042                                 case TAPI_NETTEXT_WAITING_OTHER_MSG: // bit 1..0 is 11
1043                                 {
1044                                         dcs |= 0x03;
1045                                         break;
1046                                 }
1047                                 default:
1048                                     break;
1049                         }
1050
1051                         break;
1052                 }
1053                 case TAPI_NETTEXT_CODGRP_SM_CLASS_CODING: // bit 7..4 is 1111
1054                 {
1055                         dcs |= 0xF0;
1056
1057                         switch ( pCodingScheme->alphabetType )
1058                         {
1059                                 case TAPI_NETTEXT_ALPHABET_DEFAULT: // bit 2 is 0
1060                                 {
1061                                         dcs |= 0x00;
1062                                         break;
1063                                 }
1064                                 case TAPI_NETTEXT_ALPHABET_8BIT: // bit 2 is 1
1065                                 {
1066                                         dcs |= 0x04;
1067                                         break;
1068                                 }
1069                                 default:
1070                                     break;
1071                         }
1072
1073                         switch ( pCodingScheme->classType )
1074                         {
1075                                 case TAPI_NETTEXT_CLASS_0: // bit 1..0 is 00
1076                                 {
1077                                         break;
1078                                 }
1079                                 case TAPI_NETTEXT_CLASS_1: // bit 1..0 is 01
1080                                 {
1081                                         dcs |= 0x01;
1082                                         break;
1083                                 }
1084                                 case TAPI_NETTEXT_CLASS_2: // bit 1..0 is 10
1085                                 {
1086                                         dcs |= 0x02;
1087                                         break;
1088                                 }
1089                                 case TAPI_NETTEXT_CLASS_3: // bit 1..0 is 11
1090                                 {
1091                                         dcs |= 0x03;
1092                                         break;
1093                                 }
1094                                 default:
1095                                     break;
1096                         }
1097
1098                         break;
1099                 }
1100                 case TAPI_NETTEXT_CODGRP_SM_RESERVED: // bit 7..4 is 1111
1101                 {
1102                     dcs = (pCodingScheme->codingGroup << 4) & 0xF0;
1103                     dcs |= (pCodingScheme->code & 0x0F);
1104                     break;
1105                 }
1106                 default:
1107                     break;
1108         }
1109
1110         memcpy( pDCS, &dcs, sizeof ( BYTE ) );
1111 }
1112
1113  UINT8 SmsUtilEncodeValidity( BYTE* pValidity, TapiNetTextVP* pVP )
1114 {
1115         UINT8   pos = 0;
1116
1117         switch( pVP->vpType )
1118         {
1119                 case TAPI_NETTEXT_VP_NOT_USED:
1120                         break;
1121
1122                 case TAPI_NETTEXT_VP_RELATIVE:
1123                         pValidity[pos] = (UINT8) pVP->vpValue;
1124                         pos ++;
1125                         break;
1126
1127                 case TAPI_NETTEXT_VP_ABSOLUTE:
1128                         //TO DO
1129                         //SmsUtilEncodeTimeStamp( pValidity, pVP->vpValue );
1130                         pos += 7;
1131                         break;
1132
1133                 case TAPI_NETTEXT_VP_ENHANCED:
1134                         break;
1135         }
1136
1137         return pos;
1138 }
1139