linklayerprotocols/ethernetnif/EtherPkt/CardCtl.cpp
changeset 14 b33c3d136b7e
child 61 2fc972553898
equal deleted inserted replaced
1:a579325b79dd 14:b33c3d136b7e
       
     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 // Control engine for ethernet packet driver 
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <nifman.h>
       
    23 #include <nifvar.h>
       
    24 #include <nifutl.h>
       
    25 #include <es_mbuf.h>
       
    26 #include <es_ini.h>
       
    27 #include <ir_sock.h>
       
    28 #include "PKTDRV.H"
       
    29 #include "ETHINTER.H"
       
    30 #include "Cardctl.h"
       
    31 #include <f32file.h>
       
    32 #include <e32svr.h>
       
    33 
       
    34 //#define __DebugCardCtl__ 1
       
    35 
       
    36 #if defined(__DebugCardCtl__)
       
    37 #include <e32svr.h>
       
    38  #define DPRINT(x) RDebug::Print x
       
    39  #pragma message ("Warning: this code contains RDebug::Print statements!  Do not submit to the mainline with __DebugCardCtl__ defined.")
       
    40 #else
       
    41  #define DPRINT(x)
       
    42 #endif
       
    43 
       
    44 /**
       
    45 Create a new CPcCardControlEngine object.
       
    46 @param aPktDrv Pointer to PC Card Packet Driver.
       
    47 @return A pointer to CPcCardControlEngine object.
       
    48 */
       
    49 CPcCardControlEngine *CPcCardControlEngine::NewL(CPcCardPktDrv* aPktDrv)
       
    50 {
       
    51 	CPcCardControlEngine *cc=new (ELeave) CPcCardControlEngine(aPktDrv);
       
    52 	CleanupStack::PushL(cc);
       
    53 	cc->ConstructL();
       
    54 	CleanupStack::Pop();
       
    55 	return cc;
       
    56 }
       
    57 
       
    58 /**
       
    59 Physical device driver settings
       
    60 @internalComponent
       
    61 */
       
    62 _LIT(KPddSection,"pdd_settings");
       
    63  
       
    64 /**
       
    65 PCMCIA Socket Number
       
    66 @internalComponent
       
    67 */
       
    68 _LIT(KSocketNumber,"PCMCIA_socket"); 
       
    69 
       
    70 /**
       
    71 Create the CPcCardControlEngine object.
       
    72 */
       
    73 void CPcCardControlEngine::ConstructL()
       
    74 {
       
    75 	iSender = CPcCardSender::NewL(this);
       
    76 	iReceiver = CPcCardReceiver::NewL(this);
       
    77 	iEventHandler = CPcCardEventHandler::NewL(this);
       
    78 
       
    79 	LoadDeviceDriversL();
       
    80 
       
    81 	CESockIniData* ini = CESockIniData::NewL(ETHER802_CONFIG_FILENAME);
       
    82 	CleanupStack::PushL(ini);
       
    83 
       
    84 	TInt socket;
       
    85 	if(!ini->FindVar(KPddSection,KSocketNumber,socket))
       
    86 		{
       
    87 		User::Leave(KErrNotFound);
       
    88 		}
       
    89 	
       
    90 	CleanupStack::PopAndDestroy(ini);
       
    91 
       
    92 	TInt error = iCard.Open(socket);
       
    93 	User::LeaveIfError(error);
       
    94 }
       
    95 
       
    96 /**
       
    97 Open the Card LDD
       
    98 */
       
    99 void CPcCardControlEngine::StartL()
       
   100 {
       
   101 	iCardOpen = ETrue;
       
   102 	iReceiver->QueueRead();
       
   103 	LinkLayerUp();
       
   104 }
       
   105 
       
   106 /**
       
   107 Find and loads the LDD and the PDD if the logical device driver loaded OK.
       
   108 The driver names are read from the LAN bearer table in commdb.
       
   109 */
       
   110 void CPcCardControlEngine::LoadDeviceDriversL()
       
   111 {
       
   112 	TInt err;
       
   113 
       
   114 	//
       
   115 	// Get the device driver filenames for loading
       
   116 	//
       
   117 	TBuf<KCommsDbSvrDefaultTextFieldLength> pddOrLddFileName;
       
   118 	
       
   119 	// LDD first...
       
   120 	TBuf<KCommsDbSvrMaxColumnNameLength> columnName=TPtrC(LAN_BEARER);
       
   121 	columnName.Append(TChar(KSlashChar));
       
   122 	columnName.Append(TPtrC(LAN_BEARER_LDD_FILENAME));
       
   123 	
       
   124 	err = iNotify->NifNotify()->ReadDes(columnName, pddOrLddFileName); // Get the LDD name from commdb
       
   125 	
       
   126 	if(err!=KErrNone)
       
   127 		{
       
   128 		__FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Could not find LDD filename in commdb - is .cfg file up-to-date?  See ether802.ini for information on required fields in commdb."));
       
   129 		User::Leave(err);
       
   130 		}
       
   131 	
       
   132 	err=User::LoadLogicalDevice(pddOrLddFileName);
       
   133 	if(err != KErrNone && err != KErrAlreadyExists)
       
   134 		{
       
   135 		User::Leave(err);
       
   136 		}
       
   137 	
       
   138 	// ...and now the PDD
       
   139 	columnName.Zero();
       
   140 	columnName.Append(TPtrC(LAN_BEARER));
       
   141 	columnName.Append(TChar(KSlashChar));
       
   142 	columnName.Append(TPtrC(LAN_BEARER_PDD_FILENAME));
       
   143 
       
   144 	err = iNotify->NifNotify()->ReadDes(columnName, pddOrLddFileName); // Get the PDD filename from commdb
       
   145 
       
   146 	if(err!=KErrNone)
       
   147 		{
       
   148 		__FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Could not find PDD filename in commdb - is .cfg file up-to-date?  See ether802.ini for information on required fields in commdb."));
       
   149 		User::Leave(err);
       
   150 		}
       
   151 
       
   152 	err = User::LoadPhysicalDevice(pddOrLddFileName);
       
   153 	if (err != KErrNone && err != KErrAlreadyExists)
       
   154 		{
       
   155 		User::Leave(err);
       
   156 		}
       
   157 
       
   158 	//
       
   159 	// Get device driver names for unloading
       
   160 	//
       
   161 	columnName.Zero();
       
   162 	columnName.Append(TPtrC(LAN_BEARER));
       
   163 	columnName.Append(TChar(KSlashChar));
       
   164 	columnName.Append(TPtrC(LAN_BEARER_PDD_NAME));
       
   165 
       
   166 	err = iNotify->NifNotify()->ReadDes(columnName, iPDDName); // Get the PDD name from commdb (so we can close it when we've finished with it)
       
   167 
       
   168 	if(err!=KErrNone)
       
   169 		{
       
   170 		__FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Could not find PDD name in commdb - is .cfg file up-to-date?  See ether802.ini for information on required fields in commdb."));
       
   171 
       
   172 #ifdef _DEBUG
       
   173 		// Not being able to unload the device drivers is not a fatal error, so don't worry too 
       
   174 		// much if we can't read the field out of commdb in release builds, but if the user is 
       
   175 		// using a debug nif they ought to get it right...
       
   176 		User::Leave(err);
       
   177 #endif // _DEBUG
       
   178 		}
       
   179 
       
   180 	// Rather than fiddle around trying to reuse the contents of the descriptor (problems with field name lengths), just zero and start again
       
   181 	columnName.Zero();
       
   182 	columnName.Append(TPtrC(LAN_BEARER));
       
   183 	columnName.Append(TChar(KSlashChar));
       
   184 	columnName.Append(TPtrC(LAN_BEARER_LDD_NAME));
       
   185 
       
   186 	err = iNotify->NifNotify()->ReadDes(columnName, iLDDName); // Get the LDD name from commdb (so we can close it when we've finished with it)
       
   187 	
       
   188 	if(err!=KErrNone)
       
   189 		{
       
   190 		__FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Could not find LDD name in commdb - is .cfg file up-to-date?  See ether802.ini for information on required fields in commdb."));
       
   191 
       
   192 #ifdef _DEBUG
       
   193 		User::Leave(err);	// see reasoning for LDD above
       
   194 #endif // _DEBUG
       
   195 		}
       
   196 
       
   197 	__FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Device drivers loaded"));
       
   198 }
       
   199 
       
   200 /**
       
   201 Cancel I/O and close the Card LDD.
       
   202 */
       
   203 void CPcCardControlEngine::Stop()
       
   204 {
       
   205 	// LDD Performs status checks on Read and Write
       
   206 	// Completes requests with an error code if they are pending
       
   207 	iCard.WriteCancel();
       
   208 	iSender->EmptyQueue();
       
   209 	iSender->Cancel();
       
   210 
       
   211 	iCard.ReadCancel();
       
   212 	iCardOpen = EFalse;
       
   213 	iCard.Close();
       
   214 }
       
   215 
       
   216 CPcCardControlEngine::CPcCardControlEngine(CPcCardPktDrv* aPktDrv)
       
   217 :iCardOpen(EFalse), iNotify(aPktDrv)
       
   218 /**
       
   219 Constructor.
       
   220 @param aPktDrv Pointer to PC Card Packet Driver.
       
   221 */
       
   222 {
       
   223 
       
   224 }		
       
   225 
       
   226 /**
       
   227 Destructor.
       
   228 */
       
   229 CPcCardControlEngine::~CPcCardControlEngine()
       
   230 {
       
   231 #ifdef _DEBUG
       
   232 	// see reasoning for only doing this in debug builds in LoadPacketDrivers()
       
   233 	User::FreeLogicalDevice(iLDDName);
       
   234 	User::FreePhysicalDevice(iPDDName);
       
   235 #endif
       
   236 
       
   237 	delete iReceiver;
       
   238 	delete iSender;
       
   239 	delete iEventHandler;
       
   240 }
       
   241 
       
   242 /**
       
   243 Upwards notify
       
   244 @param aBuffer A Reference to a buffer holding data.
       
   245 */
       
   246 void CPcCardControlEngine::ProcessReceivedPacket(TDesC8& aBuffer)
       
   247 {
       
   248 	iNotify->ReadDataAvailable(aBuffer);
       
   249 }
       
   250 
       
   251 /**
       
   252 Resume Sending is a notification call into NIF from the lower layer telling the NIF that a 
       
   253 previous sending congestion situation has been cleared and it can accept more downstack data.
       
   254 */
       
   255 void CPcCardControlEngine::ResumeSending()
       
   256 {
       
   257 	iNotify->ResumeSending();
       
   258 }
       
   259 
       
   260 /**
       
   261 Resume Sending is a notification call into NIF from the lower layer telling the NIF that 
       
   262 the interface is now up and can accept and transmit data. NIF subsequently calls all the 
       
   263 bearers' StartSending() methods directly.
       
   264 */
       
   265 void CPcCardControlEngine::LinkLayerUp()
       
   266 {
       
   267 	iNotify->LinkLayerUp();
       
   268 }
       
   269 
       
   270 /**
       
   271 Sender class handles queueing and takes ownership of the HBuf and the CIOBuffer.
       
   272 @param aBuffer The data to be send is set.
       
   273 @return 0 Tells the higher layer to send no more data.
       
   274 		1 Tells higher layer that it can send more data.
       
   275 */
       
   276 TInt CPcCardControlEngine::Send(HBufC8* aBuffer)
       
   277 {
       
   278 	DPRINT((_L(">CPcCardControlEngine::Send")));
       
   279 	CIOBuffer* buf = NULL;
       
   280 	TRAPD(err,buf = CIOBuffer::NewL(aBuffer));
       
   281 	if(err != KErrNone)
       
   282 		{
       
   283 		DPRINT((_L(">CPcCardControlEngine::Send No Buffer.")));
       
   284 		delete aBuffer;
       
   285 		}
       
   286 	else
       
   287 		{
       
   288 		DPRINT((_L(">CPcCardControlEngine::Send About to iSender.")));
       
   289 		err = iSender->Send(buf);
       
   290 		}
       
   291 	DPRINT((_L("<CPcCardControlEngine::Send.")));
       
   292 	return err;
       
   293 }
       
   294 
       
   295 /**
       
   296 Call to LDD or subordinate object to get the Hardware address of the LAN Device
       
   297 @return NULL Failure.
       
   298 		(NULL Terminated Binary String) The Hardware Address of the interface. LAN Device 
       
   299 		Specific
       
   300 */
       
   301 TUint8* CPcCardControlEngine::GetInterfaceAddress()
       
   302 {
       
   303 	iConfig.SetMax();
       
   304 	iCard.Config(iConfig);
       
   305 	return ((TUint8*)iConfig.Ptr())+2; // The MAC address is located 2 bytes
       
   306 					   // from the start of the buffer
       
   307 }
       
   308 
       
   309 #if !defined(__WINS__)
       
   310 //
       
   311 
       
   312 /** 
       
   313 ethermac.dat reading - work around for mac address problem 
       
   314 @internal component
       
   315 */
       
   316 _LIT(KEtherMacFileName,"C:\\System\\Data\\EtherMac.dat");
       
   317 
       
   318 /**
       
   319 Parse the Machine Address from the File.
       
   320 */
       
   321 void CPcCardControlEngine::ParseMACFromFileL()
       
   322 {
       
   323 
       
   324 	TBuf8<64> controlBuf;  // the size of this is defined in the driver as 64.
       
   325 	TBuf8<12> macAddress = 0;
       
   326 	RFile macFile;
       
   327 	RFs fileSrv;
       
   328 	
       
   329 	User::LeaveIfError(fileSrv.Connect());
       
   330 	User::LeaveIfError(macFile.Open(fileSrv,KEtherMacFileName,EFileRead));
       
   331 	User::LeaveIfError(macFile.Read(macAddress,12));
       
   332 	macFile.Close();
       
   333 	fileSrv.Close();
       
   334 	controlBuf.SetLength(8);	
       
   335 	controlBuf[0] = KEthSpeed10BaseT;
       
   336 	controlBuf[1] = KEthDuplexHalf;
       
   337 
       
   338 	TBuf<20> validChars(_L("0123456789abcdef"));
       
   339 	TUint8 value;
       
   340 	TUint8 upper=0;
       
   341 	TChar c;
       
   342 	TInt pos; 
       
   343 	iConfig.SetMax(); // MAC Address fix
       
   344 	for(TInt i=0; i<6; i++)
       
   345 	{
       
   346 		c = macAddress[2*i];
       
   347 		c.LowerCase();
       
   348 		if((pos = validChars.Locate(c))==KErrNotFound)
       
   349 		{
       
   350 			pos = upper;
       
   351 			break;
       
   352 		}
       
   353 		upper = (TUint8)pos;
       
   354 		c = macAddress[(2*i)+1];
       
   355 		c.LowerCase();
       
   356 		if((pos = validChars.Locate(c))==KErrNotFound)
       
   357 		{
       
   358 			User::Leave(KErrNotFound);
       
   359 		}
       
   360 		value = (TUint8)pos;
       
   361 		value = (TUint8)((upper<<4) | value);
       
   362 		controlBuf.Append(value);
       
   363 		iConfig[i+2]=value; // MAC Address fix 21/05/01
       
   364 	}
       
   365 	TRequestStatus status = 0;
       
   366 	DPRINT((_L("ParseMACFromFileL(), iConfig MAC set to %x %x %x %x %x %x"),
       
   367 		iConfig[2],iConfig[3],iConfig[4],iConfig[5],iConfig[6],iConfig[7]));
       
   368 	User::LeaveIfError(iCard.SetMAC(controlBuf));
       
   369 
       
   370 	User::WaitForRequest(status);
       
   371 	User::LeaveIfError(status.Int());
       
   372 }
       
   373 #endif
       
   374 
       
   375 /**
       
   376 Constructor. Generic Buffer class
       
   377 Currently used for transmit buffers
       
   378 */
       
   379 CIOBuffer::CIOBuffer() : iBufPtr(NULL,0)
       
   380 {
       
   381 }
       
   382 
       
   383 /**
       
   384 Destructor. Free the HBuf if there is one
       
   385 */
       
   386 CIOBuffer::~CIOBuffer()
       
   387 {
       
   388 	FreeData();
       
   389 }
       
   390 
       
   391 /**
       
   392 Creation where we new the HBuf.
       
   393 @param aSize Length of the Buffer.
       
   394 @return A pointer to CIOBuffer object.
       
   395 */
       
   396 CIOBuffer* CIOBuffer::NewL(const TInt aSize)
       
   397 {
       
   398 	CIOBuffer * self = new (ELeave) CIOBuffer;
       
   399 	CleanupStack::PushL(self);
       
   400 	self->ConstructL(aSize);
       
   401 	CleanupStack::Pop();
       
   402 	return self;
       
   403 }
       
   404 
       
   405 /**
       
   406 Construction where we new the HBuf
       
   407 @param aSize Length of the Buffer.
       
   408 */
       
   409 void CIOBuffer::ConstructL(const TInt aSize)
       
   410 {
       
   411 	iBuf = HBufC8::NewL(aSize);
       
   412 	TPtr8 temp=iBuf->Des();
       
   413 	iBufPtr.Set(temp);
       
   414 }
       
   415 
       
   416 /**
       
   417 HBuf provided. 
       
   418 @param aBuf The data to be assigned 
       
   419 @return A pointer to CIOBuffer object.
       
   420 */
       
   421 CIOBuffer* CIOBuffer::NewL(HBufC8* aBuf)
       
   422 {
       
   423 	CIOBuffer * self = new (ELeave) CIOBuffer;
       
   424 	self->Assign(aBuf);
       
   425 	return self;
       
   426 }
       
   427 
       
   428 /**
       
   429 Offset 
       
   430 */
       
   431 TInt CIOBuffer::LinkOffset()
       
   432 {
       
   433 	return _FOFF(CIOBuffer,iLink);	
       
   434 }
       
   435 
       
   436 /**
       
   437 Assigns the data from buffer to pointer.
       
   438 
       
   439 @param aBuffer The data to be assigned  
       
   440 */
       
   441 void CIOBuffer::Assign(HBufC8* aBuffer)
       
   442 {
       
   443 	FreeData();
       
   444 	iBuf = aBuffer;
       
   445 	if(aBuffer)
       
   446 		{
       
   447 		TPtr8 temp=iBuf->Des();
       
   448 		iBufPtr.Set(temp);
       
   449 		}
       
   450 }
       
   451 
       
   452 /**
       
   453 Frees the data.
       
   454 */
       
   455 void CIOBuffer::FreeData()
       
   456 {
       
   457 	if(iBuf)
       
   458 		{
       
   459 		delete iBuf;
       
   460 		iBuf = NULL;
       
   461 		}
       
   462 }
       
   463