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