|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Name : TSatUtility.cpp |
|
15 // Part of : Common Sim Atk TSY / commonsimatktsy |
|
16 // Sat Utility classes implementation. |
|
17 // Version : 1.0 |
|
18 // |
|
19 |
|
20 |
|
21 |
|
22 // INCLUDE FILES |
|
23 #include "tsatutility.h" // Class header |
|
24 #include "tflogger.h" // TFLOGSTRING |
|
25 #include <ctsy/serviceapi/cmmsmsutility.h> // TON and NPI constants |
|
26 |
|
27 // ----------------------------------------------------------------------------- |
|
28 // TSatUtility::TonAndNpi |
|
29 // Map TON and NPI to RSat TON and NPI values |
|
30 // ----------------------------------------------------------------------------- |
|
31 // |
|
32 EXPORT_C void TSatUtility::TonAndNpi |
|
33 ( |
|
34 const TInt aTonAndNpi, |
|
35 RSat::TTypeOfNumber* aTon, |
|
36 RSat::TNumberingPlan* aNpi |
|
37 ) |
|
38 { |
|
39 TFLOGSTRING( "UTILITY: TSatUtility::TonAndNpi" ); |
|
40 TInt ton( ( aTonAndNpi >> 4 ) & KTONMask ); // TON mask value 0x07 |
|
41 |
|
42 switch ( ton ) |
|
43 { |
|
44 case KTonUnknown: |
|
45 { |
|
46 *aTon = RSat::EUnknownNumber; |
|
47 break; |
|
48 } |
|
49 case KInternationalNumber: |
|
50 { |
|
51 *aTon = RSat::EInternationalNumber; |
|
52 break; |
|
53 } |
|
54 case KNationalNumber: |
|
55 { |
|
56 *aTon = RSat::ENationalNumber; |
|
57 break; |
|
58 } |
|
59 case KNetworkSpecificNumber: |
|
60 { |
|
61 *aTon = RSat::ENetworkSpecificNumber; |
|
62 break; |
|
63 } |
|
64 case KSubscriberNumber: |
|
65 { |
|
66 *aTon = RSat::EDedicatedNumber; |
|
67 break; |
|
68 } |
|
69 case KAlphanumeric: |
|
70 { |
|
71 *aTon = RSat::EAlphanumericNumber; |
|
72 break; |
|
73 } |
|
74 case KAbbreviatedNumber: |
|
75 { |
|
76 *aTon = RSat::EAbbreviatedNumber; |
|
77 break; |
|
78 } |
|
79 default: |
|
80 { |
|
81 *aTon = RSat::ETypeOfNumberNotSet; |
|
82 break; |
|
83 } |
|
84 } |
|
85 |
|
86 // Numbering plan |
|
87 TInt npi( aTonAndNpi & KNPIMask ); // NPI mask value 0x0F |
|
88 |
|
89 switch ( npi ) |
|
90 { |
|
91 case KNpiUnknown: |
|
92 { |
|
93 *aNpi = RSat::EUnknownNumberingPlan; |
|
94 break; |
|
95 } |
|
96 case KIsdnTelephoneNumPlan: |
|
97 { |
|
98 *aNpi = RSat::EIsdnNumberPlan; |
|
99 break; |
|
100 } |
|
101 case KDataNumPlan: |
|
102 { |
|
103 *aNpi = RSat::EDataNumberPlan; |
|
104 break; |
|
105 } |
|
106 case KTelexNumPlan: |
|
107 { |
|
108 *aNpi = RSat::ETelexNumberPlan; |
|
109 break; |
|
110 } |
|
111 case KNationalNumPlan: |
|
112 { |
|
113 *aNpi = RSat::ENationalNumberPlan; |
|
114 break; |
|
115 } |
|
116 case KPrivateNumPlan: |
|
117 { |
|
118 *aNpi = RSat::EPrivateNumberPlan; |
|
119 break; |
|
120 } |
|
121 case KServiceCentreSpecificPlan1: |
|
122 { |
|
123 *aNpi = RSat::EServiceCentreSpecificPlan1; |
|
124 break; |
|
125 } |
|
126 case KServiceCentreSpecificPlan2: |
|
127 { |
|
128 *aNpi = RSat::EServiceCentreSpecificPlan2; |
|
129 break; |
|
130 } |
|
131 case KErmesNumPlan: |
|
132 { |
|
133 *aNpi = RSat::EERMESNumberPlan; |
|
134 break; |
|
135 } |
|
136 default: |
|
137 { |
|
138 *aNpi = RSat::ENumberingPlanNotSet; |
|
139 break; |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 // ----------------------------------------------------------------------------- |
|
145 // TSatUtility::Packed7to8Unpacked |
|
146 // Converts 7-bit packed string to 8-bit unpacked format. |
|
147 // ----------------------------------------------------------------------------- |
|
148 // |
|
149 EXPORT_C TInt TSatUtility::Packed7to8Unpacked |
|
150 ( |
|
151 const TPtrC8 aSource, |
|
152 TDes8& aTarget |
|
153 ) |
|
154 { |
|
155 TFLOGSTRING( "UTILITY: TSatUtility::Packed7to8Unpacked" ); |
|
156 TInt ret( KErrNone ); |
|
157 // The string is in packed GSM default alphabet format. |
|
158 // Converted to 8-bit format |
|
159 TUint8 maskRightPartOfCurrentByte( 0x7F ); |
|
160 TUint8 shiftLeft( 0 ); |
|
161 TUint8 leftPartFromPreviousByte( 0 ); |
|
162 TInt sourceLength = aSource.Length(); |
|
163 // Initialize the target string before starting |
|
164 aTarget.Zero(); |
|
165 |
|
166 // Check out which string is the shortest and use its length as a limit |
|
167 TInt length ( Min( sourceLength, aTarget.MaxLength() ) ); |
|
168 for ( TInt i = 0; i < length; i++ ) |
|
169 { |
|
170 TUint8 leftPartOfCurrentChar = static_cast<TUint8>( ( |
|
171 aSource[i] & maskRightPartOfCurrentByte ) << shiftLeft ); |
|
172 |
|
173 // Append the character in the output text string |
|
174 aTarget.Append( leftPartOfCurrentChar | leftPartFromPreviousByte ); |
|
175 |
|
176 // Updates |
|
177 if ( 6 == shiftLeft ) |
|
178 { |
|
179 // After 6 shifts, the character is in bit7..bit1, |
|
180 // therefore it has to be shifted one bit to the right. |
|
181 aTarget.Append( aSource[i] >> 1 ); |
|
182 // Restart |
|
183 leftPartFromPreviousByte = 0; |
|
184 shiftLeft = 0; |
|
185 maskRightPartOfCurrentByte = 0x7F; |
|
186 } |
|
187 else |
|
188 { |
|
189 leftPartFromPreviousByte = static_cast<TUint8>( ( |
|
190 aSource[i] ) >> ( 7-shiftLeft ) ); |
|
191 maskRightPartOfCurrentByte = static_cast<TUint8>( |
|
192 maskRightPartOfCurrentByte >> 1 ); |
|
193 shiftLeft++; |
|
194 } |
|
195 } |
|
196 |
|
197 // Whe should still notify the requesting method about exceeding the length |
|
198 if ( length < sourceLength ) |
|
199 { |
|
200 ret = KErrOverflow; |
|
201 TFLOGSTRING2( "UTILITY: TSatUtility::Packed7to8Unpacked,\ |
|
202 Input data too long. %d bytes could not be converted", |
|
203 ( sourceLength - length ) ); |
|
204 } |
|
205 |
|
206 return ret; |
|
207 } |
|
208 |
|
209 // ----------------------------------------------------------------------------- |
|
210 // TSatUtility::UCSToPacked7 |
|
211 // Converts UCS2 string to 7-bit packed format |
|
212 // ----------------------------------------------------------------------------- |
|
213 // |
|
214 EXPORT_C void TSatUtility::UCSToPacked7 |
|
215 ( |
|
216 const TPtrC aInput, |
|
217 TDes8& aOutput |
|
218 ) |
|
219 { |
|
220 TFLOGSTRING( "UTILITY: TSatUtility::UCSToPacked7" ); |
|
221 |
|
222 TBuf8<KMaxUssdStringLengthInBytes> string; |
|
223 |
|
224 // This method interrupts converting if the target buffer is full, so |
|
225 // the length can not be exceeded |
|
226 ConvertUnicode16To7Bit( aInput, string ); |
|
227 |
|
228 TUint8 move( 0 ); |
|
229 TInt i( 0 ); |
|
230 TInt length( string.Length() ); |
|
231 |
|
232 // If the input data was too long, some data will miss from the end here |
|
233 for ( i = 0; i < length; i += 1 ) |
|
234 { |
|
235 // Get first character |
|
236 TUint8 char1 = static_cast<TUint8>( string[i] >> move ); |
|
237 TUint8 char2; |
|
238 |
|
239 if ( ( i + 1 ) < length ) |
|
240 { |
|
241 // Get next character |
|
242 char2 = static_cast<TUint8>( string[i + 1] << ( 7 - move ) ); |
|
243 } |
|
244 else |
|
245 { |
|
246 // No more characters |
|
247 char2 = 0; |
|
248 } |
|
249 // Append packed character |
|
250 aOutput.Append( static_cast<TUint8>( char1 | char2 ) ); |
|
251 |
|
252 if ( ( 6 == move ) && char2 ) |
|
253 { |
|
254 i++; |
|
255 move = 0; |
|
256 } |
|
257 else |
|
258 { |
|
259 move++; |
|
260 } |
|
261 } |
|
262 |
|
263 if ( !( ( length + 1 ) % 8 ) ) |
|
264 { |
|
265 // If the total number of characters in the text string equals (8n-1) |
|
266 // where n=1,2,3 etc. then there are 7 spare bits at the end of the |
|
267 // message. To avoid the situation where the receiving entity confuses |
|
268 // 7 binary zero pad bits as the @ character, the carriage return |
|
269 // (i.e. <CR>) character shall be used for padding in this situation, |
|
270 // as defined in TS 23.038 [5]. |
|
271 aOutput[ aOutput.Length() - 1 ] = static_cast<TUint8>( |
|
272 aOutput[ aOutput.Length() - 1 ] | KCrShiftedOneBitToLeft ); |
|
273 } |
|
274 } |
|
275 |
|
276 // ----------------------------------------------------------------------------- |
|
277 // TSatUtility::BCDToAscii |
|
278 // Converts BCD string to ASCII format |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 EXPORT_C TInt TSatUtility::BCDToAscii |
|
282 ( |
|
283 const TPtrC8 aInput, |
|
284 TDes8& aOutput |
|
285 ) |
|
286 { |
|
287 TFLOGSTRING( "UTILITY: TSatUtility::BCDToAscii" ); |
|
288 TInt ret( KErrNone ); |
|
289 |
|
290 // Convert Abbreviated dialling numbers format back to ASCII format. |
|
291 // See 3GPP TS 11.11, EFadn |
|
292 aOutput.Zero(); |
|
293 // Check out which string is the shortest and use its length as a limit |
|
294 TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); |
|
295 |
|
296 for ( TInt i = 0; i < length; i++ ) |
|
297 { |
|
298 // Two bcd string chars are coded in one byte, |
|
299 // 1st char is in low nibble and 2nd is in high nibble |
|
300 // if the high nibble doesn't contain a char it's value is 0xf |
|
301 TUint8 byte = aInput[i]; |
|
302 aOutput.Append( KAscii[byte & 0x0F] ); |
|
303 |
|
304 if ( KMaskF0 != ( byte & KMaskF0 ) ) |
|
305 { |
|
306 aOutput.Append( KAscii[byte >> 4] ); |
|
307 } |
|
308 } |
|
309 |
|
310 // Whe should still notify the requesting method about exceeding the length |
|
311 if ( length < aInput.Length() ) |
|
312 { |
|
313 ret = KErrOverflow; |
|
314 TFLOGSTRING2( "UTILITY: TSatUtility::BCDToAscii,Input data too long.\ |
|
315 %d bytes could not be converted", ( aInput.Length() - length ) ); |
|
316 } |
|
317 |
|
318 return ret; |
|
319 } |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // TSatUtility::AsciiToBCD |
|
323 // Convert ASCII string to binary coded decimal, invalid characters are dropped |
|
324 // and will not be part of bcd string. |
|
325 // ----------------------------------------------------------------------------- |
|
326 // |
|
327 EXPORT_C TInt TSatUtility::AsciiToBCD |
|
328 ( |
|
329 const TDesC8& aInput, |
|
330 TDes8& aOutput |
|
331 ) |
|
332 { |
|
333 TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD" ); |
|
334 TInt ret( KErrNone ); |
|
335 TInt i; |
|
336 TInt j; |
|
337 TInt outLen( 0 ); |
|
338 TInt length( aInput.Length() ); |
|
339 |
|
340 aOutput.Zero(); |
|
341 |
|
342 // Go through the whole string |
|
343 for ( i = 0; i < length; i++ ) |
|
344 { |
|
345 TUint8 bcd = 0x0F; // Should never be part of number |
|
346 TBool found( EFalse ); |
|
347 |
|
348 // Search for the ASCII character |
|
349 for ( j = 0; ( j < KAsciiBcdTableLength ) && !found; j++ ) |
|
350 { |
|
351 // If the character matches, set the corresponding value |
|
352 if ( KAsciiToBCD[j][0] == aInput[i] ) |
|
353 { |
|
354 bcd = KAsciiToBCD[j][1]; |
|
355 found = ETrue; |
|
356 } |
|
357 } |
|
358 |
|
359 // Add only valid bcd characters... |
|
360 if ( found ) |
|
361 { |
|
362 if( aOutput.MaxLength() > aOutput.Length() ) |
|
363 { |
|
364 // Store to string |
|
365 if ( ( outLen % 2 ) == 0 ) |
|
366 { |
|
367 aOutput.Append( bcd ); |
|
368 } |
|
369 else |
|
370 { |
|
371 aOutput[outLen / 2] |= ( bcd << 4 ); |
|
372 } |
|
373 } |
|
374 else |
|
375 { |
|
376 TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD, Overflow!" ); |
|
377 ret = KErrOverflow; |
|
378 } |
|
379 |
|
380 outLen++; |
|
381 } |
|
382 else |
|
383 { |
|
384 TFLOGSTRING3("UTILITY: TSatUtility::AsciiToBCD -- dropped \ |
|
385 character %d at i=%d", TInt( aInput[i] ), i ); |
|
386 } |
|
387 |
|
388 } // For |
|
389 |
|
390 // If odd number of digits add endmark |
|
391 if ( ( outLen % 2 ) != 0 ) |
|
392 { |
|
393 aOutput[outLen / 2] |= KMaskF0; |
|
394 } |
|
395 |
|
396 return ret; |
|
397 } |
|
398 |
|
399 // ----------------------------------------------------------------------------- |
|
400 // TSatUtility::RemoveWildAndExpansionDigit |
|
401 // Remove Wild 'w' and Expansion digit '.' from EFadn string. Used in SetUpCall |
|
402 // proactive command. |
|
403 // ----------------------------------------------------------------------------- |
|
404 // |
|
405 EXPORT_C void TSatUtility::RemoveWildAndExpansionDigit |
|
406 ( |
|
407 const TPtrC8 aString, |
|
408 TDes8& aOutput |
|
409 ) |
|
410 { |
|
411 TFLOGSTRING( "UTILITY: TSatUtility::RemoveWildAndExpansionDigit" ); |
|
412 aOutput.Zero(); |
|
413 TUint8 i( 0 ); |
|
414 TInt maxLength = aOutput.MaxLength(); |
|
415 TInt length( aString.Length() ); |
|
416 |
|
417 // Append as many characters as there is room for in the target string |
|
418 for ( i = 0; ( i < length ) && ( aOutput.Length() < maxLength ); i++ ) |
|
419 { |
|
420 if ( ( 'w' != aString[i] ) && ( '.' != aString[i] ) ) |
|
421 { |
|
422 aOutput.Append( aString[i] ); |
|
423 } |
|
424 } |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // TSatUtility::SetAlphaId |
|
429 // Set Alpha identifier as a Unicode text string and according to the alphabet |
|
430 // used |
|
431 // ----------------------------------------------------------------------------- |
|
432 // |
|
433 EXPORT_C void TSatUtility::SetAlphaId |
|
434 ( |
|
435 const TPtrC8 aRawData, |
|
436 TDes& aAlphaId |
|
437 ) |
|
438 { |
|
439 TFLOGSTRING( "UTILITY: TSatUtility::SetAlphaId" ); |
|
440 if ( ( KUCS2ArabicCoding == aRawData[0] ) |
|
441 || ( KUCS2GreekCoding == aRawData[0] ) |
|
442 || ( KUCS2TurkishCoding == aRawData[0] ) ) |
|
443 { |
|
444 ConvertAlphaFieldsToUnicode( aRawData, aAlphaId ); |
|
445 } |
|
446 else |
|
447 { |
|
448 // 8-bit |
|
449 TBuf8<RSat::KAlphaIdMaxSize> rawData8; |
|
450 rawData8.Copy( aRawData ); |
|
451 Convert7BitToUnicode16( rawData8, aAlphaId ); |
|
452 } |
|
453 } |
|
454 |
|
455 // ----------------------------------------------------------------------------- |
|
456 // TSatUtility::ConvertToSemiOctet |
|
457 // Convert integer to BCD format. Only two last digits is used. |
|
458 // Example TInt 2004 -> 0x40. |
|
459 // ----------------------------------------------------------------------------- |
|
460 // |
|
461 EXPORT_C TUint8 TSatUtility::ConvertToSemiOctet |
|
462 ( |
|
463 const TInt aTime |
|
464 ) |
|
465 { |
|
466 TFLOGSTRING( "UTILITY: TSatUtility::ConvertToSemiOctet" ); |
|
467 // Converting given time to meet the TP-Service-Centre-Time-Stamp format in |
|
468 // 3GPP TS 23.040. |
|
469 |
|
470 TInt msd( ( aTime / 10 ) % 10 ); // Most significant decimal |
|
471 TInt lsd( ( aTime % 10 ) ); // Least significant decimal |
|
472 TUint8 ret( TUint8( ( lsd << 4 ) | ( msd ) ) ); |
|
473 return ret; |
|
474 } |
|
475 |
|
476 // ----------------------------------------------------------------------------- |
|
477 // TSatUtility::Convert7BitToUnicode16 |
|
478 // Convert a text from GSM 7 bit default alphabet to Unicode format. |
|
479 // ----------------------------------------------------------------------------- |
|
480 // |
|
481 EXPORT_C void TSatUtility::Convert7BitToUnicode16 |
|
482 ( |
|
483 const TDesC8& aInput, |
|
484 TDes16& aOutput |
|
485 ) |
|
486 { |
|
487 TFLOGSTRING( "UTILITY: TSatUtility::Convert7BitToUnicode16" ); |
|
488 TInt i( 0 ); |
|
489 |
|
490 aOutput.Zero(); |
|
491 |
|
492 // Check out which string is the shortest and use its length as a limit |
|
493 TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); |
|
494 |
|
495 for( i = 0; i < length; i++ ) |
|
496 { |
|
497 TUint8 character( aInput[i] ); |
|
498 |
|
499 // This code is an escape to an extension of the 7 bit default alphabet |
|
500 // table. |
|
501 if ( 0x1B == character ) |
|
502 { |
|
503 // Extension table |
|
504 switch ( aInput[i+1] ) |
|
505 { |
|
506 case 0x28: //{ |
|
507 { |
|
508 aOutput.Append( static_cast<TUint16>( 0x7B ) ); |
|
509 break; |
|
510 } |
|
511 case 0x29: //} |
|
512 { |
|
513 aOutput.Append( static_cast<TUint16>( 0x7D ) ); |
|
514 break; |
|
515 } |
|
516 case 0x3C: //[ |
|
517 { |
|
518 aOutput.Append( static_cast<TUint16>( 0x5B ) ); |
|
519 break; |
|
520 } |
|
521 case 0x3E: //] |
|
522 { |
|
523 aOutput.Append( static_cast<TUint16>( 0x5D ) ); |
|
524 break; |
|
525 } |
|
526 case 0x3D: //~ |
|
527 { |
|
528 aOutput.Append( static_cast<TUint16>( 0x7E ) ); |
|
529 break; |
|
530 } |
|
531 case 0x2F: |
|
532 { |
|
533 aOutput.Append( static_cast<TUint16>( 0x5C ) ); |
|
534 break; |
|
535 } |
|
536 case 0x14: // ^ |
|
537 { |
|
538 aOutput.Append( static_cast<TUint16>( 0x5E ) ); |
|
539 break; |
|
540 } |
|
541 case 0x65: // Euro 0x20AC |
|
542 { |
|
543 aOutput.Append( static_cast<TUint16>( 0x20AC ) ); |
|
544 break; |
|
545 } |
|
546 case 0x40: // | |
|
547 { |
|
548 aOutput.Append( static_cast<TUint16>( 0x7C ) ); |
|
549 break; |
|
550 } |
|
551 default: |
|
552 { |
|
553 // A space if not found in the table |
|
554 aOutput.Append( static_cast<TUint16>( 0x20 ) ); |
|
555 break; |
|
556 } |
|
557 } |
|
558 // Characters in extension table takes two bytes |
|
559 i++; |
|
560 } |
|
561 // Check that bit 8 is set to '0' |
|
562 else if ( 0x7F >= character ) |
|
563 { |
|
564 // Character is in normal 7-bit table. |
|
565 aOutput.Append( KUnicode[ character ] ); |
|
566 } |
|
567 else |
|
568 { |
|
569 // Do nothing |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 // ----------------------------------------------------------------------------- |
|
575 // TSatUtility::ConvertUnicode16To7Bit |
|
576 // Converts unicode16 string to GSM 7 bit default alphabet character mode |
|
577 // ----------------------------------------------------------------------------- |
|
578 // |
|
579 EXPORT_C TInt TSatUtility::ConvertUnicode16To7Bit |
|
580 ( |
|
581 const TDesC16& aInput, |
|
582 TDes8& aOutput |
|
583 ) |
|
584 { |
|
585 TFLOGSTRING( "UTILITY: TSatUtility::ConvertUnicode16To7Bit" ); |
|
586 TInt i( 0 ); |
|
587 TInt j( 0 ); |
|
588 TInt ret( KErrNone ); |
|
589 TBool found( EFalse ); |
|
590 TInt outputMaxLength = aOutput.MaxLength(); |
|
591 |
|
592 // Check out which string is the shortest and use its length as a limit |
|
593 TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); |
|
594 for ( i = 0; i < length; i++ ) |
|
595 { |
|
596 for ( j = 0; j < KSizeOfConversionArray; j++ ) |
|
597 { |
|
598 if ( KUnicode16ToSms7[j][0] == aInput[i] ) |
|
599 { |
|
600 |
|
601 aOutput.Append( static_cast<TUint8>( |
|
602 KUnicode16ToSms7[j][1] ) ); |
|
603 found = ETrue; |
|
604 } |
|
605 } |
|
606 |
|
607 if ( !found ) |
|
608 { |
|
609 aOutput.Append( static_cast<TUint8>( aInput[i] & 0x00FF ) ); |
|
610 } |
|
611 |
|
612 found = EFalse; |
|
613 } |
|
614 |
|
615 // Whe should still notify the requesting method about exceeding the length |
|
616 if ( length < aInput.Length() ) |
|
617 { |
|
618 ret = KErrOverflow; |
|
619 TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ |
|
620 Input data too long. %d bytes could not be converted", |
|
621 ( aInput.Length() - length ) ); |
|
622 } |
|
623 |
|
624 return ret; |
|
625 } |
|
626 |
|
627 // ----------------------------------------------------------------------------- |
|
628 // TSatUtility::FillDurationStructure |
|
629 // Fill in a TDuration structure |
|
630 // ----------------------------------------------------------------------------- |
|
631 // |
|
632 EXPORT_C void TSatUtility::FillDurationStructure |
|
633 ( |
|
634 CBerTlv& aBerTlv, |
|
635 RSat::TDuration& aTDuration |
|
636 ) |
|
637 { |
|
638 TFLOGSTRING( "UTILITY: TSatUtility::FillDurationStructure" ); |
|
639 CTlv duration; |
|
640 aTDuration.iTimeUnit = RSat::ENoDurationAvailable; |
|
641 TInt returnValue( aBerTlv.TlvByTagValue( |
|
642 &duration, KTlvDurationTag ) ); |
|
643 |
|
644 if ( KErrNotFound != returnValue ) |
|
645 { |
|
646 TUint8 durationTimeUnit = duration.GetShortInfo( ETLV_TimeUnit ); |
|
647 switch ( durationTimeUnit ) |
|
648 { |
|
649 case KMinutes: |
|
650 { |
|
651 // Minutes |
|
652 aTDuration.iTimeUnit = RSat::EMinutes; |
|
653 break; |
|
654 } |
|
655 case KSeconds: |
|
656 { |
|
657 // Seconds |
|
658 aTDuration.iTimeUnit = RSat::ESeconds; |
|
659 break; |
|
660 } |
|
661 case KTenthsOfSeconds: |
|
662 { |
|
663 // Tenths of seconds |
|
664 aTDuration.iTimeUnit = RSat::ETenthsOfSeconds; |
|
665 break; |
|
666 } |
|
667 default: |
|
668 { |
|
669 aTDuration.iTimeUnit = RSat::ETimeUnitNotSet; |
|
670 } |
|
671 } |
|
672 // Time interval |
|
673 aTDuration.iNumOfUnits = duration.GetShortInfo( ETLV_TimeInterval ); |
|
674 } |
|
675 } |
|
676 |
|
677 // ----------------------------------------------------------------------------- |
|
678 // TSatUtility::FillIconStructure |
|
679 // Fill in a TIconId structure |
|
680 // ----------------------------------------------------------------------------- |
|
681 // |
|
682 EXPORT_C void TSatUtility::FillIconStructure |
|
683 ( |
|
684 CBerTlv& aBerTlv, |
|
685 RSat::TIconId& aTIconId, |
|
686 const TInt aItemNmb |
|
687 ) |
|
688 { |
|
689 TFLOGSTRING( "UTILITY: TSatUtility::FillIconStructure" ); |
|
690 CTlv iconId; |
|
691 aTIconId.iQualifier = RSat::ENoIconId; |
|
692 TInt returnValue( aBerTlv.TlvByTagValue( &iconId, KTlvIconIdentifierTag, |
|
693 aItemNmb ) ); |
|
694 |
|
695 if ( KErrNotFound != returnValue ) |
|
696 { |
|
697 TUint8 iconQualifier = iconId.GetShortInfo( ETLV_IconQualifier ); |
|
698 aTIconId.iIdentifier = iconId.GetShortInfo( ETLV_IconIdentifier ); |
|
699 // The icon qualifier indicates to the ME how the icon is to be used. |
|
700 if ( iconQualifier ) |
|
701 { |
|
702 aTIconId.iQualifier = RSat::ENotSelfExplanatory; |
|
703 } |
|
704 else |
|
705 { |
|
706 aTIconId.iQualifier = RSat::ESelfExplanatory; |
|
707 } |
|
708 } |
|
709 } |
|
710 |
|
711 // ----------------------------------------------------------------------------- |
|
712 // TSatUtility::SetText |
|
713 // Set Text string as a Unicode text string and according to the alphabet used |
|
714 // ----------------------------------------------------------------------------- |
|
715 // |
|
716 EXPORT_C void TSatUtility::SetText |
|
717 ( |
|
718 CTlv& aTextTlv, |
|
719 TDes& aUnicodeOutput |
|
720 ) |
|
721 { |
|
722 TFLOGSTRING( "UTILITY: TSatUtility::SetText" ); |
|
723 if ( aTextTlv.GetLength() ) |
|
724 { |
|
725 TPtrC8 sourceString; |
|
726 |
|
727 sourceString.Set( aTextTlv.GetData( ETLV_TextString ) ); |
|
728 |
|
729 TBuf8<KTextBufferMaxSize> string( sourceString ); |
|
730 // SMS default alphabet DCS |
|
731 if ( !( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) |
|
732 & KPacked7BitTextMask ) ) |
|
733 { |
|
734 // Unpack |
|
735 Packed7to8Unpacked( sourceString, string ); |
|
736 |
|
737 if ( aUnicodeOutput.MaxLength() < string.Length() ) |
|
738 { |
|
739 string.SetLength( aUnicodeOutput.MaxLength() ); |
|
740 } |
|
741 // Convert to unicode format |
|
742 Convert7BitToUnicode16( string, aUnicodeOutput ); |
|
743 } |
|
744 // UCS2 DCS |
|
745 else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) |
|
746 & KUCS2DCS ) |
|
747 { |
|
748 Copy8to16LE( sourceString, aUnicodeOutput ); |
|
749 } |
|
750 // 8-bit DCS |
|
751 else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) |
|
752 & K8BitDCS ) |
|
753 { |
|
754 // 8-bit string to 16-bit string |
|
755 Convert7BitToUnicode16( string, aUnicodeOutput ); |
|
756 } |
|
757 else // Reserved cases: SMS default alphabet |
|
758 { |
|
759 // Unpack |
|
760 Packed7to8Unpacked( sourceString, string ); |
|
761 |
|
762 if ( aUnicodeOutput.MaxLength() < string.Length() ) |
|
763 { |
|
764 string.SetLength( aUnicodeOutput.MaxLength() ); |
|
765 } |
|
766 // Convert to unicode format |
|
767 Convert7BitToUnicode16( string, aUnicodeOutput ); |
|
768 } |
|
769 } |
|
770 } |
|
771 |
|
772 // ----------------------------------------------------------------------------- |
|
773 // TSatUtility::ConvertAlphaFieldsToUnicode |
|
774 // Convert Alpha fields format to Unicode format. |
|
775 // ----------------------------------------------------------------------------- |
|
776 // |
|
777 EXPORT_C void TSatUtility::ConvertAlphaFieldsToUnicode |
|
778 ( |
|
779 const TDesC8& aSource, |
|
780 TDes& aTarget |
|
781 ) |
|
782 { |
|
783 TFLOGSTRING( "UTILITY: TSatUtility::ConvertAlphaFieldsToUnicode" ); |
|
784 // ArabicCoding, GreekCoding and TurkishCoding have different coding |
|
785 // methods. There is a tag for each type of alphabet (resp. 80, 81 or 82) |
|
786 // before the text, and there are base pointers used for expanding 1 byte |
|
787 // to 2 bytes as required by UCS2 |
|
788 // Ref: 3GPP TS 11.11, Annex B |
|
789 |
|
790 // Base pointer is a "half-page" in the UCS2 code space |
|
791 TUint16 basePointer( 0 ); |
|
792 TInt offset( 0 ); |
|
793 |
|
794 TInt ret( KErrNone ); |
|
795 |
|
796 switch ( aSource[0] ) |
|
797 { |
|
798 case KUCS2ArabicCoding: |
|
799 { |
|
800 // Copy everything after tag byte |
|
801 Copy8to16LE( aSource.Mid( 1, aSource.Length() - 1 ), aTarget ); |
|
802 //Check if any text present |
|
803 if ( aTarget.Length() ) |
|
804 { |
|
805 // Remove padding bytes if any |
|
806 if ( 0xFFFF == aTarget[ aTarget.Length() - 1 ] ) |
|
807 { |
|
808 aTarget.SetLength( aTarget.Length() - 1 ); |
|
809 } |
|
810 } |
|
811 // No expanding needed, already in unicode format. |
|
812 ret = KErrNotFound; |
|
813 break; |
|
814 } |
|
815 case KUCS2GreekCoding: |
|
816 { |
|
817 // Characters starts at position 3 |
|
818 offset = 3; |
|
819 // Base pointer is given in one byte |
|
820 // and needs to be sifted 7-bit to left to get correct base pointer |
|
821 basePointer = TUint16( aSource[2] << 7 ) ; |
|
822 break; |
|
823 } |
|
824 case KUCS2TurkishCoding: |
|
825 { |
|
826 // Characters starts at position 4 |
|
827 offset = 4; |
|
828 // Base pointer is two bytes, 16-bit |
|
829 TSatUtility::CopyTwo8toOne16LE( aSource, basePointer, 2 ); |
|
830 break; |
|
831 } |
|
832 default: |
|
833 // Do nothing |
|
834 break; |
|
835 } |
|
836 |
|
837 if ( ( KErrNone == ret ) && ( 2 < aSource.Length() ) ) |
|
838 { |
|
839 // The second octet contains a value indicating the number of |
|
840 // characters in the string. (Not in the case of Arabic string) |
|
841 TInt length( aSource[1] ); |
|
842 |
|
843 // Expanding 1 byte format to 2 bytes |
|
844 while ( length ) |
|
845 { |
|
846 // If bit 8 of the octet is set to zero, the remaining 7 bits of |
|
847 // the octet contain a GSM Default Alphabet character, whereas if |
|
848 // bit 8 of the octet is set to one, the remaining seven bits are |
|
849 // an offset value added to the base pointer defined in octets |
|
850 // three and four, and the resultant 16 bit value is a UCS2 code |
|
851 // point, and defines a UCS2 character. |
|
852 if ( 0x7F <= aSource[offset] ) |
|
853 { |
|
854 // Append base pointer and offset |
|
855 aTarget.Append( basePointer + ( aSource[offset] & 0x7F ) ); |
|
856 } |
|
857 else |
|
858 { |
|
859 // GSM default alphabet. |
|
860 TBuf<1> dest16bit; |
|
861 TBuf8<1> src7bit; |
|
862 // Get character |
|
863 src7bit.Append( aSource[offset] ); |
|
864 // Convert GSM default alphabet character to unicode |
|
865 Convert7BitToUnicode16( src7bit, dest16bit ); |
|
866 // Append converted character to output string |
|
867 aTarget.Append( dest16bit ); |
|
868 } |
|
869 offset++; |
|
870 length--; |
|
871 } |
|
872 } |
|
873 } |
|
874 |
|
875 // ----------------------------------------------------------------------------- |
|
876 // TSatUtility::Copy16to8LE |
|
877 // Converts 16-bit data to 8-bit data with little endian. |
|
878 // ----------------------------------------------------------------------------- |
|
879 // |
|
880 EXPORT_C TInt TSatUtility::Copy16to8LE |
|
881 ( |
|
882 const TDesC16& aSource, |
|
883 TDes8& aTarget |
|
884 ) |
|
885 { |
|
886 TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE" ); |
|
887 TInt ret( KErrNone ); |
|
888 TInt length( 0 ); |
|
889 |
|
890 // Checks that data length are acceblable |
|
891 if ( aSource.Size() > aTarget.MaxSize() ) |
|
892 { |
|
893 TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE, Length exceeded!" ); |
|
894 ret = KErrOverflow; |
|
895 length = ( aTarget.MaxSize() / 2 ); |
|
896 } |
|
897 else |
|
898 { |
|
899 length = aSource.Length(); |
|
900 } |
|
901 |
|
902 // Append source to target using rigth endian |
|
903 for ( TInt i = 0; i < length; i++ ) |
|
904 { |
|
905 aTarget.Append( TUint8( aSource[i] >> 8) ); |
|
906 aTarget.Append( TUint8( aSource[i] & 0xff ) ); |
|
907 } |
|
908 |
|
909 return ret; |
|
910 } |
|
911 |
|
912 // ----------------------------------------------------------------------------- |
|
913 // TSatUtility::Copy8to16LE |
|
914 // Converts 8-bit data to 16-bit data with little endian |
|
915 // ----------------------------------------------------------------------------- |
|
916 // |
|
917 EXPORT_C TInt TSatUtility::Copy8to16LE |
|
918 ( |
|
919 const TDesC8& aSource, |
|
920 TDes16& aTarget |
|
921 ) |
|
922 { |
|
923 TFLOGSTRING( "UTILITY: TSatUtility::Copy8to16LE" ); |
|
924 TInt ret( KErrNone ); |
|
925 // Check out which string is the shortest and use its length as a limit |
|
926 TInt length ( Min( ( ( aSource.Length() / 2 ) * 2 ), aTarget.MaxSize() ) ); |
|
927 |
|
928 // Append source to target using right endian |
|
929 for ( TInt i = 0; i < length; i += 2 ) |
|
930 { |
|
931 aTarget.Append( TUint16( aSource[i + 1] | ( aSource[i] << 8) ) ); |
|
932 } |
|
933 |
|
934 // Whe should still notify the requesting method about exceeding the length |
|
935 if ( length < aSource.Length() ) |
|
936 { |
|
937 ret = KErrOverflow; |
|
938 TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ |
|
939 Input data too long. %d bytes could not be converted", |
|
940 ( aSource.Length() - length ) ); |
|
941 } |
|
942 |
|
943 return ret; |
|
944 } |
|
945 |
|
946 // ----------------------------------------------------------------------------- |
|
947 // TSatUtility::DecodeCbsDcs |
|
948 // Finds whether the data coding scheme, coded in CBS format, is 7-bit, 8-bit |
|
949 // or 16-bit. Converts the input DCS from CBS format to SMS format. |
|
950 // Reference: 3gpp ts 23.038 |
|
951 // ----------------------------------------------------------------------------- |
|
952 // |
|
953 EXPORT_C TSmsDcs TSatUtility::DecodeCbsDcs |
|
954 ( |
|
955 const TUint8 aDcs |
|
956 ) |
|
957 { |
|
958 TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs"); |
|
959 |
|
960 // Constant values are not defined in order to |
|
961 // avoid confusion with too many constants names. |
|
962 |
|
963 // Coding group: 4 left most significant bits |
|
964 TUint8 codingGroup = ( aDcs & 0xF0 )>>4; |
|
965 // Lower quartet: 4 right most significant bits |
|
966 TUint8 lowQuartet = ( aDcs & 0x0F ); |
|
967 // Character set: bit 2 and 3, in [bit7...bit0] |
|
968 TUint8 characterSet = ( aDcs & 0x0C )>>2; |
|
969 // Initialize output to Unknown or Reserved |
|
970 TSmsDcs decodedDcs( ESmsUnknownOrReservedDcs ); |
|
971 // Switch according to the coding group |
|
972 switch ( codingGroup ) |
|
973 { |
|
974 // Language specified, usually in 7-bit |
|
975 // b0000 or b0010 or b0011 |
|
976 case 0x00: |
|
977 case 0x02: |
|
978 case 0x03: |
|
979 { |
|
980 // 7-bit alphabet |
|
981 decodedDcs = ESms7BitDcs; |
|
982 break; |
|
983 } |
|
984 // b0001 |
|
985 // Message preceded by language indication |
|
986 case 0x01: |
|
987 { |
|
988 |
|
989 if ( 0x00==lowQuartet ) |
|
990 { |
|
991 decodedDcs = ESms7BitDcs; |
|
992 } |
|
993 else if ( 0x01==lowQuartet ) |
|
994 { |
|
995 decodedDcs = ESms16BitDcs; |
|
996 } |
|
997 break; |
|
998 } |
|
999 // General data coding indication |
|
1000 // b01xx or b1001 |
|
1001 case 0x04: |
|
1002 case 0x05: |
|
1003 case 0x06: |
|
1004 case 0x07: |
|
1005 case 0x09: |
|
1006 { |
|
1007 // The character set determines the alphabet/compression |
|
1008 if ( 0x00 == characterSet ) |
|
1009 { |
|
1010 decodedDcs = ESms7BitDcs; |
|
1011 } |
|
1012 else if ( 0x01 == characterSet ) |
|
1013 { |
|
1014 decodedDcs = ESms8BitDcs; |
|
1015 } |
|
1016 else if ( 0x02 == characterSet ) |
|
1017 { |
|
1018 decodedDcs = ESms16BitDcs; |
|
1019 } |
|
1020 break; |
|
1021 } |
|
1022 // Data coding / Message handling |
|
1023 // either 8-bit or 7-bit |
|
1024 case 0x0F: |
|
1025 { |
|
1026 // only bit 2 informs about the |
|
1027 // character set. |
|
1028 if ( aDcs & 0x04 ) |
|
1029 { |
|
1030 decodedDcs = ESms8BitDcs; |
|
1031 } |
|
1032 else |
|
1033 { |
|
1034 decodedDcs = ESms7BitDcs; |
|
1035 } |
|
1036 break; |
|
1037 } |
|
1038 default: |
|
1039 { |
|
1040 // the DCS value is reserved. |
|
1041 TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs, reserved value"); |
|
1042 break; |
|
1043 } |
|
1044 } |
|
1045 return decodedDcs; |
|
1046 } |
|
1047 |
|
1048 // ----------------------------------------------------------------------------- |
|
1049 // TSatUtility::CopyTwo8toOne16LE |
|
1050 // Gets two 8-bit bytes and copies them to the one 16-bit byte with little |
|
1051 // endianes. Used when reading data from response or indication. |
|
1052 // ----------------------------------------------------------------------------- |
|
1053 // |
|
1054 EXPORT_C TInt TSatUtility::CopyTwo8toOne16LE |
|
1055 ( |
|
1056 const TDesC8& aSource, |
|
1057 TUint16& aTarget, |
|
1058 const TInt aIndex |
|
1059 ) |
|
1060 { |
|
1061 TFLOGSTRING("UTILITY: TSatUtility::CopyTwo8toOne16LE"); |
|
1062 TInt ret( KErrNone ); |
|
1063 // Check first that we dont try to read data that is not there.. |
|
1064 if ( aSource.Length() > aIndex + 1 ) |
|
1065 { |
|
1066 aTarget = static_cast<TUint16>( aSource[aIndex] << 8 ); |
|
1067 aTarget = static_cast<TUint16>( aTarget | aSource[aIndex + 1] ); |
|
1068 } |
|
1069 else |
|
1070 { |
|
1071 ret = KErrOverflow; |
|
1072 TFLOGSTRING3("UTILITY: TSatUtility::CopyTwo8toOne16LE, Index too high\ |
|
1073 Index: %d, Source data length: %d", aIndex, aSource.Length() ); |
|
1074 } |
|
1075 |
|
1076 return ret; |
|
1077 } |
|
1078 |
|
1079 |
|
1080 // End of file |