diff -r 1422c6cd3f0c -r e7dfaa7b0b8d linklayerprotocols/ethernetnif/EtherPkt/CardCtl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linklayerprotocols/ethernetnif/EtherPkt/CardCtl.cpp Thu Mar 04 11:58:36 2010 +0000 @@ -0,0 +1,452 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Control engine for ethernet packet driver +// +// + +/** + @file +*/ + +#include +#include +#include +#include +#include +#include +#include "PKTDRV.H" +#include "ETHINTER.H" +#include "Cardctl.h" +#include +#include + +//#define __DebugCardCtl__ 1 + + + +/** +Create a new CPcCardControlEngine object. +@param aPktDrv Pointer to PC Card Packet Driver. +@return A pointer to CPcCardControlEngine object. +*/ +CPcCardControlEngine *CPcCardControlEngine::NewL(CPcCardPktDrv* aPktDrv) +{ + CPcCardControlEngine *cc=new (ELeave) CPcCardControlEngine(aPktDrv); + CleanupStack::PushL(cc); + cc->ConstructL(); + CleanupStack::Pop(); + return cc; +} + +/** +Physical device driver settings +@internalComponent +*/ +_LIT(KPddSection,"pdd_settings"); + +/** +PCMCIA Socket Number +@internalComponent +*/ +_LIT(KSocketNumber,"PCMCIA_socket"); + +/** +Create the CPcCardControlEngine object. +*/ +void CPcCardControlEngine::ConstructL() +{ + iSender = CPcCardSender::NewL(this); + iReceiver = CPcCardReceiver::NewL(this); + iEventHandler = CPcCardEventHandler::NewL(this); + + LoadDeviceDriversL(); + + CESockIniData* ini = CESockIniData::NewL(ETHER802_CONFIG_FILENAME); + CleanupStack::PushL(ini); + + TInt socket; + if(!ini->FindVar(KPddSection,KSocketNumber,socket)) + { + User::Leave(KErrNotFound); + } + + CleanupStack::PopAndDestroy(ini); + + TInt error = iCard.Open(socket); + User::LeaveIfError(error); +} + +/** +Open the Card LDD +*/ +void CPcCardControlEngine::StartL() +{ + iCardOpen = ETrue; + iReceiver->QueueRead(); + LinkLayerUp(); +} + +/** +Find and loads the LDD and the PDD if the logical device driver loaded OK. +The driver names are read from the LAN bearer table in commdb. +*/ +void CPcCardControlEngine::LoadDeviceDriversL() +{ + TInt err; + + // + // Get the device driver filenames for loading + // + TBuf pddOrLddFileName; + + // LDD first... + TBuf columnName=TPtrC(LAN_BEARER); + columnName.Append(TChar(KSlashChar)); + columnName.Append(TPtrC(LAN_BEARER_LDD_FILENAME)); + + err = iNotify->NifNotify()->ReadDes(columnName, pddOrLddFileName); // Get the LDD name from commdb + + if(err!=KErrNone) + { + __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.")); + User::Leave(err); + } + + err=User::LoadLogicalDevice(pddOrLddFileName); + if(err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // ...and now the PDD + columnName.Zero(); + columnName.Append(TPtrC(LAN_BEARER)); + columnName.Append(TChar(KSlashChar)); + columnName.Append(TPtrC(LAN_BEARER_PDD_FILENAME)); + + err = iNotify->NifNotify()->ReadDes(columnName, pddOrLddFileName); // Get the PDD filename from commdb + + if(err!=KErrNone) + { + __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.")); + User::Leave(err); + } + + err = User::LoadPhysicalDevice(pddOrLddFileName); + if (err != KErrNone && err != KErrAlreadyExists) + { + User::Leave(err); + } + + // + // Get device driver names for unloading + // + columnName.Zero(); + columnName.Append(TPtrC(LAN_BEARER)); + columnName.Append(TChar(KSlashChar)); + columnName.Append(TPtrC(LAN_BEARER_PDD_NAME)); + + err = iNotify->NifNotify()->ReadDes(columnName, iPDDName); // Get the PDD name from commdb (so we can close it when we've finished with it) + + if(err!=KErrNone) + { + __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.")); + +#ifdef _DEBUG + // Not being able to unload the device drivers is not a fatal error, so don't worry too + // much if we can't read the field out of commdb in release builds, but if the user is + // using a debug nif they ought to get it right... + User::Leave(err); +#endif // _DEBUG + } + + // Rather than fiddle around trying to reuse the contents of the descriptor (problems with field name lengths), just zero and start again + columnName.Zero(); + columnName.Append(TPtrC(LAN_BEARER)); + columnName.Append(TChar(KSlashChar)); + columnName.Append(TPtrC(LAN_BEARER_LDD_NAME)); + + err = iNotify->NifNotify()->ReadDes(columnName, iLDDName); // Get the LDD name from commdb (so we can close it when we've finished with it) + + if(err!=KErrNone) + { + __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.")); + +#ifdef _DEBUG + User::Leave(err); // see reasoning for LDD above +#endif // _DEBUG + } + + __FLOG_STATIC(KEther802LogTag1,KEthLogTag3, _L("Device drivers loaded")); +} + +/** +Cancel I/O and close the Card LDD. +*/ +void CPcCardControlEngine::Stop() +{ + // LDD Performs status checks on Read and Write + // Completes requests with an error code if they are pending + iCard.WriteCancel(); + iSender->EmptyQueue(); + iSender->Cancel(); + + iCard.ReadCancel(); + iCardOpen = EFalse; + iCard.Close(); +} + +CPcCardControlEngine::CPcCardControlEngine(CPcCardPktDrv* aPktDrv) +:iCardOpen(EFalse), iNotify(aPktDrv) +/** +Constructor. +@param aPktDrv Pointer to PC Card Packet Driver. +*/ +{ + +} + +/** +Destructor. +*/ +CPcCardControlEngine::~CPcCardControlEngine() +{ +#ifdef _DEBUG + // see reasoning for only doing this in debug builds in LoadPacketDrivers() + User::FreeLogicalDevice(iLDDName); + User::FreePhysicalDevice(iPDDName); +#endif + + delete iReceiver; + delete iSender; + delete iEventHandler; +} + +/** +Upwards notify +@param aBuffer A Reference to a buffer holding data. +*/ +void CPcCardControlEngine::ProcessReceivedPacket(TDesC8& aBuffer) +{ + iNotify->ReadDataAvailable(aBuffer); +} + +/** +Resume Sending is a notification call into NIF from the lower layer telling the NIF that a +previous sending congestion situation has been cleared and it can accept more downstack data. +*/ +void CPcCardControlEngine::ResumeSending() +{ + iNotify->ResumeSending(); +} + +/** +Resume Sending is a notification call into NIF from the lower layer telling the NIF that +the interface is now up and can accept and transmit data. NIF subsequently calls all the +bearers' StartSending() methods directly. +*/ +void CPcCardControlEngine::LinkLayerUp() +{ + iNotify->LinkLayerUp(); +} + +/** +Sender class handles queueing and takes ownership of the HBuf and the CIOBuffer. +@param aBuffer The data to be send is set. +@return 0 Tells the higher layer to send no more data. + 1 Tells higher layer that it can send more data. +*/ +TInt CPcCardControlEngine::Send(HBufC8* aBuffer) +{ + CIOBuffer* buf = NULL; + TRAPD(err,buf = CIOBuffer::NewL(aBuffer)); + if(err != KErrNone) + { + delete aBuffer; + } + else + { + err = iSender->Send(buf); + } + return err; +} + +/** +Call to LDD or subordinate object to get the Hardware address of the LAN Device +@return NULL Failure. + (NULL Terminated Binary String) The Hardware Address of the interface. LAN Device + Specific +*/ +TUint8* CPcCardControlEngine::GetInterfaceAddress() +{ + iConfig.SetMax(); + iCard.Config(iConfig); + return ((TUint8*)iConfig.Ptr())+2; // The MAC address is located 2 bytes + // from the start of the buffer +} + +#if !defined(__WINS__) +// + +/** +ethermac.dat reading - work around for mac address problem +@internal component +*/ +_LIT(KEtherMacFileName,"C:\\System\\Data\\EtherMac.dat"); + +/** +Parse the Machine Address from the File. +*/ +void CPcCardControlEngine::ParseMACFromFileL() +{ + + TBuf8<64> controlBuf; // the size of this is defined in the driver as 64. + TBuf8<12> macAddress = 0; + RFile macFile; + RFs fileSrv; + + User::LeaveIfError(fileSrv.Connect()); + User::LeaveIfError(macFile.Open(fileSrv,KEtherMacFileName,EFileRead)); + User::LeaveIfError(macFile.Read(macAddress,12)); + macFile.Close(); + fileSrv.Close(); + controlBuf.SetLength(8); + controlBuf[0] = KEthSpeed10BaseT; + controlBuf[1] = KEthDuplexHalf; + + TBuf<20> validChars(_L("0123456789abcdef")); + TUint8 value; + TUint8 upper=0; + TChar c; + TInt pos; + iConfig.SetMax(); // MAC Address fix + for(TInt i=0; i<6; i++) + { + c = macAddress[2*i]; + c.LowerCase(); + if((pos = validChars.Locate(c))==KErrNotFound) + { + pos = upper; + break; + } + upper = (TUint8)pos; + c = macAddress[(2*i)+1]; + c.LowerCase(); + if((pos = validChars.Locate(c))==KErrNotFound) + { + User::Leave(KErrNotFound); + } + value = (TUint8)pos; + value = (TUint8)((upper<<4) | value); + controlBuf.Append(value); + iConfig[i+2]=value; // MAC Address fix 21/05/01 + } + TRequestStatus status = 0; + + User::LeaveIfError(iCard.SetMAC(controlBuf)); + + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); +} +#endif + +/** +Constructor. Generic Buffer class +Currently used for transmit buffers +*/ +CIOBuffer::CIOBuffer() : iBufPtr(NULL,0) +{ +} + +/** +Destructor. Free the HBuf if there is one +*/ +CIOBuffer::~CIOBuffer() +{ + FreeData(); +} + +/** +Creation where we new the HBuf. +@param aSize Length of the Buffer. +@return A pointer to CIOBuffer object. +*/ +CIOBuffer* CIOBuffer::NewL(const TInt aSize) +{ + CIOBuffer * self = new (ELeave) CIOBuffer; + CleanupStack::PushL(self); + self->ConstructL(aSize); + CleanupStack::Pop(); + return self; +} + +/** +Construction where we new the HBuf +@param aSize Length of the Buffer. +*/ +void CIOBuffer::ConstructL(const TInt aSize) +{ + iBuf = HBufC8::NewL(aSize); + TPtr8 temp=iBuf->Des(); + iBufPtr.Set(temp); +} + +/** +HBuf provided. +@param aBuf The data to be assigned +@return A pointer to CIOBuffer object. +*/ +CIOBuffer* CIOBuffer::NewL(HBufC8* aBuf) +{ + CIOBuffer * self = new (ELeave) CIOBuffer; + self->Assign(aBuf); + return self; +} + +/** +Offset +*/ +TInt CIOBuffer::LinkOffset() +{ + return _FOFF(CIOBuffer,iLink); +} + +/** +Assigns the data from buffer to pointer. + +@param aBuffer The data to be assigned +*/ +void CIOBuffer::Assign(HBufC8* aBuffer) +{ + FreeData(); + iBuf = aBuffer; + if(aBuffer) + { + TPtr8 temp=iBuf->Des(); + iBufPtr.Set(temp); + } +} + +/** +Frees the data. +*/ +void CIOBuffer::FreeData() +{ + if(iBuf) + { + delete iBuf; + iBuf = NULL; + } +} +