natplugins/natptraversalcontroller/src/cnatbinding.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natplugins/natptraversalcontroller/src/cnatbinding.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,369 @@
+/*
+* Copyright (c) 2007 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: 
+*
+*/
+
+
+#include "natfwstunbinding.h"
+#include "cnatbinding.h"
+#include "sipnattraversalrequestobserver.h"
+#include "sipnatbindingobserver.h"
+#include "cnatbindingrefresher.h"
+#include "nattraversalsocketmanager.h"
+
+// -----------------------------------------------------------------------------
+// CNATBinding::NewL
+// -----------------------------------------------------------------------------
+//
+CNATBinding* CNATBinding::NewL(
+    TUint32 aInitialRequestId,
+    RSocket& aSTUNSocket,
+    const TInetAddr& aLocalAddr,
+    MSIPNATTraversalRequestObserver& aInitialRequestObserver,
+    MSIPNATBindingObserver& aBindingObserver,
+    MNATTraversalSocketManager& aSocketManager)
+    {
+    CNATBinding* self =
+        CNATBinding::NewLC(aInitialRequestId,aSTUNSocket,aLocalAddr,
+                           aInitialRequestObserver,aBindingObserver,
+                           aSocketManager);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::NewLC
+// -----------------------------------------------------------------------------
+//
+CNATBinding* CNATBinding::NewLC(
+    TUint32 aInitialRequestId,
+    RSocket& aSTUNSocket,
+    const TInetAddr& aLocalAddr,
+    MSIPNATTraversalRequestObserver& aInitialRequestObserver,
+    MSIPNATBindingObserver& aBindingObserver,
+    MNATTraversalSocketManager& aSocketManager)
+    {
+    CNATBinding* self =
+        new(ELeave)CNATBinding(aInitialRequestId,aSTUNSocket,aLocalAddr,
+                               aInitialRequestObserver,aBindingObserver,
+                               aSocketManager);
+    CleanupStack::PushL(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::CNATBinding
+// -----------------------------------------------------------------------------
+//
+CNATBinding::CNATBinding(
+    TUint32 aInitialRequestId,
+    RSocket& aSTUNSocket,
+    const TInetAddr& aLocalAddr,
+    MSIPNATTraversalRequestObserver& aInitialRequestObserver,
+    MSIPNATBindingObserver& aBindingObserver,
+    MNATTraversalSocketManager& aSocketManager)
+    : iInitialReqId(aInitialRequestId),
+      iSTUNSocket(aSTUNSocket),
+      iInitialReqObserver(aInitialRequestObserver),
+      iBindingObserver(aBindingObserver),
+      iSocketManager(aSocketManager),
+      iPublicAddr(aLocalAddr)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::~CNATBinding
+// -----------------------------------------------------------------------------
+//
+CNATBinding::~CNATBinding()
+    {
+    iSocketManager.SendingCompleted(*this); // Make sure no requests are pending
+    delete iRefresher;
+    delete iBinding;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::PersistentConnectionRequired
+// -----------------------------------------------------------------------------
+//
+TBool CNATBinding::PersistentConnectionRequired() const
+    {
+    TBool persistentConnection = EFalse;
+    if (iRefresher)
+        {
+        persistentConnection = iRefresher->PersistentConnectionRequired();
+        }
+    return persistentConnection;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::STUNSocket
+// -----------------------------------------------------------------------------
+//
+RSocket& CNATBinding::STUNSocket()
+    {
+    return iSTUNSocket;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SetBinding
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SetBinding(CSTUNBinding* aBinding)
+    {
+    delete iBinding;
+    iBinding = aBinding;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::Binding
+// -----------------------------------------------------------------------------
+//
+CSTUNBinding* CNATBinding::Binding()
+    {
+    return iBinding;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SendSTUNRequestL
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SendSTUNRequestL()
+    {
+    __ASSERT_ALWAYS(iBinding, User::Leave(KErrNotReady));
+    if (!iSocketManager.AddToSendingQueueL(*this))
+        {
+        iBinding->SendRequestL();
+        iIsSending = ETrue;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SetBindingFailed
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SetBindingFailed(TInt aError)
+    {
+    SendingCompleted();
+    delete iBinding;
+    iBinding = NULL;
+    if (iAddressResolved)
+        {
+        iAddressResolved = EFalse;
+        iBindingObserver.FlowFailure(aError);
+        }
+    else
+        {
+        iInitialReqObserver.RequestComplete(iInitialReqId,KErrNone);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SetPublicAddr
+// -----------------------------------------------------------------------------
+//
+TBool CNATBinding::SetPublicAddr(const TInetAddr& aPublicAddr)
+    {
+    SendingCompleted();
+    TBool removeBinding = EFalse;
+    if (iAddressResolved)
+        {
+        removeBinding = !aPublicAddr.CmpAddr(iPublicAddr);
+        }
+    else
+        {
+        iAddressResolved = ETrue;
+        TBool localAddrMatchesToPublicAddr = iPublicAddr.Match(aPublicAddr);
+        iPublicAddr = aPublicAddr;
+        if (localAddrMatchesToPublicAddr)
+            {
+            // We are not behind a NAT
+            iInitialReqObserver.RequestComplete(iInitialReqId,KErrNone);
+            }
+        else
+            {
+            iInitialReqObserver.PublicAddrResolved(iInitialReqId,aPublicAddr);
+            }
+        }
+    return removeBinding;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SetRefresher
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SetRefresher(CNATBindingRefresher* aRefresher)
+    {
+    delete iRefresher;
+    iRefresher = aRefresher;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::Refresher
+// -----------------------------------------------------------------------------
+//
+CNATBindingRefresher* CNATBinding::Refresher()
+    {
+    return iRefresher;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::InitialRequestId
+// -----------------------------------------------------------------------------
+//
+TUint32 CNATBinding::InitialRequestId() const
+    {
+    return iInitialReqId;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::NATBindingObserver
+// -----------------------------------------------------------------------------
+//
+MSIPNATBindingObserver& CNATBinding::NATBindingObserver()
+    {
+    return iBindingObserver;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::AddressResolved
+// -----------------------------------------------------------------------------
+//
+TBool CNATBinding::AddressResolved() const
+    {
+    return iAddressResolved;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::PublicAddr
+// -----------------------------------------------------------------------------
+//
+const TInetAddr& CNATBinding::PublicAddr() const
+    {
+    return iPublicAddr;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::HandleDataL
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::HandleDataL(
+    const TDesC8& aData,
+    const RSocket& aSocket,
+    TBool& aConsumed)
+    {
+    aConsumed = EFalse;
+    if (iBinding &&
+        aSocket.SubSessionHandle() == iBinding->Socket().SubSessionHandle())
+        {
+        // Set a dummy remote address as the data is guaranteed not to be a
+        // TURN indication and on return the address is useless to us.
+        TInetAddr addr(KAFUnspec);
+        iBinding->HandleDataL(aData,aConsumed,addr);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::ContinueRefreshing
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::ContinueRefreshing()
+    {
+    if (iRefresher)
+        {
+        iRefresher->ContinueRefreshing();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::NATBindingRefreshComplete
+// From MNATBindingRefresherObserver
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::NATBindingRefreshComplete(TInt aCompletionCode)
+    {
+    if (aCompletionCode != KErrNone)
+        {
+        iBindingObserver.FlowFailure(aCompletionCode);
+        }
+    else
+        {
+        ContinueRefreshing();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::Socket
+// From MNATTraversalSocketUser
+// -----------------------------------------------------------------------------
+//
+const RSocket& CNATBinding::Socket() const
+    {
+    return iSTUNSocket;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SendingAllowed
+// From MNATTraversalSocketUser
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SendingAllowed()
+    {
+    if (iBinding)
+        {
+        TRAPD(err, iBinding->SendRequestL());
+        if (err)
+            {
+            SetBindingFailed(err);
+            }
+        else
+            {
+            iIsSending = ETrue;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::IsSending
+// From MNATTraversalSocketUser
+// -----------------------------------------------------------------------------
+//
+TBool CNATBinding::IsSending() const
+    {
+    return iIsSending;
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::CancelSending
+// From MNATTraversalSocketUser
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::CancelSending()
+    {
+    if (iBinding)
+        {
+        iBinding->CancelRequest();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNATBinding::SendingCompleted
+// -----------------------------------------------------------------------------
+//
+void CNATBinding::SendingCompleted()
+    {
+    iIsSending = EFalse;
+    iSocketManager.SendingCompleted(*this);
+    }