--- a/hti/PC_Tools/HTIGateway/HtiGateway/src/HtiDispatcher.cpp Tue Jul 06 16:05:13 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
-* Copyright (c) 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:
-* This file contains implementation of HtiDispatcher class.
-*/
-
-#include "stdsoap2.h" //should be first because of WinSock2.h errors
-
-#include "common.h"
-#include "HtiDispatcher.h"
-#include "soapHandler.h"
-
-#include "HtiMessage.h"
-#include "util.h"
-#include <sstream>
-
-#include <crtdbg.h>
-
-const static char* HTI_PLUGIN_FOLDER = "ServicePlugins/";
-//used to redispatch hti framework error messages (like not authorized)
-
-/**
-* namespace table is needed to correclty send fault messages
-* each service plugin should explicitly set its one namespace table before processing
-* request
-*/
-SOAP_NMAC struct Namespace namespaces[] =
-{
- {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope", NULL},
- {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-encoding", NULL},
- {NULL, NULL, NULL, NULL}
-};
-
-//**********************************************************************************
-// Class HtiDispatcher
-//
-// This class
-// -forwards Soap requests and Hti messages to correct SOAPHandlers
-// -Is used to initiate SOAPHandlers by reading them from dll's and start them
-//**********************************************************************************
-HtiDispatcher::HtiDispatcher(SafeQueue<Data*>* qIn,
- SafeQueue<Data*>* qOut)
- : m_Running(true),
- m_QueueIn(qIn),
- m_QueueOut(qOut),
- m_IncomingHtiMessage(NULL)
-{
-}
-
-HtiDispatcher::~HtiDispatcher()
-{
- for( htiSoapActionHashMap::const_iterator i = m_SoapHandlers.begin();
- i != m_SoapHandlers.end();
- ++i)
- {
- delete i->second;
- }
-}
-
-/**
- * This method is used to read all the available SoapHandler dll's and initialize an instance of them and store a reference to m_SoapHandlers(by soap action)
- * and m_HanlersUidMap(by service uid) maps.
- */
-void HtiDispatcher::InitHandlers()
-{
- Util::Info( "HtiDispatcher::InitHandlers" );
- //1. read exe/plugin directory
- WIN32_FIND_DATA FileData;
- HANDLE hSearch;
- bool fFinished = false;
-
- // Start searching for .dll files
- string searchMask = HTI_PLUGIN_FOLDER;
- searchMask.append( "*.dll" );
- hSearch = FindFirstFile( searchMask.c_str(), &FileData );
- if (hSearch == INVALID_HANDLE_VALUE)
- {
- Util::Info("No DLLs found.");
- return;
- }
-
- while (!fFinished)
- {
-
- //2. get list of all DLLs
- //SoapHandler* t = new SoapHandler("ws_hti.dll");
- string pluginPath = HTI_PLUGIN_FOLDER;
- pluginPath.append( FileData.cFileName );
- Util::Info("Try to load:");
- Util::Info(pluginPath);
- SoapHandler* t = new SoapHandler( pluginPath );
- if( t->LoadPlugin() )
- {
- //3. add them to m_SoapHandlers
- char* soapAction = t->soapAction();
- m_SoapHandlers[ soapAction ] = t;
- //add to uid map as well
- int uid = t->serviceUID();
- m_HanlersUidMap[ uid ] = t;
-
- stringstream s;
- s<<"Loaded plugin: ";
- s<<soapAction;
- s<<", service UID: ";
- s<<uid;
-
- Util::Info( s.str().c_str() );
- }
- else
- {
- delete t;
- //
- Util::Error("Failed load DLL as a plugin");
- }
-
- if (!FindNextFile(hSearch, &FileData))
- {
- if (GetLastError() == ERROR_NO_MORE_FILES)
- {
- fFinished = TRUE;
- }
- else
- {
- Util::Error("Couldn't find next plugin.");
- fFinished = TRUE;
- //return;
- }
- }
- }
-
- // Close the search handle.
-
- FindClose(hSearch);
-
- stringstream s;
- s<<"Plugins loaded ";
- s<<m_SoapHandlers.size();
- Util::Info( s.str().c_str() );
-}
-
-/**
- * This method is used to start all the SoapHandler instances that are stored in htiSoapActionHashMap
- */
-void HtiDispatcher::StartHandlers()
-{
- for( htiSoapActionHashMap::const_iterator i = m_SoapHandlers.begin();
- i != m_SoapHandlers.end();
- ++i)
- {
- (i->second)->SetDispatcher(this);
- (i->second)->Start();
- }
-}
-
-/*
- * This loop is used to forward incoming Hti messages(arriving from CommChannelPlugin to m_QueueOut side) to correct SoapHandlers
- */
-void HtiDispatcher::Run()
-{
- Util::Debug("HtiDispatcher::Run");
- //m_testHandler.SetDispatcher(this);
- //m_testHandler.Start();
- InitHandlers();
- StartHandlers();
-
- BYTE* shortData = NULL; //keep data if it's too short to have HtiHeader
- //or if one Data msg have more than one HtiMessage
- DWORD msgBufferSize = 8096;
- BYTE* msgBuffer = (BYTE*)malloc( msgBufferSize );
- DWORD shortDataLen = 0;
-
- // By setting this threads priority below others will give soaphandler threads
- // more runtime to process the received messages.. This is to avoid the situation
- // where two messages arrive so close to each other that m_hReceiveHtiEvent is
- // signalled twice before the first message has even been processed by the soap plugin.
- if(!SetThreadPriority( ThreadHandle(), THREAD_PRIORITY_BELOW_NORMAL ))
- Util::Info("Warning: Could not set HtiDispatcher priority!");
-
- while (m_Running)
- {
- try
- {
- Data* d = m_QueueOut->front(50);
- BYTE* p = (BYTE *)d->GetData();
- DWORD l = d->GetLength();
- //printf("\td = %d\n", m_QueueOut->size());
-
- if (Util::GetVerboseLevel() == Util::VerboseLevel::debug)
- {
- char tmp[64];
- sprintf(tmp, "[HtiDispatcher] HTI MsgSize = %d", l);
- string s(tmp);
- Util::Debug(s);
- //Util::Hex(p, d->GetLength());
- }
-
- //Util::Debug("leftovers");
- //copy leftovers to the beginning of the buffer
- if ( shortDataLen > 0 )
- {
- memcpy( msgBuffer, shortData, shortDataLen );
- }
- shortData = msgBuffer; //set shortData to the beginning
-
- //copy data to buffer
- if ( shortDataLen + l > msgBufferSize )
- {
- msgBufferSize = shortDataLen + l;
- msgBuffer = (BYTE*)realloc(msgBuffer, msgBufferSize);
- shortData = msgBuffer;
- }
- //copy data gotten from queue to the end of shortData
- memcpy(shortData + shortDataLen, p, l );
- shortDataLen = l + shortDataLen;
-
- while ( shortDataLen != 0 &&
- (shortDataLen >= HtiMessage::MinHeaderSize() ||
- m_IncomingHtiMessage != NULL ) )
- {
- //new message
- if ( m_IncomingHtiMessage == NULL )
- {
- if ( shortDataLen >= HtiMessage::MinHeaderSize() )
- {
- if ( HtiMessage::CheckValidHtiHeader(shortData) )
- {
- m_IncomingHtiMessage = new HtiMessage( shortData, shortDataLen );
-
- if (Util::GetVerboseLevel() == Util::VerboseLevel::debug)
- {
- char tmp[64];
- sprintf(tmp,"New hti message %d", m_IncomingHtiMessage->HtiDataSize());
- string s(tmp);
- Util::Debug(s);
- //Util::Hex(p, d->GetLength());
- }
-
- //_RPT2(_CRT_WARN, "income msg %x <%d>\n", m_IncomingHtiMessage, sizeof(HtiMessage));
- //check message
- if ( m_IncomingHtiMessage->IsMessageComplete() )
- {
- Util::Debug("HTI message complete");
- DWORD msgSize = m_IncomingHtiMessage->HtiDataSize();
- if ( msgSize < shortDataLen )
- {
- //remove used part
- //BYTE* temp = new BYTE[shortDataLen-msgSize];
- //_RPT2(_CRT_WARN, "temp %x <%d>\n", shortData , shortDataLen-msgSize);
- //memcpy(temp, shortData + msgSize, shortDataLen-msgSize);
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData);
- //delete[] shortData;
- //shortData = temp;
- shortData += msgSize; //just move pointer
- shortDataLen -= msgSize;
-
- }
- else
- {
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData);
- //delete[] shortData;
- //shortData = NULL;
- shortDataLen = 0;
- }
- //Dispatch incoming message
- DispatchToSoapHandlers();
- }
- else
- {
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData);
- //delete[] shortData;
- //shortData = NULL;
- shortDataLen = 0;
- }
- }
- else
- {
- //invalid header
- Util::Error("Invalid HTI header, dismiss Data message");
- Util::Hex(shortData, HtiMessage::MinHeaderSize() );
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData);
- //delete[] shortData;
- //shortData = NULL;
- shortDataLen = 0;
- }
- }
- }
- else //body parts
- {
- Util::Debug("add");
- DWORD added = m_IncomingHtiMessage->AddToBody( shortData,
- shortDataLen );
- //printf("reminder %d\n", m_IncomingHtiMessage->Reminder());
- if ( added < shortDataLen )
- {
- //only part of message was added
- //remove added part
- //BYTE* temp = new BYTE[shortDataLen-added];
- //_RPT2(_CRT_WARN, "temp %x <%d>\n", shortData , shortDataLen-added);
- //memcpy(temp, shortData + added, shortDataLen-added);
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData );
- //delete[] shortData;
- //shortData = temp;
- shortData += added;
- shortDataLen -= added;
- }
- else //all data were added
- {
- //_RPT1(_CRT_WARN, "del shortData %x\n", shortData );
- //delete[] shortData;
- //shortData = NULL;
- shortDataLen = 0;
- }
-
- if ( m_IncomingHtiMessage->IsMessageComplete() )
- {
- Util::Debug("HTI message complete");
- //Dispatch incoming message
- DispatchToSoapHandlers();
- }
- }
- }
-
- m_QueueOut->pop();
- //_RPT1(_CRT_WARN, "del data %x\n", d);
- delete d;
- d = NULL;
- } catch (TimeoutException te)
- {
- //Util::Debug("[DataGatewaySocketWriterThread]timeout exception");
- }
- }
- free( msgBuffer );
-}
-
-/**
- * This method is used to forward the incoming HTI message to correct SoapHandler
- * The correct SoapHandler is found by service uid
- */
-void HtiDispatcher::DispatchToSoapHandlers()
-{
- htiUIDHashMap::const_iterator i;
- int targetServiceUid;
- if ( m_IncomingHtiMessage->IsErrorMessage() )
- {
- targetServiceUid = m_IncomingHtiMessage->ErrorServiceUid();
-
- stringstream s;
- s<<"Received HTI error message\nhtiErrorCode: ";
- s<<m_IncomingHtiMessage->HtiErrorCode();
- s<<"\nserviceUid: ";
- s<<m_IncomingHtiMessage->ErrorServiceUid();
- s<<"\nserviceErrorCode: ";
- s<<m_IncomingHtiMessage->ServiceErrorCode();
- s<<"\nErrorDescription: ";
- s<<m_IncomingHtiMessage->ErrorDescription();
- s<<"\ntargetServiceUid: ";
- s<<targetServiceUid;
-
- Util::Error(s.str().c_str());
- }
- else
- {
- targetServiceUid = m_IncomingHtiMessage->GetServiceUID();
- }
-
- if ( targetServiceUid == HTI_SYSTEM_SERVICE_UID &&
- m_IncomingHtiMessage->IsErrorMessage() )
- {
- Util::Debug("dispatch error");
- //if system plugin doesn't wait for a message then find plugin that
- //is waiting for a message and delivery the incoming msg to it
- i = m_HanlersUidMap.find( targetServiceUid );
- if ( i != m_HanlersUidMap.end() )
- {
- if ( (i->second)->IsWaitsForHtiMessage() )
- {
- Util::Debug("dispatch error to system cause it waits");
- if ( !(i->second)->ReceiveHtiMessage(m_IncomingHtiMessage) )
- {
- Util::Error("Failed to dispatch hti message");
- Util::Hex(m_IncomingHtiMessage->HtiData(), HtiMessage::MinHeaderSize());
- //dismiss message
- delete m_IncomingHtiMessage;
- }
- }
- else
- {
- Util::Debug("find handler that waits");
- //find the handler that waits for hti message
- for( htiUIDHashMap::const_iterator i = m_HanlersUidMap.begin();
- i != m_HanlersUidMap.end();
- ++i)
- {
- Util::Debug((i->second)->soapAction());
- if ( (i->second)->IsWaitsForHtiMessage() )
- {
- Util::Debug("found");
- if ( !(i->second)->ReceiveHtiMessage(m_IncomingHtiMessage) )
- {
- Util::Error("Failed to dispatch hti message");
- Util::Hex(m_IncomingHtiMessage->HtiData(), HtiMessage::MinHeaderSize());
- //dismiss message
- delete m_IncomingHtiMessage;
- }
- break;
- }
- }
- }
- }
- }
- else
- {
- i = m_HanlersUidMap.find( targetServiceUid );
- if ( i != m_HanlersUidMap.end() )
- {
- if ( !(i->second)->ReceiveHtiMessage(m_IncomingHtiMessage) )
- {
- Util::Error("Failed to dispatch hti message");
- Util::Hex(m_IncomingHtiMessage->HtiData(), HtiMessage::MinHeaderSize());
- //dismiss message
- delete m_IncomingHtiMessage;
- }
- }
- else
- {
- Util::Error("Failed to dispatch hti message, no plug-in with appropriate uid",m_IncomingHtiMessage->GetServiceUID() );
- Util::Hex(m_IncomingHtiMessage->HtiData(), HtiMessage::MinHeaderSize());
- //dismiss message
- delete m_IncomingHtiMessage;
- }
- }
- m_IncomingHtiMessage = NULL;
-
- // This will give other threads (soaphandlers) some runtime to process the
- // received message.
- Sleep(0);
-}
-
-/*
- * This method is used to forward soap request to correct SOAPHandler
- * Correct SOAPHandler is found by soap action
- */
-bool HtiDispatcher::DispatchSoapServe(struct soap* soapEnv)
-{
- Util::Debug("HtiDispatcher::DispatchSoapServe()");
-/*
- _CrtMemState localMem;
- _CrtMemCheckpoint( &localMem );
-*/
- soap_begin( soapEnv );
- if (soap_begin_recv(soapEnv))
- {
- soap_set_namespaces( soapEnv, namespaces);
- soap_send_fault(soapEnv);
- return false;
- }
-
- if ( !(soapEnv->action) )
- {
- //Util::Error("soapAction is missing");
- soap_set_namespaces( soapEnv, namespaces);
- soapEnv->error = soap_sender_fault(soapEnv, "soapAction is missing", NULL);
- soap_send_fault(soapEnv);
- return false;
- }
-/*
- //_RPT0(_CRT_WARN, "!!!!!!!!!!!!!!!! Local Objects !!!!!!!!!!!!!!!!\n");
-
- _CrtMemDumpAllObjectsSince( &localMem );
- //_RPT1(_CRT_WARN, "action address %x\n", soapEnv->action);
-*/
- htiSoapActionHashMap::const_iterator it;
- it = m_SoapHandlers.find( soapEnv->action );
- if ( it != m_SoapHandlers.end() )
- {
- return (it->second)->ServeSoap( soapEnv );
- }
- else
- {
- //Util::Error("soapAction is unknown:");
- //Util::Error(soapEnv->action);
- //soapEnv->error = SOAP_NO_METHOD;
- soap_set_namespaces( soapEnv, namespaces);
- soapEnv->error = soap_sender_fault(soapEnv, "No plugin found", "no plugin found for requested service in actionSOAP header field");
- soap_send_fault(soapEnv);
- return false;
- }
-
- Util::Debug("HtiDispatcher::DispatchSoapServe() OK");
-}
-
-/*
- * SoapHandler calls this method
- * The method creates a Data object from the HtiMessage given as parameter
- * and puts the Data object into incoming queue(going eventually to CommChannelPlugin)
- */
-void HtiDispatcher::SendHtiMessage(HtiMessage* msg)
-{
- Util::Debug("HtiDispatcher::SendHtiMessage()");
- if (msg)
- {
- Data* d = new Data(msg->HtiData(), msg->HtiDataSize(), Data::EData);
- //_RPT2(_CRT_WARN, "d %x <%d>\n", d , sizeof(Data));
-
- if (Util::GetVerboseLevel() == Util::VerboseLevel::debug)
- {
- char tmp[64];
- sprintf(tmp, "[HtiDispatcher] HTI MsgSize = %d", msg->HtiDataSize());
- string s(tmp);
- Util::Debug(s);
- Util::Hex( (char*)(msg->HtiData()), 16);
- }
- m_QueueIn->push(d);
- //delete msg;
- }
- Util::Debug("HtiDispatcher::SendHtiMessage() OK");
-}
-
-void HtiDispatcher::Stop()
-{
- m_Running = false;
- HANDLE* handles = new HANDLE[ m_SoapHandlers.size() ];
- int h = 0;
- for( htiSoapActionHashMap::const_iterator i = m_SoapHandlers.begin();
- i != m_SoapHandlers.end();
- ++i)
- {
- (i->second)->Stop();
- handles[ h++ ] = (i->second)->ThreadHandle();
- }
-
- WaitForMultipleObjects(m_SoapHandlers.size(),
- handles,
- TRUE,
- 5000/*g_MaximumShutdownWaitTime*/);
-
- delete[] handles;
-}
-
-bool HtiDispatcher::IsRunning()
-{
- return m_Running;
-}