tizen 2.3 release
[framework/telephony/libslp-tapi.git] / test_src / sms_util.c
1 /*
2  * libslp-tapi
3  *
4  * Copyright (c) 2014 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 <string.h>
24 #include <tapi_log.h>
25 #include "sms_util.h"
26
27
28 void  reverse(char* x, int len)
29 {
30         int i, j = len - 1;
31
32         for (i = 0; i < j; i++)
33         {
34                 int t = x[i];
35                 x[i] = x[j];
36                 x[j--] = t;
37         }
38 }
39
40 char*  AcItoa(int n, char* str, int b)
41 {
42         int i = 0;
43
44         do
45                 str[i++] = "0123456789ABCDEF"[n%b];
46
47         while ((n /= b) > 0);
48         reverse(str, i);
49         str[i] = '\0';
50
51         return str;
52 }
53
54 int  AcToupper(int ch)
55 {
56         return (('a' <= (ch) && (ch) <= 'z')? ((ch) - ('a'-'A')) : (ch));
57 }
58
59 char* SmsUtilUnpackGSMCode(char* szData, const char* pIn, int in_len )
60 {
61         int i;
62         int pos = 0;
63         int shift = 0;
64
65         /* If the number of fill bits != 0, then it would cause an additional shift */
66         /*
67         if ( shift != 0 )
68                 pos = pos + 1;
69
70         if ( shift ==7 )
71                 shift = 0;
72         */
73
74         for ( i = 0; i < in_len; i++, pos++ )
75         {
76                 szData[i] = ( pIn[pos] << shift ) & 0x7F;
77
78                 if ( pos != 0 )
79                 {
80                         /* except the first byte, a character contains some bits
81                         ** from the previous byte.
82                         */
83                         szData[i] |= pIn[pos-1] >> (8-shift);
84                 }
85
86                 shift ++;
87
88                 if ( shift == 7 )
89                 {
90                         shift = 0;
91
92                         /* a possible extra complete character is available */
93                         i++;
94                         szData[i] = pIn[pos] >> 1;
95
96                         if( szData[i] == 0 )
97                         {
98                                 /* this is the end of the input, quit */
99                                 break;
100                         }
101                 }
102         }
103
104         return szData;
105 }
106
107 int SmsUtilPackGSMCode( unsigned char *pOut, const char* szData, int in_len )
108 {
109         int i;
110         int pos;
111         int shift = 0;
112         //shift = fill_bits;
113
114         //  memset( out, 0, out_len_max );
115
116         /* pack the ASCII characters
117         */
118         /*
119         if ( shift == 7 )
120                 shift = 0;
121         */
122
123         for( pos = 0, i = 0; /*pos < out_len_max &&*/ i < in_len; pos++, i++ )
124         {
125                 /* pack the low bits */
126                 pOut[pos] = szData[i] >> shift;
127
128                 if ( i + 1 < in_len )
129                 {
130                         /* pack the high bits using the low bits of the next character */
131                         pOut[pos] |= szData[i+1] << ( 7 - shift );
132
133                         shift++;
134
135                         if( shift == 7 )
136                         {
137                                 shift = 0;
138                                 i++;
139                         }
140                 }
141         }
142
143         /* done */
144         return pos;
145 }
146
147
148 void SmsUtilConvertBCD2Digit( char* pDigits, char* pBCD, int digitLen )
149 {
150         int             i, bcdLen;
151         char    c[2];
152         unsigned char   higher, lower;
153
154         if ( pBCD == NULL || pDigits == NULL )
155         {
156                 printf("__SmsConvertBCD2Digit: pBCD == NULL || pDigits == NULL. return.\n"  );
157                 return;
158         }
159
160         if ( digitLen == 0 )
161         {
162                 //printf("__SmsConvertBCD2Digit: digitLen == 0. return.\n" );
163
164                 pDigits[0] = 0x00;
165
166                 return;
167         }
168
169         if ( digitLen % 2 )
170                 bcdLen = digitLen / 2 + 1;
171         else
172                 bcdLen = digitLen / 2;
173
174         memset( pDigits, 0, bcdLen * 2 );
175
176         for ( i = 0; i < bcdLen; i++ )
177         {
178                 lower = pBCD[i] & 0x0F;                                 // get low nibble
179
180                 if ( lower == 0x0A )
181                         lower = '*';
182                 else if ( lower == 0x0B )
183                         lower = '#';
184                 else if ( lower == 0x0C )
185                         lower = 'p';                    //DTMF Control pDigits seperator
186                 else if ( lower == 0x0F )
187                         lower = 0;
188                 else
189                 {
190                         AcItoa( lower, c, 16 );
191                         lower = (char) AcToupper(c[0]);
192                 }
193
194                 higher = ( pBCD[i] >> 4 ) & 0x0F;                       // get high nibble
195
196                 if ( higher == 0x0A )
197                         higher = '*';           // =0x2A
198                 else if ( higher == 0x0B )
199                         higher = '#';           // =0x23
200                 else if ( higher == 0x0C )
201                         higher = 'p';           // =0x70, DTMF Control pDigits seperator
202                 else if ( higher == 0x0F ) // if higher semi-octet is 0x0F, filled bits.
203                 {
204                         //higher = 0;
205                         sprintf(pDigits + strlen(pDigits), "%c", lower);
206                         pDigits[/*digitLen-1*/bcdLen*2-1] = '\0';
207
208                         //printf("__SmsConvertBCD2Digit: pDigits [%s].\n", pDigits  );
209
210                         return;
211                 }
212                 else
213                 {
214                         AcItoa(higher, c, 16);
215                         higher = (char) AcToupper(c[0]);
216                 }
217
218                 //sprintf(pDigits, "%s%c%c", pDigits, lower, higher);
219                 sprintf(pDigits + strlen(pDigits), "%c%c", lower, higher);
220         }
221
222         pDigits[digitLen] = '\0';
223
224         //printf("__SmsConvertBCD2Digit: pDigits [%s].\n", pDigits  );
225 }
226
227
228 void SmsUtilConvertDigit2BCD( char* pBCD, char* pDigits, int digitLen )
229 {
230         int     i, j, digit;
231
232         unsigned char   higher, lower;
233
234         if ( pBCD == NULL || pDigits == NULL )
235                 return;
236
237         // 0123456789 -> 1032547698
238         for ( i = 0, j = 0; i < digitLen; i = i + 2, j++ )
239         {
240                 if ( pDigits[i] == '*' )
241                         digit = 0x0A;
242                 else if ( pDigits[i] == '#' )
243                         digit = 0x0B;
244                 else if ( AcToupper( pDigits[i] ) == 'P' )
245                         digit = 0x0C;
246                 else
247                         digit = (int) ( pDigits[i] - '0' );
248
249                 lower = digit & 0x0F;
250
251                 if ( digitLen != i + 1 )
252                 {
253                         if ( pDigits[i+1] == '*' )
254                                 digit = 0x0A;
255                         else if ( pDigits[i+1] == '#' )
256                                 digit = 0x0B;
257                         else if ( AcToupper( pDigits[i+1] ) == 'P' )
258                                 digit = 0x0C;
259                         else
260                                 digit = (int) ( pDigits[i+1] - '0' );
261
262                         higher = digit & 0x0F;
263                 }
264                 else
265                 {
266                         higher = 0xFF;
267                 }
268
269                 pBCD[j] = ( higher << 4 ) | lower;
270         }
271 }
272
273
274 TmDateTime* SmsUtilDecodeTimeStamp(char * pTimeStamp, TmDateTime *tmDateTime )
275 {
276         //TmDateTime tmDateTime;
277         char szBuf[3];
278         //TS_UINT32     time;
279
280         if ( pTimeStamp == NULL )
281                 return NULL;
282
283         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[0], 2 );
284         tmDateTime->year = atoi( szBuf ) + 2000;
285         if ( ( tmDateTime->year >= 1900 + MAX_YEAR )/* && ( tmDateTime->year < 2000 + BASE_YEAR )*/ )
286                 tmDateTime->year -= 100;
287         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[1], 2 );
288         tmDateTime->month = atoi( szBuf );
289         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[2], 2 );
290         tmDateTime->day = atoi( szBuf );
291         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[3], 2 );
292         tmDateTime->hour = atoi( szBuf );
293         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[4], 2 );
294         tmDateTime->minute = atoi( szBuf );
295         SmsUtilConvertBCD2Digit( szBuf, (char*) &pTimeStamp[5], 2 );
296         tmDateTime->second = atoi( szBuf );
297
298         if ( ( tmDateTime->year < 1900 + BASE_YEAR ) || ( tmDateTime->year > 1900 + MAX_YEAR ) )
299                 tmDateTime->year = 1900 + BASE_YEAR;
300
301         /*
302         time = TmDateTimeToSeconds( &tmDateTime );
303         if ( time > MAX_SECONDS )
304                 time = MAX_SECONDS;
305
306         */
307
308         return tmDateTime;
309 }
310
311 unsigned char* SmsUtilEncodeTimeStamp( TmDateTime* tmDateTime, unsigned char* pTimeStamp )
312 {
313         //TmDateTime tmDateTime;
314         char szBuf[3];
315         int     year;
316
317         if ( pTimeStamp == NULL )
318                 return NULL;
319
320         memset( (void*) pTimeStamp, 0x00, sizeof ( unsigned char ) * 7 );
321
322         //TmSecondsToDateTime( timeStamp, &tmDateTime );
323
324         year = tmDateTime->year - 2000;
325         if ( year < 0 )
326                 year += 100;
327         sprintf( szBuf, "%02d", year );
328         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[0], szBuf, 2 );
329         sprintf( szBuf, "%02d", tmDateTime->month );
330         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[1], szBuf, 2 );
331         sprintf( szBuf, "%02d", tmDateTime->day );
332         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[2], szBuf, 2 );
333         sprintf( szBuf, "%02d", tmDateTime->hour );
334         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[3], szBuf, 2 );
335         sprintf( szBuf, "%02d", tmDateTime->minute );
336         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[4], szBuf, 2 );
337         sprintf( szBuf, "%02d", tmDateTime->second );
338         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[5], szBuf, 2 );
339
340
341         /*      ignore Time zone (assume it is using 0x00 as default)
342         timeZone = TmGetTimeZoneOffset() /15;
343         if ( timeZone < 0 )
344                 absTimeZone = -timeZone;
345         else
346                 absTimeZone = timeZone;
347         */
348
349         sprintf( szBuf, "%02d", 0);
350         SmsUtilConvertDigit2BCD( (char*) &pTimeStamp[6], szBuf, 2 );
351
352         //if ( timeZone < 0 )
353         //      pTimeStamp[6] |= 0x80;
354
355         return pTimeStamp;
356 }
357
358
359
360 int  SmsUtilDecodeAddrField(char *diallingNum, char* pAddrField, int *result_ton, int *result_npi )
361 {
362         int local_index = 0;
363         int  ton,npi;
364         int DialNumLen=0;
365
366         ton = ( pAddrField[local_index+1] & 0x70 ) >> 4;
367         npi = pAddrField[local_index+1] & 0x0F;
368
369         if ( ton != SMS_TON_ALPHA_NUMERIC )
370         {
371                 // Origination/Destination address ï¿½Êµå¿¡ï¿½ï¿½ï¿½ï¿½ length�� ï¿½ï¿½ï¿½ï¿½ address length
372                 // origination/destination address ï¿½Êµï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ length�� 0 ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ number type/plan ï¿½Êµï¿½ï¿½ 0xFF ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½Â´ï¿½.
373                 DialNumLen = pAddrField[local_index++];
374         }
375         else
376         {
377                 DialNumLen = ( ( ( pAddrField[local_index++] + 1 ) / 2 ) * 8 ) / 7;
378         }
379
380
381
382
383         // SIM_SMSP_ADDRESS_LEN ï¿½ï¿½ï¿½ï¿½ address length ï¿½ï¿½ Å©ï¿½ï¿½ SIM_SMSP_ADDRESS_LEN ï¿½ï¿½Å­ï¿½ï¿½ ï¿½ï¿½È¯ï¿½ï¿½ ï¿½Ñ´ï¿½.
384
385         if ( DialNumLen > SMS_ADDRESS_LEN_MAX )
386         {
387                 DialNumLen = SMS_ADDRESS_LEN_MAX;
388         }
389
390         printf(" DialNumLen = %d\n", DialNumLen  );
391
392         local_index++; /* ignore Type of Address field */
393
394         if (ton != SMS_TON_ALPHA_NUMERIC )
395         {
396                 SmsUtilConvertBCD2Digit( diallingNum, (char*) &pAddrField[local_index],DialNumLen );
397         }
398         else
399         {
400                 SmsUtilUnpackGSMCode( diallingNum, &pAddrField[local_index],DialNumLen );
401         }
402
403         printf(  "__SmsDecodeAddrField: diallingNum [%s].\n", (char*) diallingNum  );
404
405         *result_ton=ton;
406         *result_npi=npi;
407
408         printf("ton %d npi %d\n",ton,npi);
409
410         return DialNumLen;
411
412
413 }
414
415 int  SmsUtilEncodeAddrField(unsigned char* pAddrField, char* diallingNum, int DialNumLen, int ton, int npi )
416 {
417         int local_index = 0;
418
419         if ( diallingNum == NULL || pAddrField == NULL )
420                 return -1;
421
422         if ( diallingNum[0] == '+' )
423         {
424                 diallingNum++;
425                 DialNumLen--;
426                 ton = SMS_TON_INTERNATIONAL;
427         }
428
429         if ( ton != SMS_TON_ALPHA_NUMERIC )
430         {
431                 // Origination/Destination address ï¿½Êµå¿¡ï¿½ï¿½ï¿½ï¿½ length�� ï¿½ï¿½ï¿½ï¿½ address length
432                 pAddrField[local_index++] = (unsigned char)DialNumLen;
433                 //printf(" addr len packet: %d\n", pAddrField[local_index]);
434         }
435         else
436         {
437                 pAddrField[local_index] = (unsigned char) ( ( ( DialNumLen * 7 + 7 ) / 8 ) * 2 );
438
439                 // ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½Æ®ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ 4��Ʈ�� ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ length ï¿½Êµå°ªï¿½ï¿½ -1�� ï¿½Ñ´ï¿½.
440                 if ( ( ( DialNumLen * 7 ) % 8 ) <= 4 )
441                         pAddrField[local_index]--;
442
443                 printf(" addr len packet: %d out of SMS_TON_ALPAHA\n", pAddrField[local_index]);
444
445                 local_index++;
446         }
447
448         SET_TON_NPI( pAddrField[local_index], ton, npi );
449
450         local_index++; // SET_TON_NPI ï¿½ï¿½ MACRO ï¿½Ì¹Ç·ï¿½ ï¿½ï¿½ï¿½Î¿ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Å°ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½
451
452         if ( ton != SMS_TON_ALPHA_NUMERIC )
453         {
454                 SmsUtilConvertDigit2BCD( (char*) &pAddrField[local_index], (char*) diallingNum, DialNumLen );
455
456                 if ( DialNumLen % 2 )
457                         local_index += DialNumLen / 2 + 1;
458                 else
459                         local_index += DialNumLen / 2;
460         }
461         else
462         {
463                 local_index += SmsUtilPackGSMCode( &pAddrField[local_index], diallingNum, (int) DialNumLen );
464         }
465
466         return local_index;
467 }
468 int SmsUtilDecodeScAddrField( SmsAddressInfo_t* pSmsAddrField, unsigned char* pAddrField )
469 {
470         int local_index = 0;
471         int length = 0;
472
473         printf("SmsUtilDecodeScAddrField\n");
474
475         if ( pSmsAddrField == NULL || pAddrField == NULL )
476         {
477                 printf( "SmsUtilDecodeScAddrField: pSimAddrField or pAddrField is NULL.\n"  );
478
479                 return 0;
480         }
481
482         // Service Center address ï¿½Êµå¿¡ï¿½ï¿½ï¿½ï¿½ length�� ï¿½Ú¿ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ byte�� ï¿½ï¿½
483         // -> ï¿½ï¿½ï¿½ï¿½ address ï¿½ï¿½ï¿½Ì´ï¿½ TON/API ï¿½ï¿½ï¿½ï¿½Æ®ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½Ï°ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½Æ®ï¿½ï¿½ 2�� or 2�� - 1(���� ï¿½ï¿½ï¿½Ì°ï¿½ È¦ï¿½ï¿½ï¿½Î°ï¿½ï¿½)
484         length = pAddrField[local_index];
485         // ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½Þ½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ì¿¡ï¿½ï¿½ service center address�� ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½Ö´ï¿½.
486         // ï¿½ï¿½ ï¿½ï¿½ì¿¡ length ï¿½ï¿½ 0 ï¿½Ì¸ï¿½ number type, plan ï¿½ï¿½ ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½
487         // length ï¿½ï¿½ 1 ï¿½Ì¸ï¿½ type, plan ï¿½ï¿½ ï¿½Ö´ï¿½ ï¿½ï¿½ï¿½
488         if ( length > 1 )
489         {
490                 pSmsAddrField->DialNumLen = ( pAddrField[local_index++] - 1 ) * 2; // -1�� TON/API ï¿½Êµï¿½
491
492                 // SMS_SMSP_ADDRESS_LEN ï¿½ï¿½ï¿½ï¿½ address length ï¿½ï¿½ Å©ï¿½ï¿½ SMS_SMSP_ADDRESS_LEN ï¿½ï¿½Å­ï¿½ï¿½ ï¿½ï¿½È¯ï¿½ï¿½ ï¿½Ñ´ï¿½.
493                 if ( pSmsAddrField->DialNumLen > SMS_ADDRESS_LEN_MAX )
494                 {
495                         pSmsAddrField->DialNumLen = SMS_ADDRESS_LEN_MAX;
496                 }
497
498                 pSmsAddrField->Ton = ( pAddrField[local_index] & 0x70 ) >> 4;
499                 pSmsAddrField->Npi = pAddrField[local_index] & 0x0F;
500
501                 local_index++; /* ignore Type of Address field */
502
503                 SmsUtilConvertBCD2Digit( (char*) pSmsAddrField->DialNumLen, (char*) &pAddrField[local_index], pSmsAddrField->DialNumLen );
504
505                 printf( "SmsUtilDecodeScAddrField: diallingNum [%s].\n", (char*) pSmsAddrField->DialNumLen  );
506
507                 printf( "length=%d , ton %d, npi =%d\n",pSmsAddrField->DialNumLen, pSmsAddrField->Ton,pSmsAddrField->Npi );
508         }
509
510         return ++length;
511 }
512
513  int  SmsUtilEncodeScAddrField( unsigned char* pAddrField, SmsAddressInfo_t * pSmsAddrField )
514 {
515         int local_index = 0;
516
517         if ( pSmsAddrField == NULL || pAddrField == NULL )
518                 return -1;
519
520         // Service Center address ï¿½Êµå¿¡ï¿½ï¿½ï¿½ï¿½ length�� ï¿½Ú¿ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ byte�� ï¿½ï¿½
521         // -> ï¿½ï¿½ï¿½ï¿½ address ï¿½ï¿½ï¿½Ì´ï¿½ TON/API ï¿½ï¿½ï¿½ï¿½Æ®ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½Ï°ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½Æ®ï¿½ï¿½ 2�� or 2�� - 1(���� ï¿½ï¿½ï¿½Ì°ï¿½ È¦ï¿½ï¿½ï¿½Î°ï¿½ï¿½)
522         if ( pSmsAddrField->DialNumLen % 2 )
523         {
524                 pAddrField[local_index++] = pSmsAddrField->DialNumLen / 2 + 1 + 1; // +1 ï¿½ï¿½ TON/NPI ï¿½Êµï¿½, È¦ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ß±ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½Ñ¹ï¿½ ï¿½ï¿½ +1
525         }
526         else
527         {
528                 pAddrField[local_index++] = pSmsAddrField->DialNumLen / 2 + 1; // +1 ï¿½ï¿½ TON/NPI ï¿½Êµï¿½
529         }
530
531         SET_TON_NPI( pAddrField[local_index], pSmsAddrField->Ton, pSmsAddrField->Npi );
532
533         local_index++; // SET_TON_NPI ï¿½ï¿½ MACRO ï¿½Ì¹Ç·ï¿½ ï¿½ï¿½ï¿½Î¿ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Å°ï¿½ï¿½ ï¿½ï¿½ï¿½×¹ß»ï¿½
534
535         SmsUtilConvertDigit2BCD( (char*) &pAddrField[local_index], (char*) pSmsAddrField->DialNumLen, pSmsAddrField->DialNumLen );
536
537         if ( pSmsAddrField->DialNumLen % 2 )
538                 local_index += pSmsAddrField->DialNumLen / 2 + 1;
539         else
540                 local_index += pSmsAddrField->DialNumLen / 2;
541
542         return local_index;
543 }
544
545 void SmsUtilDecodeDCS( Sms_coding_scheme* pCodingScheme,   unsigned char dcs )
546 {
547         assert( pCodingScheme != NULL );
548
549         memset( pCodingScheme, 0, sizeof ( Sms_coding_scheme ) );
550
551         if ( dcs < 0x40 ) // bits 7..4 = 00xx : general data coding indication
552         {
553                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_GENERAL_DCS;
554
555                 if ( dcs & 0x20 ) // bit 5 = 1 : indicates the text is compressed
556                         pCodingScheme->bCompressed = TRUE;
557
558                 if ( dcs & 0x10 ) // bit 4 = 1 : indicates that bits  1 to 0 have a message class meaning
559                 {
560                         pCodingScheme->bmsg_class_set = TRUE;
561
562                         switch ( dcs & 0x03 ) // bits 1 to 0 : message class
563                         {
564                                 case 0x00:
565                                         pCodingScheme->class_type = SMS_CLASS_0;
566                                         break;
567                                 case 0x01:
568                                         pCodingScheme->class_type = SMS_CLASS_1;
569                                         break;
570                                 case 0x02:
571                                         pCodingScheme->class_type = SMS_CLASS_2;
572                                         break;
573                                 case 0x03:
574                                         pCodingScheme->class_type = SMS_CLASS_3;
575                                         break;
576                                 default :
577                                         /*Do Nothing*/
578                                         dbg("Default case executed. Invalid option.");
579                                         break;
580                         }
581                 }
582                 else // bit 4 = 0 : indicates that bits 1 to 0 are reserved and have no message class meaning
583                         pCodingScheme->class_type = SMS_CLASS_NONE;
584
585                 switch ( dcs & 0x0C ) // bits 4 to 3 : character set
586                 {
587                         case 0x00:
588                                 pCodingScheme->alphabet_type = SMS_ALPHABET_DEFAULT;
589                                 break;
590                         case 0x04:
591                                 pCodingScheme->alphabet_type = SMS_ALPHABET_8BIT;
592                                 break;
593                         case 0x08:
594                                 pCodingScheme->alphabet_type = SMS_ALPHABET_UCS2;
595                                 break;
596                         case 0x0C:
597                                 pCodingScheme->alphabet_type = SMS_ALPHABET_MAX;
598                                 break;
599                         default :
600                                 /*Do Nothing*/
601                                 dbg("Default case executed. Invalid option.");
602                                 break;
603                 }
604         }
605         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
606         {
607                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_AUTO_DELETION;
608
609                 if ( dcs & 0x20 ) // bit 5 = 1 : indicates the text is compressed
610                         pCodingScheme->bCompressed = TRUE;
611
612                 if ( dcs & 0x10 ) // bit 4 = 1 : indicates that bits  1 to 0 have a message class meaning
613                 {
614                         pCodingScheme->bmsg_class_set = TRUE;
615
616                         switch ( dcs & 0x03 ) // bits 1 to 0 : message class
617                         {
618                                 case 0x00:
619                                         pCodingScheme->class_type = SMS_CLASS_0;
620                                         break;
621                                 case 0x01:
622                                         pCodingScheme->class_type = SMS_CLASS_1;
623                                         break;
624                                 case 0x02:
625                                         pCodingScheme->class_type = SMS_CLASS_2;
626                                         break;
627                                 case 0x03:
628                                         pCodingScheme->class_type = SMS_CLASS_3;
629                                         break;
630                                 default :
631                                         /*Do Nothing*/
632                                         dbg("Default case executed. Invalid option.");
633                                         break;
634                         }
635                 }
636                 else // bit 4 = 0 : indicates that bits 1 to 0 are reserved and have no message class meaning
637                         pCodingScheme->class_type = SMS_CLASS_NONE;
638
639                 switch ( dcs & 0x0C ) // bits 4 to 3 : character set
640                 {
641                         case 0x00:
642                                 pCodingScheme->alphabet_type = SMS_ALPHABET_DEFAULT;
643                                 break;
644                         case 0x04:
645                                 pCodingScheme->alphabet_type = SMS_ALPHABET_8BIT;
646                                 break;
647                         case 0x08:
648                                 pCodingScheme->alphabet_type = SMS_ALPHABET_UCS2;
649                                 break;
650                         case 0x0C:
651                                 pCodingScheme->alphabet_type = SMS_ALPHABET_MAX;
652                                 break;
653                         default :
654                                 /*Do Nothing*/
655                                 dbg("Default case executed. Invalid option.");
656                                 break;
657                 }
658         }
659         // bits 7..4 = 1000 ~ 1011 : reserved
660         else if ( dcs == 0xC0 ) // bits 7..4 = 1100 : message waiting indication group, discard message
661         {
662                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_WAITING_DISCARD;
663         }
664         else if ( dcs < 0xE0 )
665         {
666                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_WAITING_STORE;
667
668                 if ( dcs & 0x08 )
669                         pCodingScheme->bmsg_ind_active = TRUE;
670
671                 switch ( dcs & 0x03 )
672                 {
673                         case 0x00:
674                                 pCodingScheme->waiting_type = SMS_WAITING_VOICE_MSG;
675                                 break;
676                         case 0x01:
677                                 pCodingScheme->waiting_type = SMS_WAITING_FAX_MSG;
678                                 break;
679                         case 0x02:
680                                 pCodingScheme->waiting_type = SMS_WAITING_EMAIL_MSG;
681                                 break;
682                         case 0x03:
683                                 pCodingScheme->waiting_type = SMS_WAITING_OTHER_MSG;
684                                 break;
685                         default :
686                                 /*Do Nothing*/
687                                 dbg("Default case executed. Invalid option.");
688                                 break;
689                 }
690         }
691         else if ( dcs < 0xF0 )
692         {
693                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_WAITING_STORE_UCS2;
694
695                 if ( dcs & 0x08 )
696                         pCodingScheme->bmsg_ind_active = TRUE;
697
698                 switch ( dcs & 0x03 )
699                 {
700                         case 0x00:
701                                 pCodingScheme->waiting_type = SMS_WAITING_VOICE_MSG;
702                                 break;
703                         case 0x01:
704                                 pCodingScheme->waiting_type = SMS_WAITING_FAX_MSG;
705                                 break;
706                         case 0x02:
707                                 pCodingScheme->waiting_type = SMS_WAITING_EMAIL_MSG;
708                                 break;
709                         case 0x03:
710                                 pCodingScheme->waiting_type = SMS_WAITING_OTHER_MSG;
711                                 break;
712                         default :
713                                 /*Do Nothing*/
714                                 dbg("Default case executed. Invalid option.");
715                                 break;
716                 }
717         }
718         else
719         {
720                 pCodingScheme->coding_group_type = SMS_CODGRP_SM_CLASS_CODING;
721
722                 if ( dcs & 0x04 )
723                         pCodingScheme->alphabet_type = SMS_ALPHABET_8BIT;
724
725                 switch ( dcs & 0x03 )
726                 {
727                         case 0x00:
728                                 pCodingScheme->class_type = SMS_CLASS_0;
729                                 break;
730                         case 0x01:
731                                 pCodingScheme->class_type = SMS_CLASS_1;
732                                 break;
733                         case 0x02:
734                                 pCodingScheme->class_type = SMS_CLASS_2;
735                                 break;
736                         case 0x03:
737                                 pCodingScheme->class_type = SMS_CLASS_3;
738                                 break;
739                         default :
740                                 /*Do Nothing*/
741                                 dbg("Default case executed. Invalid option.");
742                                 break;
743                 }
744         }
745 }
746
747 void SmsUtilEncodeDCS( unsigned char* pDCS, Sms_coding_scheme* pCodingScheme )
748 {
749         unsigned char dcs = 0x00;
750
751         printf("SmsUtilEncodeDCS Start\n");
752
753         assert( pCodingScheme != NULL );
754
755         if( pCodingScheme->coding_group_type == SMS_CODGRP_SM_GENERAL_DCS ) // bit 7..4 is 00xx
756         {
757                 if ( pCodingScheme->bCompressed )
758                                 dcs |= 0x20; // bit 5 is 1
759
760                         if ( pCodingScheme->bmsg_class_set )
761                         {
762                                 dcs |= 0x10; // bit 4 is 1
763
764                                 if( pCodingScheme->class_type== SMS_CLASS_0 )
765                                         dcs |= 0x00;
766
767                                 else if ( pCodingScheme->class_type == SMS_CLASS_1 )
768                                         dcs |= 0x01;
769
770                                 else if ( pCodingScheme->class_type == SMS_CLASS_2 )
771                                         dcs |= 0x02;
772
773                                 else if ( pCodingScheme->class_type == SMS_CLASS_3 )
774                                         dcs |= 0x03;
775                         }
776
777                         switch ( pCodingScheme->alphabet_type )
778                         {
779                                 case SMS_ALPHABET_DEFAULT: // bit 3..2 is 00
780                                 {
781                                         dcs |= 0x00;
782                                         break;
783                                 }
784                                 case SMS_ALPHABET_8BIT: // bit 3..2 is 01
785                                 {
786                                         dcs |= 0x04;
787                                         break;
788                                 }
789                                 case SMS_ALPHABET_UCS2: // bit 3..2 is 10
790                                 {
791                                         dcs |= 0x08;
792                                         break;
793                                 }
794                                 default: // bit 3..2 is 11
795                                 {
796                                         dcs |= 0x0C;
797                                         break;
798                                 }
799                         }
800         }
801         else if ( pCodingScheme->coding_group_type == SMS_CODGRP_SM_WAITING_DISCARD ) // bit 7..4 is 1100
802         {
803                 dcs |= 0xC0;
804         }
805         else if ( pCodingScheme->coding_group_type == SMS_CODGRP_SM_WAITING_STORE ) // bit 7..4 is 1101
806         {
807                 dcs |= 0xD0;
808
809                 if ( pCodingScheme->bmsg_ind_active ) // bit 3..2 is 10
810                         dcs |= 0x08;
811
812                 else if( pCodingScheme->waiting_type == SMS_WAITING_VOICE_MSG)
813                         dcs |= 0x00;
814
815                 else if( pCodingScheme->waiting_type == SMS_WAITING_FAX_MSG)
816                         dcs |= 0x01;
817
818                 else if( pCodingScheme->waiting_type == SMS_WAITING_EMAIL_MSG)  // bit 1..0 is 10
819                         dcs |= 0x02;
820
821                 else if( pCodingScheme->waiting_type == SMS_WAITING_OTHER_MSG)  // bit 1..0 is 11
822                         dcs |= 0x03;
823
824         }
825         else if ( pCodingScheme->coding_group_type == SMS_CODGRP_SM_WAITING_STORE_UCS2 ) // bit 7..4 is 1110
826         {
827                 dcs |= 0xE0;
828
829                 if ( pCodingScheme->bmsg_ind_active ) // bit 3..2 is 10
830                         dcs |= 0x08;
831
832                 if( pCodingScheme->waiting_type == SMS_WAITING_VOICE_MSG ) // bit 1..0 is 00
833                         dcs |= 0x00;
834
835                 else if( pCodingScheme->waiting_type == SMS_WAITING_FAX_MSG )
836                         dcs |= 0x01;
837
838                 else if( pCodingScheme->waiting_type == SMS_WAITING_EMAIL_MSG )
839                         dcs |= 0x02;
840
841                 else if( pCodingScheme->waiting_type == SMS_WAITING_OTHER_MSG )
842                         dcs |= 0x03;
843         }
844         else if ( pCodingScheme->coding_group_type == SMS_CODGRP_SM_CLASS_CODING )      // bit 7..4 is 1111
845         {
846                 dcs |= 0xF0;
847
848                 if( pCodingScheme->alphabet_type == SMS_ALPHABET_DEFAULT )      // bit 2 is 0
849                         dcs |= 0x00;
850                 else if( pCodingScheme->alphabet_type == SMS_ALPHABET_8BIT ) // bit 2 is 1
851                         dcs |= 0x04;
852
853                 if( pCodingScheme->class_type == SMS_CLASS_0) // bit 1..0 is 00
854                         ;
855
856                 else if( pCodingScheme->class_type == SMS_CLASS_1) // bit 1..0 is 01
857                         dcs |= 0x01;
858
859                 else if( pCodingScheme->class_type == SMS_CLASS_2) // bit 1..0 is 10
860                         dcs |= 0x02;
861
862                 else if( pCodingScheme->class_type == SMS_CLASS_3) // bit 1..0 is 11
863                         dcs |= 0x03;
864         }
865
866         memcpy( pDCS, &dcs, sizeof ( unsigned char ) );
867
868         printf("SmsUtilEncodeDCS End\n");
869 }
870
871 unsigned char SmsUtilEncodeValidity( unsigned char* pValidity, Sms_vp* pVP )
872 {
873         unsigned char pos = 0;
874
875         switch( pVP->vp_type )
876         {
877                 case SMS_VP_NOT_USED:
878                         break;
879
880                 case SMS_VP_RELATIVE:
881                         pValidity[pos] = (unsigned char) pVP->vpValue;
882                         pos ++;
883                         break;
884
885                 case SMS_VP_ABSOLUTE:
886                         //TO DO
887                         //SmsUtilEncodeTimeStamp( pValidity, pVP->vpValue );
888                         pos += 7;
889                         break;
890
891                 case SMS_VP_ENHANCED:
892                         break;
893
894                 default :
895                         /*Do Nothing*/
896                         dbg("Default Case executed. Invalid Option.");
897                         break;
898         }
899
900         return pos;
901 }
902