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