|
1 // Copyright (c) 2002-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 a complete CSY for physical serial ports |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <cs_port.h> |
|
23 #include <d32comm.h> |
|
24 #include <c32comm.h> |
|
25 #include <e32hal.h> |
|
26 // new header file introduced in C32 V2, old ecuart had no header file |
|
27 #include "ECUART.H" |
|
28 #include <c32comm_internal.h> |
|
29 |
|
30 // This header import is new for C32 V2 but is not configured since then we don't need to configure all |
|
31 // the logging we've added to this file during V2. The ecuartlog header file when pre-processed for pre-V2 |
|
32 // will resolve all the logging to nothing since all its log macros for pre-V2 are defined empty. |
|
33 #include "ECUARTLOG.H" |
|
34 |
|
35 const TUint KCommLowUnit=0; //< lowest port unit number for this CSY (i.e. COMM::0) |
|
36 |
|
37 #if defined(__WINS__) |
|
38 const TUint KCommHighUnit=1; //< highest port unit number for this CSY (i.e. COMM::1) |
|
39 #else // _MARM_ |
|
40 const TUint KCommHighUnit=0; //< highest port unit number for this CSY (i.e. COMM::0) |
|
41 #endif |
|
42 |
|
43 const TUint KDefaultBufSize = 0x100; //< size of the Tx/Rx buffers used in CCommWriter and CCommReader |
|
44 |
|
45 _LIT(KSerialDescription, "Built in Serial ports"); //< CSY description returned by RCommServ::GetPortInfo |
|
46 #define SERIAL_NAME _S("COMM") //< name of prefix for each com port |
|
47 |
|
48 const TInt KReaderPriority=100; //< priority for the CCommReader active object |
|
49 const TInt KWriterPriority=50; //< priority for the CCommWriter active object |
|
50 const TInt KBreakerPriority=0; //< priority for the CCommBreaker active object |
|
51 const TInt KNotifyPriority=0; //< priority for CCommNotifyBase derived active objects |
|
52 |
|
53 |
|
54 //Security policy for a port. |
|
55 class TPortSecurityPolicy |
|
56 { |
|
57 public: |
|
58 //Port number which this policy will apply. |
|
59 TInt iPort; |
|
60 //Security policy. |
|
61 TStaticSecurityPolicy iPolicy; |
|
62 }; |
|
63 |
|
64 _LIT_SECURITY_POLICY_PASS(KDefaultPortPassPolicy); |
|
65 _LIT_SECURITY_POLICY_FAIL(KPortAlwaysFailPolicy); |
|
66 |
|
67 #define KPlaceholderPortNumber -1 //a place holder port number used to initiliase KExplicitPortSecurityPolicies when no other ports require a policy different than the default. |
|
68 |
|
69 //Define policy for ports which are different from default policy (KDefaultPortPolicy) here. |
|
70 //Default policy is EAlwaysPass but to provide example ports 0-1 are explicitly set to EAlwaysPass as well. |
|
71 //Port policies must only apply for port number 0-(KMaxUnits-1). |
|
72 //Add to this array for other ports that need policing with capabilities. |
|
73 const TUint KExplicitPortPoliciesCount = 0; //Count of the number of entries in KExplicitPortSecurityPolicies. Currently only a place holder entry exists so the count = 0. |
|
74 const struct TPortSecurityPolicy KExplicitPortSecurityPolicies[]= |
|
75 { |
|
76 {KPlaceholderPortNumber, _INIT_SECURITY_POLICY_FAIL} //this is a place holder entry which should be replaced with proper port policy when required to police a port with different capabiltiies to default policy. |
|
77 // {0, _INIT_SECURITY_POLICY_C1( ECapabilityCommDD)}, //Example showing explicitly setting a policy different than default for Port 0 |
|
78 // {1, _INIT_SECURITY_POLICY_C2( ECapabilityReadUserData, ECapabilityWriteUserData)} //Example showing explicitly setting a policy different than default for Port 1 |
|
79 }; |
|
80 |
|
81 |
|
82 // #define _DEBUG_CONSOLE_ |
|
83 |
|
84 #if defined(_DEBUG_CONSOLE_) |
|
85 #include <e32twin.h> |
|
86 class RDebugConsole : public RConsole |
|
87 { |
|
88 public: |
|
89 RDebugConsole(); |
|
90 public: |
|
91 void Printf(TRefByValue<const TDesC> aFmt,...); |
|
92 }; |
|
93 |
|
94 #define DEBUG_TRACE(m) m |
|
95 |
|
96 #else // (_DEBUG) |
|
97 |
|
98 // debug trace (disabled in Release builds) |
|
99 #define DEBUG_TRACE(m) |
|
100 // |
|
101 #endif |
|
102 |
|
103 // |
|
104 // CCommReader CCommWriter and CCommBreaker are active objects which wait on |
|
105 // completion from the serial channel for various actions. |
|
106 // |
|
107 class CHWPort; |
|
108 |
|
109 /** |
|
110 * base class for CCommReader and CCommWriter |
|
111 * |
|
112 */ |
|
113 class CCommReadWriteBase : public CActive |
|
114 { |
|
115 public: |
|
116 CCommReadWriteBase(TInt aPriority, CHWPort* aParent); |
|
117 ~CCommReadWriteBase(); |
|
118 TInt SetServerConfig(TCommServerConfig& aConfig); |
|
119 void GetServerConfig(TCommServerConfig& aConfig) const; |
|
120 void FreeMemory(); |
|
121 // set the role of this port unit @param aRole new role |
|
122 inline void SetRole(TCommRole aRole){iRole=aRole;}; |
|
123 protected: |
|
124 void SetBuffersL(); |
|
125 // return ETrue if partial buffering used |
|
126 TBool UsePartial() {return ((iBufFlags & KCommBufferPartial)==KCommBufferPartial);} |
|
127 protected: |
|
128 HBufC8* iBuffer; //< pointer to the Tx/Rx buffer |
|
129 TPtr8* iBuf; //< pointer to a TPtr8 that points to the current buffer |
|
130 TUint iBufFlags; //< contains buffer flags e.g for partial read/write |
|
131 TInt iBufSize; //< size of the Tx/Rx buffer |
|
132 TCommRole iRole; //< DTE or DCE role for this port unit |
|
133 CHWPort* iParent; //< pointer to the CHWPort object |
|
134 }; |
|
135 |
|
136 |
|
137 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_) |
|
138 class CCommDebugDumper : public CActive |
|
139 { |
|
140 public: |
|
141 static CCommDebugDumper* NewL(RDebugConsole &aConsole); |
|
142 virtual void RunL(); |
|
143 virtual void DoCancel(); |
|
144 CCommDebugDumper::~CCommDebugDumper(); |
|
145 // set the role of this port unit @param aRole new role |
|
146 inline void SetRole(TCommRole aRole){iRole=aRole;}; |
|
147 private: |
|
148 CCommDebugDumper(RDebugConsole &aConsole); |
|
149 private: |
|
150 TCommRole iRole; //< DTE or DCE role for this port unit |
|
151 RDebugConsole *iConsole; |
|
152 TConsoleKey iKeystroke; |
|
153 }; |
|
154 #endif |
|
155 |
|
156 |
|
157 /** |
|
158 * Active Comm port Reader |
|
159 * |
|
160 * This class is responsible for reading data from the physical |
|
161 * comm port. |
|
162 */ |
|
163 class CCommReader : public CCommReadWriteBase |
|
164 { |
|
165 public: |
|
166 static CCommReader* NewL(CHWPort* aParent); |
|
167 ~CCommReader(); |
|
168 // from CActive |
|
169 virtual void DoCancel(); |
|
170 virtual void RunL(); |
|
171 // |
|
172 void Read(const TAny* aClientBuffer, TInt aLength); |
|
173 void ReadCancel(); |
|
174 private: |
|
175 CCommReader(CHWPort* aParent); |
|
176 void InitL(); |
|
177 private: |
|
178 TUint iLength; //< number of bytes to read |
|
179 TAny* iClientBuffer; //< pointer to Client's buffer |
|
180 TUint iBufPos; //< position in Client's buffer to read into (write) |
|
181 TUint iBufActive; //< TRUE if partial buffering active |
|
182 TInt iBufOneOrMoreSize; //< buffer size of ReadOneOrMore method |
|
183 }; |
|
184 |
|
185 |
|
186 /** |
|
187 * Active Comm port Writer |
|
188 * |
|
189 * This class is responsible for writing data to the physical |
|
190 * comm port. |
|
191 */ |
|
192 class CCommWriter : public CCommReadWriteBase |
|
193 { |
|
194 public: |
|
195 static CCommWriter* NewL(CHWPort* aParent); |
|
196 ~CCommWriter(); |
|
197 // from CActive |
|
198 virtual void DoCancel(); |
|
199 virtual void RunL(); |
|
200 // |
|
201 void Write(const TAny* aClientBuffer, TInt aLength); |
|
202 void WriteCancel(); |
|
203 inline void NotificationEnable(); |
|
204 inline void NotificationDisable(); |
|
205 inline TBool IsNotificationEnabled(); |
|
206 private: |
|
207 CCommWriter(CHWPort* aParent); |
|
208 void InitL(); |
|
209 private: |
|
210 TUint iLength; //< number of bytes to write |
|
211 TAny* iClientBuffer; //< pointer to Client's buffer |
|
212 TUint iBufPos; //< position in Client's buffer to read from |
|
213 TUint iBufActive; //< TRUE if partial buffering active |
|
214 TBool iNotificationEnabled; //< true if notification is enabled |
|
215 }; |
|
216 |
|
217 |
|
218 |
|
219 /** |
|
220 * Active Comm port Breaker |
|
221 * |
|
222 * This class is responsible for handling breaks on the physical |
|
223 * comm port. |
|
224 */ |
|
225 class CCommBreaker : public CActive |
|
226 { |
|
227 public: |
|
228 static CCommBreaker * NewL(CHWPort* aParent); |
|
229 ~CCommBreaker(); |
|
230 // from CActive |
|
231 virtual void DoCancel(); |
|
232 virtual void RunL(); |
|
233 // |
|
234 void Break(TInt aTime); |
|
235 // set the role of this port unit @param aRole new role |
|
236 inline void SetRole(TCommRole aRole){iRole=aRole;}; |
|
237 private: |
|
238 CCommBreaker(CHWPort* aParent); |
|
239 private: |
|
240 TCommRole iRole; //< DTE or DCE role for this port unit |
|
241 CHWPort* iParent; //< pointer to the CHWPort object |
|
242 }; |
|
243 |
|
244 |
|
245 /** |
|
246 * Base class for Notifiers |
|
247 * |
|
248 */ |
|
249 class CCommNotifyBase : public CActive |
|
250 { |
|
251 public: |
|
252 // set the role of this port unit @param aRole new role |
|
253 inline void SetRole(TCommRole aRole){iRole=aRole;}; |
|
254 protected: |
|
255 CCommNotifyBase(CHWPort* aParent); |
|
256 ~CCommNotifyBase(); |
|
257 protected: |
|
258 TCommRole iRole; //< DTE or DCE role for this port unit |
|
259 CHWPort* iParent; //< pointer to the CHWPort object |
|
260 }; |
|
261 |
|
262 |
|
263 /** |
|
264 * This class is responsible for notifying the client when |
|
265 * the signal control lines are changing, including breaks. |
|
266 */ |
|
267 class CCommSignalNotifier : public CCommNotifyBase |
|
268 { |
|
269 public: |
|
270 CCommSignalNotifier(CHWPort* aParent); |
|
271 ~CCommSignalNotifier(); |
|
272 // from CActive |
|
273 virtual void DoCancel(); |
|
274 virtual void RunL(); |
|
275 // |
|
276 void Start(); |
|
277 void NotifySignal(TUint aSignalMask); |
|
278 void NotifySignalCancel(); |
|
279 void NotifyBreak(); |
|
280 void NotifyBreakCancel(); |
|
281 private: |
|
282 TUint iSignals; //< bitmask with the new signal after notification completed |
|
283 TUint iSignalMask; //< bitmask with the signals to be notified |
|
284 TInt iNotifyCount; //< increased when either NotifySignals or NotifyBreak is using this class |
|
285 //< decreased when RunL is called. Ensures that RComm::NotifyBreak will not |
|
286 //< interfere with operation of RComm::NotifySignalsChange |
|
287 }; |
|
288 |
|
289 |
|
290 /** |
|
291 * this class is responsible for notifying the client when |
|
292 * there are some incoming data available. |
|
293 */ |
|
294 class CCommAvailableDataNotifier : public CCommNotifyBase |
|
295 { |
|
296 public: |
|
297 CCommAvailableDataNotifier(CHWPort* aParent); |
|
298 ~CCommAvailableDataNotifier(); |
|
299 // from CActive |
|
300 virtual void DoCancel(); |
|
301 virtual void RunL(); |
|
302 // |
|
303 void Start(); |
|
304 }; |
|
305 |
|
306 |
|
307 /** |
|
308 * this class is responsible for notifying the client when |
|
309 * the flow control is changing. |
|
310 */ |
|
311 class CCommFlowControlChangeNotifier : public CCommNotifyBase |
|
312 { |
|
313 public: |
|
314 CCommFlowControlChangeNotifier(CHWPort* aParent); |
|
315 ~CCommFlowControlChangeNotifier(); |
|
316 // from CActive |
|
317 virtual void DoCancel(); |
|
318 virtual void RunL(); |
|
319 // |
|
320 void Start(); |
|
321 private: |
|
322 TFlowControl iFlowControl; //< current flow control settings |
|
323 }; |
|
324 |
|
325 |
|
326 /** |
|
327 * this class is responsible for notifying the client when |
|
328 * the configuration is changing. |
|
329 */ |
|
330 class CCommConfigChangeNotifier : public CCommNotifyBase |
|
331 { |
|
332 public: |
|
333 CCommConfigChangeNotifier(CHWPort* aParent); |
|
334 ~CCommConfigChangeNotifier(); |
|
335 void Start(); |
|
336 // from CActive |
|
337 virtual void DoCancel(); |
|
338 virtual void RunL(); |
|
339 private: |
|
340 TCommNotificationPckg iConfig; //< current configuration package |
|
341 }; |
|
342 |
|
343 |
|
344 /** |
|
345 * CPort is the object which interfaces to the commserver |
|
346 */ |
|
347 class CHWPort : public CPort |
|
348 { |
|
349 public: |
|
350 static CHWPort* NewL(TUint aUnit); |
|
351 private: |
|
352 CHWPort(); |
|
353 public: |
|
354 virtual void StartRead(const TAny* aClientBuffer,TInt aLength); |
|
355 virtual void ReadCancel(); |
|
356 virtual TInt QueryReceiveBuffer(TInt& aLength) const; |
|
357 virtual void ResetBuffers(TUint aFlags); |
|
358 virtual void StartWrite(const TAny* aClientBuffer,TInt aLength); |
|
359 virtual void WriteCancel(); |
|
360 virtual void Break(TInt aTime); |
|
361 virtual void BreakCancel(); |
|
362 virtual TInt GetConfig(TDes8& aDes) const; |
|
363 virtual TInt SetConfig(const TDesC8& aDes); |
|
364 virtual TInt SetServerConfig(const TDesC8& aDes); |
|
365 virtual TInt GetServerConfig(TDes8& aDes); |
|
366 virtual TInt GetCaps(TDes8& aDes); |
|
367 virtual TInt GetSignals(TUint& aSignals); |
|
368 virtual TInt SetSignalsToMark(TUint aSignals); |
|
369 virtual TInt SetSignalsToSpace(TUint aSignals); |
|
370 virtual TInt GetReceiveBufferLength(TInt& aLength) const; |
|
371 virtual TInt SetReceiveBufferLength(TInt aSignals); |
|
372 virtual void Destruct(); |
|
373 virtual void FreeMemory(); |
|
374 virtual void NotifySignalChange(TUint aSignalMask); |
|
375 virtual void NotifySignalChangeCancel(); |
|
376 virtual void NotifyConfigChange(); |
|
377 virtual void NotifyConfigChangeCancel(); |
|
378 virtual void NotifyFlowControlChange(); |
|
379 virtual void NotifyFlowControlChangeCancel(); |
|
380 virtual void NotifyBreak(); |
|
381 virtual void NotifyBreakCancel(); |
|
382 virtual void NotifyDataAvailable(); |
|
383 virtual void NotifyDataAvailableCancel(); |
|
384 virtual void NotifyOutputEmpty(); |
|
385 virtual void NotifyOutputEmptyCancel(); |
|
386 virtual TInt GetFlowControlStatus(TFlowControl& aFlowControl); |
|
387 virtual TInt GetRole(TCommRole& aRole); |
|
388 virtual TInt SetRole(TCommRole aRole); |
|
389 |
|
390 virtual ~CHWPort(); |
|
391 #if defined (_DEBUG_DEVCOMM) |
|
392 virtual void DoDumpDebugInfo(const RMessage2 &aMessage); |
|
393 #endif |
|
394 RBusDevComm& DTEPort(); |
|
395 RBusDevCommDCE& DCEPort(); |
|
396 private: |
|
397 CCommReader* iReader; //< pointer to the Active Reader |
|
398 CCommWriter* iWriter; //< pointer to the Active Writer |
|
399 CCommBreaker* iBreaker; //< pointer to the Active Breaker |
|
400 CCommSignalNotifier* iSignalNotifier; //< pointer to the Active Signal Notifier |
|
401 CCommAvailableDataNotifier* iDataAvailableNotifier; //< pointer to the Active Data available notifier |
|
402 CCommFlowControlChangeNotifier* iFlowControlChangeNotifier; //< pointer to the Active Flow Control notifier |
|
403 CCommConfigChangeNotifier* iConfigChangeNotifier; //< pointer to the Active Config Change notifier |
|
404 |
|
405 RBusDevComm iPort; //< interface to the logical Comm port device (DTE role) |
|
406 RBusDevCommDCE iPortDCE; //< interface to the logical Comm port device (DCE role) |
|
407 TCommRole iRole; //< DTE or DCE role for this port unit |
|
408 TUint iPortName; //< contains the port unit number (i.e. 0 for COMM::0) |
|
409 TBool iEarlyWriteCompletion; //< ETrue if early write completion enabled |
|
410 #if defined (_DEBUG_CONSOLE_) |
|
411 #if defined (_DEBUG_DEVCOMM) |
|
412 CCommDebugDumper *iDumper; |
|
413 #endif |
|
414 public: |
|
415 RDebugConsole iConsole; |
|
416 #endif |
|
417 }; |
|
418 |
|
419 |
|
420 /** |
|
421 * "Entry point object" makes the objects which do the work |
|
422 */ |
|
423 class CHWPortFactory : public CSerial |
|
424 { |
|
425 public: |
|
426 CHWPortFactory(); |
|
427 virtual CPort* NewPortL(const TUint aUnit); |
|
428 virtual void Info(TSerialInfo &aSerialInfo); |
|
429 |
|
430 public: //from CSerial |
|
431 TSecurityPolicy PortPlatSecCapability(TUint aPort) const; |
|
432 }; |
|
433 |
|
434 |
|
435 /** |
|
436 * this class handles the 'Read one or more' method |
|
437 * for ports with role DTE |
|
438 */ |
|
439 class RMaxComm : public RBusDevComm |
|
440 { |
|
441 public: |
|
442 static void ReadOneOrMore(RBusDevComm& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen); |
|
443 }; |
|
444 |
|
445 |
|
446 void RMaxComm::ReadOneOrMore(RBusDevComm& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen) |
|
447 /** |
|
448 * reads one or more bytes from the physical DTE com port |
|
449 * |
|
450 * @param aComm handle to the logical com port device |
|
451 * @param aStatus handle for asyncronous communications |
|
452 * @param aDes buffer to be read into |
|
453 * @param aLen max number of bytes to read |
|
454 */ |
|
455 { |
|
456 LOGECUART2(_L8("RMaxComm::ReadOneOrMore(), (max. bytes to read) aLen = %d"), aLen); |
|
457 RMaxComm& r = (RMaxComm&)aComm; |
|
458 aLen = -aLen; // Note: negative length here means ReadOneOrMore |
|
459 // see RComm::ReadOneOrMore in CC_CLI.CPP |
|
460 r.DoRequest(ERequestRead, aStatus, &aDes, &aLen); |
|
461 } |
|
462 |
|
463 |
|
464 /** |
|
465 * this class handles the 'Read one or more' method |
|
466 * for ports with role DCE |
|
467 */ |
|
468 class RMaxCommDCE : public RBusDevCommDCE |
|
469 { |
|
470 public: |
|
471 static void ReadOneOrMore(RBusDevCommDCE& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen); |
|
472 }; |
|
473 |
|
474 |
|
475 void RMaxCommDCE::ReadOneOrMore(RBusDevCommDCE& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen) |
|
476 /** |
|
477 * reads one or more bytes from the physical DCE com port |
|
478 * |
|
479 * @param aComm handle to the logical com port device |
|
480 * @param aStatus handle for asyncronous communications |
|
481 * @param aDes buffer to be read into |
|
482 * @param aLen max number of bytes to read |
|
483 */ |
|
484 { |
|
485 LOGECUART2(_L8("RMaxCommDCE::ReadOneOrMore(), (max. bytes to read) aLen = %d"), aLen); |
|
486 RMaxCommDCE& r = (RMaxCommDCE&)aComm; |
|
487 aLen = -aLen; // Note: negative length here means ReadOneOrMore |
|
488 // see RComm::ReadOneOrMore in CC_CLI.CPP |
|
489 r.DoRequest(ERequestRead, aStatus, &aDes, &aLen); |
|
490 } |
|
491 |
|
492 |
|
493 |
|
494 |
|
495 void Fault(TCommFault aFault) |
|
496 /** |
|
497 * Panic the comm module (us) |
|
498 * |
|
499 * @param aFault Panic code |
|
500 */ |
|
501 { |
|
502 LOGECUART3(_L8("Fault(), (TCommFault) aFault = %d (%S)"), aFault, &TECUARTLOG::CommFaultStr(aFault)); |
|
503 _LIT(KCsyPanicCategory, "CHWComm" ); |
|
504 User::Panic(KCsyPanicCategory, aFault); |
|
505 } |
|
506 |
|
507 |
|
508 // |
|
509 // implementation of CCommReadWriteBase |
|
510 // |
|
511 |
|
512 |
|
513 CCommReadWriteBase::CCommReadWriteBase(TInt aPriority, CHWPort* aParent) |
|
514 /** |
|
515 * C'tor |
|
516 * |
|
517 * @param aPriority priority of the Active Object |
|
518 * @param aParent pointer to the owner, the CHWPort object |
|
519 */ |
|
520 :CActive(aPriority) |
|
521 ,iBufSize(KDefaultBufSize) |
|
522 ,iRole(ECommRoleDTE) |
|
523 ,iParent(aParent) |
|
524 { |
|
525 LOGECUART1(_L8("CCommReadWriteBase::CCommReadWriteBase()")); |
|
526 } |
|
527 |
|
528 |
|
529 CCommReadWriteBase::~CCommReadWriteBase() |
|
530 /** |
|
531 * D'tor |
|
532 */ |
|
533 { |
|
534 LOGECUART1(_L8("CCommReadWriteBase::~CCommReadWriteBase()")); |
|
535 delete iBuffer; |
|
536 delete iBuf; |
|
537 } |
|
538 |
|
539 |
|
540 TInt CCommReadWriteBase::SetServerConfig(TCommServerConfig& aConfig) |
|
541 /** |
|
542 * Set the port to use partial reads/writes or the bungee buffer |
|
543 * |
|
544 * @param aConfig new Comm server configurations |
|
545 * @return TInt error code. KErrNone for sucess |
|
546 */ |
|
547 { |
|
548 LOGECUART1(_L8("CCommReadWriteBase::SetServerConfig()")); |
|
549 TCommServerConfigV01& c = aConfig(); |
|
550 TInt res = KErrNone; |
|
551 if (c.iBufFlags & KCommBufferPartial) |
|
552 { |
|
553 TInt bufSave = iBufSize; |
|
554 iBufSize = c.iBufSize; |
|
555 TRAP(res, SetBuffersL();) |
|
556 if (res==KErrNone) |
|
557 iBufFlags = c.iBufFlags; |
|
558 else |
|
559 iBufSize = bufSave; |
|
560 } |
|
561 return res; |
|
562 } |
|
563 |
|
564 |
|
565 void CCommReadWriteBase::GetServerConfig(TCommServerConfig& aConfig) const |
|
566 /** |
|
567 * read the comm server buffer config from the reader |
|
568 * |
|
569 * @param aConfig reference to Comm server configurations to be changed |
|
570 */ |
|
571 { |
|
572 LOGECUART1(_L8("CCommReadWriteBase::GetServerConfig()")); |
|
573 aConfig().iBufFlags = iBufFlags; |
|
574 aConfig().iBufSize = iBufSize; |
|
575 } |
|
576 |
|
577 |
|
578 void CCommReadWriteBase::FreeMemory() |
|
579 /** |
|
580 * Reduce allocation levels by order of the comm server |
|
581 */ |
|
582 { |
|
583 LOGECUART1(_L8("CCommReadWriteBase::FreeMemory()")); |
|
584 TRAP_IGNORE(SetBuffersL()); |
|
585 } |
|
586 |
|
587 |
|
588 void CCommReadWriteBase::SetBuffersL() |
|
589 /** |
|
590 * Attempt to free up some memory |
|
591 * |
|
592 * @leave This function may leave in case of OOM |
|
593 */ |
|
594 { |
|
595 LOGECUART1(_L8("CCommReadWriteBase::SetBuffersL()")); |
|
596 if (!IsActive()) |
|
597 { |
|
598 TInt allocLen = Align4(iBufSize); |
|
599 delete iBuffer; |
|
600 delete iBuf; |
|
601 iBuf = NULL; // set to NULL, in case new leaves |
|
602 iBuffer = NULL; |
|
603 iBuffer = HBufC8::NewMaxL(allocLen); |
|
604 iBuf = new (ELeave) TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen); |
|
605 } |
|
606 } |
|
607 |
|
608 |
|
609 // |
|
610 // implementation of CCommReader |
|
611 // |
|
612 |
|
613 |
|
614 CCommReader* CCommReader::NewL(CHWPort* aParent) |
|
615 /** |
|
616 * static function, create and init a comm reader active object |
|
617 * |
|
618 * @param aParent pointer to the CHWPort object |
|
619 * @return a newly created CCommReader object |
|
620 */ |
|
621 { |
|
622 LOGECUART1(_L8("CCommReader::NewL()")); |
|
623 CCommReader* c = new (ELeave) CCommReader(aParent); |
|
624 CleanupStack::PushL(c); |
|
625 c->InitL(); |
|
626 CleanupStack::Pop(); |
|
627 CActiveScheduler::Add(c); |
|
628 return c; |
|
629 } |
|
630 |
|
631 |
|
632 CCommReader::~CCommReader() |
|
633 /** |
|
634 * D'tor |
|
635 */ |
|
636 { |
|
637 LOGECUART1(_L8("CCommReader::~CCommReader()")); |
|
638 Cancel(); |
|
639 } |
|
640 |
|
641 |
|
642 void CCommReader::DoCancel() |
|
643 /** |
|
644 * Cancel an outstanding request |
|
645 */ |
|
646 { |
|
647 LOGECUART1(_L8("CCommReader::DoCancel()")); |
|
648 __ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding)); |
|
649 if (iRole==ECommRoleDTE) |
|
650 iParent->DTEPort().ReadCancel(); |
|
651 else |
|
652 iParent->DCEPort().ReadCancel(); |
|
653 } |
|
654 |
|
655 |
|
656 void CCommReader::RunL() |
|
657 /** |
|
658 * Read request has completed |
|
659 */ |
|
660 { |
|
661 LOGECUART2(_L8("CCommReader::RunL(), iStatus = %d"), iStatus.Int()); |
|
662 DEBUG_TRACE((iParent->iConsole.Printf(_L("CCommReader::RunL\n\r")))); |
|
663 |
|
664 TInt len = iLength; |
|
665 |
|
666 DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to 0x%x+%x\n\r"),iBuf->Size(),iPendingRead.Ptr0(),iBufPos))); |
|
667 iParent->IPCWrite(iClientBuffer,*iBuf, iBufPos); |
|
668 |
|
669 if (iBufActive) |
|
670 { |
|
671 iBufPos+=iBufSize; |
|
672 TInt left; |
|
673 |
|
674 if (iBufOneOrMoreSize) |
|
675 { |
|
676 // |
|
677 // We are in ReadOneOrMore HELL |
|
678 // |
|
679 left=iBufOneOrMoreSize-iBufPos; |
|
680 if (left<iBufSize) |
|
681 { |
|
682 len=left; |
|
683 iBufActive=EFalse; |
|
684 } |
|
685 else |
|
686 len=iBufSize; |
|
687 } |
|
688 else |
|
689 { |
|
690 left=len-iBufPos; |
|
691 if (left<iBufSize) |
|
692 { |
|
693 len=left; |
|
694 iBufActive=EFalse; |
|
695 } |
|
696 else |
|
697 len=iBufSize; |
|
698 } |
|
699 // |
|
700 // Next block |
|
701 // |
|
702 iBuf->SetLength(0); |
|
703 |
|
704 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
705 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
706 if (iRole==ECommRoleDTE) |
|
707 iParent->DTEPort().Read(iStatus,*iBuf,len); |
|
708 else |
|
709 iParent->DCEPort().Read(iStatus,*iBuf,len);; |
|
710 SetActive(); |
|
711 return; |
|
712 } |
|
713 LOGECUART1(_L8("Read Completed")); |
|
714 DEBUG_TRACE((iParent->iConsole.Write(_L("readCompleted \n\r")))); |
|
715 |
|
716 iParent->ReadCompleted(iStatus.Int()); |
|
717 } |
|
718 |
|
719 |
|
720 |
|
721 void CCommReader::Read(const TAny* aClientBuffer, TInt aLength) |
|
722 /** |
|
723 * resize the buffer and queue a read |
|
724 * |
|
725 * @param aClientBuffer pointer to the Client's buffer |
|
726 * @param aLength number of bytes to read |
|
727 */ |
|
728 { |
|
729 LOGECUART2(_L8("CCommReader::Read(), aLength (number of Bytes to read) = %d"), aLength); |
|
730 iClientBuffer=(TAny*)aClientBuffer; |
|
731 iLength=aLength; |
|
732 TInt& len=aLength; |
|
733 if (len==0) |
|
734 { |
|
735 iParent->ReadCompleted(KErrNone); |
|
736 return; |
|
737 } |
|
738 |
|
739 TBool doOneOrMore=EFalse; |
|
740 if (len<0) |
|
741 { |
|
742 doOneOrMore=ETrue; |
|
743 len=-len; |
|
744 } |
|
745 |
|
746 |
|
747 if ((UsePartial() && len>iBufSize) || (UsePartial()==EFalse && len>iBuf->MaxLength())) |
|
748 { |
|
749 if (UsePartial()==EFalse) |
|
750 { |
|
751 TInt allocLen=Align4(len); |
|
752 |
|
753 TRAPD(res, iBuffer=iBuffer->ReAllocL(allocLen)); |
|
754 if(res != KErrNone) |
|
755 { |
|
756 delete iBuffer; |
|
757 iBuffer=NULL; |
|
758 LOGECUART1(_L8("Read Completed")); |
|
759 DEBUG_TRACE((iParent->iConsole.Write(_L("readCompleted \n\r")))); |
|
760 iParent->ReadCompleted(res); |
|
761 return; |
|
762 } |
|
763 |
|
764 delete iBuf; |
|
765 iBuf=NULL; |
|
766 iBuf=new TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen); |
|
767 if (iBuf == NULL) |
|
768 { |
|
769 iParent->ReadCompleted(KErrNoMemory); |
|
770 return; |
|
771 } |
|
772 } |
|
773 else |
|
774 { |
|
775 iBufActive=ETrue; |
|
776 iBufPos=0; |
|
777 len=iBufSize; |
|
778 } |
|
779 } |
|
780 |
|
781 |
|
782 iBuf->SetLength(0); |
|
783 if (iBufActive) |
|
784 { |
|
785 if (doOneOrMore) |
|
786 { |
|
787 if (iRole==ECommRoleDTE) |
|
788 { |
|
789 RBusDevComm port = iParent->DTEPort(); |
|
790 iBufOneOrMoreSize = port.QueryReceiveBuffer(); |
|
791 if (iBufOneOrMoreSize < iBuffer->Length()) |
|
792 { |
|
793 RMaxComm::ReadOneOrMore(port, iStatus, *iBuf, len); |
|
794 iBufActive = EFalse; // Not needed |
|
795 } |
|
796 else |
|
797 { |
|
798 // Just do normal reads on it |
|
799 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
800 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
801 port.Read(iStatus,*iBuf,len); |
|
802 } |
|
803 } |
|
804 else |
|
805 { |
|
806 RBusDevCommDCE port = iParent->DCEPort(); |
|
807 iBufOneOrMoreSize=port.QueryReceiveBuffer(); |
|
808 if (iBufOneOrMoreSize<iBuffer->Length()) |
|
809 { |
|
810 RMaxCommDCE::ReadOneOrMore(port,iStatus,*iBuf,len); |
|
811 iBufActive=EFalse; // Not needed |
|
812 } |
|
813 else |
|
814 { |
|
815 // Just do normal reads on it |
|
816 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
817 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
818 port.Read(iStatus,*iBuf,len); |
|
819 } |
|
820 } |
|
821 } |
|
822 else |
|
823 { |
|
824 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
825 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
826 if (iRole==ECommRoleDTE) |
|
827 iParent->DTEPort().Read(iStatus,*iBuf,len); |
|
828 else |
|
829 iParent->DCEPort().Read(iStatus,*iBuf,len); |
|
830 } |
|
831 } |
|
832 else |
|
833 { |
|
834 if (iRole==ECommRoleDTE) |
|
835 { |
|
836 RBusDevComm port = iParent->DTEPort(); |
|
837 if (doOneOrMore) |
|
838 RMaxComm::ReadOneOrMore(port,iStatus,*iBuf,len); |
|
839 else |
|
840 { |
|
841 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
842 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
843 port.Read(iStatus,*iBuf,len); |
|
844 } |
|
845 } |
|
846 else |
|
847 { |
|
848 RBusDevCommDCE port = iParent->DCEPort(); |
|
849 if (doOneOrMore) |
|
850 RMaxCommDCE::ReadOneOrMore(port,iStatus,*iBuf,len); |
|
851 else |
|
852 { |
|
853 LOGECUART2(_L8("Read %d bytes from serial"), len); |
|
854 DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len))); |
|
855 port.Read(iStatus,*iBuf,len); |
|
856 } |
|
857 } |
|
858 } |
|
859 |
|
860 SetActive(); |
|
861 } |
|
862 |
|
863 |
|
864 void CCommReader::ReadCancel() |
|
865 /** |
|
866 * Cancel a read |
|
867 */ |
|
868 { |
|
869 LOGECUART1(_L8("CCommReader::ReadCancel()")); |
|
870 if(IsActive()) |
|
871 { |
|
872 Cancel(); |
|
873 if(iBuf->Length()) // Copy any data to client |
|
874 iParent->IPCWrite(iClientBuffer, *iBuf, iBufPos); // todo check return value ? |
|
875 } |
|
876 } |
|
877 |
|
878 |
|
879 CCommReader::CCommReader(CHWPort* aParent) |
|
880 /** |
|
881 * C'tor - pass priority up to CActive |
|
882 */ |
|
883 :CCommReadWriteBase(KReaderPriority, aParent) |
|
884 { |
|
885 } |
|
886 |
|
887 |
|
888 void CCommReader::InitL() |
|
889 /** |
|
890 * Allocate buffers |
|
891 */ |
|
892 { |
|
893 SetBuffersL(); |
|
894 } |
|
895 |
|
896 |
|
897 // |
|
898 // implementation of CCommWriter |
|
899 // |
|
900 |
|
901 |
|
902 CCommWriter* CCommWriter::NewL(CHWPort* aParent) |
|
903 /** |
|
904 * static function, create and init a comm writer active object |
|
905 * |
|
906 * @param aParent pointer to the CHWPort object |
|
907 * @return a newly created CCommWriter object |
|
908 */ |
|
909 { |
|
910 LOGECUART1(_L8("CCommWriter::NewL()")); |
|
911 CCommWriter* c = new (ELeave) CCommWriter(aParent); |
|
912 CleanupStack::PushL(c); |
|
913 c->InitL(); |
|
914 CleanupStack::Pop(); |
|
915 CActiveScheduler::Add(c); |
|
916 return c; |
|
917 } |
|
918 |
|
919 |
|
920 CCommWriter::~CCommWriter() |
|
921 /** |
|
922 * D'tor |
|
923 */ |
|
924 { |
|
925 LOGECUART1(_L8("CCommWriter::~CCommWriter()")); |
|
926 Cancel(); |
|
927 } |
|
928 |
|
929 |
|
930 void CCommWriter::DoCancel() |
|
931 /** |
|
932 * Cancel a pending write |
|
933 */ |
|
934 { |
|
935 LOGECUART1(_L8("CCommWriter::DoCancel()")); |
|
936 __ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding)); |
|
937 if (iRole==ECommRoleDTE) |
|
938 iParent->DTEPort().WriteCancel(); |
|
939 else |
|
940 iParent->DCEPort().WriteCancel(); |
|
941 } |
|
942 |
|
943 |
|
944 void CCommWriter::RunL() |
|
945 /** |
|
946 * a write has completed |
|
947 */ |
|
948 { |
|
949 LOGECUART2(_L8("CCommWriter::RunL(), iStatus = %d"), iStatus.Int()); |
|
950 DEBUG_TRACE((iParent->iConsole.Write(_L("CCommWriter::RunL\n\r")))); |
|
951 if (iBufActive) |
|
952 { |
|
953 // |
|
954 // Did the last chunk get through OK ? |
|
955 // |
|
956 if (iStatus.Int() != KErrNone) |
|
957 { |
|
958 iBufActive=EFalse; |
|
959 iBufPos=0; |
|
960 iParent->WriteCompleted(iStatus.Int()); |
|
961 return; |
|
962 } |
|
963 |
|
964 TInt len=iLength; |
|
965 TInt left=len-iBufPos; |
|
966 // |
|
967 // Read the next chunk into our buffer |
|
968 // |
|
969 DEBUG_TRACE((iParent->iConsole.Printf(_L("Read %x bytes from 0x%x+%x\n\r"),iBuf->Size(),iPendingWrite.Ptr0(),iBufPos))); |
|
970 TInt res; |
|
971 if((res=iParent->IPCRead(iClientBuffer,*iBuf, iBufPos))!=KErrNone) |
|
972 { |
|
973 iParent->WriteCompleted(res); |
|
974 return; |
|
975 } |
|
976 // |
|
977 // Still need buffering ? |
|
978 // |
|
979 if (left<iBufSize) |
|
980 { |
|
981 iBufActive=EFalse; |
|
982 iBufPos=0; |
|
983 len=left; |
|
984 } |
|
985 else |
|
986 { |
|
987 iBufPos+=iBufSize; |
|
988 len=iBufSize; |
|
989 } |
|
990 iBuf->SetLength(len); |
|
991 LOGECUART2(_L8("Write %x bytes to serial"), len); |
|
992 DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to serial\n\r"),len))); |
|
993 if (iRole==ECommRoleDTE) |
|
994 iParent->DTEPort().Write(iStatus,*iBuf,len); |
|
995 else |
|
996 iParent->DCEPort().Write(iStatus,*iBuf,len); |
|
997 SetActive(); |
|
998 return; |
|
999 } |
|
1000 LOGECUART1(_L8("Write Completed")); |
|
1001 DEBUG_TRACE((iParent->iConsole.Write(_L("writeCompleted \n\r")))); |
|
1002 |
|
1003 if (iNotificationEnabled) |
|
1004 { |
|
1005 iParent->NotifyOutputEmptyCompleted(iStatus.Int()); |
|
1006 iNotificationEnabled=EFalse; |
|
1007 } |
|
1008 iParent->WriteCompleted(iStatus.Int()); |
|
1009 } |
|
1010 |
|
1011 |
|
1012 void CCommWriter::Write(const TAny* aClientBuffer, TInt aLength) |
|
1013 /** |
|
1014 * resize the buffer and queue a write |
|
1015 * |
|
1016 * @param aClientBuffer pointer to the Client's buffer |
|
1017 * @param aLength number of bytes to write |
|
1018 */ |
|
1019 { |
|
1020 LOGECUART2(_L8("CCommWriter::Write(), aLength = %d"), aLength); |
|
1021 iClientBuffer = (TAny*)aClientBuffer; |
|
1022 iLength = aLength; |
|
1023 |
|
1024 TInt& len = aLength; |
|
1025 if (len==0) |
|
1026 { |
|
1027 if (iRole==ECommRoleDTE) |
|
1028 iParent->DTEPort().Write(iStatus, TPtrC8(NULL,0)); |
|
1029 else |
|
1030 iParent->DCEPort().Write(iStatus, TPtrC8(NULL,0)); |
|
1031 } |
|
1032 else |
|
1033 { |
|
1034 if ((UsePartial() && len>iBufSize) || (UsePartial()==EFalse && len>iBuf->MaxLength())) |
|
1035 { |
|
1036 if (UsePartial()==EFalse) |
|
1037 { |
|
1038 TInt allocLen=Align4(len); |
|
1039 |
|
1040 TRAPD(res, iBuffer=iBuffer->ReAllocL(allocLen)); |
|
1041 if(res!=KErrNone) |
|
1042 { |
|
1043 delete iBuffer; |
|
1044 iBuffer=NULL; |
|
1045 iParent->WriteCompleted(res); |
|
1046 return; |
|
1047 } |
|
1048 |
|
1049 delete iBuf; |
|
1050 iBuf=NULL; |
|
1051 iBuf = new TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen); |
|
1052 if (iBuf == NULL) |
|
1053 { |
|
1054 iParent->WriteCompleted(KErrNoMemory); |
|
1055 return; |
|
1056 } |
|
1057 } |
|
1058 else |
|
1059 { |
|
1060 iBufActive=ETrue; |
|
1061 len=iBufSize; |
|
1062 iBufPos=len; |
|
1063 } |
|
1064 } |
|
1065 |
|
1066 iBuf->SetLength(len); |
|
1067 LOGECUART4(_L8("Read %d bytes from 0x%x+%x"), iBuf->Size(), aClientBuffer, iBufPos); |
|
1068 DEBUG_TRACE((iParent->iConsole.Printf(_L("Read %x bytes from 0x%x+%x\n\r"),iBuf->Size(),aClientBuffer,iBufPos))); |
|
1069 TInt res; |
|
1070 if((res=iParent->IPCRead(aClientBuffer,*iBuf))!=KErrNone) |
|
1071 { |
|
1072 iParent->WriteCompleted(res); |
|
1073 return; |
|
1074 } |
|
1075 LOGECUART2(_L8("Write %x bytes to serial"), len); |
|
1076 DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to serial\n\r"),len))); |
|
1077 |
|
1078 if (iRole==ECommRoleDTE) |
|
1079 iParent->DTEPort().Write(iStatus, *iBuf, len); |
|
1080 else |
|
1081 iParent->DCEPort().Write(iStatus, *iBuf, len); |
|
1082 } |
|
1083 |
|
1084 SetActive(); |
|
1085 } |
|
1086 |
|
1087 |
|
1088 void CCommWriter::WriteCancel() |
|
1089 /** |
|
1090 * Cancel a write |
|
1091 */ |
|
1092 { |
|
1093 LOGECUART1(_L8("CCommWriter::WriteCancel()")); |
|
1094 Cancel(); |
|
1095 } |
|
1096 |
|
1097 |
|
1098 void CCommWriter::NotificationEnable() |
|
1099 /** |
|
1100 * enables notification when output buffer is empty. |
|
1101 * activated when a clients calls RComm::NotifyOutputEmpty |
|
1102 */ |
|
1103 { |
|
1104 LOGECUART1(_L8("CCommWriter::NotificationEnable()")); |
|
1105 iNotificationEnabled = ETrue; |
|
1106 } |
|
1107 |
|
1108 |
|
1109 void CCommWriter::NotificationDisable() |
|
1110 /** |
|
1111 * disables notification when output buffer is empty |
|
1112 * deactivated when a clients calls RComm::NotifyOutputEmptyCancel |
|
1113 */ |
|
1114 { |
|
1115 LOGECUART1(_L8("CCommWriter::NotificationDisable()")); |
|
1116 iNotificationEnabled = EFalse; |
|
1117 } |
|
1118 |
|
1119 |
|
1120 TBool CCommWriter::IsNotificationEnabled() |
|
1121 /** |
|
1122 * returns ETrue if notification on output buffer empty is enabled |
|
1123 */ |
|
1124 { |
|
1125 LOGECUART2(_L8("CCommWriter::IsNotificationEnabled(), iNotificationEnabled = %d"), iNotificationEnabled); |
|
1126 return iNotificationEnabled; |
|
1127 } |
|
1128 |
|
1129 |
|
1130 CCommWriter::CCommWriter(CHWPort* aParent) |
|
1131 /** |
|
1132 * C'Tor |
|
1133 */ |
|
1134 :CCommReadWriteBase(KWriterPriority, aParent) |
|
1135 { |
|
1136 } |
|
1137 |
|
1138 |
|
1139 void CCommWriter::InitL() |
|
1140 /** |
|
1141 * Allocate buffers |
|
1142 */ |
|
1143 { |
|
1144 SetBuffersL(); |
|
1145 } |
|
1146 |
|
1147 |
|
1148 // |
|
1149 // implementation of CCommBreaker |
|
1150 // |
|
1151 |
|
1152 |
|
1153 CCommBreaker* CCommBreaker::NewL(CHWPort* aParent) |
|
1154 /** |
|
1155 * static function, create a comm breaker object |
|
1156 * |
|
1157 * @param aParent pointer to the CHWPort object |
|
1158 * @return a newly created CCommBreaker object |
|
1159 */ |
|
1160 { |
|
1161 LOGECUART1(_L8("CCommBreaker::NewL()")); |
|
1162 CCommBreaker* c = new (ELeave) CCommBreaker(aParent); |
|
1163 CActiveScheduler::Add(c); |
|
1164 return c; |
|
1165 } |
|
1166 |
|
1167 |
|
1168 CCommBreaker::~CCommBreaker() |
|
1169 /** |
|
1170 * D'Tor |
|
1171 */ |
|
1172 { |
|
1173 LOGECUART1(_L8("CCommBreaker::~CCommBreaker()")); |
|
1174 Cancel(); |
|
1175 } |
|
1176 |
|
1177 |
|
1178 void CCommBreaker::DoCancel() |
|
1179 /** |
|
1180 * Cancel a pending break. |
|
1181 */ |
|
1182 { |
|
1183 LOGECUART1(_L8("CCommBreaker::DoCancel()")); |
|
1184 __ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding)); |
|
1185 if (iRole==ECommRoleDTE) |
|
1186 iParent->DTEPort().BreakCancel(); |
|
1187 else |
|
1188 iParent->DCEPort().BreakCancel(); |
|
1189 } |
|
1190 |
|
1191 |
|
1192 void CCommBreaker::RunL() |
|
1193 /** |
|
1194 * a break has completed. forward the news to the parent |
|
1195 */ |
|
1196 { |
|
1197 TInt status = iStatus.Int(); |
|
1198 LOGECUART2(_L8("CCommBreaker::RunL(), iStatus = %d"), status); |
|
1199 iParent->BreakCompleted(status); |
|
1200 } |
|
1201 |
|
1202 |
|
1203 void CCommBreaker::Break(TInt aTime) |
|
1204 /** |
|
1205 * Queue a break operation |
|
1206 * |
|
1207 * @param aTime Length of break in micro seconds |
|
1208 */ |
|
1209 { |
|
1210 LOGECUART2(_L8("CCommBreaker::Break(), aTime (length of break in micro secs) = %d"), aTime); |
|
1211 if (aTime==0) |
|
1212 { |
|
1213 iParent->BreakCompleted(KErrNone); |
|
1214 } |
|
1215 if (iRole==ECommRoleDTE) |
|
1216 iParent->DTEPort().Break(iStatus, aTime); |
|
1217 else |
|
1218 iParent->DCEPort().Break(iStatus, aTime); |
|
1219 SetActive(); |
|
1220 } |
|
1221 |
|
1222 |
|
1223 CCommBreaker::CCommBreaker(CHWPort* aParent) |
|
1224 /** |
|
1225 * C'Tor |
|
1226 * |
|
1227 * @param aParent pointer to the CHWPort object |
|
1228 */ |
|
1229 :CActive(KBreakerPriority) |
|
1230 ,iRole(ECommRoleDTE) |
|
1231 ,iParent(aParent) |
|
1232 { |
|
1233 } |
|
1234 |
|
1235 |
|
1236 // |
|
1237 // implementation of CCommNotifyBase |
|
1238 // |
|
1239 |
|
1240 |
|
1241 CCommNotifyBase::CCommNotifyBase(CHWPort* aParent) |
|
1242 /** |
|
1243 * C'tor |
|
1244 * |
|
1245 * @param aParent pointer to the CHWPort object |
|
1246 */ |
|
1247 :CActive(KNotifyPriority) |
|
1248 ,iRole(ECommRoleDTE) |
|
1249 ,iParent(aParent) |
|
1250 { |
|
1251 CActiveScheduler::Add(this); |
|
1252 } |
|
1253 |
|
1254 |
|
1255 CCommNotifyBase::~CCommNotifyBase() |
|
1256 /** |
|
1257 * D'tor |
|
1258 */ |
|
1259 { |
|
1260 LOGECUART1(_L8("CCommNotifyBase::~CCommNotifyBase()")); |
|
1261 } |
|
1262 |
|
1263 |
|
1264 // |
|
1265 // implementation of CCommSignalNotifier |
|
1266 // |
|
1267 |
|
1268 |
|
1269 CCommSignalNotifier::CCommSignalNotifier(CHWPort* aParent) |
|
1270 /** |
|
1271 * C'tor |
|
1272 * |
|
1273 * @param aParent pointer to the CHWPort object |
|
1274 */ |
|
1275 :CCommNotifyBase(aParent) |
|
1276 { |
|
1277 LOGECUART1(_L8("CCommSignalNotifier::CCommSignalNotifier()")); |
|
1278 } |
|
1279 |
|
1280 |
|
1281 CCommSignalNotifier::~CCommSignalNotifier() |
|
1282 /** |
|
1283 * D'tor |
|
1284 */ |
|
1285 { |
|
1286 LOGECUART1(_L8("CCommSignalNotifier::~CCommSignalNotifier()")); |
|
1287 } |
|
1288 |
|
1289 |
|
1290 void CCommSignalNotifier::DoCancel() |
|
1291 /** |
|
1292 * Cancel a pending notification. |
|
1293 */ |
|
1294 { |
|
1295 LOGECUART1(_L8("CCommSignalNotifier::DoCancel()")); |
|
1296 __ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding)); |
|
1297 if (iRole==ECommRoleDTE) |
|
1298 iParent->DTEPort().NotifySignalChangeCancel(); |
|
1299 else |
|
1300 iParent->DCEPort().NotifySignalChangeCancel(); |
|
1301 } |
|
1302 |
|
1303 |
|
1304 void CCommSignalNotifier::RunL() |
|
1305 /** |
|
1306 * a notification has completed |
|
1307 */ |
|
1308 { |
|
1309 LOGECUART2(_L8("CCommSignalNotifier::RunL(), iStatus = %d"), iStatus.Int()); |
|
1310 if (iStatus.Int()) |
|
1311 { |
|
1312 iParent->SignalChangeCompleted(iSignals,iStatus.Int()); |
|
1313 iParent->BreakNotifyCompleted(iStatus.Int()); |
|
1314 iSignalMask = 0; |
|
1315 iNotifyCount = 0; |
|
1316 return; |
|
1317 } |
|
1318 |
|
1319 if (iSignals & ((KSignalDTEOutputs|KSignalDTEInputs)*KSignalChanged)) // these don't include BREAK |
|
1320 { |
|
1321 iNotifyCount--; |
|
1322 iParent->SignalChangeCompleted(iSignals,iStatus.Int()); |
|
1323 iSignalMask &= (KSignalBreak); // mask out everything but the BREAK signal |
|
1324 } |
|
1325 if (iSignals & KBreakChanged) |
|
1326 { |
|
1327 iNotifyCount--; |
|
1328 iParent->BreakNotifyCompleted(iStatus.Int()); |
|
1329 iSignalMask&=(~KSignalBreak); |
|
1330 } |
|
1331 __ASSERT_ALWAYS(iNotifyCount>=0, Fault(ENegativeCount)); |
|
1332 if (iNotifyCount>0) |
|
1333 Start(); |
|
1334 } |
|
1335 |
|
1336 void CCommSignalNotifier::Start() |
|
1337 /** |
|
1338 * start the notification |
|
1339 */ |
|
1340 { |
|
1341 LOGECUART1(_L8("CCommSignalNotifier::Start()")); |
|
1342 if (IsActive()) |
|
1343 Cancel(); |
|
1344 if (iRole==ECommRoleDTE) |
|
1345 iParent->DTEPort().NotifySignalChange(iStatus, iSignals, iSignalMask); |
|
1346 else |
|
1347 iParent->DCEPort().NotifySignalChange(iStatus, iSignals, iSignalMask); |
|
1348 SetActive(); |
|
1349 } |
|
1350 |
|
1351 |
|
1352 void CCommSignalNotifier::NotifySignal(TUint aSignalMask) |
|
1353 /** |
|
1354 * notify client when signal changes |
|
1355 * |
|
1356 * @param aSignalMask bitmask with the signals to be notified on |
|
1357 */ |
|
1358 { |
|
1359 LOGECUART2(_L8("CCommSignalNotifier::NotifySignal(), aSignalMask = %d"), aSignalMask); |
|
1360 TUint reqSigs = aSignalMask & ~KSignalBreak; |
|
1361 if (!reqSigs) |
|
1362 {// User has only asked to be notified of break. |
|
1363 iParent->SignalChangeCompleted(iSignals, KErrArgument); |
|
1364 return; |
|
1365 } |
|
1366 iNotifyCount++; |
|
1367 iSignalMask |= reqSigs; |
|
1368 Start(); |
|
1369 } |
|
1370 |
|
1371 |
|
1372 void CCommSignalNotifier::NotifySignalCancel() |
|
1373 /** |
|
1374 * cancel an outstanding signal change notification |
|
1375 */ |
|
1376 { |
|
1377 LOGECUART1(_L8("CCommSignalNotifier::NotifySignalCancel()")); |
|
1378 Cancel(); |
|
1379 iSignalMask &= (KSignalBreak); // set mask to zero, excluding BREAK |
|
1380 if (--iNotifyCount>0) // NotifyBreak may still be outstanding |
|
1381 Start(); |
|
1382 } |
|
1383 |
|
1384 |
|
1385 void CCommSignalNotifier::NotifyBreak() |
|
1386 /** |
|
1387 * notify client if break occurs |
|
1388 */ |
|
1389 { |
|
1390 LOGECUART1(_L8("CCommSignalNotifier::NotifyBreak()")); |
|
1391 iNotifyCount++; |
|
1392 iSignalMask |= KSignalBreak; |
|
1393 Start(); |
|
1394 } |
|
1395 |
|
1396 |
|
1397 void CCommSignalNotifier::NotifyBreakCancel() |
|
1398 /** |
|
1399 * cancel an outstanding break notification |
|
1400 */ |
|
1401 { |
|
1402 LOGECUART1(_L8("CCommSignalNotifier::NotifyBreakCancel()")); |
|
1403 Cancel(); |
|
1404 iSignalMask &= (~KSignalBreak); // mask out the BREAK signal |
|
1405 if (--iNotifyCount>0) // NotifySignals may still be outstanding |
|
1406 Start(); |
|
1407 } |
|
1408 |
|
1409 |
|
1410 // |
|
1411 // implementation of CCommAvailableDataNotifier |
|
1412 // |
|
1413 |
|
1414 |
|
1415 CCommAvailableDataNotifier::CCommAvailableDataNotifier(CHWPort* aParent) |
|
1416 /** |
|
1417 * C'tor |
|
1418 * |
|
1419 * @param aParent pointer to the CHWPort object |
|
1420 */ |
|
1421 :CCommNotifyBase(aParent) |
|
1422 { |
|
1423 } |
|
1424 |
|
1425 |
|
1426 CCommAvailableDataNotifier::~CCommAvailableDataNotifier() |
|
1427 /** |
|
1428 * D'tor |
|
1429 */ |
|
1430 { |
|
1431 LOGECUART1(_L8("CCommAvailableDataNotifier::~CCommAvailableDataNotifier()")); |
|
1432 } |
|
1433 |
|
1434 |
|
1435 void CCommAvailableDataNotifier::DoCancel() |
|
1436 /** |
|
1437 * Cancel a pending data available notification. |
|
1438 */ |
|
1439 { |
|
1440 __ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding)); |
|
1441 if (iRole==ECommRoleDTE) |
|
1442 iParent->DTEPort().NotifyReceiveDataAvailableCancel(); |
|
1443 else |
|
1444 iParent->DCEPort().NotifyReceiveDataAvailableCancel(); |
|
1445 } |
|
1446 |
|
1447 |
|
1448 void CCommAvailableDataNotifier::RunL() |
|
1449 /** |
|
1450 * the notification has completed, and data is available |
|
1451 */ |
|
1452 { |
|
1453 LOGECUART2(_L8("CCommAvailableDataNotifier::RunL(), iStatus = %d"), iStatus.Int()); |
|
1454 iParent->NotifyDataAvailableCompleted(iStatus.Int()); |
|
1455 } |
|
1456 |
|
1457 |
|
1458 void CCommAvailableDataNotifier::Start() |
|
1459 /** |
|
1460 * start notification on data available |
|
1461 */ |
|
1462 { |
|
1463 LOGECUART1(_L8("CCommAvailableDataNotifier::Start()")); |
|
1464 if (iRole==ECommRoleDTE) |
|
1465 iParent->DTEPort().NotifyReceiveDataAvailable(iStatus); |
|
1466 else |
|
1467 iParent->DCEPort().NotifyReceiveDataAvailable(iStatus); |
|
1468 SetActive(); |
|
1469 } |
|
1470 |
|
1471 |
|
1472 // |
|
1473 // implementation of CCommFlowControlChangeNotifier |
|
1474 // |
|
1475 |
|
1476 |
|
1477 CCommFlowControlChangeNotifier::CCommFlowControlChangeNotifier(CHWPort* aParent) |
|
1478 /** |
|
1479 * C'tor |
|
1480 * |
|
1481 * @param aParent pointer to the CHWPort object |
|
1482 */ |
|
1483 :CCommNotifyBase(aParent) |
|
1484 { |
|
1485 } |
|
1486 |
|
1487 |
|
1488 CCommFlowControlChangeNotifier::~CCommFlowControlChangeNotifier() |
|
1489 /** |
|
1490 * D'tor |
|
1491 */ |
|
1492 { |
|
1493 LOGECUART1(_L8("CCommFlowControlChangeNotifier::~CCommFlowControlChangeNotifier()")); |
|
1494 } |
|
1495 |
|
1496 |
|
1497 void CCommFlowControlChangeNotifier::DoCancel() |
|
1498 /** |
|
1499 * Cancel a pending flow control change notification. |
|
1500 */ |
|
1501 { |
|
1502 LOGECUART1(_L8("CCommFlowControlChangeNotifier::DoCancel()")); |
|
1503 __ASSERT_ALWAYS(iRole==ECommRoleDCE,Fault(EWrongRole)); |
|
1504 __ASSERT_ALWAYS(IsActive(),Fault(ECancelNotOutstanding)); |
|
1505 iParent->DCEPort().NotifyFlowControlChangeCancel(); |
|
1506 } |
|
1507 |
|
1508 |
|
1509 void CCommFlowControlChangeNotifier::RunL() |
|
1510 /** |
|
1511 * The device driver does not give the new value of flow control status when the notification |
|
1512 * completes so we go and ask for it. If this impedes performance, it may be worth taking the |
|
1513 * plunge and working out the value ourselves - it should just be the opposite (ON/OFF) each time |
|
1514 * it completes. |
|
1515 */ |
|
1516 { |
|
1517 LOGECUART2(_L8("CCommFlowControlChangeNotifier::RunL(), iStatus = %d"), iStatus.Int()); |
|
1518 __ASSERT_ALWAYS(iRole==ECommRoleDCE, Fault(EWrongRole)); |
|
1519 iParent->DCEPort().GetFlowControlStatus(iFlowControl); |
|
1520 iParent->FlowControlChangeCompleted(iFlowControl,iStatus.Int()); |
|
1521 } |
|
1522 |
|
1523 |
|
1524 void CCommFlowControlChangeNotifier::Start() |
|
1525 /** |
|
1526 * start notification on flow control change |
|
1527 * |
|
1528 * @note Only supported for DCE role |
|
1529 */ |
|
1530 { |
|
1531 LOGECUART1(_L8("CCommFlowControlChangeNotifier::Start()")); |
|
1532 if (iRole==ECommRoleDTE) |
|
1533 iParent->FlowControlChangeCompleted(iFlowControl, KErrNotSupported); |
|
1534 else |
|
1535 { |
|
1536 iParent->DCEPort().NotifyFlowControlChange(iStatus); |
|
1537 SetActive(); |
|
1538 } |
|
1539 } |
|
1540 |
|
1541 |
|
1542 // |
|
1543 // implementation of CCommConfigChangeNotifier |
|
1544 // |
|
1545 |
|
1546 |
|
1547 CCommConfigChangeNotifier::CCommConfigChangeNotifier(CHWPort* aParent) |
|
1548 /** |
|
1549 * C'tor |
|
1550 * |
|
1551 * @param aParent pointer to the CHWPort object |
|
1552 */ |
|
1553 :CCommNotifyBase(aParent) |
|
1554 { |
|
1555 LOGECUART1(_L8("CCommConfigChangeNotifier::CCommConfigChangeNotifier()")); |
|
1556 } |
|
1557 |
|
1558 |
|
1559 CCommConfigChangeNotifier::~CCommConfigChangeNotifier() |
|
1560 /** |
|
1561 * D'tor |
|
1562 */ |
|
1563 { |
|
1564 LOGECUART1(_L8("CCommConfigChangeNotifier::~CCommConfigChangeNotifier()")); |
|
1565 } |
|
1566 |
|
1567 |
|
1568 void CCommConfigChangeNotifier::Start() |
|
1569 /** |
|
1570 * start notification on config change |
|
1571 * |
|
1572 * @note Only supported for DCE role |
|
1573 */ |
|
1574 { |
|
1575 LOGECUART1(_L8("CCommConfigChangeNotifier::Start()")); |
|
1576 if (iRole==ECommRoleDTE) |
|
1577 iParent->ConfigChangeCompleted(iConfig, KErrNotSupported); |
|
1578 else |
|
1579 { |
|
1580 iParent->DCEPort().NotifyConfigChange(iStatus, iConfig); |
|
1581 SetActive(); |
|
1582 } |
|
1583 } |
|
1584 |
|
1585 |
|
1586 void CCommConfigChangeNotifier::DoCancel() |
|
1587 /** |
|
1588 * Cancel a pending config change notification. |
|
1589 */ |
|
1590 { |
|
1591 LOGECUART1(_L8("CCommConfigChangeNotifier::DoCancel()")); |
|
1592 __ASSERT_ALWAYS(iRole==ECommRoleDCE,Fault(EWrongRole)); |
|
1593 __ASSERT_ALWAYS(IsActive(),Fault(ECancelNotOutstanding)); |
|
1594 iParent->DCEPort().NotifyConfigChangeCancel(); |
|
1595 } |
|
1596 |
|
1597 |
|
1598 void CCommConfigChangeNotifier::RunL() |
|
1599 /** |
|
1600 * the config change notification has completed, |
|
1601 * forward the news to the client. |
|
1602 */ |
|
1603 { |
|
1604 LOGECUART2(_L8("CCommConfigChangeNotifier::RunL(), iStatus = %d"), iStatus.Int()); |
|
1605 iParent->ConfigChangeCompleted(iConfig, iStatus.Int()); |
|
1606 } |
|
1607 |
|
1608 |
|
1609 void CloseObject(TAny* aObject) |
|
1610 /** |
|
1611 * Close an object from the cleanup stack |
|
1612 * |
|
1613 * @param aObject pointer to the object to close |
|
1614 */ |
|
1615 { |
|
1616 LOGECUART1(_L8("CloseObject()")); |
|
1617 ((CObject*)aObject)->Close(); |
|
1618 } |
|
1619 |
|
1620 |
|
1621 // |
|
1622 // implementation of CHWPort |
|
1623 // |
|
1624 |
|
1625 |
|
1626 CHWPort* CHWPort::NewL(TUint aUnit) |
|
1627 /** |
|
1628 * Make a new CPort for the comm server |
|
1629 * |
|
1630 * @param aUnit unit number of comm port (i.e. 0 for COMM::0) |
|
1631 * @return a newly created CHWPort object |
|
1632 */ |
|
1633 { |
|
1634 LOGECUART2(_L8("CHWPort::NewL(), aUint = %d (unit number of comm port)"), aUnit); |
|
1635 CHWPort* p = new (ELeave) CHWPort; |
|
1636 TCleanupItem closePort(CloseObject, p); |
|
1637 |
|
1638 CleanupStack::PushL(closePort); |
|
1639 |
|
1640 p->iReader=CCommReader::NewL(p); |
|
1641 p->iWriter=CCommWriter::NewL(p); |
|
1642 p->iBreaker=CCommBreaker::NewL(p); |
|
1643 p->iSignalNotifier=new (ELeave) CCommSignalNotifier(p); |
|
1644 p->iDataAvailableNotifier=new (ELeave) CCommAvailableDataNotifier(p); |
|
1645 p->iFlowControlChangeNotifier=new (ELeave) CCommFlowControlChangeNotifier(p); |
|
1646 p->iConfigChangeNotifier=new (ELeave) CCommConfigChangeNotifier(p); |
|
1647 |
|
1648 TName name; |
|
1649 name.Format(_L("%d"), aUnit); |
|
1650 p->SetName(&name); // todo check return value? |
|
1651 |
|
1652 // the C32 server does not check for the port number beeing to big. |
|
1653 // this is up to the CSY. If the aUnit number passed to the Logical |
|
1654 // device driver is greater than KMaxUnits, the kernel will Panic. |
|
1655 // We want to avoid this by gracefully leaving with Not Supported instead. |
|
1656 if(aUnit >= (TUint)KMaxUnits) |
|
1657 User::Leave(KErrNotSupported); |
|
1658 |
|
1659 p->iPortName = aUnit; |
|
1660 #if defined (_DEBUG_CONSOLE_) |
|
1661 name.Format(_L("Comm::%d"),aUnit); |
|
1662 p->iConsole.SetTitle(name); |
|
1663 #if defined (_DEBUG_DEVCOMM) |
|
1664 p->iDumper=CCommDebugDumper::NewL(p->iConsole); |
|
1665 #endif |
|
1666 #endif |
|
1667 CleanupStack::Pop(); |
|
1668 return p; |
|
1669 } |
|
1670 |
|
1671 |
|
1672 CHWPort::CHWPort() |
|
1673 /** |
|
1674 * C'Tor |
|
1675 */ |
|
1676 { |
|
1677 } |
|
1678 |
|
1679 |
|
1680 void CHWPort::StartRead(const TAny* aClientBuffer, TInt aLength) |
|
1681 /** |
|
1682 * Queue a read |
|
1683 * |
|
1684 * @param aClientBuffer pointer to the Client's buffer |
|
1685 * @param aLength number of bytes to read |
|
1686 */ |
|
1687 { |
|
1688 LOGECUART2(_L8("CHWPort::StartRead(), aLength = %d"), aLength); |
|
1689 DEBUG_TRACE((iConsole.Write(_L("DoRead \n\r")))); |
|
1690 if(iDataAvailableNotifier->IsActive()) |
|
1691 { |
|
1692 ReadCompleted(KErrInUse); |
|
1693 return; |
|
1694 } |
|
1695 iReader->Read(aClientBuffer, aLength); |
|
1696 } |
|
1697 |
|
1698 |
|
1699 void CHWPort::ReadCancel() |
|
1700 /** |
|
1701 * Cancel a read |
|
1702 */ |
|
1703 { |
|
1704 LOGECUART1(_L8("CHWPort::ReadCancel()")); |
|
1705 iReader->ReadCancel(); |
|
1706 } |
|
1707 |
|
1708 |
|
1709 TInt CHWPort::QueryReceiveBuffer(TInt& aLength) const |
|
1710 /** |
|
1711 * Get the size of the receive buffer from the real serial port |
|
1712 * |
|
1713 * @param aLength reference to where the size will be written to |
|
1714 * @return KErrNone always |
|
1715 */ |
|
1716 { |
|
1717 LOGECUART1(_L8("CHWPort::QueryReceiveBuffer()")); |
|
1718 // casting away constness with (CHWPort *)this |
|
1719 if (iRole==ECommRoleDTE) |
|
1720 aLength=((CHWPort *)this)->iPort.QueryReceiveBuffer(); |
|
1721 else |
|
1722 aLength=((CHWPort *)this)->iPortDCE.QueryReceiveBuffer(); |
|
1723 return KErrNone; |
|
1724 } |
|
1725 |
|
1726 |
|
1727 void CHWPort::ResetBuffers(TUint) |
|
1728 /** |
|
1729 * reset Tx and Rx buffers |
|
1730 * |
|
1731 * @note both Tx and Rx buffers are reset here |
|
1732 */ |
|
1733 { |
|
1734 LOGECUART1(_L8("CHWPort::ResetBuffers()")); |
|
1735 if (iRole==ECommRoleDTE) |
|
1736 iPort.ResetBuffers(); |
|
1737 else |
|
1738 iPortDCE.ResetBuffers(); |
|
1739 } |
|
1740 |
|
1741 |
|
1742 void CHWPort::StartWrite(const TAny* aClientBuffer, TInt aLength) |
|
1743 /** |
|
1744 * Queue a write |
|
1745 * |
|
1746 * @param aClientBuffer pointer to the Client's buffer |
|
1747 * @param aLength number of bytes to write |
|
1748 */ |
|
1749 { |
|
1750 LOGECUART2(_L8("CHWPort::StartWrite(), aLength = %d"), aLength); |
|
1751 DEBUG_TRACE((iConsole.Write(_L("DoWrite \n\r")))); |
|
1752 iWriter->Write(aClientBuffer,aLength); |
|
1753 } |
|
1754 |
|
1755 |
|
1756 void CHWPort::WriteCancel() |
|
1757 /** |
|
1758 * Cancel a pending write |
|
1759 */ |
|
1760 { |
|
1761 LOGECUART1(_L8("CHWPort::WriteCancel()")); |
|
1762 iWriter->WriteCancel(); |
|
1763 } |
|
1764 |
|
1765 |
|
1766 void CHWPort::Break(TInt aTime) |
|
1767 /** |
|
1768 * Queue a break |
|
1769 * |
|
1770 * @param aTime Length of break in micro seconds |
|
1771 */ |
|
1772 { |
|
1773 LOGECUART2(_L8("CHWPort::Break(), aTime = %d"), aTime); |
|
1774 iBreaker->Break(aTime); |
|
1775 } |
|
1776 |
|
1777 |
|
1778 void CHWPort::BreakCancel() |
|
1779 /** |
|
1780 * Cancel a pending break |
|
1781 */ |
|
1782 { |
|
1783 LOGECUART1(_L8("CHWPort::BreakCancel()")); |
|
1784 iBreaker->Cancel(); |
|
1785 } |
|
1786 |
|
1787 |
|
1788 TInt CHWPort::GetConfig(TDes8& aDes) const |
|
1789 /** |
|
1790 * Pass a config request |
|
1791 * |
|
1792 * @param aDes config will be written to this descriptor |
|
1793 * @return KErrNone always |
|
1794 */ |
|
1795 { |
|
1796 LOGECUART1(_L8("CHWPort::GetConfig()")); |
|
1797 if (iRole==ECommRoleDTE) |
|
1798 ((CHWPort*)this)->iPort.Config(aDes); |
|
1799 else |
|
1800 ((CHWPort*)this)->iPortDCE.Config(aDes); |
|
1801 return KErrNone; |
|
1802 } |
|
1803 |
|
1804 |
|
1805 TInt CHWPort::SetConfig(const TDesC8& aDes) |
|
1806 /** |
|
1807 * Set up the Comm LDD/PDD |
|
1808 * |
|
1809 * @param aDes descriptor containing the new config |
|
1810 * @return TInt error code |
|
1811 */ |
|
1812 { |
|
1813 LOGECUART1(_L8("CHWPort::SetConfig()")); |
|
1814 if (aDes.Length()<(TInt)sizeof(TCommConfigV01)) |
|
1815 return KErrGeneral; |
|
1816 TCommConfigV01 config(*(TCommConfigV01*)aDes.Ptr()); |
|
1817 |
|
1818 if (config.iHandshake & KConfigWriteBufferedComplete) |
|
1819 { |
|
1820 if (iWriter->IsNotificationEnabled()) |
|
1821 return KErrAccessDenied; |
|
1822 iEarlyWriteCompletion = ETrue; |
|
1823 } |
|
1824 else |
|
1825 { |
|
1826 iEarlyWriteCompletion = EFalse; |
|
1827 } |
|
1828 if (iRole==ECommRoleDTE) |
|
1829 return iPort.SetConfig(aDes); |
|
1830 else |
|
1831 return iPortDCE.SetConfig(aDes); |
|
1832 } |
|
1833 |
|
1834 |
|
1835 TInt CHWPort::SetServerConfig(const TDesC8& aDes) |
|
1836 /** |
|
1837 * Set the port to use partial reads/writes or the bungee buffer |
|
1838 * |
|
1839 * @param aDes package with new server configurations |
|
1840 * @return TInt error code |
|
1841 */ |
|
1842 { |
|
1843 LOGECUART1(_L8("CHWPort::SetServerConfig()")); |
|
1844 if (aDes.Length()<(TInt)sizeof(TCommServerConfigV01)) |
|
1845 return KErrGeneral; |
|
1846 TCommServerConfig c(*(TCommServerConfigV01*)aDes.Ptr()); |
|
1847 TInt r=0; |
|
1848 if ((r=iReader->SetServerConfig(c))==KErrNone) |
|
1849 r=iWriter->SetServerConfig(c); |
|
1850 return r; |
|
1851 } |
|
1852 |
|
1853 |
|
1854 TInt CHWPort::GetServerConfig(TDes8& aDes) |
|
1855 /** |
|
1856 * Get the server configs |
|
1857 * |
|
1858 * @param aDes server configs will be written to this descriptor |
|
1859 * @return TInt error code |
|
1860 */ |
|
1861 { |
|
1862 LOGECUART1(_L8("CHWPort::GetServerConfig()")); |
|
1863 if (aDes.Length()<(TInt)sizeof(TCommServerConfigV01)) |
|
1864 return KErrGeneral; |
|
1865 TCommServerConfig c; |
|
1866 |
|
1867 iReader->GetServerConfig(c); |
|
1868 aDes=c; |
|
1869 |
|
1870 return KErrNone; |
|
1871 } |
|
1872 |
|
1873 |
|
1874 TInt CHWPort::GetCaps(TDes8& aDes) |
|
1875 /** |
|
1876 * Read capabilities from the driver |
|
1877 * |
|
1878 * @param aDes caps will be written to this descriptor |
|
1879 * @return KErrNone always |
|
1880 */ |
|
1881 { |
|
1882 LOGECUART1(_L8("CHWPort::GetCaps()")); |
|
1883 if (iRole==ECommRoleDTE) |
|
1884 iPort.Caps(aDes); |
|
1885 else |
|
1886 iPortDCE.Caps(aDes); |
|
1887 if (aDes.Length()==sizeof(TCommCapsV02)) |
|
1888 { |
|
1889 TCommCapsV02* commcaps = (TCommCapsV02*)(aDes.Ptr()); |
|
1890 commcaps->iNotificationCaps |= KNotifyOutputEmptySupported; |
|
1891 commcaps->iRoleCaps = KCapsRoleSwitchSupported; |
|
1892 } |
|
1893 return KErrNone; |
|
1894 } |
|
1895 |
|
1896 |
|
1897 TInt CHWPort::GetSignals(TUint& aSignals) |
|
1898 /** |
|
1899 * get the status of the signal pins |
|
1900 * |
|
1901 * @param aSignals signals will be written to this descriptor |
|
1902 * @return KErrNone always |
|
1903 */ |
|
1904 { |
|
1905 LOGECUART1(_L8("CHWPort::GetSignals()")); |
|
1906 if (iRole==ECommRoleDTE) |
|
1907 aSignals=iPort.Signals(); |
|
1908 else |
|
1909 aSignals=iPortDCE.Signals(); |
|
1910 return KErrNone; |
|
1911 } |
|
1912 |
|
1913 |
|
1914 TInt CHWPort::SetSignalsToMark(TUint aSignals) |
|
1915 /** |
|
1916 * set selected signals to high (logical 1) |
|
1917 * |
|
1918 * @param aSignals bitmask with the signals to be set |
|
1919 * @return KErrNone always |
|
1920 */ |
|
1921 { |
|
1922 LOGECUART2(_L8("CHWPort::SetSignalsToMark(), aSignals = %d"), aSignals); |
|
1923 if (iRole==ECommRoleDTE) |
|
1924 iPort.SetSignals(aSignals,0); |
|
1925 else |
|
1926 iPortDCE.SetSignals(aSignals,0); |
|
1927 return KErrNone; |
|
1928 } |
|
1929 |
|
1930 |
|
1931 TInt CHWPort::SetSignalsToSpace(TUint aSignals) |
|
1932 /** |
|
1933 * set selected signals to low (logical 0) |
|
1934 * |
|
1935 * @param aSignals bitmask with the signals to be cleared |
|
1936 * @return KErrNone always |
|
1937 */ |
|
1938 { |
|
1939 LOGECUART2(_L8("CHWPort::SetSignalsToSpace(), aSignals = %d"), aSignals); |
|
1940 if (iRole==ECommRoleDTE) |
|
1941 iPort.SetSignals(0,aSignals); |
|
1942 else |
|
1943 iPortDCE.SetSignals(0,aSignals); |
|
1944 return KErrNone; |
|
1945 } |
|
1946 |
|
1947 |
|
1948 TInt CHWPort::GetReceiveBufferLength(TInt& aLength) const |
|
1949 /** |
|
1950 * get size of Tx and Rx buffer |
|
1951 * |
|
1952 * @param aLength reference to where the length will be written to |
|
1953 * @return KErrNone always |
|
1954 */ |
|
1955 { |
|
1956 LOGECUART1(_L8("CHWPort::GetReceiveBufferLength()")); |
|
1957 // casting away constness with (CHWPort *)this |
|
1958 if (iRole==ECommRoleDTE) |
|
1959 aLength=((CHWPort *)this)->iPort.ReceiveBufferLength(); |
|
1960 else |
|
1961 aLength=((CHWPort *)this)->iPortDCE.ReceiveBufferLength(); |
|
1962 return KErrNone; |
|
1963 } |
|
1964 |
|
1965 |
|
1966 TInt CHWPort::SetReceiveBufferLength(TInt aLength) |
|
1967 /** |
|
1968 * set the size of Tx and Rx buffer |
|
1969 * |
|
1970 * @param aLength new length of Tx and Rx buffer |
|
1971 * @return TInt error code |
|
1972 */ |
|
1973 { |
|
1974 LOGECUART2(_L8("CHWPort::SetReceiveBufferLength(), aLength = %d"), aLength); |
|
1975 if (iRole==ECommRoleDTE) |
|
1976 return iPort.SetReceiveBufferLength(aLength); |
|
1977 else |
|
1978 return iPortDCE.SetReceiveBufferLength(aLength); |
|
1979 } |
|
1980 |
|
1981 |
|
1982 void CHWPort::Destruct() |
|
1983 /** |
|
1984 * Destruct - we must (eventually) call delete this |
|
1985 */ |
|
1986 { |
|
1987 LOGECUART1(_L8("CHWPort::Destruct()")); |
|
1988 delete this; |
|
1989 } |
|
1990 |
|
1991 |
|
1992 void CHWPort::FreeMemory() |
|
1993 /** |
|
1994 * Attempt to reduce out memory foot print. |
|
1995 */ |
|
1996 { |
|
1997 LOGECUART1(_L8("CHWPort::FreeMemory()")); |
|
1998 iReader->FreeMemory(); |
|
1999 iWriter->FreeMemory(); |
|
2000 } |
|
2001 |
|
2002 |
|
2003 void CHWPort::NotifySignalChange(TUint aSignalMask) |
|
2004 /** |
|
2005 * notify client when the signals change |
|
2006 * |
|
2007 * @param aSignalMask bitmask with signal to be notified on |
|
2008 */ |
|
2009 { |
|
2010 LOGECUART2(_L8("CHWPort::NotifySignalChange(), aSignalMask = %d"), aSignalMask); |
|
2011 iSignalNotifier->NotifySignal(aSignalMask); |
|
2012 } |
|
2013 |
|
2014 |
|
2015 void CHWPort::NotifySignalChangeCancel() |
|
2016 /** |
|
2017 * cancel an outstanding signal change notification |
|
2018 */ |
|
2019 { |
|
2020 LOGECUART1(_L8("CHWPort::NotifySignalChangeCancel()")); |
|
2021 iSignalNotifier->NotifySignalCancel(); |
|
2022 } |
|
2023 |
|
2024 |
|
2025 void CHWPort::NotifyConfigChange() |
|
2026 /** |
|
2027 * notify client when the configation changes |
|
2028 */ |
|
2029 { |
|
2030 LOGECUART1(_L8("CHWPort::NotifyConfigChange()")); |
|
2031 iConfigChangeNotifier->Start(); |
|
2032 } |
|
2033 |
|
2034 |
|
2035 void CHWPort::NotifyConfigChangeCancel() |
|
2036 /** |
|
2037 * cancel an outstanding config change notification |
|
2038 */ |
|
2039 { |
|
2040 LOGECUART1(_L8("CHWPort::NotifyConfigChangeCancel()")); |
|
2041 iConfigChangeNotifier->Cancel(); |
|
2042 } |
|
2043 |
|
2044 |
|
2045 void CHWPort::NotifyFlowControlChange() |
|
2046 /** |
|
2047 * notify client when the flow control changes |
|
2048 */ |
|
2049 { |
|
2050 LOGECUART1(_L8("CHWPort::NotifyFlowControlChange()")); |
|
2051 iFlowControlChangeNotifier->Start(); |
|
2052 } |
|
2053 |
|
2054 |
|
2055 void CHWPort::NotifyFlowControlChangeCancel() |
|
2056 /** |
|
2057 * cancel an outstanding flow control change notification |
|
2058 */ |
|
2059 { |
|
2060 LOGECUART1(_L8("CHWPort::NotifyFlowControlChangeCancel()")); |
|
2061 iFlowControlChangeNotifier->Cancel(); |
|
2062 } |
|
2063 |
|
2064 |
|
2065 void CHWPort::NotifyBreak() |
|
2066 /** |
|
2067 * notify client when a break occurs |
|
2068 */ |
|
2069 { |
|
2070 LOGECUART1(_L8("CHWPort::NotifyBreak()")); |
|
2071 iSignalNotifier->NotifyBreak(); |
|
2072 } |
|
2073 |
|
2074 |
|
2075 void CHWPort::NotifyBreakCancel() |
|
2076 /** |
|
2077 * cancel an outstanding break notification |
|
2078 */ |
|
2079 { |
|
2080 LOGECUART1(_L8("CHWPort::NotifyBreakCancel()")); |
|
2081 iSignalNotifier->NotifyBreakCancel(); |
|
2082 } |
|
2083 |
|
2084 |
|
2085 void CHWPort::NotifyDataAvailable() |
|
2086 /** |
|
2087 * notify client when data is available |
|
2088 */ |
|
2089 { |
|
2090 LOGECUART1(_L8("CHWPort::NotifyDataAvailable()")); |
|
2091 if(iReader->IsActive()) |
|
2092 { |
|
2093 NotifyDataAvailableCompleted(KErrInUse); |
|
2094 return; |
|
2095 } |
|
2096 iDataAvailableNotifier->Start(); |
|
2097 } |
|
2098 |
|
2099 |
|
2100 void CHWPort::NotifyDataAvailableCancel() |
|
2101 /** |
|
2102 * cancel an outstanding data availalbe notification |
|
2103 */ |
|
2104 { |
|
2105 LOGECUART1(_L8("CHWPort::NotifyDataAvailableCancel()")); |
|
2106 iDataAvailableNotifier->Cancel(); |
|
2107 } |
|
2108 |
|
2109 |
|
2110 void CHWPort::NotifyOutputEmpty() |
|
2111 /** |
|
2112 * notify client when output buffer is empty |
|
2113 */ |
|
2114 { |
|
2115 LOGECUART1(_L8("CHWPort::NotifyOutputEmpty()")); |
|
2116 if (iEarlyWriteCompletion) |
|
2117 NotifyOutputEmptyCompleted(KErrAccessDenied); |
|
2118 else |
|
2119 iWriter->NotificationEnable(); |
|
2120 } |
|
2121 |
|
2122 |
|
2123 void CHWPort::NotifyOutputEmptyCancel() |
|
2124 /** |
|
2125 * cancel an outstanding output empty notification |
|
2126 */ |
|
2127 { |
|
2128 LOGECUART1(_L8("CHWPort::NotifyOutputEmptyCancel()")); |
|
2129 iWriter->NotificationDisable(); |
|
2130 } |
|
2131 |
|
2132 |
|
2133 TInt CHWPort::GetFlowControlStatus(TFlowControl& aFlowControl) |
|
2134 /** |
|
2135 * get the flow control status |
|
2136 * |
|
2137 * @param aFlowControl flow control status will be written to this descriptor |
|
2138 * @return TInt error code |
|
2139 * |
|
2140 * @note only supported for DCE role |
|
2141 */ |
|
2142 { |
|
2143 if (iRole==ECommRoleDTE) |
|
2144 return KErrNotSupported; |
|
2145 else |
|
2146 iPortDCE.GetFlowControlStatus(aFlowControl); |
|
2147 return KErrNone; |
|
2148 } |
|
2149 |
|
2150 |
|
2151 TInt CHWPort::GetRole(TCommRole& aRole) |
|
2152 /** |
|
2153 * get the role of this port unit |
|
2154 * |
|
2155 * @param aRole reference to where the role will be written to |
|
2156 * @return KErrNone always |
|
2157 */ |
|
2158 { |
|
2159 aRole = iRole; |
|
2160 return KErrNone; |
|
2161 } |
|
2162 |
|
2163 |
|
2164 TInt CHWPort::SetRole(TCommRole aRole) |
|
2165 /** |
|
2166 * set the role of this port unit |
|
2167 * |
|
2168 * @param aRole the new role |
|
2169 * @return TInt error code |
|
2170 */ |
|
2171 { |
|
2172 iRole=aRole; |
|
2173 TInt ret=KErrNone; |
|
2174 if (aRole==ECommRoleDTE) |
|
2175 ret = iPort.Open(iPortName); |
|
2176 else |
|
2177 ret = iPortDCE.Open(iPortName); |
|
2178 if (ret!=KErrNone) |
|
2179 { |
|
2180 LOGECUART3(_L8("CHWPort::SetRole - failed with %d when attempting to open hardware port unit: %d"),ret,iPortName); |
|
2181 return ret; |
|
2182 } |
|
2183 iReader->SetRole(aRole); |
|
2184 iWriter->SetRole(aRole); |
|
2185 iBreaker->SetRole(aRole); |
|
2186 iSignalNotifier->SetRole(aRole); |
|
2187 iDataAvailableNotifier->SetRole(aRole); |
|
2188 iFlowControlChangeNotifier->SetRole(aRole); |
|
2189 iConfigChangeNotifier->SetRole(aRole); |
|
2190 |
|
2191 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_) |
|
2192 iDumper->SetRole(aRole); |
|
2193 #endif |
|
2194 return KErrNone; |
|
2195 } |
|
2196 |
|
2197 |
|
2198 CHWPort::~CHWPort() |
|
2199 /** |
|
2200 * D'tor |
|
2201 */ |
|
2202 { |
|
2203 LOGECUART1(_L8("CHWPort::~CHWPort()")); |
|
2204 delete iReader; |
|
2205 delete iWriter; |
|
2206 delete iBreaker; |
|
2207 delete iSignalNotifier; |
|
2208 delete iDataAvailableNotifier; |
|
2209 delete iFlowControlChangeNotifier; |
|
2210 delete iConfigChangeNotifier; |
|
2211 |
|
2212 iPort.Close(); |
|
2213 iPortDCE.Close(); |
|
2214 |
|
2215 #if defined (_DEBUG_CONSOLE_) |
|
2216 #if defined (_DEBUG_DEVCOMM) |
|
2217 delete iDumper; |
|
2218 #endif |
|
2219 iConsole.Close(); |
|
2220 #endif |
|
2221 } |
|
2222 |
|
2223 |
|
2224 #ifdef _DEBUG_DEVCOMM |
|
2225 void CHWPort::DoDumpDebugInfo(const RMessage2 &aMessage) |
|
2226 { |
|
2227 TCommDebugInfoPckg d; |
|
2228 if (iRole==ECommRoleDTE) |
|
2229 iPort.DebugInfo(d); |
|
2230 else |
|
2231 iPortDCE.DebugInfo(d); |
|
2232 TRAPD(ret, aMessage.WriteL(0,aMessage,d) ); |
|
2233 aMessage.Complete(ret); |
|
2234 } |
|
2235 #endif |
|
2236 |
|
2237 |
|
2238 RBusDevComm& CHWPort::DTEPort() |
|
2239 /** |
|
2240 * return the handle to the logical DTE port |
|
2241 */ |
|
2242 { |
|
2243 return iPort; |
|
2244 } |
|
2245 |
|
2246 |
|
2247 RBusDevCommDCE& CHWPort::DCEPort() |
|
2248 /** |
|
2249 * return the handle to the logical DCE port |
|
2250 */ |
|
2251 { |
|
2252 return iPortDCE; |
|
2253 } |
|
2254 |
|
2255 |
|
2256 // |
|
2257 // todo implement this - for further improvements |
|
2258 // |
|
2259 #if 0 |
|
2260 RBusWhatever& CHWPort::Port() |
|
2261 /** |
|
2262 * return a handle to our port |
|
2263 */ |
|
2264 { |
|
2265 if (iRole==ECommRoleDTE) |
|
2266 return iPort; |
|
2267 else |
|
2268 return iPortDCE; |
|
2269 } |
|
2270 #endif |
|
2271 |
|
2272 |
|
2273 // |
|
2274 // implementation of CHWPortFactory |
|
2275 // |
|
2276 |
|
2277 |
|
2278 CHWPortFactory::CHWPortFactory() |
|
2279 /** |
|
2280 * C'tor |
|
2281 */ |
|
2282 { |
|
2283 TName name(SERIAL_NAME); |
|
2284 SetName(&name); // todo check return value? |
|
2285 iVersion = TVersion(KEC32MajorVersionNumber, KEC32MinorVersionNumber, KEC32BuildVersionNumber); |
|
2286 } |
|
2287 |
|
2288 |
|
2289 CPort* CHWPortFactory::NewPortL(const TUint aUnit) |
|
2290 /** |
|
2291 * Create a new port for the supplied unit number |
|
2292 * |
|
2293 * @param aUnit port unit number (i.e. 0 for COMM::0) |
|
2294 */ |
|
2295 { |
|
2296 LOGECUART2(_L8("CHWPortFactory::NewPortL(), aUnit = %d"), aUnit); |
|
2297 // __ASSERT_ALWAYS(aUnit>=KCommLowUnit,User::Leave(KErrNotSupported)); |
|
2298 // __ASSERT_ALWAYS(aUnit<=KCommHighUnit,User::Leave(KErrNotSupported)); |
|
2299 return (CPort *)CHWPort::NewL(aUnit); |
|
2300 } |
|
2301 |
|
2302 |
|
2303 void CHWPortFactory::Info(TSerialInfo& aSerialInfo) |
|
2304 /** |
|
2305 * get info about this CSY, fill in the supplied structure. |
|
2306 * |
|
2307 * @param aSerialInfo where info will be written to |
|
2308 */ |
|
2309 { |
|
2310 aSerialInfo.iDescription = KSerialDescription; |
|
2311 aSerialInfo.iName = SERIAL_NAME; |
|
2312 aSerialInfo.iLowUnit = KCommLowUnit; |
|
2313 aSerialInfo.iHighUnit = KCommHighUnit; |
|
2314 } |
|
2315 |
|
2316 /** |
|
2317 Returns capabilities for requested port |
|
2318 */ |
|
2319 TSecurityPolicy CHWPortFactory::PortPlatSecCapability(TUint aPort) const |
|
2320 { |
|
2321 LOGECUART2(_L8("CHWPortFactory::PortPlatSecCapability(), aPort = %d"), aPort); |
|
2322 TSecurityPolicy csySecurityPolicy(KDefaultPortPassPolicy); |
|
2323 |
|
2324 if(aPort >= (TUint)KMaxUnits) //if greater than KMaxUnits it is an invalid port so fail. |
|
2325 { |
|
2326 csySecurityPolicy = KPortAlwaysFailPolicy; |
|
2327 } |
|
2328 else //see if it is defined in explicit policy list. |
|
2329 { |
|
2330 for(int i = 0;i < KExplicitPortPoliciesCount; i++) |
|
2331 { |
|
2332 // coverity [dead_error_line] : KExplicitPortPoliciesCount is currently 0, but this could change. |
|
2333 if(aPort == KExplicitPortSecurityPolicies[i].iPort) |
|
2334 { |
|
2335 csySecurityPolicy = KExplicitPortSecurityPolicies[i].iPolicy; |
|
2336 break; |
|
2337 } |
|
2338 } |
|
2339 } |
|
2340 return csySecurityPolicy; |
|
2341 } |
|
2342 |
|
2343 extern "C" |
|
2344 { |
|
2345 IMPORT_C CSerial* LibEntry(void); // Force export |
|
2346 }; |
|
2347 |
|
2348 |
|
2349 EXPORT_C CSerial* LibEntry() |
|
2350 /** |
|
2351 * Lib main entry point |
|
2352 */ |
|
2353 { |
|
2354 LOGECUART1(_L8("LibEntry()")); |
|
2355 return new CHWPortFactory; |
|
2356 } |
|
2357 |
|
2358 |
|
2359 #if defined(_DEBUG_CONSOLE_) |
|
2360 |
|
2361 RDebugConsole::RDebugConsole() |
|
2362 { |
|
2363 Create(); |
|
2364 Set(_L(""),TSize(64,15)); |
|
2365 |
|
2366 } |
|
2367 |
|
2368 void RDebugConsole::Printf(TRefByValue<const TDesC> aFmt,...) |
|
2369 // |
|
2370 // Print to a console screen. |
|
2371 // |
|
2372 { |
|
2373 |
|
2374 VA_LIST list; |
|
2375 VA_START(list,aFmt); |
|
2376 TBuf<0x100> aBuf; |
|
2377 aBuf.AppendFormatList(aFmt,list); |
|
2378 Write(aBuf); |
|
2379 } |
|
2380 #endif |
|
2381 |
|
2382 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_) |
|
2383 CCommDebugDumper* CCommDebugDumper::NewL(RDebugConsole &aConsole) |
|
2384 { |
|
2385 CCommDebugDumper* p=new CCommDebugDumper(aConsole); |
|
2386 return p; |
|
2387 } |
|
2388 |
|
2389 CCommDebugDumper::CCommDebugDumper(RDebugConsole &aConsole) |
|
2390 :CActive(EPriorityStandard) |
|
2391 { |
|
2392 iRole=ECommRoleDTE; |
|
2393 iConsole=&aConsole; |
|
2394 CActiveScheduler::Add(this); |
|
2395 SetActive(); |
|
2396 iConsole->Read(iKeystroke,iStatus); |
|
2397 }; |
|
2398 |
|
2399 CCommDebugDumper::~CCommDebugDumper() |
|
2400 { |
|
2401 Cancel(); |
|
2402 } |
|
2403 |
|
2404 void CCommDebugDumper::RunL() |
|
2405 { |
|
2406 TInt key=iKeystroke.Code(); |
|
2407 switch(key) |
|
2408 { |
|
2409 case 'd': |
|
2410 case 'D': |
|
2411 { |
|
2412 TCommDebugInfoPckg d; |
|
2413 if (iRole==ECommRoleDTE) |
|
2414 iParent->DTEPort().DebugInfo(d); |
|
2415 else |
|
2416 iParent->DCEPort().DebugInfo(d); |
|
2417 TCommDebugInfo& debug=d(); |
|
2418 iConsole->Printf(_L("rxbusy : 0x%04x, rxHeld : 0x%04x, \n\r"),debug.iRxBusy,debug.iRxHeld); |
|
2419 iConsole->Printf(_L("txbusy : 0x%04x, txHeld : 0x%04x, \n\r"),debug.iTxBusy,debug.iTxHeld); |
|
2420 iConsole->Printf(_L("drainRx : 0x%04x, fillTx : 0x%04x\n\r"),debug.iDrainingRxBuf,debug.iFillingTxBuf); |
|
2421 iConsole->Printf(_L("Txonchar: 0x%04x, TxOffchar: 0x%04x\n\r"),debug.iTxXon,debug.iTxXoff); |
|
2422 iConsole->Printf(_L("RxonChar: 0x%04x, RxOffchar: 0x%04x\n\r"),debug.iRxXon,debug.iRxXoff); |
|
2423 iConsole->Printf(_L("NumTX : 0x%04x, NumRx : 0x%04x\n\r"),debug.iTxChars,debug.iRxChars); |
|
2424 iConsole->Printf(_L("TxLen : 0x%04x, RxLen : 0x%04x\n\r"),debug.iTxLength,debug.iRxLength); |
|
2425 iConsole->Printf(_L("TxOffset: 0x%04x, RxOffset : 0x%04x\n\r"),debug.iTxOffset,debug.iRxOffset); |
|
2426 iConsole->Printf(_L("TxInts : 0x%04x, RxInts : 0x%04x\n\r"),debug.iTxIntCount,debug.iRxIntCount); |
|
2427 } |
|
2428 break; |
|
2429 case 's': |
|
2430 case 'S': |
|
2431 { |
|
2432 TUint signals=0; |
|
2433 if (iRole==ECommRoleDTE) |
|
2434 signals=iParent->DTEPort().Signals(); |
|
2435 else |
|
2436 signals=iParent->DCEPort().Signals(); |
|
2437 iConsole->Printf(_L("Signals: ")); |
|
2438 if (signals&KSignalCTS) |
|
2439 iConsole->Printf(_L("CTS ")); |
|
2440 if (signals&KSignalDSR) |
|
2441 iConsole->Printf(_L("DSR ")); |
|
2442 if (signals&KSignalDCD) |
|
2443 iConsole->Printf(_L("DCD ")); |
|
2444 if (signals&KSignalRTS) |
|
2445 iConsole->Printf(_L("RTS ")); |
|
2446 if (signals&KSignalDTR) |
|
2447 iConsole->Printf(_L("DTR ")); |
|
2448 iConsole->Printf(_L("\n\r")); |
|
2449 } |
|
2450 break; |
|
2451 default: |
|
2452 break; |
|
2453 } |
|
2454 |
|
2455 SetActive(); |
|
2456 iConsole->Read(iKeystroke,iStatus); |
|
2457 }; |
|
2458 |
|
2459 void CCommDebugDumper::DoCancel() |
|
2460 { |
|
2461 iConsole->ReadCancel(); |
|
2462 } |
|
2463 |
|
2464 #endif |
|
2465 |
|
2466 // EOF - ECUART.CPP |