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: The CChannelMgrBase class defines a single 3GPP 27.010 based logical channel |
|
15 // * called DLC. This base class is inherited by derived control and data channel |
|
16 // * classes which add specific channel type behavior. |
|
17 // |
|
18 |
|
19 // ChannelMgrBase.cpp |
|
20 |
|
21 /** @file ChannelMgrBase.cpp |
|
22 * |
|
23 */ |
|
24 |
|
25 #include "ChannelMgrBase.h" |
|
26 #include "CsyMsgBufBpFrame.h" |
|
27 #include "PortC32Interface.h" |
|
28 #include "Mux0710Protocol.h" |
|
29 #include "CsyDebugLogger.h" |
|
30 #include "CommFrameWriterAo.h" |
|
31 |
|
32 CChannelMgrBase::CChannelMgrBase(const TUint8 aDlcNum, |
|
33 CPortFactory& aPortFactory, |
|
34 CMux0710Protocol& aMux0710Protocol) |
|
35 : iV24Signals(0x0D), |
|
36 iDlcNum(aDlcNum), |
|
37 #ifndef __CSY_PROTOTYPE__ |
|
38 iChannelState(ECsyChannelStateDisconnected), |
|
39 #else |
|
40 iChannelState(ECsyChannelStateConnected), |
|
41 #endif |
|
42 iPortFactory(aPortFactory), |
|
43 iPortC32Interface(NULL), |
|
44 #ifndef __CSY_PROTOTYPE__ |
|
45 iMux0710Protocol(aMux0710Protocol), |
|
46 #else |
|
47 iMux0710Protocol(aMux0710Protocol), |
|
48 iChannelReady(ETrue), |
|
49 iInitFinished(ETrue), |
|
50 #endif |
|
51 iModemAllowedToSendFrames(EFlowControlOff) |
|
52 /** |
|
53 * Constructor. |
|
54 * @param aDlcNum - DLC number for the channel |
|
55 * @param aPortFactory - Reference to port factory |
|
56 * @param aMux0710Protocol - Reference to the Mux 27.010 object |
|
57 */ |
|
58 { |
|
59 } |
|
60 |
|
61 CChannelMgrBase::~CChannelMgrBase() |
|
62 /** |
|
63 * Destructor. Delete all resources and memory allocated by this object. |
|
64 */ |
|
65 { |
|
66 _LOG_L4C1("CChannelMgrBase::~CChannelMgrBase"); |
|
67 |
|
68 delete iChannelObserverAo; |
|
69 delete iTimeouter; |
|
70 } |
|
71 |
|
72 void CChannelMgrBase::ConstructL() |
|
73 /** |
|
74 * Create any instances and allocate any memory used by this object. |
|
75 */ |
|
76 { |
|
77 _LOG_L4C1("CChannelMgrBase::ConstructL"); |
|
78 |
|
79 iChannelObserverAo = CChannelObserverAo::NewL(); |
|
80 CActiveScheduler::Add(iChannelObserverAo); |
|
81 |
|
82 iTimeouter = CActiveTimeouter::NewL(*this); |
|
83 iTimeoutVal = KOneSecond; |
|
84 iTxCountLimit = 10; |
|
85 } |
|
86 |
|
87 TDes8& CChannelMgrBase::RefToMsgBuffer() |
|
88 /** |
|
89 * This method returns a pointer to the message buffer to use |
|
90 * to format a message to send to the baseband. |
|
91 * |
|
92 * @return pointer |
|
93 */ |
|
94 { |
|
95 // only one buffer is available for messages to the baseband |
|
96 return iDataToSendToModem; |
|
97 } |
|
98 |
|
99 void CChannelMgrBase::ProcessRecvFrame(CCsyMsgBufBpFrame* aBpFrame) |
|
100 /** |
|
101 * This method is called to process a frame that was received |
|
102 * |
|
103 * @param aBpFrame - Pointer to the frame buffer |
|
104 */ |
|
105 { |
|
106 if (aBpFrame->GetFrameType() != KCsy0710CTLUIH) |
|
107 ProcessNonUihRecvFrame(aBpFrame); |
|
108 else |
|
109 ProcessRecvUihFrame(aBpFrame); |
|
110 } |
|
111 |
|
112 TInt CChannelMgrBase::PlaceOnOutboundQueue() |
|
113 /** |
|
114 * This method is called to process the "to baseband Message Q" event |
|
115 * for the channel. This event indicates that there is a message |
|
116 * that needs to be sent to the baseband. |
|
117 */ |
|
118 { |
|
119 _LOG_L4C2(">>CChannelMgrBase::PlaceOnOutboundQueue [iDlcNum=%d]",iDlcNum); |
|
120 |
|
121 TInt ret = KErrNone; |
|
122 |
|
123 if (iCsyAllowedToSendFrames == EFlowControlOn) |
|
124 { |
|
125 _LOG_L4C1("Csy -> modem flow control = ON"); |
|
126 iDelayedWriteToModem = ETrue; |
|
127 |
|
128 // We cannot fragment and place it on the write queue yet since |
|
129 // flow control in the direction of Csy to modem is set to ON. |
|
130 |
|
131 _LOG_L4C1("<<CChannelMgrBase::PlaceOnOutboundQueue - write delayed"); |
|
132 return KErrNone; |
|
133 } |
|
134 |
|
135 if (iChannelState != ECsyChannelStateConnected) |
|
136 { |
|
137 // this should not happen (should be caught by flow control above) |
|
138 // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); |
|
139 _LOG_L4C1("<<CChannelMgrBase::PlaceOnOutboundQueue - write ignored"); |
|
140 return KErrNone; |
|
141 } |
|
142 |
|
143 ret = iMux0710Protocol.Create0710DataFrames(iDataToSendToModem, iDlcNum); |
|
144 |
|
145 _LOG_L4C2("<<CChannelMgrBase::PlaceOnOutboundQueue [ret=%d]",ret); |
|
146 return ret; |
|
147 } |
|
148 |
|
149 void CChannelMgrBase::WriteCancel() |
|
150 /** |
|
151 * The client has requested the write by this DLC be cancelled. |
|
152 */ |
|
153 { |
|
154 _LOG_L4C1(">>CChannelMgrBase::WriteCancel"); |
|
155 |
|
156 if (iDelayedWriteToModem) |
|
157 { |
|
158 _LOG_L4C1("Delayed write has been cancelled"); |
|
159 iDelayedWriteToModem = EFalse; |
|
160 } |
|
161 |
|
162 _LOG_L4C1("Remove any frames on write queue"); |
|
163 |
|
164 // remove any frames (if any exist) from the writer Ao and |
|
165 // place them on the free queue |
|
166 |
|
167 CCommFrameWriterAo* writer = iPortFactory.GetCommWriterAo(); |
|
168 |
|
169 writer->RemoveAnyDlcFramesOnWriteList(iDlcNum, EFalse); |
|
170 writer->RemoveAnyDlcFramesFromWaitList(iDlcNum, EFalse); |
|
171 |
|
172 _LOG_L4C1("<<CChannelMgrBase::WriteCancel"); |
|
173 } |
|
174 |
|
175 TInt CChannelMgrBase::Connect() |
|
176 /** |
|
177 * Request to connect the channel. If the channel state is not "Connected" |
|
178 * then issue a SABM frame and change the channel state to "Connecting". |
|
179 * |
|
180 * @return KErrNone or KErrGeneral |
|
181 */ |
|
182 { |
|
183 _LOG_L4C3(">>CChannelMgrBase::Connect [iDlcNum=%d,iChannelState=%d]", |
|
184 iDlcNum,iChannelState); |
|
185 |
|
186 TInt ret = KErrNone; |
|
187 if (iChannelState != ECsyChannelStateConnected) |
|
188 { |
|
189 _LOG_L4C1("Dlc is not currently connected"); |
|
190 ret = iMux0710Protocol.Create0710ControlFrame(CMux0710Protocol::ESABM, iDlcNum); |
|
191 if (ret == KErrNone) |
|
192 { |
|
193 iChannelState = ECsyChannelStateConnecting; |
|
194 iInitFinished = EFalse; |
|
195 iTimeouter->Stop(); |
|
196 iTimeouter->Start(iTimeoutVal); |
|
197 iTxCount = iTxCountLimit; |
|
198 } |
|
199 else |
|
200 { |
|
201 _LOG_L1C1("** Cannot send SABM **"); |
|
202 } |
|
203 } |
|
204 else |
|
205 { |
|
206 _LOG_L2C1("** Ignored Connect **"); |
|
207 ret = KErrGeneral; |
|
208 } |
|
209 |
|
210 _LOG_L4C2("<<CChannelMgrBase::Connect [ret=%d]",ret); |
|
211 return ret; |
|
212 } |
|
213 |
|
214 TInt CChannelMgrBase::ParameterNegotiate() |
|
215 /** |
|
216 * Request to parameter negotiation for the channel. If the channel state is not |
|
217 * "Connected" then issue a UIH frame and with the parameter negotiation. |
|
218 * |
|
219 * @return KErrNone or KErrGeneral |
|
220 */ |
|
221 { |
|
222 _LOG_L4C3(">>CChannelMgrBase::ParameterNegotiate [iDlcNum=%d,iChannelState=%d]", |
|
223 iDlcNum,iChannelState); |
|
224 |
|
225 TInt ret = KErrNone; |
|
226 if (iChannelState != ECsyChannelStateConnected) |
|
227 { |
|
228 _LOG_L4C1("Dlc is not currently connected"); |
|
229 if (iMux0710Protocol.Create0710ControlFrame(CMux0710Protocol::EUIH, iDlcNum) == KErrNone) |
|
230 { |
|
231 iChannelState = ECsyChannelStateParameterNegotiating; |
|
232 iTimeouter->Stop(); |
|
233 iTimeouter->Start(iTimeoutVal); |
|
234 iTxCount = iTxCountLimit; |
|
235 } |
|
236 else |
|
237 { |
|
238 _LOG_L1C1("** Cannot send EUIH Param Neg. **"); |
|
239 ret = KErrGeneral; |
|
240 } |
|
241 } |
|
242 else |
|
243 { |
|
244 _LOG_L2C1("** Ignored ParameterNegotiate **"); |
|
245 } |
|
246 |
|
247 _LOG_L4C2("<<CChannelMgrBase::ParameterNegotiate [ret=%d]",ret); |
|
248 return ret; |
|
249 } |
|
250 |
|
251 TInt CChannelMgrBase::Disconnect() |
|
252 /** |
|
253 * Request to disconnect the channel. If the channel is not "Disconnected" |
|
254 * then issue a DISC frame and change the channel state to "Disconnecting". |
|
255 * |
|
256 * @return KErrNone or error code |
|
257 */ |
|
258 { |
|
259 _LOG_L4C3(">>CChannelMgrBase::Disconnect [iDlcNum=%d,iChannelState=%d]", |
|
260 iDlcNum,iChannelState); |
|
261 |
|
262 TInt ret = KErrNone; |
|
263 if (iChannelState == ECsyChannelStateConnected) |
|
264 { |
|
265 _LOG_L4C1("Dlc is currently connected"); |
|
266 if (iMux0710Protocol.Create0710ControlFrame(CMux0710Protocol::EDISC, iDlcNum) == KErrNone) |
|
267 { |
|
268 iChannelState = ECsyChannelStateDisconnecting; |
|
269 _LOG_L1C2("** Setting Channel Ready to False for DLC %d **",iDlcNum); |
|
270 iChannelReady = EFalse; |
|
271 iTimeouter->Stop(); |
|
272 |
|
273 // Allow time for the channel to disconnect... |
|
274 User::After(1); |
|
275 } |
|
276 else |
|
277 { |
|
278 _LOG_L1C1("** Cannot send EDISC **"); |
|
279 ret = KErrGeneral; |
|
280 } |
|
281 } |
|
282 else if (iChannelState == ECsyChannelStateTransmitError) |
|
283 { |
|
284 _LOG_L2C1("** Disconnect request for channel with transmit error **"); |
|
285 ret = KErrNone; |
|
286 } |
|
287 else |
|
288 { |
|
289 _LOG_L2C1("** Ignored disconnect **"); |
|
290 ret = KErrGeneral; |
|
291 } |
|
292 |
|
293 _LOG_L4C2("<<CChannelMgrBase::Disconnect [ret=%d]",ret); |
|
294 return ret; |
|
295 } |
|
296 |
|
297 void CChannelMgrBase::ProcessNonUihRecvFrame(CCsyMsgBufBpFrame* aBpFrame) |
|
298 /** |
|
299 * This method is called to process a Non-UIH frame which the channel |
|
300 * has received from the baseband for the channel. |
|
301 * |
|
302 * @param aBpFrame - Pointer to the received Non-UIH frame |
|
303 */ |
|
304 { |
|
305 _LOG_L4C2(">>CChannelMgrBase::ProcessNonUihRecvFrame [iDlcNum=%d]", iDlcNum); |
|
306 |
|
307 TUint8 frameType = aBpFrame->GetFrameType(); |
|
308 iMux0710Protocol.AddFrameFreeQ(aBpFrame); |
|
309 |
|
310 switch (frameType) |
|
311 { |
|
312 case KCsy0710CTLSABM: |
|
313 _LOG_L4C1("SABM"); |
|
314 // MAF we should respond to this |
|
315 break; |
|
316 |
|
317 case KCsy0710CTLUA: |
|
318 { |
|
319 _LOG_L4C1("UA"); |
|
320 iTimeouter->Stop(); |
|
321 |
|
322 if (iChannelState == ECsyChannelStateConnecting) |
|
323 { |
|
324 _LOG_L4C1("SABM received by remote end - send MSC command"); |
|
325 if (SendMscCommand(iV24Signals) == KErrNone) |
|
326 iChannelState = ECsyChannelStateMSCsent; |
|
327 } |
|
328 else if (iChannelState == ECsyChannelStateDisconnecting) |
|
329 { |
|
330 _LOG_L4C2("Channel disconnected %d", iDlcNum); |
|
331 iChannelState = ECsyChannelStateDisconnected; |
|
332 |
|
333 if (iPortFactory.DecrementNumOfOpenPorts()) |
|
334 { |
|
335 NotifyChannelReady(); |
|
336 } |
|
337 } |
|
338 } |
|
339 break; |
|
340 |
|
341 case KCsy0710CTLDM: // 0x0F |
|
342 _LOG_L4C1("DM"); |
|
343 break; |
|
344 |
|
345 case KCsy0710CTLDISC: // 0x43 |
|
346 _LOG_L4C1("DISC"); |
|
347 // MAF we should respond to this |
|
348 break; |
|
349 |
|
350 case KCsy0710CTLUIH: |
|
351 case KCsy0710CTLUI: |
|
352 // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); here |
|
353 break; |
|
354 |
|
355 default: |
|
356 _LOG_L1C2("** Unknown FrameType = 0x%02x **", frameType); |
|
357 break; |
|
358 } |
|
359 |
|
360 _LOG_L4C1("<<CChannelMgrBase::ProcessNonUihRecvFrame"); |
|
361 } |
|
362 |
|
363 TInt CChannelMgrBase::SendMscCommand(TUint8 aV24Signals) |
|
364 /** |
|
365 * Sends an MSC command |
|
366 * |
|
367 * @param aV24Signals |
|
368 * @return error if failed to send |
|
369 */ |
|
370 { |
|
371 _LOG_L4C2(">>CChannelMgrBase::SendMscCommand [aV24Signals=0x%02x]", |
|
372 aV24Signals); |
|
373 |
|
374 if (iMscReplyExpected) |
|
375 { |
|
376 _LOG_L4C1("<<CChannelMgrBase::SendMscCommand - already doing MSC"); |
|
377 return KErrNotReady; |
|
378 } |
|
379 |
|
380 // Keep the signals in case of resend |
|
381 iV24Signals = aV24Signals; |
|
382 TInt ret = iMux0710Protocol.Create0710ControlFrame( |
|
383 CMux0710Protocol::EUIH, iDlcNum, CMux0710Protocol::EMSC, iV24Signals); |
|
384 |
|
385 if (ret != KErrNone) |
|
386 { |
|
387 _LOG_L1C1("** Could not send MSC command **"); |
|
388 } |
|
389 else |
|
390 { |
|
391 iTimeouter->Stop(); |
|
392 iTimeouter->Start(iTimeoutVal); |
|
393 iTxCount = iTxCountLimit; |
|
394 iMscReplyExpected = ETrue; |
|
395 } |
|
396 |
|
397 _LOG_L4C2("<<CChannelMgrBase::SendMscCommand [ret=%d]",ret); |
|
398 return ret; |
|
399 } |
|
400 |
|
401 void CChannelMgrBase::MscReceived(TUint8 aV24Signals) |
|
402 /** |
|
403 * Processes a received MSC command |
|
404 * |
|
405 * @param aV24Signals |
|
406 */ |
|
407 { |
|
408 _LOG_L4C2(">>CChannelMgrBase::MscReceived [aV24Signals=0x%x]", |
|
409 aV24Signals); |
|
410 |
|
411 if (!iMscReplyExpected) |
|
412 { |
|
413 _LOG_L2C1("*** Not expecting MscReceived? ***"); |
|
414 return; |
|
415 } |
|
416 |
|
417 iMscReplyExpected = EFalse; |
|
418 iTimeouter->Stop(); |
|
419 |
|
420 if (iChannelState == ECsyChannelStateMSCsent) |
|
421 { |
|
422 _LOG_L4C1("MSC cmd part of start up sequence"); |
|
423 iChannelState = ECsyChannelStateWaitingForChannelReady; |
|
424 |
|
425 //different type of channel may need different init process. |
|
426 if (iPortC32Interface) |
|
427 { |
|
428 #ifdef _27010ADVANCEOPTION |
|
429 if (iPortC32Interface->GetClientType() == CPortFactory::EC32ClientIpNif) |
|
430 { |
|
431 _LOG_L4C1(" IpNif Channel Initialized"); |
|
432 // Don't need to wait for AT command interpreter ready since not AT |
|
433 iChannelState = ECsyChannelStateConnected; |
|
434 NotifyChannelReady(); |
|
435 ModemAndCsyToClientFlowCtrl(EFlowControlOff); |
|
436 } |
|
437 #endif |
|
438 } |
|
439 else |
|
440 { |
|
441 // Command channel |
|
442 iChannelState = ECsyChannelStateConnected; |
|
443 NotifyChannelReady(); |
|
444 } |
|
445 } |
|
446 |
|
447 if ((iDlcNum)&&(iV24Signals != aV24Signals)) |
|
448 { |
|
449 _LOG_L4C3("Data Dlc - Response different to sent [%x != %x]", |
|
450 iV24Signals, aV24Signals); |
|
451 |
|
452 ReceivedV24Signals(aV24Signals); |
|
453 } |
|
454 |
|
455 _LOG_L4C1("<<CChannelMgrBase::MscReceived"); |
|
456 } |
|
457 |
|
458 void CChannelMgrBase::ModemAndCsyToClientFlowCtrl(const TFlowControl aFlowControl) |
|
459 /** |
|
460 * Set the channel's flow control to the specified value. |
|
461 * Update the associate port object's flow control if the port object |
|
462 * exists. |
|
463 * |
|
464 * @param aFlowControl - New flow control state |
|
465 */ |
|
466 { |
|
467 _LOG_L4C3(">>CChannelMgrBase::ModemAndCsyToClientFlowCtrl [aFlowControl=%d,iDlcNum=%d]", |
|
468 aFlowControl,iDlcNum); |
|
469 |
|
470 iCsyAllowedToSendFrames = aFlowControl; |
|
471 if ((aFlowControl == EFlowControlOff)&&(iDelayedWriteToModem)) |
|
472 { |
|
473 _LOG_L4C1("Flow control now OFF - delayed frame to send"); |
|
474 |
|
475 TInt ret = iMux0710Protocol.Create0710DataFrames(iDataToSendToModem, iDlcNum); |
|
476 if (ret) |
|
477 { |
|
478 _LOG_L1C2("** Fragmentation failed [ret=%d] **",ret); |
|
479 } |
|
480 else |
|
481 { |
|
482 _LOG_L4C1("Delayed write placed on write queue"); |
|
483 iDelayedWriteToModem = EFalse; |
|
484 } |
|
485 } |
|
486 |
|
487 CPortC32InterfaceBase* port = GetC32Port(); |
|
488 if (port) |
|
489 port->ModemAndCsyToClientFlowCtrl(aFlowControl); |
|
490 else |
|
491 { |
|
492 _LOG_L2C1("** GetC32Port() returned NULL **"); |
|
493 } |
|
494 |
|
495 _LOG_L4C1("<<CChannelMgrBase::ModemAndCsyToClientFlowCtrl"); |
|
496 } |
|
497 |
|
498 void CChannelMgrBase::ReceivedV24Signals(const TUint8 aV24Signals) |
|
499 /** |
|
500 * Set the channel's signals to the specified value. |
|
501 * Update the associate port object's flow control if the port object |
|
502 * exists. |
|
503 * |
|
504 * @param aSignals - new signal state |
|
505 */ |
|
506 { |
|
507 _LOG_L4C3(">>CChannelMgrBase::ReceivedV24Signals [aV24Signals=0x%x,iDlcNum=%d]", |
|
508 aV24Signals,iDlcNum); |
|
509 |
|
510 CPortC32InterfaceBase* port = GetC32Port(); |
|
511 if (port) |
|
512 { |
|
513 // Flow control |
|
514 TFlowControl flowControl = EFlowControlOff; |
|
515 |
|
516 // FC (bit 2) |
|
517 if (aV24Signals & 0x02) |
|
518 { |
|
519 _LOG_L4C2("FC=1 - modem dlc %d unable to accept frames",iDlcNum); |
|
520 flowControl = EFlowControlOn; |
|
521 _LOG_L4C1("flowControl On (i.e stop flow)"); |
|
522 |
|
523 // move frames for this dlc from write list to wait list |
|
524 iPortFactory.GetCommWriterAo()->RemoveAnyDlcFramesOnWriteList(iDlcNum); |
|
525 } |
|
526 else |
|
527 { |
|
528 // move any frames for this dlc from wait to write list |
|
529 iPortFactory.GetCommWriterAo()->RemoveAnyDlcFramesFromWaitList(iDlcNum); |
|
530 } |
|
531 |
|
532 ModemAndCsyToClientFlowCtrl(flowControl); |
|
533 |
|
534 port->ReceivedV24Signals(aV24Signals); |
|
535 } |
|
536 else |
|
537 { |
|
538 _LOG_L2C1("** GetC32Port() returned NULL **"); |
|
539 } |
|
540 |
|
541 _LOG_L4C1("<<CChannelMgrBase::ReceivedV24Signals"); |
|
542 } |
|
543 |
|
544 void CChannelMgrBase::WaitForChannelReady() |
|
545 /** |
|
546 * This method starts an active object and waits for the channel ready |
|
547 * call back signal. |
|
548 */ |
|
549 { |
|
550 _LOG_L4C1(">>CChannelMgrBase::WaitForChannelReady"); |
|
551 |
|
552 if (iMux0710Protocol.MaxRetriesReached()) |
|
553 { |
|
554 _LOG_L4C1("Mux Max Retries reached - so skip Channel Ready"); |
|
555 } |
|
556 else |
|
557 { |
|
558 // kick off an active object and wait for channel ready call back |
|
559 if (iChannelReady) |
|
560 { |
|
561 _LOG_L4C2("iChannelReady=%d",iChannelReady); |
|
562 } |
|
563 else if (!iChannelObserverAo->IsActive()) |
|
564 { |
|
565 // start the active object. CSY will wait here until channel is ready |
|
566 // nest active scheduler is used here as we did not want to block whole thread (reading/writing) |
|
567 |
|
568 iChannelObserverAo->StartWait(); |
|
569 |
|
570 // start a nested scheduling; blocks until CActiveScheduler::Stop() |
|
571 // is called in DoCancel() |
|
572 |
|
573 // MAF look at use CActiveSchedulerWait instead of this |
|
574 |
|
575 // One basic assumption here is that CSY will process port open request one by one |
|
576 // (although there may be mutiple port open requests from clients, c32 will call PortFactory::NewPortL |
|
577 // one by one.) This assumption should be valid as it is only one thread for c32 |
|
578 // if this assumption does not hold, headache follows. |
|
579 _LOG_L4C1("Start wait for channel ready"); |
|
580 |
|
581 CActiveScheduler::Start(); |
|
582 _LOG_L4C1("End wait for channel ready"); |
|
583 } |
|
584 else |
|
585 { |
|
586 _LOG_L4C1("We are here only when others are already waiting"); |
|
587 } |
|
588 } |
|
589 _LOG_L4C1("<<CChannelMgrBase::WaitForChannelReady"); |
|
590 } |
|
591 |
|
592 void CChannelMgrBase::TimedOut() |
|
593 /** |
|
594 * This method will be called when we have a timeout During receive a reply. |
|
595 * It will retransmit if needed. |
|
596 */ |
|
597 { |
|
598 _LOG_L4C1(">>CChannelMgrBase::TimedOut"); |
|
599 |
|
600 iTxCount--; |
|
601 if (iTxCount > 0) // retransmit |
|
602 { |
|
603 _LOG_L4C2("iTxCount=%d",iTxCount); |
|
604 |
|
605 TInt ret = KErrNone; |
|
606 if (iMscReplyExpected) |
|
607 { |
|
608 iMscReplyExpected = EFalse; |
|
609 ret = SendMscCommand(iV24Signals); |
|
610 } |
|
611 else |
|
612 { |
|
613 switch(iChannelState) |
|
614 { |
|
615 case ECsyChannelStateParameterNegotiating: |
|
616 ret = iMux0710Protocol.Create0710ControlFrame( |
|
617 CMux0710Protocol::EUIH, iDlcNum, CMux0710Protocol::EParamNeg); |
|
618 break; |
|
619 case ECsyChannelStateConnecting: |
|
620 ret = iMux0710Protocol.Create0710ControlFrame( |
|
621 CMux0710Protocol::ESABM, iDlcNum); |
|
622 break; |
|
623 case ECsyChannelStateDisconnecting: |
|
624 ret = iMux0710Protocol.Create0710ControlFrame( |
|
625 CMux0710Protocol::EDISC, iDlcNum); |
|
626 break; |
|
627 default: |
|
628 // should never reach here |
|
629 _LOG_L1C1("** unexpected receiving timeout **"); |
|
630 } |
|
631 } |
|
632 if (ret) |
|
633 { |
|
634 // Error sending - we shall just wait until the timeout and try again |
|
635 _LOG_L1C2("** Error sending on dlc 0 [ret=%d] **",ret); |
|
636 } |
|
637 iTimeouter->Stop(); |
|
638 iTimeouter->Start(iTimeoutVal); |
|
639 } |
|
640 else |
|
641 { |
|
642 _LOG_L1C1("** Retries expired **"); |
|
643 if (iMscReplyExpected) |
|
644 { |
|
645 _LOG_L1C1("** Retries expired for MSC command **"); |
|
646 iMscReplyExpected = EFalse; |
|
647 } |
|
648 |
|
649 // we have problem communication, may need to reset? |
|
650 iChannelState = ECsyChannelStateTransmitError; |
|
651 NotifyChannelReady(); |
|
652 } |
|
653 |
|
654 _LOG_L4C1("<<CChannelMgrBase::TimedOut"); |
|
655 } |
|
656 |
|
657 void CChannelMgrBase::NotifyChannelReady() |
|
658 /** |
|
659 * This method stops the waiting for a channel. |
|
660 */ |
|
661 { |
|
662 _LOG_L4C1("CChannelMgrBase::NotifyChannelReady"); |
|
663 |
|
664 iChannelReady = ETrue; |
|
665 iInitFinished = ETrue; |
|
666 |
|
667 // complete the active object if it is running |
|
668 if (iChannelObserverAo->IsActive()) |
|
669 { |
|
670 iChannelObserverAo->ChannelReady(); |
|
671 } |
|
672 } |
|
673 |
|
674 TInt CChannelMgrBase::SetCsyToModemFlowControl(TFlowControl aFlowControl) |
|
675 /** |
|
676 * |
|
677 */ |
|
678 { |
|
679 _LOG_L4C3(">>CChannelMgrBase::SetCsyToModemFlowControl [aFlowControl=%d,iDlcNum=%d]", |
|
680 aFlowControl,iDlcNum); |
|
681 |
|
682 TInt ret = KErrNone; |
|
683 if (aFlowControl != iModemAllowedToSendFrames) |
|
684 { |
|
685 TUint8 v24Signals = iV24Signals; |
|
686 TBool sendCommand = EFalse; |
|
687 if (aFlowControl == EFlowControlOn) |
|
688 { |
|
689 _LOG_L4C1("aFlowControl = ON"); |
|
690 if (v24Signals & 0x02) |
|
691 { |
|
692 _LOG_L4C1("** Flow control already set **"); |
|
693 } |
|
694 else |
|
695 { |
|
696 v24Signals |= 0x02; |
|
697 sendCommand = ETrue; |
|
698 } |
|
699 } |
|
700 else |
|
701 { |
|
702 _LOG_L4C1("aFlowControl = OFF"); |
|
703 if (v24Signals & 0x02) |
|
704 { |
|
705 v24Signals ^= 0x02; |
|
706 sendCommand = ETrue; |
|
707 } |
|
708 else |
|
709 { |
|
710 _LOG_L4C1("Flow control already off"); |
|
711 } |
|
712 } |
|
713 if (sendCommand) |
|
714 { |
|
715 ret = SendMscCommand(v24Signals); |
|
716 if (ret) |
|
717 { |
|
718 _LOG_L4C1("SendMscCommand failed"); |
|
719 } |
|
720 else |
|
721 { |
|
722 _LOG_L4C3("Csy to modem flow control changed %d -> %d", |
|
723 iModemAllowedToSendFrames,aFlowControl); |
|
724 iModemAllowedToSendFrames = aFlowControl; |
|
725 } |
|
726 } |
|
727 } |
|
728 |
|
729 _LOG_L4C2("<<CChannelMgrBase::SetCsyToModemFlowControl [ret=%d]",ret); |
|
730 return ret; |
|
731 } |
|
732 |
|
733 // |
|
734 // class CChannelObserverAo |
|
735 // |
|
736 |
|
737 CChannelObserverAo::CChannelObserverAo() |
|
738 : CActive(CActive::EPriorityStandard) |
|
739 /** |
|
740 * Constructor. Pass priority of active object to base class. |
|
741 * |
|
742 */ |
|
743 {} |
|
744 |
|
745 CChannelObserverAo* CChannelObserverAo::NewL() |
|
746 /** |
|
747 * This method uses two phase construction and the cleanup stack |
|
748 * to create an instance of class CChannelObserverAo. |
|
749 * |
|
750 * @return Pointer to the created instance |
|
751 */ |
|
752 { |
|
753 _LOG_L4C1("CChannelObserverAo::NewL"); |
|
754 return new (ELeave) CChannelObserverAo(); |
|
755 } |
|
756 |
|
757 CChannelObserverAo::~CChannelObserverAo() |
|
758 /** |
|
759 * Destructor. Cancel any outstanding request. |
|
760 */ |
|
761 { |
|
762 if (IsActive()) |
|
763 Cancel(); |
|
764 } |
|
765 |
|
766 void CChannelObserverAo::RunL() |
|
767 /** |
|
768 * This method should not be called. Request of this |
|
769 * active object will only be canceled. |
|
770 */ |
|
771 { |
|
772 // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); |
|
773 _LOG_L1C1("** CChannelObserverAo::RunL() - should not be called **"); |
|
774 } |
|
775 |
|
776 void CChannelObserverAo::DoCancel() |
|
777 /** |
|
778 * Cancel an outstanding request. This will complete request |
|
779 * with KErrCancel and stop waiting. |
|
780 */ |
|
781 { |
|
782 _LOG_L4C1("CChannelObserverAo::DoCancel"); |
|
783 |
|
784 iStatus = KErrCancel; |
|
785 TRequestStatus* temp = &iStatus; |
|
786 User::RequestComplete(temp, KErrCancel); |
|
787 |
|
788 _LOG_L4C1("CChannelObserverAo stop scheduler"); |
|
789 CActiveScheduler::Stop(); |
|
790 } |
|
791 |
|
792 void CChannelObserverAo::StartWait() |
|
793 /** |
|
794 * Set active and start waiting. |
|
795 */ |
|
796 { |
|
797 _LOG_L4C1("CChannelObserverAo::StartWait"); |
|
798 if (!IsActive()) |
|
799 { |
|
800 iStatus = KRequestPending; |
|
801 SetActive(); |
|
802 } |
|
803 } |
|
804 |
|
805 void CChannelObserverAo::ChannelReady() |
|
806 /** |
|
807 * Called when expected event occured to stop waiting. |
|
808 */ |
|
809 { |
|
810 _LOG_L4C1("CChannelObserverAo::ChannelReady"); |
|
811 |
|
812 // complete current request |
|
813 if (IsActive()) |
|
814 { |
|
815 _LOG_L4C1("CChannelObserverAo Active"); |
|
816 Cancel(); |
|
817 } |
|
818 } |
|