|
1 // Copyright (c) 2000-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 // Implements utility classes private to the GSMU dll |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include "gsmupriv.h" |
|
23 #include "Gsmumain.h" |
|
24 #include <exterror.h> |
|
25 |
|
26 // |
|
27 // TSmsPacker - packs and unpacks data encoded in an SMS alphabet |
|
28 // |
|
29 |
|
30 /** |
|
31 * Constructor |
|
32 */ |
|
33 TSmsAlphabetPacker::TSmsAlphabetPacker(TSmsDataCodingScheme::TSmsAlphabet aAlphabet,TBool aIsBinary,TInt aStartBit) |
|
34 : iAlphabet(aAlphabet),iIsBinary(aIsBinary),iStartBit(aStartBit) |
|
35 { |
|
36 // NOP |
|
37 } // TSmsAlphabetPacker::TSmsAlphabetPacker |
|
38 |
|
39 |
|
40 /** |
|
41 * Packs user data units from aIn and appends to aOut. |
|
42 */ |
|
43 TInt TSmsAlphabetPacker::PackL(TDes8& aOut,const TDesC8& aIn) |
|
44 { |
|
45 LOGGSMU1("TSmsAlphabetPacker::PackL()"); |
|
46 |
|
47 // Ensure we've got the right length |
|
48 TInt packedOctetsRequired=PackedOctetsRequiredL(aIn.Length()); |
|
49 if (packedOctetsRequired>(aOut.MaxLength()-aOut.Length())) |
|
50 User::Leave(KErrOverflow); |
|
51 // Do the conversion |
|
52 TInt elementSizeInBits=ElementSizeInBitsL(); |
|
53 if (elementSizeInBits==8) |
|
54 { |
|
55 // Straight copy here |
|
56 aOut.Append(aIn); |
|
57 } |
|
58 else if (elementSizeInBits==7) |
|
59 { |
|
60 // Get raw pointers and do packing |
|
61 TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length(); |
|
62 const TUint8* inPtr=aIn.Ptr(); |
|
63 |
|
64 outPtr[0]=0; |
|
65 for (TInt i=0; i<aIn.Length(); i++) |
|
66 { |
|
67 TUint8 to=inPtr[i]; |
|
68 *outPtr|=(to<<iStartBit); |
|
69 if (iStartBit) |
|
70 { |
|
71 outPtr++; |
|
72 *outPtr=(TUint8) (to>>(8-iStartBit)); |
|
73 } |
|
74 iStartBit=(iStartBit+7)%8; |
|
75 } |
|
76 // Increment the length for the packed data |
|
77 aOut.SetLength(aOut.Length()+packedOctetsRequired); |
|
78 } |
|
79 else |
|
80 { |
|
81 __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid)); |
|
82 } |
|
83 // Return number of bytes used |
|
84 return packedOctetsRequired; |
|
85 } // TSmsAlphabetPacker::PackL |
|
86 |
|
87 |
|
88 /** |
|
89 * Unpacks user data units from aIn and appends to aOut. |
|
90 */ |
|
91 TInt TSmsAlphabetPacker::UnpackL(const TDesC8& aIn,TDes8& aOut,TInt aNumUDUnits) |
|
92 { |
|
93 LOGGSMU1("TSmsAlphabetPacker::UnpackL()"); |
|
94 |
|
95 TInt length=aNumUDUnits; |
|
96 // Ensure we've got enough input and output buffer |
|
97 // defect fix for |
|
98 // EDNOPMA-4YPJ34 Short message with alphanumeric address in From field is not received |
|
99 // aIn.length is constant (KSmsAddressMaxAddressValueLength = 10) |
|
100 // PackedOctetsRequiredL is dependant on aNumUDUnits |
|
101 // otheriwse if a short alphanumeric address is received GSMU leaves |
|
102 // and the smsprot returns protocol error to the service center |
|
103 // if (PackedOctetsRequiredL(aIn.Length())>aNumUDUnits) |
|
104 if (PackedOctetsRequiredL(aNumUDUnits)>aIn.Length()) |
|
105 User::Leave(KErrCorrupt); |
|
106 if (aOut.Length()+length>aOut.MaxLength()) |
|
107 User::Leave(KErrCorrupt); |
|
108 TInt elementSizeInBits=ElementSizeInBitsL(); |
|
109 if (elementSizeInBits==8) |
|
110 { |
|
111 aOut.Append(aIn); |
|
112 } |
|
113 else if (elementSizeInBits==7) |
|
114 { |
|
115 // Get raw pointers and do packing |
|
116 TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length(); |
|
117 const TUint8* inPtr=aIn.Ptr(); |
|
118 |
|
119 for (TInt i=0; i<length; i++) |
|
120 { |
|
121 TInt from=(*inPtr>>iStartBit) & 0x7F; |
|
122 if (iStartBit) |
|
123 { |
|
124 inPtr++; |
|
125 from|=(*inPtr<<(8-iStartBit)) & 0x7F; |
|
126 } |
|
127 outPtr[i]=(TUint8) from; |
|
128 iStartBit=(iStartBit+7)%8; |
|
129 } |
|
130 aOut.SetLength(aOut.Length()+length); |
|
131 } |
|
132 else |
|
133 { |
|
134 __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid)); |
|
135 } |
|
136 return length; |
|
137 } // TSmsAlphabetPacker::UnpackL |
|
138 |
|
139 |
|
140 /** |
|
141 * Converts then packs the input data, aIn, and appends to aOut |
|
142 */ |
|
143 TInt TSmsAlphabetPacker::ConvertAndPackL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TDes8& aOut,const TDesC& aIn,TInt& aConvertedNumUDUnits) |
|
144 { |
|
145 LOGGSMU1("TSmsAlphabetPacker::ConvertAndPackL()"); |
|
146 |
|
147 // Do the conversion |
|
148 // VEP Fix for defect EXT-568BMW, when length of alphanumeric destination address |
|
149 // was set wrong and also special characters defined in 7-bit default aplhabet (ä,ö...) |
|
150 // were converted incorrectly |
|
151 CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary); |
|
152 TPtrC8 convertedPtr=converter->ConvertFromNativeL(aIn); |
|
153 aConvertedNumUDUnits=convertedPtr.Length(); |
|
154 // Do the packing |
|
155 TInt octetsUsed=PackL(aOut,convertedPtr); |
|
156 // Cleanup and return |
|
157 CleanupStack::PopAndDestroy(converter); |
|
158 return octetsUsed; |
|
159 } // TSmsAlphabetPacker::ConvertAndPackL |
|
160 |
|
161 |
|
162 /** |
|
163 * Unpacks the converts the input data, aIn, and appends to aOut |
|
164 */ |
|
165 TInt TSmsAlphabetPacker::UnpackAndConvertL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,const TDesC8& aIn,TDes& aOut,TInt aNumUDUnits) |
|
166 { |
|
167 LOGGSMU1("TSmsAlphabetPacker::UnpackAndConvertL()"); |
|
168 |
|
169 // Unpack first |
|
170 HBufC8* unpackedBuffer=HBufC8::NewLC(aNumUDUnits); |
|
171 TPtr8 unpackedBufferPtr(unpackedBuffer->Des()); |
|
172 UnpackL(aIn,unpackedBufferPtr,aNumUDUnits); |
|
173 // Convert |
|
174 CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary); |
|
175 TPtrC convertedPtr=converter->ConvertToNativeL(*unpackedBuffer); |
|
176 if (convertedPtr.Length()>(aOut.MaxLength()-aOut.Length())) |
|
177 User::Leave(KErrCorrupt); |
|
178 // Cleanup and return |
|
179 aOut.Append(convertedPtr); |
|
180 CleanupStack::PopAndDestroy(2); // unpackedBuffer,converter |
|
181 return aNumUDUnits; |
|
182 } // TSmsAlphabetPacker::UnpackAndConvertL |
|
183 |
|
184 |
|
185 /** |
|
186 * Returns the number of octets needed to pack the specified number of |
|
187 */ |
|
188 TInt TSmsAlphabetPacker::PackedOctetsRequiredL(TInt aNumUDUnits) const |
|
189 { |
|
190 LOGGSMU1("TSmsAlphabetPacker::PackedOctetsRequiredL()"); |
|
191 |
|
192 TInt octetsRequired=0; |
|
193 TInt elementSizeInBits=ElementSizeInBitsL(); |
|
194 if (elementSizeInBits==8) |
|
195 octetsRequired=aNumUDUnits; |
|
196 else |
|
197 octetsRequired=(iStartBit+aNumUDUnits*elementSizeInBits + 7)/8; // Rounds up |
|
198 return octetsRequired; |
|
199 } // TSmsAlphabetPacker::PackedOctetsRequiredL |
|
200 |
|
201 /** |
|
202 * Returns the number of UD units that are packed in the specified number of octets |
|
203 */ |
|
204 TInt TSmsAlphabetPacker::NumUDUnitsL(TInt aOctets) const |
|
205 { |
|
206 TInt numUD=0; |
|
207 TInt elementSizeInBits=ElementSizeInBitsL(); |
|
208 if (elementSizeInBits==8) |
|
209 numUD=aOctets; |
|
210 else |
|
211 numUD=(8*aOctets - iStartBit)/elementSizeInBits; |
|
212 return numUD; |
|
213 } |
|
214 |
|
215 /** |
|
216 * Returns the size in bits of a UDL element for the alphabet. Leaves if |
|
217 * invalid data coding scheme. |
|
218 */ |
|
219 TInt TSmsAlphabetPacker::ElementSizeInBitsL() const |
|
220 { |
|
221 LOGGSMU1("TSmsAlphabetPacker::ElementSizeInBitsL()"); |
|
222 |
|
223 TInt ret = 8; |
|
224 |
|
225 if (iIsBinary) |
|
226 return ret; |
|
227 switch (iAlphabet) |
|
228 { |
|
229 case TSmsDataCodingScheme::ESmsAlphabet7Bit: |
|
230 { |
|
231 ret = 7; |
|
232 break; |
|
233 } |
|
234 case TSmsDataCodingScheme::ESmsAlphabet8Bit: |
|
235 case TSmsDataCodingScheme::ESmsAlphabetUCS2: |
|
236 { |
|
237 ret = 8; |
|
238 break; |
|
239 } |
|
240 default: |
|
241 { |
|
242 User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); |
|
243 } |
|
244 } |
|
245 return ret; |
|
246 } // TSmsAlphabetPacker::ElementSizeInBitsL |