sdkcreationmw/sdkruntimes/wsock/src/WinsockInterface.cpp
changeset 0 b26acd06ea60
child 1 ac50fd48361b
--- /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);
+}