1 // |
|
2 // * Copyright 2004 Neusoft America Inc. |
|
3 // * All rights reserved. |
|
4 // * This component and the accompanying materials are made available |
|
5 // * under the terms of the 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 // * Contributors: |
|
10 // * Keith Collins (Neusoft America Inc.) original software development and additional code and modifications. |
|
11 // * Thomas Gahagen (Neusoft America Inc.) additional code and modifications. |
|
12 // * Zhen Yuan (Neusoft America Inc.) additional code and modifications. |
|
13 // * |
|
14 // * Description: This file contains the implementation for the CPortC32Interface class. |
|
15 // * This class contains methods which are invoked by C32 when the |
|
16 // * associated client RComm public API is invoked. These methods |
|
17 // * are used to create, configure, read, write, and close logical |
|
18 // * serial ports. Instances of this class are created by the CSY's |
|
19 // * Port Factory. |
|
20 // |
|
21 |
|
22 /** @file PortC32InterfaceBase.cpp |
|
23 * This file contains the implementation for the CPortC32InterfaceBase class. |
|
24 * This base class contains methods which are invoked by C32 when the |
|
25 * associated client RComm public API is invoked. These methods |
|
26 * are used to create, configure, read, write, and close logical |
|
27 * serial ports. Instances of this class are created by the CSY's |
|
28 * Port Factory. |
|
29 */ |
|
30 |
|
31 #include <cdbcols.h> |
|
32 |
|
33 #include "PortC32InterfaceBase.h" |
|
34 #include "Portfactory.h" |
|
35 #include "Mux0710Protocol.h" |
|
36 #include "CsyMsgBufBPFrame.h" |
|
37 #include "ChannelMgrCmdData.h" |
|
38 #include "CommFrameReaderAo.h" |
|
39 #include "CsyDebugLogger.h" |
|
40 |
|
41 CPortC32InterfaceBase::CPortC32InterfaceBase(CPortFactory& aPortFactory, |
|
42 CPortFactory::TC32PortInfo& aPortInfo) |
|
43 /** |
|
44 * Constructor. |
|
45 * |
|
46 * @param aPortFactory - Reference to the port factory |
|
47 * @param aPortInfo - Reference to the port information |
|
48 */ |
|
49 : CPort(), |
|
50 iFramesWaitingToBeReadList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)), |
|
51 iFramesWaitingToBeReadIter(iFramesWaitingToBeReadList), |
|
52 iRole(ECommRoleDTE), |
|
53 iPortFactory(aPortFactory), |
|
54 iPortInfo(aPortInfo) |
|
55 {} |
|
56 |
|
57 void CPortC32InterfaceBase::ConstructL() |
|
58 /** |
|
59 * Base construction for channels |
|
60 */ |
|
61 { |
|
62 _LOG_L4C1("CPortC32InterfaceBase::ConstructL"); |
|
63 |
|
64 // create active objects to handle events |
|
65 iConfig.iTerminatorCount = 0; |
|
66 } |
|
67 |
|
68 CPortC32InterfaceBase::~CPortC32InterfaceBase() |
|
69 /** |
|
70 * Destructor. |
|
71 */ |
|
72 { |
|
73 _LOG_L4C1(">>CPortC32InterfaceBase::~CPortC32InterfaceBase"); |
|
74 |
|
75 // remove all frames from queue and delete |
|
76 RemoveWaitingAllFrames(EFalse); |
|
77 |
|
78 if (iMuxChannel) |
|
79 iMuxChannel->Close(this); |
|
80 |
|
81 _LOG_L4C1("<<CPortC32InterfaceBase::~CPortC32InterfaceBase"); |
|
82 } |
|
83 |
|
84 void CPortC32InterfaceBase::RemoveWaitingAllFrames(TBool aAddToFreeList) |
|
85 /** |
|
86 * |
|
87 */ |
|
88 { |
|
89 _LOG_L4C2("CPortC32InterfaceBase::RemoveWaitingAllFrames [aAddToFreeList=%d]", |
|
90 aAddToFreeList); |
|
91 |
|
92 CCsyMsgBufBpFrame* frame = NULL; |
|
93 iFramesWaitingToBeReadIter.SetToFirst(); |
|
94 while ((frame = iFramesWaitingToBeReadIter++) != NULL) |
|
95 { |
|
96 iFramesWaitingToBeReadList.Remove(*frame); |
|
97 if (aAddToFreeList) |
|
98 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(frame); |
|
99 else |
|
100 delete frame; |
|
101 } |
|
102 } |
|
103 |
|
104 /********************************************************************************/ |
|
105 /* Start of methods from CPort */ |
|
106 /********************************************************************************/ |
|
107 |
|
108 void CPortC32InterfaceBase::NotifySignalChange(TUint aSignalMask) |
|
109 /** |
|
110 * Called by C32 when the client requests NotifySignalChange. |
|
111 * |
|
112 * @param aSignal |
|
113 */ |
|
114 { |
|
115 _LOG_L4C2("CPortC32InterfaceBase::NotifySignalChange [port=%d]", GetPortNumber()); |
|
116 |
|
117 TUint reqSigs = aSignalMask & ~KSignalBreak; |
|
118 if (!reqSigs) |
|
119 { |
|
120 // User has only asked to be notified of break. |
|
121 SignalChangeCompleted(iSignals, KErrArgument); |
|
122 return; |
|
123 } |
|
124 iSignalMask |= reqSigs; |
|
125 |
|
126 iSignalChangeNotifyPending = ETrue; |
|
127 } |
|
128 |
|
129 void CPortC32InterfaceBase::NotifySignalChangeCancel() |
|
130 /** |
|
131 * Called by C32 when the client requests to cancel a NotifySignalChange |
|
132 * request. |
|
133 */ |
|
134 { |
|
135 _LOG_L4C2("CPortC32InterfaceBase::NotifySignalChangeCancel [port=%d]", GetPortNumber()); |
|
136 |
|
137 iSignalMask &= (KSignalBreak); // set mask to zero, excluding BREAK |
|
138 if (iSignalChangeNotifyPending) |
|
139 { |
|
140 iSignalChangeNotifyPending = EFalse; |
|
141 SignalChangeCompleted(iSignals, KErrCancel); |
|
142 } |
|
143 } |
|
144 |
|
145 void CPortC32InterfaceBase::StartRead(const TAny* aClientBuffer, TInt aLength) |
|
146 /** |
|
147 * This method is called by C32 to read data from the CSY in response to a |
|
148 * read request by a client RComm object. |
|
149 * |
|
150 * @param aClientBuffer - Pointer to where to put the new data |
|
151 * @param aLength - Length of data to read |
|
152 */ |
|
153 { |
|
154 _LOG_L4C1(" "); // please leave in this separator |
|
155 _LOG_L4C3(">>CPortC32InterfaceBase::StartRead [aLength=%d, port=%d] called by client", |
|
156 aLength, GetPortNumber()); |
|
157 |
|
158 if (iIsReadInProgress) |
|
159 { |
|
160 // Something has gone wrong - either the flag was not reset correctly |
|
161 // or C32 has lost track of a read |
|
162 // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); |
|
163 _LOG_L1C1("** Read waiting to complete already set **"); |
|
164 } |
|
165 |
|
166 // Set the flag that there is a read request outstanding |
|
167 iIsReadInProgress = ETrue; |
|
168 |
|
169 if (aLength == 0) |
|
170 { |
|
171 _LOG_L3C1("<<CPortC32InterfaceBase::StartRead - Length of 0?"); |
|
172 CompleteReadRequest(KErrArgument); |
|
173 return; |
|
174 } |
|
175 |
|
176 // save client info |
|
177 iClientBuffer = (TAny*) aClientBuffer; |
|
178 iPos = 0; |
|
179 |
|
180 if (aLength > 0) |
|
181 { |
|
182 _LOG_L3C1("Normal read"); |
|
183 iClientLength = aLength; |
|
184 iOneOrMore = EFalse; |
|
185 } |
|
186 else |
|
187 { |
|
188 _LOG_L3C1("Read one or more"); |
|
189 iClientLength = -aLength; |
|
190 iOneOrMore = ETrue; |
|
191 } |
|
192 |
|
193 if(!ReadFromBufOrQueue()) |
|
194 { |
|
195 _LOG_L3C1("No data to be read - request is outstanding"); |
|
196 } |
|
197 |
|
198 _LOG_L4C1("<<CPortC32InterfaceBase::StartRead"); |
|
199 _LOG_L4C1(" "); // please leave in this separator |
|
200 } |
|
201 |
|
202 void CPortC32InterfaceBase::StartWrite(const TAny* aClientBuffer, TInt aLength) |
|
203 /** |
|
204 * This method is called by C32 to write data to the CSY in response to a |
|
205 * write request by a client RComm object. |
|
206 * |
|
207 * @param aClientBuffer - Pointer to where to put the new data |
|
208 * @param aLength - Length of data to read |
|
209 */ |
|
210 { |
|
211 _LOG_L4C1(" "); // please leave in this separator |
|
212 _LOG_L4C3(">>CPortC32InterfaceBase::StartWrite [aLength=%d, port=%d] called by client", |
|
213 aLength, GetPortNumber()); |
|
214 |
|
215 if (iIsWriteInProgress) |
|
216 { |
|
217 // Something has gone wrong - either the flag was not reset correctly |
|
218 // or C32 has lost track of a write |
|
219 // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); |
|
220 _LOG_L1C1("** Write already waiting to complete **"); |
|
221 iIsWriteInProgress = EFalse; |
|
222 } |
|
223 |
|
224 iIsWriteInProgress = ETrue; |
|
225 |
|
226 if (aLength > 0) |
|
227 { |
|
228 // Get the outgoing message buffer for this dlc/port |
|
229 TDes8& buffer = iMuxChannel->RefToMsgBuffer(); |
|
230 |
|
231 // zero the buffer |
|
232 buffer.Zero(); |
|
233 |
|
234 // read data from client's address space |
|
235 TInt err = IPCRead(aClientBuffer, buffer); |
|
236 if (err == KErrNone) |
|
237 { |
|
238 iMuxChannel->SetOwner(this); |
|
239 err = iMuxChannel->PlaceOnOutboundQueue(); |
|
240 } |
|
241 else |
|
242 { |
|
243 _LOG_L1C2("** Read of client buffer failed [err=%d] **",err); |
|
244 } |
|
245 |
|
246 if (err) |
|
247 { |
|
248 CompleteWriteRequest(err); |
|
249 } |
|
250 } |
|
251 else |
|
252 { |
|
253 // no data to write is not an error, so just complete |
|
254 CompleteWriteRequest(KErrNone); |
|
255 } |
|
256 |
|
257 _LOG_L4C1("<<CPortC32InterfaceBase::StartWrite"); |
|
258 _LOG_L4C1(" "); // please leave in this separator |
|
259 } |
|
260 |
|
261 void CPortC32InterfaceBase::Destruct() |
|
262 /** |
|
263 * Called by C32 in response to a client Close request. |
|
264 */ |
|
265 { |
|
266 _LOG_L4C2(">>CPortC32InterfaceBase::Destruct [port=%d]", GetPortNumber()); |
|
267 |
|
268 // C32 requires us to do this here. |
|
269 delete this; |
|
270 |
|
271 _LOG_L4C1("<<CPortC32InterfaceBase::Destruct()"); |
|
272 } |
|
273 |
|
274 TInt CPortC32InterfaceBase::SetConfig(const TDesC8& aConfiguration) |
|
275 /** |
|
276 * Called by C32 in response to a client calling RComm::SetConfig(). |
|
277 * This method is used by the client to tell the CSY what parameters |
|
278 * are needed to instantiate the lower-level driver. |
|
279 * Note that the CSY reads the config data from CommDb and bpcaps.ini |
|
280 * and does not need or want the client to overwrite the config |
|
281 * parameters. |
|
282 * |
|
283 * @param aConfiguration - Descriptor containing the config params |
|
284 * @return KErrNone |
|
285 */ |
|
286 { |
|
287 _LOG_L4C2("CPortC32InterfaceBase::SetConfig [port=%d]",iPortInfo.iPortNumber); |
|
288 |
|
289 TCommConfigV01 c; |
|
290 |
|
291 Mem::FillZ(&c,sizeof(c)); |
|
292 TInt len=Min(aConfiguration.Length(),sizeof(c)); |
|
293 Mem::Copy(&c, aConfiguration.Ptr(),len); |
|
294 |
|
295 if(c.iTerminatorCount > KConfigMaxTerminators) |
|
296 { |
|
297 return KErrNotSupported; |
|
298 } |
|
299 else |
|
300 { |
|
301 for (TInt i=0; i < c.iTerminatorCount;i++) |
|
302 { |
|
303 _LOG_L4C2("Terminator: %d" ,c.iTerminator[i]); |
|
304 } |
|
305 } |
|
306 |
|
307 iConfig = c; |
|
308 //we will only use Terminators of this configure |
|
309 return KErrNone; |
|
310 } |
|
311 |
|
312 void CPortC32InterfaceBase::ReadCancel() |
|
313 /** |
|
314 * Called by C32 when the client requests to cancel a Read. |
|
315 */ |
|
316 { |
|
317 _LOG_L4C2(">>CPortC32InterfaceBase::ReadCancel [port=%d]", GetPortNumber()); |
|
318 |
|
319 iClientBuffer = NULL; |
|
320 iClientLength = 0; |
|
321 |
|
322 CompleteReadRequest(KErrCancel); |
|
323 |
|
324 _LOG_L4C1("<<CPortC32InterfaceBase::ReadCancel()"); |
|
325 } |
|
326 |
|
327 void CPortC32InterfaceBase::WriteCancel() |
|
328 /** |
|
329 * Called by C32 when the client requests to cancel a write operation. |
|
330 * Empty the mux queue of a possible message that is destined for the |
|
331 * baseband on the channel associated with this C32 port interface |
|
332 */ |
|
333 { |
|
334 _LOG_L4C2("CPortC32InterfaceBase::WriteCancel [port=%d]", GetPortNumber()); |
|
335 |
|
336 iMuxChannel->WriteCancel(); |
|
337 |
|
338 CompleteWriteRequest(KErrCancel); |
|
339 } |
|
340 |
|
341 /*****************************************************************************/ |
|
342 // Functions below here are the C32 pure virtuals which must be implemented // |
|
343 // by the CSY, but may not be supported by the CSY. // |
|
344 /*****************************************************************************/ |
|
345 |
|
346 void CPortC32InterfaceBase::Break(TInt /*aTime*/) |
|
347 /** |
|
348 * Called by C32. |
|
349 * Note that this method is not supported. |
|
350 * |
|
351 * @param aTime |
|
352 */ |
|
353 { |
|
354 _LOG_L4C2("CPortC32InterfaceBase::Break [port=%d]", GetPortNumber()); |
|
355 } |
|
356 |
|
357 void CPortC32InterfaceBase::BreakCancel() |
|
358 /** |
|
359 * Called by C32. |
|
360 * Note that this method is not supported. |
|
361 */ |
|
362 { |
|
363 _LOG_L4C2("CPortC32InterfaceBase::BreakCancel [port=%d]", GetPortNumber()); |
|
364 } |
|
365 |
|
366 TInt CPortC32InterfaceBase::GetConfig(TDes8& /*aPackage*/) const |
|
367 /** |
|
368 * Called by C32. |
|
369 * Note that this method is not supported. |
|
370 * @param aPackage - Reference to package |
|
371 * @return KErrNotSupported |
|
372 */ |
|
373 { |
|
374 _LOG_L4C2("CPortC32InterfaceBase::GetConfig [port=%d]", GetPortNumber()); |
|
375 return KErrNotSupported; |
|
376 } |
|
377 |
|
378 TInt CPortC32InterfaceBase::SetServerConfig(const TDesC8& /*aPackage*/) |
|
379 /** |
|
380 * Called by C32. |
|
381 * Note that this method is not supported. |
|
382 * @param aPackage - Reference to package |
|
383 * @return KErrNotSupported |
|
384 */ |
|
385 { |
|
386 _LOG_L4C2("CPortC32InterfaceBase::SetServerConfig [port=%d]", GetPortNumber()); |
|
387 return KErrNotSupported; |
|
388 } |
|
389 |
|
390 TInt CPortC32InterfaceBase::GetServerConfig(TDes8& /*aPackage*/) |
|
391 /** |
|
392 * Called by C32. |
|
393 * Note that this method is not supported. |
|
394 * @param aPackage - Reference to package |
|
395 * @return KErrNotSupported |
|
396 */ |
|
397 { |
|
398 _LOG_L4C2("CPortC32InterfaceBase::GetServerConfig [port=%d]", GetPortNumber()); |
|
399 return KErrNotSupported; |
|
400 } |
|
401 |
|
402 TInt CPortC32InterfaceBase::GetCaps(TDes8& aPackage) |
|
403 /** |
|
404 * Called by C32. |
|
405 * @param aPackage - Reference to package |
|
406 * @return KErrNone |
|
407 */ |
|
408 { |
|
409 _LOG_L4C2("CPortC32InterfaceBase::GetCaps [port=%d]", GetPortNumber()); |
|
410 |
|
411 // create a Package pointer |
|
412 TCommCaps* pckg = (TCommCaps*) &aPackage; |
|
413 |
|
414 // create a V01 reference |
|
415 TCommCapsV01& caps = (*pckg)(); |
|
416 |
|
417 // fill in the capabilities |
|
418 caps.iRate = KCapsBps19200 | KCapsBps115200; |
|
419 |
|
420 caps.iDataBits = KCapsData8; |
|
421 caps.iStopBits = KCapsStop1; |
|
422 caps.iParity = KCapsParityNone; |
|
423 caps.iHandshake = KCapsSignalCTSSupported | |
|
424 KCapsSignalDSRSupported | |
|
425 KCapsSignalDCDSupported | |
|
426 KCapsSignalRTSSupported | |
|
427 KCapsSignalDTRSupported; |
|
428 caps.iSignals = KCapsObeyCTSSupported | KCapsObeyDSRSupported; |
|
429 caps.iFifo = KCapsHasFifo; |
|
430 caps.iSIR = KCapsSIR115kbps; |
|
431 |
|
432 // TCommCapsV02 support |
|
433 if (aPackage.Length()==sizeof(TCommCapsV02)) |
|
434 { |
|
435 TCommCapsV02* commcaps = (TCommCapsV02*)(aPackage.Ptr()); |
|
436 commcaps->iNotificationCaps = |
|
437 KNotifyFlowControlChangeSupported | |
|
438 KNotifyDataAvailableSupported; |
|
439 commcaps->iFlowControlCaps = KCapsFlowControlStatusSupported; |
|
440 } |
|
441 |
|
442 return KErrNone; |
|
443 } |
|
444 |
|
445 TInt CPortC32InterfaceBase::GetSignals(TUint& aSignals) |
|
446 /** |
|
447 * get the status of the signal pins |
|
448 * |
|
449 * @param aSignals signals will be written to this descriptor |
|
450 * @return KErrNone always |
|
451 */ |
|
452 { |
|
453 _LOG_L4C2("CPortC32InterfaceBase::GetSignals [port=%d]", GetPortNumber()); |
|
454 aSignals = iSignals; |
|
455 return KErrNone; |
|
456 } |
|
457 |
|
458 TInt CPortC32InterfaceBase::SetSignalsToMark(TUint aSignals) |
|
459 /** |
|
460 * set selected signals to high (logical 1) |
|
461 * |
|
462 * @param aSignals bitmask with the signals to be set |
|
463 * @return KErrNone always |
|
464 */ |
|
465 { |
|
466 _LOG_L4C2("CPortC32InterfaceBase::SetSignalsToMark [port=%d]", GetPortNumber()); |
|
467 |
|
468 TInt ret = KErrNone; |
|
469 TUint alreadySent = iSentSignals & aSignals; |
|
470 if (alreadySent == aSignals) |
|
471 { |
|
472 _LOG_L4C1("Signals already set to high"); |
|
473 } |
|
474 else |
|
475 { |
|
476 TUint temp = iSentSignals | aSignals; |
|
477 ret = SetV24Signals(temp); |
|
478 if (ret == KErrNone) |
|
479 { |
|
480 iSentSignals = temp; |
|
481 _LOG_L4C2("iSentSignals 0x%08x",iSentSignals); |
|
482 } |
|
483 } |
|
484 |
|
485 return ret; |
|
486 } |
|
487 |
|
488 TInt CPortC32InterfaceBase::SetSignalsToSpace(TUint aSignals) |
|
489 /** |
|
490 * set selected signals to low (logical 0) |
|
491 * |
|
492 * @param aSignals bitmask with the signals to be cleared |
|
493 * @return KErrNone always |
|
494 */ |
|
495 { |
|
496 _LOG_L4C2("CPortC32InterfaceBase::SetSignalsToSpace [port=%d]", GetPortNumber()); |
|
497 |
|
498 TInt ret = KErrNone; |
|
499 TUint change = iSentSignals & aSignals; |
|
500 if (change) |
|
501 { |
|
502 TUint temp = iSentSignals & ~aSignals; |
|
503 ret = SetV24Signals(temp); |
|
504 if (ret == KErrNone) |
|
505 { |
|
506 iSentSignals = temp; |
|
507 _LOG_L4C2("iSentSignals 0x%08x",iSentSignals); |
|
508 } |
|
509 } |
|
510 else |
|
511 { |
|
512 _LOG_L4C1("Signals already set to low"); |
|
513 } |
|
514 |
|
515 return ret; |
|
516 } |
|
517 |
|
518 TInt CPortC32InterfaceBase::GetReceiveBufferLength(TInt& aLength) const |
|
519 /** |
|
520 * Called by C32. |
|
521 * @param aLength |
|
522 * @return KErrNone |
|
523 */ |
|
524 { |
|
525 _LOG_L4C2("CPortC32InterfaceBase::GetReceiveBufferLength [port=%d]", GetPortNumber()); |
|
526 |
|
527 aLength = KMaxIpPacketSize; |
|
528 return KErrNone; |
|
529 } |
|
530 |
|
531 TInt CPortC32InterfaceBase::SetReceiveBufferLength(TInt /*aLength*/) |
|
532 /** |
|
533 * Called by C32. |
|
534 * Note that this method is not supported. |
|
535 * @param aLength |
|
536 * @return KErrNotSupported |
|
537 */ |
|
538 { |
|
539 _LOG_L4C2("CPortC32InterfaceBase::SetReceiveBufferLength [port=%d]", GetPortNumber()); |
|
540 return KErrNotSupported; |
|
541 } |
|
542 |
|
543 void CPortC32InterfaceBase::NotifyConfigChange() |
|
544 /** |
|
545 * Called by C32. |
|
546 * Note that this method is not supported. |
|
547 */ |
|
548 { |
|
549 _LOG_L4C2("CPortC32InterfaceBase::NotifyConfigChange [port=%d]", GetPortNumber()); |
|
550 } |
|
551 |
|
552 void CPortC32InterfaceBase::NotifyDataAvailable() |
|
553 /** |
|
554 * Called by C32. |
|
555 * Note that this method is not supported. |
|
556 */ |
|
557 { |
|
558 _LOG_L4C2("CPortC32InterfaceBase::NotifyDataAvailable [port=%d]", GetPortNumber()); |
|
559 |
|
560 iDataAvailableNotifyPending = ETrue; |
|
561 } |
|
562 |
|
563 void CPortC32InterfaceBase::NotifyDataAvailableCancel() |
|
564 /** |
|
565 * Called by C32. |
|
566 * Note that this method is not supported. |
|
567 */ |
|
568 { |
|
569 _LOG_L4C2("CPortC32InterfaceBase::NotifyDataAvailableCancel [port=%d]", GetPortNumber()); |
|
570 |
|
571 if (iDataAvailableNotifyPending) |
|
572 { |
|
573 iDataAvailableNotifyPending = EFalse; |
|
574 NotifyDataAvailableCompleted(KErrCancel); |
|
575 } |
|
576 } |
|
577 |
|
578 void CPortC32InterfaceBase::NotifyConfigChangeCancel() |
|
579 /** |
|
580 * Called by C32. |
|
581 * Note that this method is not supported. |
|
582 */ |
|
583 { |
|
584 _LOG_L4C2("CPortC32InterfaceBase::NotifyConfigChangeCancel [port=%d]", GetPortNumber()); |
|
585 } |
|
586 |
|
587 void CPortC32InterfaceBase::NotifyFlowControlChange() |
|
588 /** |
|
589 * Called by C32. |
|
590 * Note that this method is not supported. |
|
591 */ |
|
592 { |
|
593 _LOG_L3C2("CPortC32InterfaceBase::NotifyFlowControlChange [port=%d]", GetPortNumber()); |
|
594 |
|
595 iFlowControlNotifyPending = ETrue; |
|
596 } |
|
597 |
|
598 void CPortC32InterfaceBase::NotifyFlowControlChangeCancel() |
|
599 /** |
|
600 * Called by C32 to cancel a previous notification request. |
|
601 */ |
|
602 { |
|
603 _LOG_L4C2("CPortC32InterfaceBase::NotifyFlowControlChangeCancel [port=%d]", GetPortNumber()); |
|
604 |
|
605 if (iFlowControlNotifyPending) |
|
606 { |
|
607 iFlowControlNotifyPending = EFalse; |
|
608 FlowControlChangeCompleted(iCsyAllowedToSendFrames, KErrCancel); |
|
609 } |
|
610 } |
|
611 |
|
612 void CPortC32InterfaceBase::NotifyBreak() |
|
613 /** |
|
614 * Called by C32. |
|
615 * Note that this method is not supported. |
|
616 */ |
|
617 { |
|
618 _LOG_L4C2("CPortC32InterfaceBase::NotifyBreak [port=%d]", GetPortNumber()); |
|
619 } |
|
620 |
|
621 void CPortC32InterfaceBase::NotifyBreakCancel() |
|
622 /** |
|
623 * Called by C32. |
|
624 * Note that this method is not supported. |
|
625 */ |
|
626 { |
|
627 _LOG_L4C2("CPortC32InterfaceBase::NotifyBreakCancel [port=%d]", GetPortNumber()); |
|
628 } |
|
629 |
|
630 void CPortC32InterfaceBase::NotifyOutputEmpty() |
|
631 /** |
|
632 * Called by C32. |
|
633 * Note that this method is not supported. |
|
634 */ |
|
635 { |
|
636 _LOG_L4C2("CPortC32InterfaceBase::NotifyOutputEmpty [port=%d]", GetPortNumber()); |
|
637 } |
|
638 |
|
639 void CPortC32InterfaceBase::NotifyOutputEmptyCancel() |
|
640 /** |
|
641 * Called by C32. |
|
642 * Note that this method is not supported. |
|
643 */ |
|
644 { |
|
645 _LOG_L4C2("CPortC32InterfaceBase::NotifyOutputEmptyCancel [port=%d]", GetPortNumber()); |
|
646 } |
|
647 |
|
648 TInt CPortC32InterfaceBase::GetFlowControlStatus(TFlowControl& aFlowControl) |
|
649 /** |
|
650 * Called by C32 to return the port's flow control state. |
|
651 * |
|
652 * @param aFlowControl Reference to location to write the flow control value |
|
653 * @return KErrNone |
|
654 */ |
|
655 { |
|
656 _LOG_L3C2("CPortC32InterfaceBase::GetFlowControlStatus [Port=%d]", GetPortNumber()); |
|
657 |
|
658 aFlowControl = EFlowControlOff; |
|
659 if ((iCsyAllowedToSendFrames == EFlowControlOn) || |
|
660 (iMuxChannel->CsyToModemFlowControl() == EFlowControlOn)) |
|
661 aFlowControl = EFlowControlOn; |
|
662 |
|
663 return KErrNone; |
|
664 } |
|
665 |
|
666 TInt CPortC32InterfaceBase::GetRole(TCommRole& aRole) |
|
667 /** |
|
668 * Called by C32 to return the port's role. The role will be either |
|
669 * DTE or DCE. |
|
670 * @param aRole - Reference to location to write the port role (DTE or DCE). |
|
671 * @return KErrNone |
|
672 */ |
|
673 { |
|
674 _LOG_L4C2("CPortC32InterfaceBase::GetRole [port=%d]", GetPortNumber()); |
|
675 |
|
676 aRole = iRole; // or get from RDevComm instance ??? |
|
677 return KErrNone; |
|
678 } |
|
679 |
|
680 TInt CPortC32InterfaceBase::SetRole(TCommRole aRole) |
|
681 /** |
|
682 * Called by C32 to set the port role to either DTE or DCE. |
|
683 * @param aRole - DTE or DCE |
|
684 * @return KErrNone. |
|
685 */ |
|
686 { |
|
687 _LOG_L4C2("CPortC32InterfaceBase::SetRole [aRole=%d]", aRole); |
|
688 |
|
689 #if defined _DEBUG |
|
690 if (aRole == ECommRoleDTE) |
|
691 { |
|
692 _LOG_L4C2("CPortC32InterfaceBase::SetRole() - DTE for Port %d", iPortInfo.iPortNumber); |
|
693 } |
|
694 else if (aRole == ECommRoleDCE) |
|
695 { |
|
696 _LOG_L4C2("CPortC32InterfaceBase::SetRole() - DCE for Port %d", iPortInfo.iPortNumber); |
|
697 } |
|
698 else |
|
699 { |
|
700 _LOG_L4C3("CPortC32InterfaceBase::SetRole() - Unknown Role %d for Port %d", aRole, iPortInfo.iPortNumber); |
|
701 } |
|
702 #endif |
|
703 |
|
704 iRole = aRole; |
|
705 return KErrNone; |
|
706 } |
|
707 |
|
708 |
|
709 void CPortC32InterfaceBase::FreeMemory() |
|
710 /** |
|
711 * Called by C32 when the client wishes the CSY to free some memory. |
|
712 * Note that this method does nothing. The CSY uses statically-allocated |
|
713 * memory. In principle there is no memory that can be freed within the CSY. |
|
714 * |
|
715 * |
|
716 */ |
|
717 { |
|
718 _LOG_L4C2("CPortC32InterfaceBase::FreeMemory [port=%d]", GetPortNumber()); |
|
719 |
|
720 // MAF missing functionality |
|
721 } |
|
722 |
|
723 /********************************************************************************/ |
|
724 /* End of methods from CPort */ |
|
725 /********************************************************************************/ |
|
726 |
|
727 void CPortC32InterfaceBase::CompleteWriteRequest(TInt aStatus) |
|
728 /** |
|
729 * This method is called by the CSY object writing to the LDD and is used to |
|
730 * signal C32 that its message has been sent to the BP. C32 is now free to |
|
731 * write another message to the CSY on this port interface. |
|
732 * @param aStatus - Status of message write to BP |
|
733 * |
|
734 */ |
|
735 { |
|
736 _LOG_L4C3("CPortC32InterfaceBase::CompleteWriteRequest [aStatus=%d, Port=%d]", aStatus, GetPortNumber()); |
|
737 |
|
738 if (iIsWriteInProgress) |
|
739 { |
|
740 iIsWriteInProgress = EFalse; |
|
741 WriteCompleted(aStatus); |
|
742 } |
|
743 else |
|
744 { |
|
745 _LOG_L3C1("* No write outstanding to complete *"); |
|
746 } |
|
747 } |
|
748 |
|
749 void CPortC32InterfaceBase::CompleteReadRequest(TInt aStatus) |
|
750 /** |
|
751 * This method is called to complete the C32 client's read request. |
|
752 * |
|
753 * @param aStatus - Status read result |
|
754 */ |
|
755 { |
|
756 _LOG_L4C2("CPortC32InterfaceBase::CompleteReadRequest [aStatus=%d]", aStatus); |
|
757 |
|
758 if (iIsReadInProgress) |
|
759 { |
|
760 iIsReadInProgress = EFalse; |
|
761 ReadCompleted(aStatus); |
|
762 } |
|
763 else |
|
764 { |
|
765 _LOG_L3C1("* No read outstanding to complete *"); |
|
766 } |
|
767 } |
|
768 |
|
769 void CPortC32InterfaceBase::Shutdown() |
|
770 /** |
|
771 * Returns all the used memory |
|
772 * |
|
773 * |
|
774 */ |
|
775 { |
|
776 _LOG_L4C2("CPortC32InterfaceBase::Shutdown [port=%d]", GetPortNumber()); |
|
777 |
|
778 // MAF missing functionality |
|
779 } |
|
780 |
|
781 void CPortC32InterfaceBase::ModemAndCsyToClientFlowCtrl(const TFlowControl aFlowControl) |
|
782 /** |
|
783 * This method is called to update the port's flow control state. |
|
784 * If a notification is pending then complete it. |
|
785 * @param aFlowControl New flow control state |
|
786 * |
|
787 */ |
|
788 { |
|
789 _LOG_L4C2("CPortC32InterfaceBase::ModemAndCsyToClientFlowCtrl [aFlowControl=%d]", aFlowControl); |
|
790 _LOG_L4C2("[port=%d]", GetPortNumber()); |
|
791 |
|
792 if (iCsyAllowedToSendFrames != aFlowControl) |
|
793 { |
|
794 iCsyAllowedToSendFrames = aFlowControl; |
|
795 if (iFlowControlNotifyPending) |
|
796 { |
|
797 iFlowControlNotifyPending = EFalse; |
|
798 FlowControlChangeCompleted(iCsyAllowedToSendFrames, KErrNone); |
|
799 } |
|
800 } |
|
801 } |
|
802 |
|
803 TInt CPortC32InterfaceBase::SetV24Signals(const TUint aRs232Signals) |
|
804 { |
|
805 _LOG_L4C2("CPortC32InterfaceBase::SetV24Signals [aRs232Signals=0x%08x]", |
|
806 aRs232Signals); |
|
807 _LOG_L4C2("port=%d", GetPortNumber()); |
|
808 |
|
809 // From 27.010 Sending |
|
810 // |
|
811 // Bit number/name DTE DCE |
|
812 // |
|
813 // 3, RTC DTR DSR |
|
814 // 4, RTR RTS CTS |
|
815 // 7, IC always 0 RI |
|
816 // 8, DV always 1 DCD |
|
817 |
|
818 TUint8 v24signals = 0; |
|
819 if (iRole == ECommRoleDTE) |
|
820 { |
|
821 _LOG_L3C1("DTE sending entity"); |
|
822 |
|
823 if (aRs232Signals & KSignalDTR) |
|
824 { |
|
825 _LOG_L3C1("DTR set (setting RTC)"); |
|
826 v24signals |= KV24SignalRTC; |
|
827 } |
|
828 |
|
829 if (aRs232Signals & KSignalRTS) |
|
830 { |
|
831 _LOG_L3C1("RTS set (setting RTR)"); |
|
832 v24signals |= KV24SignalRTR; |
|
833 } |
|
834 |
|
835 // DV always 1 |
|
836 v24signals |= 0x80; |
|
837 } |
|
838 else if (iRole == ECommRoleDCE) |
|
839 { |
|
840 _LOG_L3C1("DCE sending entity"); |
|
841 |
|
842 if (aRs232Signals & KSignalDSR) |
|
843 { |
|
844 _LOG_L3C1("DSR set (setting RTC)"); |
|
845 v24signals |= KV24SignalRTC; |
|
846 } |
|
847 |
|
848 if (aRs232Signals & KSignalCTS) |
|
849 { |
|
850 _LOG_L3C1("CTS set (setting RTR)"); |
|
851 v24signals |= KV24SignalRTR; |
|
852 } |
|
853 |
|
854 if (aRs232Signals & KSignalRNG) |
|
855 { |
|
856 _LOG_L3C1("RNG set (setting IC)"); |
|
857 v24signals |= KV24SignalIC; |
|
858 } |
|
859 |
|
860 if (aRs232Signals & KSignalDCD) |
|
861 { |
|
862 _LOG_L3C1("DCD set (setting DV)"); |
|
863 v24signals |= KV24SignalDV; |
|
864 } |
|
865 } |
|
866 else |
|
867 { |
|
868 _LOG_L3C1("** Unknown role **"); |
|
869 } |
|
870 |
|
871 return iMuxChannel->SendMscCommand(v24signals); |
|
872 } |
|
873 |
|
874 void CPortC32InterfaceBase::ReceivedV24Signals(const TUint8 aV24Signals) |
|
875 { |
|
876 _LOG_L4C2("CPortC32InterfaceBase::ReceivedV24Signals [aV24Signals=0x%x]", |
|
877 aV24Signals); |
|
878 _LOG_L4C2("port=%d", GetPortNumber()); |
|
879 |
|
880 // From 27.010 Receiving (mapping from control signal octet) |
|
881 // |
|
882 // Bit number/name DTE DCE |
|
883 // |
|
884 // 3, RTC DSR DTR |
|
885 // 4, RTR CTS RFR/RTS |
|
886 // 7, IC RI -ignored |
|
887 // 8, DV DCD -ignored |
|
888 |
|
889 TUint signals = 0; |
|
890 if (iRole == ECommRoleDTE) |
|
891 { |
|
892 _LOG_L3C1("DTE receiving entity"); |
|
893 |
|
894 // RTC (bit 3) |
|
895 if (aV24Signals & KV24SignalRTC) |
|
896 { |
|
897 _LOG_L3C1("Device ready to communicate (setting DSR)"); |
|
898 signals |= KSignalDSR; |
|
899 } |
|
900 // RTR (bit 4) |
|
901 if (aV24Signals & KV24SignalRTR) |
|
902 { |
|
903 _LOG_L3C1("Device ready to receive (setting CTS)"); |
|
904 signals |= KSignalCTS; |
|
905 } |
|
906 // IC (bit 7) |
|
907 if (aV24Signals & KV24SignalIC) |
|
908 { |
|
909 _LOG_L3C1("Incoming call (setting RNG)"); |
|
910 signals |= KSignalRNG; |
|
911 } |
|
912 // DV (bit 8) |
|
913 if (aV24Signals & KV24SignalDV) |
|
914 { |
|
915 _LOG_L3C1("Data valid (setting DCD)"); |
|
916 signals |= KSignalDCD; |
|
917 } |
|
918 } |
|
919 else if (iRole == ECommRoleDCE) |
|
920 { |
|
921 _LOG_L3C1("DCE receiving entity"); |
|
922 |
|
923 // RTC (bit 3) |
|
924 if (aV24Signals & KV24SignalRTC) |
|
925 { |
|
926 _LOG_L3C1("Device ready to communicate (setting DTR)"); |
|
927 signals |= KSignalDTR; |
|
928 } |
|
929 // RTR (bit 4) |
|
930 if (aV24Signals & KV24SignalRTR) |
|
931 { |
|
932 _LOG_L3C1("Device ready to receive (setting RTS)"); |
|
933 signals |= KSignalRTS; |
|
934 } |
|
935 } |
|
936 else |
|
937 { |
|
938 _LOG_L3C1("** Unknown role **"); |
|
939 } |
|
940 |
|
941 signals &= iSignalMask; |
|
942 if (signals != iSignals) |
|
943 { |
|
944 iSignals = signals; |
|
945 |
|
946 // notification processing |
|
947 if (iSignalChangeNotifyPending) |
|
948 SignalChangeCompleted(iSignals, KErrNone); |
|
949 } |
|
950 } |
|
951 |
|
952 void CPortC32InterfaceBase::SetMuxChannel(CChannelMgrCmdData* aMuxChannel) |
|
953 /** |
|
954 * This method sets the flow control state for the port object |
|
955 * by reading the specified channel's flow control state. |
|
956 * @param aMuxChannel - Pointer to the channel |
|
957 * |
|
958 */ |
|
959 { |
|
960 iMuxChannel = aMuxChannel; |
|
961 if (iMuxChannel != NULL) |
|
962 { |
|
963 ModemAndCsyToClientFlowCtrl(iMuxChannel-> |
|
964 GetModemAndCsyToClientFlowControl()); |
|
965 } |
|
966 else |
|
967 { |
|
968 _LOG_L1C1("** SetMuxChannel - channel not ready **"); |
|
969 } |
|
970 } |
|
971 |
|
972 void CPortC32InterfaceBase::SetDataAvailable() |
|
973 /** |
|
974 * This method is called to set the port's data available state. |
|
975 * If the data available notification is pending then complete it. |
|
976 */ |
|
977 { |
|
978 _LOG_L4C2("CPortC32InterfaceBase::SetDataAvailable [port=%d]", GetPortNumber()); |
|
979 |
|
980 if (iDataAvailableNotifyPending) |
|
981 { |
|
982 iDataAvailableNotifyPending = EFalse; |
|
983 NotifyDataAvailableCompleted(KErrNone); |
|
984 } |
|
985 } |
|
986 |
|
987 void CPortC32InterfaceBase::CompleteOutstandingRequest() |
|
988 /** |
|
989 * This method is called to complete an outstanding request. |
|
990 * There can be read and write requests that are outstanding. |
|
991 */ |
|
992 { |
|
993 _LOG_L4C1("CPortC32InterfaceBase::CompleteOutstandingRequest"); |
|
994 |
|
995 if (iIsReadInProgress) |
|
996 CompleteReadRequest(KErrCancel); |
|
997 |
|
998 if (iIsWriteInProgress) |
|
999 CompleteWriteRequest(KErrCancel); |
|
1000 } |
|
1001 |
|
1002 |
|