|
1 // Copyright (c) 2003-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 // |
|
15 |
|
16 |
|
17 |
|
18 #include "smspdudbitems.h" |
|
19 #include "Gsmumsg.h" |
|
20 #include "gsmubuf.h" |
|
21 #include <testconfigfileparser.h> |
|
22 |
|
23 |
|
24 EXPORT_C CSmsPduDbConcatSegment* CSmsPduDbConcatSegment::NewL(RFs& aFs, const CTestConfigItem& aItem, CSmsPDU::TSmsPDUType aType) |
|
25 { |
|
26 CSmsPduDbConcatSegment* self = new (ELeave) CSmsPduDbConcatSegment(aType); |
|
27 CleanupStack::PushL(self); |
|
28 self->DecodeL(aFs, aItem); |
|
29 CleanupStack::Pop(self); |
|
30 return self; |
|
31 } |
|
32 |
|
33 |
|
34 |
|
35 EXPORT_C CSmsPduDbMessage* CSmsPduDbMessage::NewL(RFs& aFs, const CTestConfigItem& aItem, CSmsPDU::TSmsPDUType aType) |
|
36 { |
|
37 CSmsPduDbMessage* pdu = new (ELeave) CSmsPduDbMessage(aType); |
|
38 CleanupStack::PushL(pdu); |
|
39 |
|
40 pdu->DecodeL(aFs, aItem); |
|
41 |
|
42 CleanupStack::Pop(pdu); |
|
43 |
|
44 return pdu; |
|
45 } |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 EXPORT_C CSmsPduDbPdu* CSmsPduDbPdu::NewL(RFs& aFs, const CTestConfigItem& aItem, CSmsPDU::TSmsPDUType aType) |
|
52 { |
|
53 CSmsPduDbPdu* self = new (ELeave) CSmsPduDbPdu(aType); |
|
54 CleanupStack::PushL(self); |
|
55 self->DecodeL(aFs, aItem); |
|
56 CleanupStack::Pop(self); |
|
57 return self; |
|
58 } |
|
59 |
|
60 |
|
61 |
|
62 EXPORT_C CSmsPduDbBase::~CSmsPduDbBase() |
|
63 { |
|
64 delete iSmsMessage; |
|
65 } |
|
66 |
|
67 EXPORT_C CSmsPduDbConcat::~CSmsPduDbConcat() |
|
68 { |
|
69 iSegments.ResetAndDestroy(); |
|
70 } |
|
71 |
|
72 void CSmsPduDbPdu::DecodeL(RFs& aFs, const CTestConfigItem& aItem) |
|
73 { |
|
74 const TDesC8& val = aItem.Value(); |
|
75 |
|
76 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, CSmsPduDbBase::ESmsPduDbId, iId)); |
|
77 |
|
78 TPtrC8 pdu; |
|
79 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, EPdu, pdu)); |
|
80 SetPduL(pdu); |
|
81 |
|
82 const TInt err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EPduError, iDecodeError); |
|
83 if (err != KErrNone) |
|
84 { |
|
85 iDecodeError = KErrNone; |
|
86 } |
|
87 |
|
88 (void) CTestConfig::GetElement(val, KSmsPduDbDelimiter, EPduDesc, iDescription); //ignore error |
|
89 |
|
90 TRAP(iSmsMessageError, ConstructSmsMessageL(aFs)); |
|
91 } |
|
92 |
|
93 void CSmsPduDbPdu::ConstructSmsMessageL(RFs& aFs) |
|
94 { |
|
95 delete iSmsMessage; |
|
96 iSmsMessage = NULL; |
|
97 TGsmSms sms; |
|
98 sms.SetPdu(iPdu); |
|
99 const TBool mt = IsMobileTerminatedL(); |
|
100 iSmsMessage = CSmsMessage::NewL(aFs, sms, CSmsBuffer::NewL(), EFalse, mt); |
|
101 } |
|
102 |
|
103 void CSmsPduDbConcatSegment::DecodeL(RFs& aFs, const CTestConfigItem& aItem) |
|
104 { |
|
105 const TDesC8& val = aItem.Value(); |
|
106 |
|
107 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, CSmsPduDbBase::ESmsPduDbId, iId)); |
|
108 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, EConcatSegment, iSegment)); |
|
109 |
|
110 TPtrC8 pdu; |
|
111 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, EConcatPdu, pdu)); |
|
112 SetPduL(pdu); |
|
113 |
|
114 const TInt err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EConcatError, iDecodeError); |
|
115 if (err != KErrNone) |
|
116 { |
|
117 iDecodeError = KErrNone; |
|
118 } |
|
119 |
|
120 (void) CTestConfig::GetElement(val, KSmsPduDbDelimiter, EConcatDesc, iDescription); //ignore error |
|
121 |
|
122 TRAP(iSmsMessageError, ConstructSmsMessageL(aFs)); |
|
123 } |
|
124 |
|
125 EXPORT_C void CSmsPduDbPdu::GetHexPdu(TDes8& aHexPdu) const |
|
126 { |
|
127 const TInt len = iPdu.Length(); |
|
128 aHexPdu.Zero(); |
|
129 |
|
130 for (TInt i=0; i < len; i++) |
|
131 { |
|
132 _LIT8(KHexFormat, "%02X"); |
|
133 const TUint8 val = iPdu[i]; |
|
134 aHexPdu.AppendFormat(KHexFormat, val); |
|
135 } |
|
136 } |
|
137 |
|
138 void CSmsPduDbPdu::SetPduL(const TDesC8& aHexPdu) |
|
139 { |
|
140 const TInt len = aHexPdu.Length(); |
|
141 |
|
142 if (len % 2 != 0) |
|
143 User::Leave(KErrArgument); |
|
144 |
|
145 for (TInt i = 0; i < len; i+=2) |
|
146 { |
|
147 const TPtrC8 ptr(aHexPdu.Mid(i, 2)); |
|
148 TLex8 lex(ptr); |
|
149 TUint8 val; |
|
150 User::LeaveIfError(lex.Val(val, EHex)); |
|
151 iPdu.Append(val); |
|
152 } |
|
153 } |
|
154 |
|
155 TBool CSmsPduDbPdu::IsMobileTerminatedL() const |
|
156 { |
|
157 TBool ret(EFalse); |
|
158 |
|
159 switch(iType) |
|
160 { |
|
161 case CSmsPDU::ESmsSubmit: |
|
162 case CSmsPDU::ESmsCommand: |
|
163 |
|
164 ret = EFalse; |
|
165 break; |
|
166 |
|
167 case CSmsPDU::ESmsDeliver: |
|
168 case CSmsPDU::ESmsStatusReport: |
|
169 |
|
170 ret = ETrue; |
|
171 break; |
|
172 |
|
173 default: |
|
174 |
|
175 User::Leave(KErrNotSupported); |
|
176 break; |
|
177 } |
|
178 |
|
179 |
|
180 return ret; |
|
181 } |
|
182 |
|
183 void CSmsPduDbMessage::DecodeL(RFs& aFs, const CTestConfigItem& aItem) |
|
184 { |
|
185 const TDesC8& val = aItem.Value(); |
|
186 |
|
187 iPdus.Reset(); |
|
188 delete iSmsMessage; |
|
189 iSmsMessage = NULL; |
|
190 |
|
191 CSmsBuffer* buffer = CSmsBuffer::NewL(); |
|
192 iSmsMessage = CSmsMessage::NewL(aFs, iType, buffer); //takes ownership of buffer |
|
193 |
|
194 TPtrC8 body; |
|
195 TBool statusReport(EFalse); |
|
196 TInt dataCodingScheme(0); |
|
197 TInt protocolIdentifier(0); |
|
198 |
|
199 User::LeaveIfError(CTestConfig::GetElement(val, KSmsPduDbDelimiter, CSmsPduDbBase::ESmsPduDbId, iId)); |
|
200 |
|
201 TInt err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EMsgBody, body); |
|
202 if (err == KErrNone) |
|
203 { |
|
204 SetBufferL(body, *buffer); |
|
205 } |
|
206 |
|
207 err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EMsgStatusReport, statusReport); |
|
208 if (err == KErrNone) |
|
209 { |
|
210 if (iType == CSmsPDU::ESmsSubmit) |
|
211 { |
|
212 CSmsSubmit& submit = static_cast<CSmsSubmit&>(iSmsMessage->SmsPDU()); |
|
213 submit.SetStatusReportRequest(statusReport); |
|
214 } |
|
215 else if (iType == CSmsPDU::ESmsCommand) |
|
216 { |
|
217 CSmsCommand& command = static_cast<CSmsCommand&>(iSmsMessage->SmsPDU()); |
|
218 command.SetStatusReportRequest(statusReport); |
|
219 } |
|
220 } |
|
221 |
|
222 err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EMsgDCS, dataCodingScheme); |
|
223 if (err == KErrNone) |
|
224 { |
|
225 SetDataCodingScheme(dataCodingScheme); |
|
226 } |
|
227 |
|
228 err = CTestConfig::GetElement(val, KSmsPduDbDelimiter, EMsgPID, protocolIdentifier); |
|
229 if (err == KErrNone) |
|
230 { |
|
231 SetProtocolIdentifier(protocolIdentifier); |
|
232 } |
|
233 |
|
234 (void) CTestConfig::GetElement(val, KSmsPduDbDelimiter, EMsgDesc, iDescription); //ignore error |
|
235 |
|
236 TRAP(iPdusError, iSmsMessage->EncodeMessagePDUsL(iPdus)); |
|
237 } |
|
238 |
|
239 void CSmsPduDbMessage::SetDataCodingScheme(TInt aDCS) |
|
240 { |
|
241 TSmsOctet octet(aDCS); |
|
242 TSmsDataCodingScheme& dcs = reinterpret_cast<TSmsDataCodingScheme&>(octet); |
|
243 |
|
244 CSmsPDU& pdu = iSmsMessage->SmsPDU(); |
|
245 |
|
246 pdu.SetBits7To4(dcs.Bits7To4()); |
|
247 |
|
248 TSmsDataCodingScheme::TSmsClass dcsClass; |
|
249 const TBool hasClass = dcs.Class(dcsClass); |
|
250 pdu.SetClass(hasClass, dcsClass); |
|
251 |
|
252 pdu.SetAlphabet(dcs.Alphabet()); |
|
253 pdu.SetTextCompressed(dcs.TextCompressed()); |
|
254 pdu.SetIndicationState(dcs.IndicationState()); |
|
255 pdu.SetIndicationType(dcs.IndicationType()); |
|
256 } |
|
257 |
|
258 void CSmsPduDbMessage::SetProtocolIdentifier(TInt aPID) |
|
259 { |
|
260 TSmsOctet octet(aPID); |
|
261 TSmsProtocolIdentifier& pid = reinterpret_cast<TSmsProtocolIdentifier&>(octet); |
|
262 CSmsPDU& pdu = iSmsMessage->SmsPDU(); |
|
263 |
|
264 pdu.SetPIDType(pid.PIDType()); |
|
265 pdu.SetTelematicDeviceIndicator(pid.TelematicDeviceIndicator()); |
|
266 |
|
267 if (pid.PIDType()==TSmsProtocolIdentifier::ESmsPIDShortMessageType) |
|
268 { |
|
269 TSmsProtocolIdentifier::TSmsShortMessageType pidSMT = (TSmsProtocolIdentifier::TSmsShortMessageType) pid.ShortMessageType(); |
|
270 pdu.SetShortMessageType(pidSMT); |
|
271 } |
|
272 |
|
273 if (pid.TelematicDeviceIndicator()==TSmsProtocolIdentifier::ESmsTelematicDevice) |
|
274 { |
|
275 pdu.SetTelematicDeviceType(pid.TelematicDeviceType()); |
|
276 } |
|
277 } |
|
278 |
|
279 void CSmsPduDbMessage::SetBufferL(const TDesC8& aBody, CSmsBufferBase& aBuffer) |
|
280 { |
|
281 TLex8 body(aBody); |
|
282 body.Mark(); |
|
283 TPtrC8 marked; |
|
284 |
|
285 |
|
286 while (!body.Eos()) |
|
287 { |
|
288 if (body.Peek() == KSmsPduDbTagStart) |
|
289 { |
|
290 marked.Set(body.MarkedToken()); |
|
291 AppendToBufferL(marked, aBuffer); |
|
292 body.Mark(); |
|
293 ProcessUnicodeL(body, aBuffer); |
|
294 } |
|
295 else |
|
296 { |
|
297 body.Inc(); |
|
298 } |
|
299 } |
|
300 |
|
301 marked.Set(body.MarkedToken()); |
|
302 if (marked.Length() != 0) |
|
303 { |
|
304 AppendToBufferL(marked, aBuffer); |
|
305 } |
|
306 } |
|
307 |
|
308 void CSmsPduDbMessage::ProcessUnicodeL(TLex8& aBody, CSmsBufferBase& aBuffer) |
|
309 { |
|
310 const TPtrC8 remainder(aBody.Remainder()); |
|
311 const TInt locate = remainder.Locate(KSmsPduDbTagEnd); |
|
312 |
|
313 if (locate != KErrNotFound) |
|
314 { |
|
315 aBody.Inc(); |
|
316 if (!aBody.Eos() && aBody.Peek().IsDigit()) |
|
317 { |
|
318 aBody.Mark(); |
|
319 aBody.Inc(locate - 1); |
|
320 TPtrC8 marked(aBody.MarkedToken()); |
|
321 ParseUnicodeL(marked, aBuffer); |
|
322 aBody.Inc(); |
|
323 if (!aBody.Eos()) |
|
324 aBody.Mark(); |
|
325 } |
|
326 } |
|
327 else |
|
328 aBody.Inc(); |
|
329 } |
|
330 |
|
331 void CSmsPduDbMessage::AppendToBufferL(const TDesC8& aItem, CSmsBufferBase& aBuffer) |
|
332 { |
|
333 HBufC* body16 = HBufC::NewLC(aItem.Length()); |
|
334 body16->Des().Copy(aItem); |
|
335 |
|
336 const TInt len = aBuffer.Length(); |
|
337 aBuffer.InsertL(len, *body16); |
|
338 |
|
339 CleanupStack::PopAndDestroy(body16); |
|
340 } |
|
341 |
|
342 void CSmsPduDbMessage::ParseUnicodeL(const TDesC8& aUnicode, CSmsBufferBase& aBuffer) |
|
343 { |
|
344 TInt unicodeChar(0); |
|
345 TInt unicodeRepeat(1); |
|
346 |
|
347 User::LeaveIfError(CTestConfig::GetElement(aUnicode, KSmsPduDbTagDelimitier, EUnicodeChar, unicodeChar)); |
|
348 |
|
349 TInt err = CTestConfig::GetElement(aUnicode, KSmsPduDbTagDelimitier, EUnicodeCharRepeat, unicodeRepeat); |
|
350 |
|
351 if (err != KErrNone || unicodeRepeat < 1) |
|
352 { |
|
353 unicodeRepeat = 1; |
|
354 } |
|
355 |
|
356 TBuf8<1> buf; |
|
357 buf.Append(unicodeChar); |
|
358 |
|
359 while (unicodeRepeat--) |
|
360 { |
|
361 AppendToBufferL(buf, aBuffer); |
|
362 } |
|
363 } |
|
364 |
|
365 EXPORT_C void CSmsPduDbConcat::DecodeL(RFs& aFs) |
|
366 { |
|
367 delete iSmsMessage; |
|
368 iSmsMessage = NULL; |
|
369 const CSmsPDU::TSmsPDUType type = iSegments[0]->iType; |
|
370 iSmsMessage = CSmsMessage::NewL(aFs, type, CSmsBuffer::NewL()); |
|
371 |
|
372 CArrayFixFlat<TGsmSms>* pdus = new (ELeave) CArrayFixFlat<TGsmSms>(1); |
|
373 CleanupStack::PushL(pdus); |
|
374 |
|
375 const TInt count = iSegments.Count(); |
|
376 |
|
377 for (TInt i=0; i<count; i++) |
|
378 { |
|
379 const CSmsPduDbConcatSegment& segment = *iSegments[i]; |
|
380 TGsmSms sms; |
|
381 sms.SetPdu(segment.iPdu); |
|
382 pdus->AppendL(sms); |
|
383 } |
|
384 |
|
385 TRAP(iSmsMessageError, iSmsMessage->DecodeMessagePDUsL(*pdus)); |
|
386 CleanupStack::PopAndDestroy(pdus); |
|
387 } |