--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdkcreationmw/sdkruntimes/wsock/src/WinsockInterface.cpp Mon Mar 08 12:09:11 2010 +0530
@@ -0,0 +1,441 @@
+/*
+* Copyright (c) 2004-2005 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:
+*
+*/
+
+
+#define TRACE_PREFIX "WSOCK: Interface: "
+#include "wsock.h"
+#include "WinsockInterface.h"
+#include "WinsockProtocolFamily.h"
+
+const TInt KWinsockSubConnectionId = 1;
+const TConnectionType EWinsockConnectionType = EConnectionEthernet;
+#define super CNifIfLink
+
+// CWinsockInterface::CallbackQueueEntry
+class CWinsockInterface::CallbackQueueEntry
+{
+private:
+ CWinsockInterface* iInterface;
+ CallbackMethod iMethod;
+ TInt iParam1;
+ TInt iParam2;
+public:
+ TSglQueLink iLink;
+ CallbackQueueEntry(CWinsockInterface* aInterface, CallbackMethod aMethod,
+ TInt aParam1, TInt aParam2) : iInterface(aInterface),
+ iMethod(aMethod), iParam1(aParam1), iParam2(aParam2) {}
+ void Invoke() { (iInterface->*iMethod)(iParam1, iParam2); }
+};
+
+// CWinsockInterface
+CWinsockInterface::CWinsockInterface(CNifIfFactory* aFactory,
+ MNifIfNotify* aNotify) :
+super(*aFactory),
+iSignature(KWinsockInterfaceSignature),
+iCallbackQueue(_FOFF(CallbackQueueEntry,iLink)),
+iCallback(TCallBack(AsyncCallbackProc,this),CActive::EPriorityStandard)
+{
+ iNotify = aNotify;
+ iTimeStarted.HomeTime();
+ TRACE1("created [%08X]",this);
+}
+
+CWinsockInterface::~CWinsockInterface()
+{
+ CancelOutstandingCallbacks();
+ TRACE1("destroyed [%08X]",this);
+}
+
+TInt CWinsockInterface::Signature() const
+{
+ return KWinsockInterfaceSignature;
+}
+
+TInt CWinsockInterface::AsyncCallbackProc(TAny* aPtr)
+{
+ CWinsockInterface* self = (CWinsockInterface*)aPtr;
+ self->HandleAsyncCallback();
+ return KErrNone;
+}
+
+void CWinsockInterface::HandleAsyncCallback()
+{
+ // Invoke the first callback in the queue
+ if (!iCallbackQueue.IsEmpty()) {
+ CallbackQueueEntry* entry = iCallbackQueue.First();
+ iCallbackQueue.Remove(*entry);
+ entry->Invoke();
+ delete entry;
+
+ // Schedule the next one
+ if (!iCallbackQueue.IsEmpty()) {
+ iCallback.CallBack();
+ }
+ }
+}
+
+void CWinsockInterface::ScheduleAsyncCallback(CallbackMethod aMethod,
+ TInt aP1, TInt aP2)
+{
+ CallbackQueueEntry* entry = new CallbackQueueEntry(this,aMethod,aP1,aP2);
+ if (entry) {
+ iCallbackQueue.AddLast(*entry);
+ iCallback.Cancel();
+ iCallback.CallBack();
+ }
+}
+
+void CWinsockInterface::CancelOutstandingCallbacks()
+{
+ iCallback.Cancel();
+ while (!iCallbackQueue.IsEmpty()) {
+ CallbackQueueEntry* entry = iCallbackQueue.First();
+ iCallbackQueue.Remove(*entry);
+ delete entry;
+ }
+}
+
+void CWinsockInterface::NotifyLinkLayerUp(TInt, TInt)
+{
+ ScheduleAsyncCallback(NotifySubConnectionOpened);
+ TRACE("firing LinkLayerUp event");
+ iNotify->LinkLayerUp();
+}
+
+void CWinsockInterface::NotifyLinkLayerOpen(TInt, TInt)
+{
+ TRACE("firing LinkLayerOpen event");
+ iNotify->IfProgress(KLinkLayerOpen, KErrNone);
+}
+
+// Sends a subconnection opened event for the entire connection
+void CWinsockInterface::NotifySubConnectionOpened(TInt, TInt)
+{
+ ScheduleAsyncCallback(NotifyLinkLayerOpen);
+
+ TRACE("firing TSubConnectionOpenedEvent");
+ TSubConnectionOpenedEvent event;
+ event.iSubConnectionUniqueId = KNifEntireConnectionSubConnectionId;
+ TPckg<TSubConnectionOpenedEvent> eventPtr(event);
+ iNotify->NifEvent(ESubConnectionEvent, ESubConnectionOpened, eventPtr);
+}
+
+// Sends a subconnection Closed event for the entire connection
+void CWinsockInterface::NotifySubConnectionClosed(TInt aReason, TInt)
+{
+ ScheduleAsyncCallback(NotifyLinkLayerClosed, aReason);
+
+ TRACE("firing TSubConnectionClosedEvent");
+ TSubConnectionClosedEvent event;
+ event.iSubConnectionUniqueId = KNifEntireConnectionSubConnectionId;
+ event.iTotalUplinkDataVolume = iBytesReceived;
+ event.iTotalDownlinkDataVolume = iBytesSent;
+ event.iTimeClosed.UniversalTime();
+ TPckg<TSubConnectionClosedEvent> eventPtr(event);
+ iNotify->NifEvent(ESubConnectionEvent, ESubConnectionClosed, eventPtr);
+}
+
+void CWinsockInterface::NotifyLinkLayerDown(TInt aReason, TInt aAction)
+{
+ ScheduleAsyncCallback(NotifySubConnectionClosed, aReason);
+ TRACE("firing LinkLayerDown event");
+ iNotify->LinkLayerDown(aReason, (MNifIfNotify::TAction)aAction);
+}
+
+void CWinsockInterface::NotifyLinkLayerClosed(TInt aReason, TInt)
+{
+ TRACE("firing LinkLayerClosed event");
+ iNotify->IfProgress(KLinkLayerClosed, aReason);
+}
+
+void CWinsockInterface::DataSent(TUint aBytes)
+{
+ // Handle rollover?
+ iBytesSent += aBytes;
+ if (iBytesSentGranularity)
+ {
+ TUint delta = iBytesSent - iBytesSentMark;
+ if (delta >= iBytesSentGranularity)
+ {
+ int chunks = delta/iBytesSentGranularity;
+ iBytesSentMark += chunks*iBytesSentGranularity;
+ iNotify->NotifyDataSent(KWinsockSubConnectionId,
+ delta*iBytesSentGranularity);
+ }
+ }
+}
+
+void CWinsockInterface::DataReceived(TUint aBytes)
+{
+ // Handle rollover?
+ iBytesReceived += aBytes;
+ if (iBytesReceivedGranularity)
+ {
+ TUint delta = iBytesReceived - iBytesReceivedMark;
+ if (delta >= iBytesReceivedGranularity)
+ {
+ int chunks = delta/iBytesReceivedGranularity;
+ iBytesReceivedMark += chunks*iBytesReceivedGranularity;
+ iNotify->NotifyDataReceived(KWinsockSubConnectionId,
+ delta*iBytesReceivedGranularity);
+ }
+ }
+}
+
+// CNifIfBase
+void CWinsockInterface::Info(TNifIfInfo& aInfo) const
+{
+ aInfo.iName = KWinsockInterface;
+ aInfo.iVersion = TVersion(1,0,0);
+ aInfo.iFlags = KNifIfIsBase | KNifIfIsLink | KNifIfUsesNotify | KNifIfCreatedByFactory;
+ aInfo.iProtocolSupported = 0;
+ for (TInt i=0; i<CWinsockProtocolFamily::ProtocolCount(); i++)
+ {
+ const TServerProtocolDesc* p = CWinsockProtocolFamily::ProtocolDesc(i);
+ aInfo.iProtocolSupported |= p->iProtocol;
+ }
+}
+
+TInt CWinsockInterface::Send(RMBufChain& /*aPdu*/, TAny* /*aSource*/)
+{
+ TRACE("Send()");
+ return KErrNotSupported;
+}
+
+TInt CWinsockInterface::Notification(TAgentToNifEventType DEBUG_ONLY(aEvent),
+ TAny* /*aInfo*/)
+{
+ TRACE1("Notification(%d)",aEvent);
+ return KErrNotSupported;
+}
+
+// CNifIfLink
+TInt CWinsockInterface::Start()
+{
+ TRACE("Start()");
+ ScheduleAsyncCallback(NotifyLinkLayerUp);
+ return KErrNone;
+}
+
+void CWinsockInterface::Stop(TInt aReason, MNifIfNotify::TAction aAction)
+{
+ TRACE2("Stop(%d,%d)",aReason, aAction);
+ CancelOutstandingCallbacks();
+ ScheduleAsyncCallback(NotifyLinkLayerDown, aReason, aAction);
+}
+
+CNifIfBase* CWinsockInterface::GetBinderL(const TDesC& DEBUG_ONLY(aName))
+{
+ TRACE1("GetBinderL(%S)",&aName);
+ return this;
+}
+
+TInt CWinsockInterface::Control(TUint aLevel,TUint aName,TDes8& aOption,
+ TAny* aSource)
+{
+ TRACE3("Control(%d,%08X), %d bytes",aLevel,aName,aOption.Length());
+ switch (aLevel)
+ {
+ case KCOLInterface:
+ switch (aName)
+ {
+ case KCOGetNifEMIPtr:
+ default:
+ {
+ MNifIfExtendedManagementInterface** that =
+ (MNifIfExtendedManagementInterface**)aOption.Ptr();
+ if (aOption.Length() == sizeof(*that))
+ {
+ MNifIfExtendedManagementInterface* This = this;
+ TRACE1("MNifIfExtendedManagementInterface = %08X",This);
+ *that = This;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrArgument;
+ }
+ }
+ break;
+ }
+ break;
+
+ case KCOLAgent:
+ switch (aName)
+ {
+ case KCOGetAgentEMIPtr:
+ {
+ MNifAgentExtendedManagementInterface** that =
+ (MNifAgentExtendedManagementInterface**)aOption.Ptr();
+ if (aOption.Length() == sizeof(*that))
+ {
+ MNifAgentExtendedManagementInterface* This = this;
+ TRACE1("MNifAgentExtendedManagementInterface = %08X",This);
+ *that = This;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrArgument;
+ }
+ }
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return super::Control(aLevel, aName, aOption, aSource);
+}
+
+// MNifIfExtendedManagementInterface
+TInt CWinsockInterface::Stop(TSubConnectionUniqueId aId,
+ TInt DEBUG_ONLY(aReason))
+{
+ TRACE2("Stop(%d,%d)", aId, aReason);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::GetDataTransferred(TSubConnectionUniqueId aId,
+ TUint& aSentBytes,
+ TUint& aReceivedBytes)
+{
+ TRACE1("GetDataTransferred(%d)", aId);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ aSentBytes = iBytesSent;
+ aReceivedBytes = iBytesReceived;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::SetDataSentNotificationGranularity(TSubConnectionUniqueId aId,
+ TUint aGranularity)
+{
+ TRACE2("SetDataSentNotificationGranularity(%d,%d)", aId, aGranularity);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ iBytesSentGranularity = aGranularity;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::CancelDataSentNotification(TSubConnectionUniqueId aId)
+{
+ TRACE1("CancelDataSentNotification(%d)", aId);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ iBytesSentGranularity = 0;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::SetDataReceivedNotificationGranularity(TSubConnectionUniqueId aId,
+ TUint aGranularity)
+{
+ TRACE2("SetDataReceivedNotificationGranularity(%d,%d)", aId, aGranularity);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ iBytesReceivedGranularity = aGranularity;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::CancelDataReceivedNotification(TSubConnectionUniqueId aId)
+{
+ TRACE1("CancelDataReceivedNotification(%d)", aId);
+ switch (aId)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ iBytesReceivedGranularity = 0;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+// MNifAgentExtendedManagementInterface
+TInt CWinsockInterface::GetInterfaceType(TConnectionType& aConnectionType)
+{
+ aConnectionType = EWinsockConnectionType;
+ return KErrNone;
+}
+
+TInt CWinsockInterface::EnumerateSubConnections(TUint& aCount)
+{
+ aCount = 1;
+ return KErrNone;
+}
+
+TInt CWinsockInterface::GetSubConnectionInfo(TUint aIndex,
+ TDes8& aInfo)
+{
+ if (aInfo.Length() != sizeof(TSubConnectionInfo))
+ {
+ return KErrArgument;
+ }
+
+ TSubConnectionInfo* info = (TSubConnectionInfo*)aInfo.Ptr();
+ switch (aIndex)
+ {
+ case KNifEntireConnectionSubConnectionId:
+ case KWinsockSubConnectionId:
+ info->iConnectionType = EWinsockConnectionType;
+ info->iSubConnectionUniqueId = aIndex;
+ info->iTimeStarted = iTimeStarted;
+ return KErrNone;
+ default:
+ return KErrNotFound;
+ }
+}
+
+TInt CWinsockInterface::GetSubConnectionInfo(TDes8& aInfo)
+{
+ if (aInfo.Length() != sizeof(TSubConnectionInfo))
+ {
+ return KErrArgument;
+ }
+
+ TSubConnectionInfo* info = (TSubConnectionInfo*)aInfo.Ptr();
+ return GetSubConnectionInfo(info->iSubConnectionUniqueId, aInfo);
+}