bluetoothengine/btsap/src/BTSapRequestHandler.cpp
changeset 0 f63038272f30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsap/src/BTSapRequestHandler.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,197 @@
+/*
+* Copyright (c) 2004 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: 
+*     This class handles data exchange between BTSap server and client
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include "BTSapRequestHandler.h"
+#include "BTSapServerState.h"
+#include "BTSapSocketHandler.h"
+#include "debug.h"
+
+const TInt KSegmentTimeout = 1000000; // 1s
+
+CBTSapRequestHandler::CBTSapRequestHandler(CBTSapServerState& aServerState)
+    : CActive(EPriorityNormal), 
+      iServerState(aServerState),
+      iRequestMessage(aServerState.BTSapRequestMessage())
+    {
+    CActiveScheduler::Add(this);
+    }
+
+CBTSapRequestHandler::~CBTSapRequestHandler()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  ~CBTSapRequestHandler")));
+
+    Cancel();
+    delete iSegmentTimer;
+    }
+
+// ---------------------------------------------------------
+// NewL()
+// ---------------------------------------------------------
+//
+CBTSapRequestHandler* CBTSapRequestHandler::NewL(CBTSapServerState& aServerState)
+    {
+    CBTSapRequestHandler* self = new (ELeave) CBTSapRequestHandler(aServerState);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// ---------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------
+//
+void CBTSapRequestHandler::ConstructL()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapRequestHandler: ConstructL")));
+
+    iSegmentTimer = CSegmentTimer::NewL(this);
+
+    iStatus = KRequestPending;
+    SetActive();
+    }
+
+// ---------------------------------------------------------
+// DoCancel
+// ---------------------------------------------------------
+//
+void CBTSapRequestHandler::DoCancel()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapRequestHandler: DoCancel")));
+
+    TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrCancel);
+    }
+
+// ---------------------------------------------------------
+// RunL
+// ---------------------------------------------------------
+//
+void CBTSapRequestHandler::RunL()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapRequestHandler: RunL")));
+    TInt status = iStatus.Int();
+    
+    if ( status != KErrNone )
+        {
+        HandleSapMessage(EInvalidSegmented);
+        }
+    else
+        {
+        while (!iRawMessage.IsEmpty())
+            {
+            TValidationResult result = iRawMessage.Validate();
+           
+            if (result == EInvalidSegmented)
+	            {
+	            // start timer if not started
+                iSegmentTimer->Cancel();
+                iSegmentTimer->After(KSegmentTimeout);
+                break;
+                }
+            else
+                {
+                // complete message
+                HandleSapMessage(result);
+                }
+            }
+        }
+    iStatus = KRequestPending;
+    SetActive();
+    }
+
+void CBTSapRequestHandler::HandleSapMessage(const TValidationResult aResult)
+    {
+    // stop timer
+    iSegmentTimer->Cancel();
+
+    iRequestMessage.SetData(iRawMessage.Data());
+    //DEB(Hex(_L8("[BTSap]  Request: %S"), &iRequestMessage.Data()));
+
+    iRawMessage.Reset();
+
+    TBTSapServerState nextState = EStateIdle;
+
+    if (aResult == EValidFormat)
+        {
+        nextState = KStateByRequest[(TInt)iRequestMessage.MsgID()];
+        }
+
+    if (iServerState.HandleStateChangeRequest(nextState) != KErrNone)
+        {
+        iServerState.SendErrorResponse();
+
+        if (nextState != iServerState.CurrentState())
+            {
+            iServerState.ChangeState(nextState);
+            }
+        }
+    else
+        {
+        // always change state if request is acceptable
+        iServerState.ChangeState(nextState);
+        }
+    }
+
+void CBTSapRequestHandler::HandleSapData(const TDes8& aData)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapRequestHandler: HandleSapData")));
+
+    TInt result = iRawMessage.AppendData(aData);
+    
+    if (IsActive() && iStatus == KRequestPending)
+        {
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete(status, result);
+        }
+
+    }
+
+void CBTSapRequestHandler::HandleSegmentTimeout()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapRequestHandler: HandleIncompleteMessage")));
+
+    TValidationResult result = iRawMessage.Validate();
+    HandleSapMessage(result);
+    }
+
+CBTSapRequestHandler::CSegmentTimer::CSegmentTimer(CBTSapRequestHandler* aRequestHandler)
+    : CTimer(EPriorityStandard), iRequestHandler(aRequestHandler)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CBTSapRequestHandler::CSegmentTimer* CBTSapRequestHandler::CSegmentTimer::NewL(
+    CBTSapRequestHandler* aRequestHandler)
+	{
+	CSegmentTimer* self = new (ELeave) CSegmentTimer(aRequestHandler);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CBTSapRequestHandler::CSegmentTimer::RunL()
+	{
+	iRequestHandler->HandleSegmentTimeout();
+	}
+
+// End of file