telephonyprotocols/rawipnif/src/BcaIoController.cpp
branchRCL_3
changeset 7 fe8b59ab9fa0
parent 6 fc69e1e37771
child 19 630d2f34d719
equal deleted inserted replaced
6:fc69e1e37771 7:fe8b59ab9fa0
    19  @file BcaIoController.cpp
    19  @file BcaIoController.cpp
    20 */
    20 */
    21 
    21 
    22 #include <e32uid.h>
    22 #include <e32uid.h>
    23 #include <nifmbuf.h>
    23 #include <nifmbuf.h>
       
    24 #include <e32svr.h>
       
    25 #include <u32hal.h>
    24 
    26 
    25 #include "Constants.h"
    27 #include "Constants.h"
    26 #include "BcaIoController.h"
    28 #include "BcaIoController.h"
    27 #include "Sender.h"
    29 #include "Sender.h"
    28 #include "Receiver.h"
    30 #include "Receiver.h"
    29 
    31 
       
    32 const TUint KDefaultSendQueueSize=5;
       
    33 
       
    34 #ifdef __EABI__
       
    35 // Patch data is used and KMaxTxIPPacketSize and KMaxRxIPPacketSize can be modified to a different value in RawIpNif.iby file
       
    36 extern const TInt KMaxSendQueueLen = KDefaultSendQueueSize;
       
    37 extern const TInt KMaxTxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
       
    38 extern const TInt KMaxRxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
       
    39 #endif
       
    40 
    30 CBcaIoController::CBcaIoController(MControllerObserver& aObserver,
    41 CBcaIoController::CBcaIoController(MControllerObserver& aObserver,
    31 	CBttLogger* aTheLogger)
    42 	CBttLogger* aTheLogger)
    32 /**
    43 /**
    33  * Constructor. 
    44  * Constructor. 
    34  *
    45  *
    35  * @param aObserver Reference to the observer of this state machine
    46  * @param aObserver Reference to the observer of this state machine
    36  * @param aTheLogger The logging object
    47  * @param aTheLogger The logging object
    37  */
    48  */
    38 	: 
    49     : iTheLogger(aTheLogger),
    39 	  CBcaController(aObserver, aTheLogger),
    50       iSendState(EIdle),
    40 	  iMBca(NULL),
    51       iFlowBlocked(EFalse),
    41 	  iSender(NULL),
    52       iNumPacketsInSendQueue(0),
    42 	  iReceiver(NULL),
    53       iObserver(aObserver),
    43 	  iLoader(NULL)	  
    54       iMBca(NULL),
    44 	{
    55       iSender(NULL),
    45 	}
    56       iReceiver(NULL),
       
    57       iLoader(NULL)	  
       
    58     {
       
    59     }
    46 
    60 
    47 CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver, CBttLogger* aTheLogger)
    61 CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver, CBttLogger* aTheLogger)
    48 /**
    62 /**
    49  * Two-phase constructor. Creates a new CBcaIoController object, performs 
    63  * Two-phase constructor. Creates a new CBcaIoController object, performs 
    50  * second-phase construction, then returns it.
    64  * second-phase construction, then returns it.
    51  *
    65  *
    52  * @param aObserver The observer, to which events will be reported
    66  * @param aObserver The observer, to which events will be reported
    53  * @param aTheLogger The logging object
    67  * @param aTheLogger The logging object
    54  * @return A newly constructed CBcaIoController object
    68  * @return A newly constructed CBcaIoController object
    55  */
    69  */
    56 	{
    70     {
    57 	CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger);
    71     CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger);
    58 	CleanupStack::PushL(self);
    72     CleanupStack::PushL(self);
    59 	self->ConstructL();
    73     self->ConstructL();
    60 	CleanupStack::Pop(self);
    74     CleanupStack::Pop(self);
    61 	return self;
    75     return self;
    62 	}
    76     }
    63 
    77 
    64 void CBcaIoController::ConstructL()
    78 void CBcaIoController::ConstructL()
    65 /**
    79 /**
    66  * Second-phase constructor. Creates all the state objects it owns.
    80  * Second-phase constructor. Creates all the state objects it owns.
    67  */
    81  */
    68 	{
    82     {
    69 	_LOG_L1C1(_L8("CBcaIoController::ConstructL"));
    83     _LOG_L1C1(_L8("CBcaIoController::ConstructL"));
    70 	BaseConstructL();
    84 
    71 	iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize);
    85 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
    72 	iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize);
    86     iIPTagHeader = new (ELeave) CIPTagHeader(iTheLogger);
    73 	iLoader = new (ELeave) CBcaControl(*this, iTheLogger);
    87 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS
    74 	}
    88 
       
    89 #if defined __EABI__
       
    90     // Default value for queue length
       
    91     iMaxSendQueueLen = KMaxSendQueueLen;
       
    92     // Default value for Tx and Rx packet size
       
    93     iMaxTxPacketSize = KMaxTxIPPacketSize;
       
    94     iMaxRxPacketSize = KMaxRxIPPacketSize;
       
    95 #else // WINS
       
    96     // Set default values in case patch is not present in epocrawip.ini
       
    97     iMaxSendQueueLen = KDefaultSendQueueSize;    
       
    98     iMaxTxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
       
    99     iMaxRxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
       
   100            
       
   101     // for the emulator process is patched via the epocrawip.ini file
       
   102     UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxSendQueueLen",&iMaxSendQueueLen);
       
   103     UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxTxIPPacketSize",&iMaxTxPacketSize);
       
   104     UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxRxIPPacketSize",&iMaxRxPacketSize);
       
   105 #endif
       
   106     
       
   107     // end note
       
   108     
       
   109     iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize);
       
   110     iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize);
       
   111     iLoader = new (ELeave) CBcaControl(*this, iTheLogger);
       
   112     }
    75 
   113 
    76 
   114 
    77 CBcaIoController::~CBcaIoController()
   115 CBcaIoController::~CBcaIoController()
    78 /**
   116 /**
    79  * Destructor.
   117  * Destructor.
    80  */
   118  */
    81 	{
   119 	{
       
   120     iSendQueue.Free();
       
   121     iNumPacketsInSendQueue = 0;
       
   122     
    82 	delete iReceiver;
   123 	delete iReceiver;
    83 	delete iSender;
   124 	delete iSender;
    84 	delete iLoader;
   125 	delete iLoader;
    85 
   126 	
       
   127 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
       
   128     delete iIPTagHeader;
       
   129 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS
    86 	}
   130 	}
    87 
   131 
    88 /** sets the BCA Stack name
   132 /** sets the BCA Stack name
    89 
   133 
    90 * @param aBcaStack Text composed of bca stack and next bca names
   134 * @param aBcaStack Text composed of bca stack and next bca names
   101  *  Used to kick off the initialisation for this module
   145  *  Used to kick off the initialisation for this module
   102  */
   146  */
   103 	{
   147 	{
   104 	_LOG_L1C1(_L8("CBcaIoController::StartL is called."));
   148 	_LOG_L1C1(_L8("CBcaIoController::StartL is called."));
   105 
   149 
   106 	InitialiseBcaL();
   150     iLoader->StartLoadL();
   107 	}
   151 	}
   108 
   152 
   109 void CBcaIoController::Stop(TInt aError)
   153 void CBcaIoController::Stop(TInt aError)
   110 /**
   154 /**
   111  *  Used to shutdown this module. This will cancel all the outstanding 
   155  *  Used to shutdown this module. This will cancel all the outstanding 
   116 	_LOG_L1C1(_L8("CBcaIoController::Stop is called."));
   160 	_LOG_L1C1(_L8("CBcaIoController::Stop is called."));
   117 
   161 
   118 	//Stop all the active objects
   162 	//Stop all the active objects
   119 	iReceiver->Cancel();
   163 	iReceiver->Cancel();
   120 
   164 
   121 	if(GetSendState() == ESending)
   165 	if (iSendState == ESending)
   122 		{
   166 		{
   123 		iSender->Cancel();
   167 		iSender->Cancel();
   124 		}
   168 		}
   125 
   169 
   126 	// Update module state
   170 	// Update module state
   127 	SendState(EShuttingDown);
   171 	SendState(EShuttingDown);
   128 	
   172 	
   129     iLoader->ShutdownBca(aError);  
   173     iLoader->ShutdownBca(aError);  
   130 	}
   174 	}
   131 
   175 
   132 void CBcaIoController::InitialiseBcaL()
   176 
   133 /**
   177 ESock::MLowerDataSender::TSendResult CBcaIoController::Send(RMBufChain& aPdu)
   134  *  Load & Initialise Bca.
   178 /**
   135  */
   179  *  This method is called by CRawIPFlow in order to send a packet down
   136 	{
   180  *  to the BCA. 
   137 	_LOG_L1C1(_L8("<<CBcaIoController::InitialiseBcaL"));
       
   138     iLoader->StartLoadL();
       
   139 	}
       
   140 
       
   141 void CBcaIoController::BcaProcess(TDesC8& aPdu)
       
   142 /**
       
   143  *  This method will pass on the received data to CRawIPNifMain. 
       
   144  *
   181  *
   145  * @param aPdu a data packet
   182  *  @param aPdu a data packet
   146  */
   183  */
   147 	{
   184     {
   148 	_LOG_L1C1(_L8(">>CBcaIoController::Process"));
   185     _LOG_L1C1(_L8(">>CBcaIoController::Send"));
   149 
   186 
   150 	Process(aPdu);
   187     // Check if flow is shutting down
   151 
   188     if (iSendState == EShuttingDown)
   152 	_LOG_L1C1(_L8("<<CBcaIoController::Process"));
   189         {
   153 	}
   190         _LOG_L2C1(_L8("    ERROR: Nif is shutting down"));
   154 
   191         
   155 void CBcaIoController::BcaSend(RMBufChain& aPdu)
   192         // when the flow is destroyed the memory for this packet will be 
   156 /**
   193         // cleaned up - just tell the layers above to stop sending.
   157  *  This method is called by CRawIPNifMain in order to send a packet down
   194         aPdu.Free();
   158  * to the BCA. The CSender active object will be activated by calling the send
   195         
   159  * method.
   196         return ESock::MLowerDataSender::ESendBlocked;
   160  *
   197         }
   161  *	@param aPdu a data packet
   198     
   162  */
   199     // check that this packet isnt too big - If it is, we dont want to send it or
   163 	{
   200     // add it to our queue
   164 	_LOG_L1C1(_L8("CBcaIoController::BcaSend"));
   201     if ((aPdu.Length() - aPdu.First()->Length()) > iMaxTxPacketSize)
   165 
   202         {
   166 	iSender->Send(aPdu);
   203         _LOG_L2C1(_L8("Packet is too large - discarding"));
   167 	}
   204         _LOG_L1C1(_L8("<<CSender::Send -> Error"));
   168 
   205 
   169 TInt CBcaIoController::BcaSendBufferLength()
   206         // in debug panic - this should not happen, MTU on the uplink should
   170 	{
   207         // be strictly enforced
   171 	return iSender->SendBufferLength();
   208         __ASSERT_DEBUG(ETrue,Panic(KFlowInvalidULPacketSize));
   172 	}
   209         
   173 
   210         aPdu.Free();
   174 void CBcaIoController::BcaSendComplete()	
   211        
   175 /**
   212         // may be counter intuitive, however the only options here are either 
   176  *  This method is called after a packet was sent to the board. 
   213         // send accepted or blocked (MLowerDataSender).
   177  *  If allowed by flow contol flags the NIF can signal the TCP/IP
   214         
   178  *  protocol indicating that is available to send more packets.
   215         _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending"));
   179  */
   216         return ESock::MLowerDataSender::ESendAccepted;
   180 	{
   217         }
   181 	_LOG_L1C1(_L8("CBcaController::SendComplete"));
   218     
   182 
   219     // transmit flow control.
   183 	SendComplete();
   220     if (iFlowBlocked)
   184 	}
   221         {
   185 
   222         // Transmit is off for this flow - we must have received a block
   186 	
   223         // message from our control.  append this message to the queue
       
   224         // and tell the layer above it to kindly stop sending.
       
   225         _LOG_L1C1(_L8("    Sender blocked, appending packet to queue"));
       
   226         
       
   227         AppendToSendQueue(aPdu);
       
   228         
       
   229         // may be a bit counter-intuitive, however, even if the flow is blocked
       
   230         // there is no reason not to ask for more data as long as our send
       
   231         // queue isn't full.
       
   232         
       
   233         if (IsSendQueueFull())
       
   234             {
       
   235             _LOG_L2C1(_L8("<<CBcaIoController::Send - return StopSending"));
       
   236             return ESock::MLowerDataSender::ESendBlocked;
       
   237             }
       
   238         else
       
   239             {
       
   240             _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending"));
       
   241             return ESock::MLowerDataSender::ESendAccepted;       
       
   242             }
       
   243         }
       
   244     
       
   245     // transmit is on for this flow.  send a packet or queue it
       
   246     // if we're already sending one.
       
   247 
       
   248     if (iSendState == ESending)
       
   249         // If this happens, it means that TCP/IP has sent us an IP packet
       
   250         // while we're still sending the previous one. 
       
   251         {    
       
   252         _LOG_L1C1(_L8("    Sender busy, appending packet to queue"));
       
   253         AppendToSendQueue(aPdu);
       
   254         
       
   255         if (IsSendQueueFull())
       
   256             {
       
   257             _LOG_L2C1(_L8("<<CBcaIoController::Send - return StopSending"));
       
   258             return ESock::MLowerDataSender::ESendBlocked;
       
   259             }
       
   260         }
       
   261     else
       
   262         {
       
   263         // if we're idle, then we must not be sending.  If we're not idle
       
   264         // then the SendComplete() will handle sending any additional 
       
   265         // packets that might have been queued onto the send queue.
       
   266     
       
   267         // Update module state
       
   268         _LOG_L2C1(_L8("     set State to ESending"));
       
   269         iSendState = ESending;
       
   270          
       
   271         iSender->Send(aPdu);
       
   272         }
       
   273 
       
   274     // if our send queue isn't full, then the send is accepted
       
   275     // otherwise, block this flow until we have room for the next
       
   276     // packet
       
   277     
       
   278     _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending"));
       
   279 
       
   280     return ESock::MLowerDataSender::ESendAccepted;
       
   281     }
       
   282 	
       
   283 void CBcaIoController::SendComplete()
       
   284 /**
       
   285  *  A packet has finished sending - check to see if we need
       
   286  *  to process more packets.
       
   287  */
       
   288     {
       
   289     _LOG_L1C1(_L8(">>CBcaIoController::SendComplete"));
       
   290 
       
   291     // if we've been blocked while in the middle of a 
       
   292     // send - don't continue sending, this will happen
       
   293     // when the flow is resumed.
       
   294 
       
   295     iSendState = EIdle;
       
   296 
       
   297     // are we available to transmit?
       
   298     
       
   299     if (iFlowBlocked == EFalse)
       
   300         {
       
   301         // flow transmit is on
       
   302     
       
   303         TBool resumeSending = EFalse;
       
   304     
       
   305         // if the queue is full, it means that while a packet was
       
   306         // outstanding in BCA, we've filled up our send queue and
       
   307         // informed the upper layers to stop sending.
       
   308         
       
   309         if (IsSendQueueFull())
       
   310             {
       
   311             resumeSending = ETrue;
       
   312             }
       
   313         
       
   314         // if the queue has anything inside it, we need to send the 
       
   315         // first packet in the queue.  note: the resumeSending check is to 
       
   316         // short circuit this so we don't check the queue length twice
       
   317         // in the case that it is full
       
   318         
       
   319         if ((resumeSending) || (!IsSendQueueEmpty()))
       
   320             {
       
   321             iSendState = ESending;
       
   322             
       
   323             RMBufChain tmpPdu;
       
   324             _LOG_L1C1(_L8("    Packet removed from queue to send"));
       
   325             RemoveFromSendQueue(tmpPdu);
       
   326             
       
   327             // Update module state
       
   328             _LOG_L2C1(_L8("     set State to ESending"));
       
   329           
       
   330             iSender->Send(tmpPdu);
       
   331             
       
   332             // if the queue was full, again, we told the upper layers
       
   333             // to stop sending, we need to resume this flow.  order is
       
   334             // important as we don't want to get a packet before we've 
       
   335             // given one to BCA to send.
       
   336             if (resumeSending)
       
   337                 {
       
   338                 iObserver.ResumeSending();
       
   339                 }
       
   340             }
       
   341         }
       
   342     
       
   343     _LOG_L1C1(_L8("<<CBcaIoController::SendComplete"));
       
   344     }
       
   345 
       
   346 
       
   347 void CBcaIoController::ResumeSending()
       
   348 /**
       
   349  *  Flow is being unblocked this will resume sending.
       
   350  */
       
   351     {
       
   352     _LOG_L1C1(_L8(">>CBcaIoController::ResumeSending"));
       
   353 
       
   354     // allows for normal SendComplete behaviour if there is
       
   355     // a packet outstanding with BCA
       
   356     iFlowBlocked = EFalse;
       
   357     
       
   358     // If the send state is idle, then there isn't a packet
       
   359     // outstanding, check the send queue to see if there are
       
   360     // packets to send.
       
   361     
       
   362     if (iSendState == EIdle)
       
   363         {
       
   364         // flow transmit is on
       
   365     
       
   366         TBool resumeSending = EFalse; 
       
   367         
       
   368         if (IsSendQueueFull())
       
   369             {
       
   370             resumeSending = ETrue;
       
   371             }
       
   372     
       
   373         // if the queue has anything inside it, we need to send the 
       
   374         // first packet in the queue.  note: the resumeSending check is to 
       
   375         // short circuit this so we don't check the queue length twice
       
   376         // in the case that it is full
       
   377         
       
   378         if ((resumeSending) || (!IsSendQueueEmpty()))
       
   379             {
       
   380             RMBufChain tmpPdu;
       
   381             _LOG_L1C1(_L8("    Packet removed from queue to send"));
       
   382             RemoveFromSendQueue(tmpPdu);
       
   383             
       
   384             // Update module state
       
   385             _LOG_L2C1(_L8("     set State to ESending"));
       
   386             iSendState = ESending;
       
   387           
       
   388             iSender->Send(tmpPdu);
       
   389             
       
   390             // if the queue was full, again, we told the upper layers
       
   391             // to stop sending, we need to resume this flow.  order is
       
   392             // important as we don't want to get a packet before we've 
       
   393             // given one to BCA to send.
       
   394             if (resumeSending)
       
   395                 {
       
   396                 iObserver.ResumeSending();
       
   397                 }
       
   398             }
       
   399         }
       
   400     
       
   401     _LOG_L1C1(_L8("<<CBcaIoController::ResumeSending"));
       
   402     }
       
   403 
       
   404 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
       
   405 void CBcaIoController::SetType(TUint16 aType)
       
   406     {
       
   407 /**
       
   408  *  Used to specify the type of the IP header.
       
   409  */
       
   410     _LOG_L1C1(_L8("CBcaController::SetType"));
       
   411     
       
   412     iIPTagHeader->SetType(aType);   
       
   413     }
       
   414 
       
   415 void CBcaIoController::AddHeader(TDes8& aDes)
       
   416 /**
       
   417  *  Used to add the IP header to the packet before sending to the BCA.
       
   418  */
       
   419     {
       
   420     _LOG_L1C1(_L8("CBcaController::AddHeader"));
       
   421 
       
   422     iIPTagHeader->AddHeader(aDes);
       
   423     }
       
   424 
       
   425 TUint16 CBcaIoController::RemoveHeader(RMBufChain& aPdu)
       
   426 /**
       
   427  *  Used to remove the IP header from the received the packet before sending to the 
       
   428  *  TCP/IP layer.  
       
   429  * @return The IP header that has been removed from the packet
       
   430  */
       
   431     {
       
   432     _LOG_L1C1(_L8("CBcaController::RemoveHeader"));
       
   433 
       
   434     return (iIPTagHeader->RemoveHeader(aPdu));
       
   435     }   
       
   436 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS
       
   437 
       
   438 
   187 CBcaControl::CBcaControl(CBcaIoController& aObserver, CBttLogger* aTheLogger)
   439 CBcaControl::CBcaControl(CBcaIoController& aObserver, CBttLogger* aTheLogger)
   188 /**
   440 /**
   189  * Constructor. Performs standard active object initialisation.
   441  * Constructor. Performs standard active object initialisation.
   190  *
   442  *
   191  * @param aObserver Reference to the observer of this state machine
   443  * @param aObserver Reference to the observer of this state machine