cbsref/csyrefplugins/csy27010/src/ChannelMgrBase.cpp
branchRCL_3
changeset 65 630d2f34d719
equal deleted inserted replaced
61:17af172ffa5f 65:630d2f34d719
       
     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 	}