|
1 /* |
|
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <iscapi.h> // isc api |
|
22 #include <pipeisi.h> // isi pipe |
|
23 |
|
24 #include "dpdef.h" // dataport definitions |
|
25 #include "dpdataport.h" // dataport main and c32 interface |
|
26 #include "dppif.h" // dcs pipe interface |
|
27 #include "dpescdetect.h" // escape sequence detection |
|
28 #include "dpdataconfig.h" // configuration store |
|
29 #include "pep_comm_types.h" // structures for isi-message interface |
|
30 #include "dpmif.h" // dcs pipe interface |
|
31 #include "dplog.h" // dataport logging |
|
32 |
|
33 #include <pipe_sharedisi.h> |
|
34 |
|
35 #ifdef USE_FILE_DEBUG |
|
36 #include <f32file.h> |
|
37 extern RFile DpLogFile; |
|
38 #endif // USE_FILE_DEBUG |
|
39 |
|
40 #include "osttracedefinitions.h" |
|
41 #ifdef OST_TRACE_COMPILER_IN_USE |
|
42 #include "dpescdetecttraces.h" |
|
43 #endif |
|
44 |
|
45 |
|
46 // LOCAL FUNCTION PROTOTYPES |
|
47 // none |
|
48 |
|
49 // ==================== LOCAL FUNCTIONS ==================== |
|
50 |
|
51 // ================= MEMBER FUNCTIONS ======================= |
|
52 |
|
53 // --------------------------------------------------------- |
|
54 // CDpEscDetect::CDpEscDetect |
|
55 // C++ default constructor. |
|
56 // --------------------------------------------------------- |
|
57 CDpEscDetect::CDpEscDetect( |
|
58 CDpDataPort& aDataPort ) : |
|
59 CActive( KDpEscDetectPriority ), |
|
60 iDataPort( aDataPort ), |
|
61 iDataConfig( iDataPort.DataConfig() ) |
|
62 { |
|
63 OstTrace0( TRACE_NORMAL, CDPESCDETECT_CDPESCDETECT, "CDpEscDetect::CDpEscDetect" ); |
|
64 LOGM(" CDpEscDetect::CDpEscDetect"); |
|
65 |
|
66 // Create escape sequence detection timer |
|
67 iEscTimer.CreateLocal(); |
|
68 |
|
69 iEscCharTimeArray[ 0 ] = 0; |
|
70 iEscCharTimeArray[ 1 ] = 0; |
|
71 iEscCharTimeArray[ 2 ] = 0; |
|
72 |
|
73 CActiveScheduler::Add( this ); |
|
74 } |
|
75 |
|
76 // --------------------------------------------------------- |
|
77 // CDpEscDetect::~CDpEscDetect |
|
78 // Destructor |
|
79 // --------------------------------------------------------- |
|
80 CDpEscDetect::~CDpEscDetect() |
|
81 { |
|
82 OstTrace0( TRACE_NORMAL, DUP1_CDPESCDETECT_CDPESCDETECT, "CDpEscDetect::~CDpEscDetect" ); |
|
83 LOGM(" CDpEscDetect::~CDpEscDetect"); |
|
84 |
|
85 iEscTimer.Close(); |
|
86 } |
|
87 |
|
88 // --------------------------------------------------------- |
|
89 // CDpEscDetect::RunL |
|
90 // This method is used with escape detection time checking. |
|
91 // This active object is signalled when timer between last |
|
92 // escape sequence character (e.g. '+') has expired. If this |
|
93 // happens we are sure that it was correct escape sequence |
|
94 // and we can send escapesequence indication to DCS. |
|
95 // --------------------------------------------------------- |
|
96 // |
|
97 void CDpEscDetect::RunL() |
|
98 { |
|
99 OstTrace0( TRACE_NORMAL, CDPESCDETECT_RUNL, "CDpEscDetect::RunL" ); |
|
100 LOGM("CDpEscDetect::RunL"); |
|
101 |
|
102 if ( iTimerRunning ) |
|
103 { |
|
104 SendEscapeIndication(); |
|
105 iTimerRunning = EFalse; |
|
106 } |
|
107 // no else |
|
108 } |
|
109 |
|
110 // --------------------------------------------------------- |
|
111 // CDpEscDetect::RunError |
|
112 // Leave in RunL() is handled here. Error code is returned, |
|
113 // when error has occured. |
|
114 // --------------------------------------------------------- |
|
115 // |
|
116 TInt CDpEscDetect::RunError( |
|
117 TInt aError ) |
|
118 { |
|
119 OstTrace0( TRACE_NORMAL, CDPESCDETECT_RUNERROR, "CDpEscDetect::RunError" ); |
|
120 OstTrace1( TRACE_NORMAL, DUP1_CDPESCDETECT_RUNERROR, "CDpEscDetect::Error code: %d", aError ); |
|
121 |
|
122 LOGM1("CDpEscDetect::RunError, error code: %d", aError ); |
|
123 |
|
124 return aError; |
|
125 } |
|
126 |
|
127 // --------------------------------------------------------- |
|
128 // CDpEscDetect::SendEscapeIndication |
|
129 // This method sends the escape indication to DCS. |
|
130 // --------------------------------------------------------- |
|
131 // |
|
132 void CDpEscDetect::SendEscapeIndication() |
|
133 { |
|
134 OstTrace0( TRACE_NORMAL, CDPESCDETECT_SENDESCAPEINDICATION, "CDpEscDetect::SendEscapeIndication" ); |
|
135 LOGM(" CDpEscDetect::SendEscapeIndication"); |
|
136 |
|
137 TBuf8<SIZE_PNS_PEP_STATUS_IND> messageData; |
|
138 // Pipe Handle |
|
139 messageData.Append( iDataPort.Pif().PipeHandle() ); |
|
140 // PEP Type |
|
141 messageData.Append( PN_PEP_TYPE_COMM ); |
|
142 // Indication ID |
|
143 messageData.Append( PEP_COMM_IND_ID_ESCAPE ); |
|
144 // Filler bytes |
|
145 messageData.Append( KDpPadding ); |
|
146 messageData.Append( KDpPadding ); |
|
147 |
|
148 // Send message |
|
149 #ifdef _DEBUG |
|
150 TInt ret = |
|
151 #endif |
|
152 iDataPort.Mif().SendMessage( |
|
153 PN_PIPE, |
|
154 iDataPort.CreateTransactionId(), |
|
155 PNS_PEP_STATUS_IND, |
|
156 messageData ); |
|
157 |
|
158 LOG(" <== PNS_PEP_STATUS_IND sent (PEP_COMM_IND_ID_ESCAPE)"); |
|
159 OstTrace0( TRACE_NORMAL, DUP1_CDPESCDETECT_SENDESCAPEINDICATION, "CDpEscDetect:: <== PNS_PEP_STATUS_IND sent (PEP_COMM_IND_ID_ESCAPE)" ); |
|
160 |
|
161 #if defined(_DEBUG) |
|
162 if ( KErrNone != ret ) |
|
163 { |
|
164 LOG1("Error isc api send %d", ret ); |
|
165 OstTrace1( TRACE_NORMAL, DUP2_CDPESCDETECT_SENDESCAPEINDICATION, "CDpEscDetect:: Error isc api send %d", ret ); |
|
166 } |
|
167 // no else |
|
168 #endif |
|
169 |
|
170 iHowManyEscCharsReceived = 0; |
|
171 } |
|
172 |
|
173 // --------------------------------------------------------- |
|
174 // CDpEscDetect::DoCancel |
|
175 // This method cancels active request. |
|
176 // Status : Proposal |
|
177 // --------------------------------------------------------- |
|
178 // |
|
179 void CDpEscDetect::DoCancel() |
|
180 { |
|
181 OstTrace0( TRACE_NORMAL, CDPESCDETECT_DOCANCEL, "CDpEscDetect::DoCancel" ); |
|
182 LOGM(" CDpEscDetect::DoCancel"); |
|
183 |
|
184 if ( IsActive() ) |
|
185 { |
|
186 // do the required signaling |
|
187 TRequestStatus* status = &iStatus; |
|
188 User::RequestComplete( status, KErrCancel ); |
|
189 } |
|
190 // no else |
|
191 } |
|
192 |
|
193 // --------------------------------------------------------- |
|
194 // CDpEscDetect::Scan |
|
195 // Scans escape sequence. |
|
196 // |
|
197 // There must be time (>gt) between last received data and |
|
198 // first escape character. Escape characters must come with |
|
199 // time between them, which is smaller than gt. And finally |
|
200 // time between last escape character and next data must be |
|
201 // larger than gt. |
|
202 // |
|
203 // Example: |
|
204 // "DATADATADATA" t>gt "+" t<gt "+" t<gt "+" t>gt "DATADATA" |
|
205 // |
|
206 // So it is also applicable escape sequence if there comes |
|
207 // three escape character in same message and time between |
|
208 // previous and next message is large enough. |
|
209 // Status : Proposal |
|
210 // --------------------------------------------------------- |
|
211 // |
|
212 TInt CDpEscDetect::Scan( |
|
213 TPtr8& aDes ) |
|
214 { |
|
215 OstTrace0( TRACE_NORMAL, CDPESCDETECT_SCAN, "CDpEscDetect::Scan" ); |
|
216 LOGM(" CDpEscDetect::Scan"); |
|
217 |
|
218 TInt len( aDes.Length() ); |
|
219 TInt ret( KErrNone ); |
|
220 |
|
221 // New data, cancel timer |
|
222 if ( iTimerRunning ) |
|
223 { |
|
224 iEscTimer.Cancel(); |
|
225 iTimerRunning = EFalse; |
|
226 iHowManyEscCharsReceived = 0; |
|
227 iLatestIndex = 0; |
|
228 iTimeToPrevReceivedMessage.HomeTime(); |
|
229 ret = KErrNotFound; |
|
230 } |
|
231 else if ( ( 3 < len ) || ( 0 == len ) ) |
|
232 { |
|
233 // if the length of the string is greater than 3 then it can't hold |
|
234 // escape sequence because the time before the first (or time after the |
|
235 // last) escape char is not greater than gt. Actually the time can't be |
|
236 // calculated so it is assumed to be 0. |
|
237 iHowManyEscCharsReceived = 0; |
|
238 iLatestIndex = 0; |
|
239 iTimeToPrevReceivedMessage.HomeTime(); |
|
240 ret = KErrNotFound; |
|
241 } |
|
242 else |
|
243 { |
|
244 TInt ref( 0 ); |
|
245 TTime timeNow( 0 ); |
|
246 |
|
247 timeNow.HomeTime(); |
|
248 |
|
249 TUint8 escChar( iDataConfig.EscChar() ); |
|
250 TUint8 escTime( iDataConfig.EscTime() ); |
|
251 |
|
252 // Interval time in microseconds. EscTime is defined in 20 milliseconds so |
|
253 // it has to be calculated |
|
254 |
|
255 TTimeIntervalMicroSeconds intervalEscTime( |
|
256 escTime * KDpEscapeTimeMultiplier * KDpEscapeSecondAsMilliseconds ); |
|
257 |
|
258 TTimeIntervalMicroSeconds32 intervalEscTime32( |
|
259 escTime * KDpEscapeTimeMultiplier * KDpEscapeSecondAsMilliseconds ); |
|
260 |
|
261 // length is 3 or less |
|
262 for ( TInt i( 0 ); i < len; i++ ) |
|
263 { |
|
264 // non escape char was found => can't be escape sequence or even part of it. |
|
265 if ( aDes[i] != escChar ) |
|
266 { |
|
267 iHowManyEscCharsReceived = 0; |
|
268 iLatestIndex = 0; |
|
269 iTimeToPrevReceivedMessage.HomeTime(); |
|
270 ret = KErrNotFound; |
|
271 break; |
|
272 } |
|
273 // no else |
|
274 } |
|
275 |
|
276 if ( KErrNone == ret ) |
|
277 { |
|
278 // the whole string is full of escape chars. There can be one escape sequence |
|
279 // (3 escape chars) or |
|
280 // just part of the sequence (2 or 1 escape chars) |
|
281 for ( TInt j( 0 ); j < len; j++ ) |
|
282 { |
|
283 //if j>0 more than one "+" received in same message |
|
284 if ( timeNow < TTime( iTimeToPrevReceivedMessage + intervalEscTime ) |
|
285 || 0 < j ) |
|
286 { |
|
287 // smaller than gt |
|
288 iEscCharTimeArray[(iLatestIndex + 1) % 3] = ( - 1); |
|
289 iLatestIndex = ( iLatestIndex + 1 ) % 3; |
|
290 } |
|
291 else |
|
292 { |
|
293 // greater than gt |
|
294 iEscCharTimeArray[(iLatestIndex + 1) % 3] = 1; |
|
295 iLatestIndex = ( iLatestIndex + 1 ) % 3; |
|
296 } |
|
297 iHowManyEscCharsReceived++; |
|
298 } |
|
299 |
|
300 if ( KDpEscapeSeqLength == iHowManyEscCharsReceived ) |
|
301 { |
|
302 if ( CheckEscCharIntervals( iLatestIndex ) ) |
|
303 { |
|
304 if ( !IsActive() ) |
|
305 { |
|
306 iEscTimer.After( iStatus, intervalEscTime32 ); |
|
307 iTimerRunning = ETrue; |
|
308 |
|
309 SetActive(); |
|
310 } |
|
311 // no else |
|
312 |
|
313 ret = KErrCompletion; |
|
314 } |
|
315 else |
|
316 { |
|
317 iHowManyEscCharsReceived = 0; |
|
318 iLatestIndex = 0; |
|
319 iTimeToPrevReceivedMessage.HomeTime(); |
|
320 ret = KErrNotFound; |
|
321 } |
|
322 } |
|
323 else |
|
324 { |
|
325 if ( ( 1 == iHowManyEscCharsReceived ) || |
|
326 ( 2 == iHowManyEscCharsReceived ) ) |
|
327 { |
|
328 if ( 0 == iLatestIndex ) |
|
329 { |
|
330 ref = ( -1 ); |
|
331 } |
|
332 else if ( 1 == iLatestIndex ) |
|
333 { |
|
334 ref= 1; |
|
335 } |
|
336 else if ( 2 == iLatestIndex ) |
|
337 { |
|
338 ref = ( -1 ); |
|
339 } |
|
340 //no else |
|
341 |
|
342 if ( ( 3 > iLatestIndex ) && |
|
343 ( ( 1 == aDes.Length() ) || ( 2 == aDes.Length() ) ) ) |
|
344 { |
|
345 if ( iEscCharTimeArray[ iLatestIndex ] != ref ) |
|
346 { |
|
347 iHowManyEscCharsReceived = 0; |
|
348 iLatestIndex = 0; |
|
349 } |
|
350 // no else |
|
351 } |
|
352 // no else |
|
353 |
|
354 iTimeToPrevReceivedMessage.HomeTime(); |
|
355 } |
|
356 else |
|
357 { |
|
358 iTimeToPrevReceivedMessage.HomeTime(); |
|
359 } |
|
360 ret = KErrNotFound; |
|
361 } |
|
362 } |
|
363 //no else |
|
364 } |
|
365 |
|
366 return ret; |
|
367 } |
|
368 |
|
369 // --------------------------------------------------------- |
|
370 // CDpEscDetect::CheckEscCharIntervals |
|
371 // This method checks latest timing of escape characters. |
|
372 // --------------------------------------------------------- |
|
373 // |
|
374 TBool CDpEscDetect::CheckEscCharIntervals( |
|
375 const TInt aLatestIndex ) |
|
376 { |
|
377 OstTrace0( TRACE_NORMAL, CDPESCDETECT_CHECKESCCHARINTERVALS, "CDpEscDetect::CheckEscCharIntervals" ); |
|
378 LOGM(" CDpEscDetect::CheckEscCharIntervals"); |
|
379 |
|
380 TBool ret( EFalse ); |
|
381 |
|
382 if ( 3 > aLatestIndex ) |
|
383 { |
|
384 if ( 0 > iEscCharTimeArray[ aLatestIndex ] && |
|
385 0 < iEscCharTimeArray[ ( aLatestIndex + 1 ) % 3 ] && |
|
386 0 > iEscCharTimeArray[ ( aLatestIndex + 2 ) % 3 ] ) |
|
387 { |
|
388 ret = ETrue; |
|
389 } |
|
390 //no else |
|
391 } |
|
392 //no else |
|
393 |
|
394 return ret; |
|
395 } |
|
396 |
|
397 // OTHER EXPORTED FUNCTIONS |
|
398 // none |
|
399 |
|
400 // End of File |