--- /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 <nifman.h>
+#include <nifvar.h>
+#include <nifutl.h>
+#include <es_mbuf.h>
+#include <es_ini.h>
+#include <ir_sock.h>
+#include "PKTDRV.H"
+#include "ETHINTER.H"
+#include "Cardctl.h"
+#include <f32file.h>
+#include <e32svr.h>
+
+//#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<KCommsDbSvrDefaultTextFieldLength> pddOrLddFileName;
+
+ // LDD first...
+ TBuf<KCommsDbSvrMaxColumnNameLength> 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;
+ }
+}
+