linklayerprotocols/ethernetnif/EtherPkt/CardIo.cpp
branchRCL_3
changeset 6 e7dfaa7b0b8d
equal deleted inserted replaced
5:1422c6cd3f0c 6:e7dfaa7b0b8d
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // 
       
    15 //
       
    16 
       
    17 /**
       
    18  @file
       
    19 */
       
    20 
       
    21 #include <nifman.h>
       
    22 #include <nifvar.h>
       
    23 #include <nifutl.h>
       
    24 #include <es_mbuf.h>
       
    25 #include "PKTDRV.H"
       
    26 #include "ETHINTER.H"
       
    27 #include "Cardctl.h"
       
    28 
       
    29 
       
    30 
       
    31  
       
    32 #ifdef __DebugCardLo__
       
    33 // TCP packet tracing debug
       
    34 const TUint8 ETHER2_TYPE_IP_MSB = 0x08;
       
    35 const TUint8 ETHER2_TYPE_IP_LSB = 0x00;
       
    36 const TUint8 IP_TYPE_TCP        = 0x06;
       
    37 static inline TBool IsTcp(TDesC8 &aFrame)
       
    38 {
       
    39 	return (aFrame[12] == ETHER2_TYPE_IP_MSB && aFrame[13] == ETHER2_TYPE_IP_LSB && aFrame[23] == IP_TYPE_TCP);
       
    40 }
       
    41 static TInt GetTcpSeqNumber(TDesC8 &aFrame)
       
    42 	{
       
    43 	TInt seqNum = 0;
       
    44 	if (IsTcp(aFrame))
       
    45 		seqNum = aFrame[38] << 24 | aFrame[39] << 16 | aFrame[40] << 8| aFrame[41];
       
    46 	return seqNum;
       
    47 	}
       
    48 static TInt GetTcpAckNumber(TDesC8 &aFrame)
       
    49 	{
       
    50 	TInt ackNum = 0;
       
    51 	if (IsTcp(aFrame))
       
    52 		ackNum = aFrame[42] << 24 | aFrame[43] << 16 | aFrame[44] << 8| aFrame[45];
       
    53 	return ackNum;
       
    54 	}
       
    55 #endif
       
    56 
       
    57 
       
    58 /**
       
    59 Send active object class
       
    60 When CIOBuffer's are passed to SendL() the class takes ownership and is
       
    61 therefore resposible for freeing them in the RunL()
       
    62 @internalComponent
       
    63 */
       
    64 const TInt KTxQueueThreshold = 40;
       
    65 
       
    66 /**
       
    67 Constructor.
       
    68 */
       
    69 CPcCardSender::CPcCardSender() : CActive(EPriorityStandard)
       
    70 {
       
    71 	
       
    72 }
       
    73 
       
    74 /**
       
    75 Destructor.
       
    76 Could be buffers on the transmit queue, free them as this class should be sole owner.
       
    77 */
       
    78 CPcCardSender::~CPcCardSender()
       
    79 {
       
    80 	EmptyQueue();
       
    81 	Cancel();
       
    82 }
       
    83 
       
    84 /**
       
    85 Standard CActive construction.
       
    86 @param aParent Pointer to the parent CPcCardControlEngine class.
       
    87 @return A pointer to CPcCardSender object.
       
    88 */
       
    89 CPcCardSender* CPcCardSender::NewL(CPcCardControlEngine* aParent)
       
    90 {
       
    91 	CPcCardSender *sd=new (ELeave) CPcCardSender;
       
    92 	CleanupStack::PushL(sd);
       
    93 	sd->InitL(aParent);
       
    94 	CActiveScheduler::Add(sd);
       
    95 	CleanupStack::Pop();
       
    96 	return sd;
       
    97 }
       
    98 
       
    99 /**
       
   100 Add the newly created object to an object container.
       
   101 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   102 */
       
   103 void CPcCardSender::InitL(CPcCardControlEngine* aParent)
       
   104 {
       
   105 	iParent=aParent;
       
   106 	iTxQueue.SetOffset(CIOBuffer::LinkOffset());
       
   107 	iQueueLength = 0;
       
   108 	iStopSending = EFalse;
       
   109 }
       
   110 
       
   111 /** 
       
   112 Protocol inspects return
       
   113 It blocks sending if it receives a return <= 0
       
   114 This value should be propogated up through the stack
       
   115 @internalComponent
       
   116 */
       
   117 const TInt KStopSending		= 0;
       
   118 
       
   119 /**
       
   120 Protocol inspects return to indicate Keep sending the data.
       
   121 @internalComponent
       
   122 */
       
   123 const TInt KContinueSending	= 1;
       
   124 
       
   125 /**
       
   126 Writes the data to buffer.
       
   127 
       
   128 @param aBuffer The data to be send.
       
   129 @return 0 Tells the higher layer to stop sending the data.
       
   130 		1 Tells higher layer that it can continue sending more data.
       
   131 */
       
   132 TInt CPcCardSender::Send(CIOBuffer *aBuffer)
       
   133 {
       
   134 	
       
   135 	// Check to see if we need to start transmission
       
   136 	// Pseudo interrupt queue
       
   137 	TBool startTx = iTxQueue.IsEmpty();
       
   138 
       
   139 	iTxQueue.AddLast(*aBuffer);
       
   140 	iQueueLength++;
       
   141 	if(startTx)
       
   142 		{
       
   143 		// Transmitter was idle start next transmit
       
   144 		iParent->iCard.Write(iStatus,aBuffer->Ptr());
       
   145 		SetActive();
       
   146 		}
       
   147 	else
       
   148 	{
       
   149 	}	
       
   150 	// The stack could saturate us with data
       
   151 	// Tell the stack to send no more
       
   152 	// We will unblock the stack when the queue size drops below
       
   153 	// the the threshold
       
   154 	if(iQueueLength >= KTxQueueThreshold)
       
   155 		{
       
   156 		iStopSending = ETrue;
       
   157 		return KStopSending;
       
   158 		}
       
   159 	else
       
   160 		{
       
   161 		return KContinueSending;
       
   162 		}
       
   163 }
       
   164 
       
   165 /**
       
   166 Free all queued buffers. Should be safe as this class owns them
       
   167 */
       
   168 void CPcCardSender::EmptyQueue()
       
   169 {
       
   170 	
       
   171 	while(!iTxQueue.IsEmpty())
       
   172 		{
       
   173 		CIOBuffer* buf = iTxQueue.First();
       
   174 		iTxQueue.Remove(*buf);
       
   175 		delete buf;
       
   176 		}
       
   177 	iQueueLength = 0;
       
   178 	iStopSending = EFalse;
       
   179 }
       
   180 
       
   181 /**
       
   182 Write completion from the LDD. Pseudo transmit interrupt handler
       
   183 */
       
   184 void CPcCardSender::RunL()
       
   185 {
       
   186 	// Check for error, all we can do is free the buffers
       
   187 	if(iStatus.Int()!=KErrNone)
       
   188 		{
       
   189 		EmptyQueue();
       
   190 		return;
       
   191 		}
       
   192 
       
   193 	if(!iTxQueue.IsEmpty())
       
   194 		{
       
   195 		// Head of the queue has been transmitted
       
   196 		// Remove it and free it
       
   197 		CIOBuffer* buf = iTxQueue.First();
       
   198 		iTxQueue.Remove(*buf);
       
   199 		iQueueLength--;
       
   200 		delete buf;
       
   201 		
       
   202 
       
   203 		// Check to see if there are still buffers queued.
       
   204 		// Start next transmit if there are
       
   205 		TBool startTx;
       
   206 		(iTxQueue.IsEmpty()) ? (startTx = EFalse) : (startTx = ETrue);
       
   207 		if(startTx)
       
   208 			{
       
   209 			buf = iTxQueue.First();
       
   210 			iParent->iCard.Write(iStatus,buf->Ptr());
       
   211 			SetActive();
       
   212 			}
       
   213 		else
       
   214 		{
       
   215 			
       
   216 		}
       
   217 		// Resume sending if the protocol was previously blocked
       
   218 		if(iStopSending && iQueueLength < KTxQueueThreshold)
       
   219 			{
       
   220 			iStopSending = EFalse;
       
   221 			iParent->ResumeSending();
       
   222 			}
       
   223 		}
       
   224 }
       
   225 
       
   226 /**
       
   227 cancellation of an outstanding request.
       
   228 */
       
   229 void CPcCardSender::DoCancel()
       
   230 {
       
   231 	iParent->iCard.WriteCancel();
       
   232 }
       
   233 
       
   234 /**
       
   235 Read active object class.
       
   236 Read kept permanently on the LDD
       
   237 Read completion is notified immediately up through the stack
       
   238 with the one receive buffer therefore no Q.
       
   239 */
       
   240 CPcCardReceiver::CPcCardReceiver() : CActive(EPriorityMore)  , iRecvBufPtr(NULL,0) 
       
   241 {
       
   242 	
       
   243 }
       
   244 
       
   245 /**
       
   246 Constructor.
       
   247 */
       
   248 CPcCardReceiver::~CPcCardReceiver()
       
   249 {
       
   250 	Cancel();
       
   251 	// One buffer only
       
   252 	delete iRecvBuffer;
       
   253 }
       
   254 
       
   255 /**
       
   256 Standard CActive construction.
       
   257 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   258 @return A pointer to CPcCardReceiver object.
       
   259 */
       
   260 CPcCardReceiver* CPcCardReceiver::NewL(CPcCardControlEngine* aParent)
       
   261 {
       
   262 	CPcCardReceiver *rv=new (ELeave) CPcCardReceiver;
       
   263 	CleanupStack::PushL(rv);
       
   264 	rv->InitL(aParent);
       
   265 	CActiveScheduler::Add(rv);
       
   266 	CleanupStack::Pop();
       
   267 	return rv;
       
   268 }
       
   269 
       
   270 /**
       
   271 Allocate the one and only read buffer.
       
   272 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   273 */
       
   274 void CPcCardReceiver::InitL(CPcCardControlEngine* aParent)
       
   275 {
       
   276 	iParent=aParent;
       
   277 	iRecvBufLength=KEtherBufSize;
       
   278 	iRecvBuffer=HBufC8::NewMaxL(iRecvBufLength);
       
   279 	TPtr8 temp=iRecvBuffer->Des();
       
   280 	iRecvBufPtr.Set(temp);
       
   281 }
       
   282 
       
   283 /**
       
   284 Pass the receive buffer to the Card.
       
   285 */
       
   286 void CPcCardReceiver::QueueRead()
       
   287 {
       
   288 	iRecvBufPtr.SetMax();
       
   289 	iParent->iCard.Read(iStatus,iRecvBufPtr);
       
   290 	SetActive();
       
   291 }
       
   292 
       
   293 /**
       
   294 Pseudo read interrupt handler.
       
   295 */
       
   296 void CPcCardReceiver::RunL()
       
   297 {
       
   298 	if (iParent->CardOpen())
       
   299 		{
       
   300 		if (iStatus.Int()!=KErrNone)
       
   301 			{
       
   302 			QueueRead();
       
   303 			return;
       
   304 			}
       
   305 		// Pass the buffer up the stack
       
   306 		// and queue the next read, safe to reuse the buffer.
       
   307 		if(iRecvBufPtr.Length())
       
   308 			{
       
   309 			iParent->ProcessReceivedPacket(iRecvBufPtr);
       
   310 			}
       
   311 		QueueRead();
       
   312 		}
       
   313 	else
       
   314 	{
       
   315 		
       
   316 	}
       
   317 }
       
   318 
       
   319 /**
       
   320 Cancellation of an outstanding request.
       
   321 */
       
   322 void CPcCardReceiver::DoCancel()
       
   323 {
       
   324 	iParent->iCard.ReadCancel();
       
   325 }
       
   326 
       
   327 /**
       
   328 Constructor.
       
   329 */
       
   330 CPcCardEventHandler::CPcCardEventHandler() : CActive(EPriorityStandard) 
       
   331 {
       
   332 	
       
   333 }
       
   334 
       
   335 /**
       
   336 Destructor.
       
   337 */
       
   338 CPcCardEventHandler::~CPcCardEventHandler()
       
   339 {
       
   340 	Cancel();
       
   341 }
       
   342 
       
   343 /**
       
   344 Allocate the one and only read buffer.
       
   345 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   346 */
       
   347 void CPcCardEventHandler::InitL(CPcCardControlEngine* aParent)
       
   348 {
       
   349 	iParent = aParent;
       
   350 }
       
   351 
       
   352 /**
       
   353 Standard CActive construction
       
   354 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   355 @return A pointer to the CPcCardEventHandler object.
       
   356 */
       
   357 CPcCardEventHandler* CPcCardEventHandler::NewL(CPcCardControlEngine* aParent)
       
   358 {
       
   359 	CPcCardEventHandler *p=new (ELeave) CPcCardEventHandler;
       
   360 	CleanupStack::PushL(p);
       
   361 	p->InitL(aParent);
       
   362 	CActiveScheduler::Add(p);
       
   363 	CleanupStack::Pop();
       
   364 	return p;
       
   365 }
       
   366 
       
   367 /**
       
   368 Handles an active object’s request completion event.
       
   369 */
       
   370 void CPcCardEventHandler::RunL()
       
   371 {
       
   372 	// TODO Parse code in iStatus for type of event
       
   373 }
       
   374 
       
   375 /**
       
   376 Cancellation of an outstanding request.
       
   377 */
       
   378 void CPcCardEventHandler::DoCancel()
       
   379 {
       
   380 }
       
   381 
       
   382 /**
       
   383 Gets the Event generated by the device drivers.
       
   384 */
       
   385 void CPcCardEventHandler::GetEvent()
       
   386 {
       
   387 	// Tell the device driver we want ALL Events
       
   388 	iEventBuffer.SetLength(1);
       
   389 	iEventBuffer[0] = 0xFF;
       
   390 	SetActive();
       
   391 }
       
   392 
       
   393 /**
       
   394 Constructor.
       
   395 */
       
   396 CPcCardIOCTL::CPcCardIOCTL() : CActive(EPriorityStandard) 
       
   397 {
       
   398 	
       
   399 }
       
   400 
       
   401 /**
       
   402 Destructor.
       
   403 */
       
   404 CPcCardIOCTL::~CPcCardIOCTL()
       
   405 {
       
   406 	Cancel();
       
   407 }
       
   408 
       
   409 /**
       
   410 Add the newly created object to an object container.
       
   411 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   412 */
       
   413 void CPcCardIOCTL::InitL(CPcCardControlEngine* aParent)
       
   414 {
       
   415 	iParent = aParent;
       
   416 }
       
   417 
       
   418 TInt CPcCardIOCTL::Ioctl(const TUint8 aIOCTLCode)
       
   419 {
       
   420 	if(IsActive())
       
   421 		return KErrNotReady;
       
   422 	iIOCTLBuffer.SetLength(1);
       
   423 	iIOCTLBuffer[0] = aIOCTLCode;
       
   424 	iCurrentIOCTL = aIOCTLCode;
       
   425 	SetActive();
       
   426 	return KErrNone;
       
   427 }
       
   428 
       
   429 
       
   430 /**
       
   431 Standard CActive construction.
       
   432 @param aParent Pointer to the parent CPcCardControlEngine class.
       
   433 @return A pointer to CPcCardIOCTL object.
       
   434 */
       
   435 CPcCardIOCTL* CPcCardIOCTL::NewL(CPcCardControlEngine* aParent)
       
   436 {
       
   437 	CPcCardIOCTL *p=new (ELeave) CPcCardIOCTL;
       
   438 	CleanupStack::PushL(p);
       
   439 	p->InitL(aParent);
       
   440 	CActiveScheduler::Add(p);
       
   441 	CleanupStack::Pop();
       
   442 	return p;
       
   443 }
       
   444 
       
   445 /**
       
   446 Handles an active object’s request completion event.
       
   447 */
       
   448 void CPcCardIOCTL::RunL()
       
   449 {
       
   450 			{
       
   451 			iParent->iReceiver->QueueRead();
       
   452 			iParent->LinkLayerUp();
       
   453 			}
       
   454 }
       
   455 
       
   456 /**
       
   457 Cancellation of an outstanding request.
       
   458 */
       
   459 void CPcCardIOCTL::DoCancel()
       
   460 {
       
   461 }