e3afe740ce
2006/01/14 13:04:57 pjanik 1.3.18.1: #i59252#: Fix the usage of PacketHandler::ReceiveData according to its declaration. Patch from jan Holesovsky (JCA).
694 lines
20 KiB
C++
694 lines
20 KiB
C++
/*************************************************************************
|
||
*
|
||
* OpenOffice.org - a multi-platform office productivity suite
|
||
*
|
||
* $RCSfile: simplecm.cxx,v $
|
||
*
|
||
* $Revision: 1.4 $
|
||
*
|
||
* last change: $Author: kz $ $Date: 2006-02-28 10:31:02 $
|
||
*
|
||
* The Contents of this file are made available subject to
|
||
* the terms of GNU Lesser General Public License Version 2.1.
|
||
*
|
||
*
|
||
* GNU Lesser General Public License Version 2.1
|
||
* =============================================
|
||
* Copyright 2005 by Sun Microsystems, Inc.
|
||
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
* License version 2.1, as published by the Free Software Foundation.
|
||
*
|
||
* This library is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
* Lesser General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with this library; if not, write to the Free Software
|
||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||
* MA 02111-1307 USA
|
||
*
|
||
************************************************************************/
|
||
|
||
|
||
#define ENABLE_BYTESTRING_STREAM_OPERATORS
|
||
#include <tools/solar.h>
|
||
|
||
#ifndef _SIMPLECM_HXX
|
||
#include "simplecm.hxx"
|
||
#endif
|
||
|
||
#include "commdefines.hxx"
|
||
#include "packethandler.hxx"
|
||
#include "tcpio.hxx"
|
||
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
#include <stdio.h>
|
||
void debug_printf( const char *chars )
|
||
{
|
||
static BOOL bPrint = (getenv("DEBUG") != NULL);
|
||
if ( bPrint )
|
||
{
|
||
printf( chars );
|
||
fflush( stdout );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
CommunicationLink::CommunicationLink( CommunicationManager *pMan )
|
||
: pMyManager(pMan)
|
||
, pServiceData(NULL)
|
||
, nServiceProtocol( 0 )
|
||
, bIsInsideCallback( FALSE )
|
||
, nTotalBytes( 0 )
|
||
, aApplication("Undefined")
|
||
, bFlag( FALSE )
|
||
, nSomething( 0 )
|
||
{
|
||
}
|
||
|
||
CommunicationLink::~CommunicationLink()
|
||
{
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
if ( !bFlag ) // bFlag will be set if deletion is expected else we can set a breakpoint
|
||
bFlag = FALSE;
|
||
#endif
|
||
if ( pMyManager )
|
||
pMyManager->DestroyingLink( this );
|
||
}
|
||
|
||
void CommunicationLink::CallInfoMsg( InfoString aMsg )
|
||
{
|
||
if ( pMyManager )
|
||
pMyManager->InfoMsg( aMsg );
|
||
};
|
||
|
||
CM_InfoType CommunicationLink::GetInfoType()
|
||
{
|
||
if ( pMyManager )
|
||
return pMyManager->GetInfoType();
|
||
else
|
||
return CM_NO_TEXT;
|
||
}
|
||
|
||
IMPL_LINK( CommunicationLink, ConnectionClosed, void*, EMPTYARG )
|
||
{
|
||
if ( pMyManager )
|
||
pMyManager->CallConnectionClosed( this );
|
||
return 1;
|
||
}
|
||
|
||
IMPL_LINK( CommunicationLink, DataReceived, void*, EMPTYARG )
|
||
{
|
||
if ( pMyManager )
|
||
pMyManager->CallDataReceived( this );
|
||
return 1;
|
||
}
|
||
|
||
BOOL CommunicationLink::DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
|
||
{
|
||
INFO_MSG( CByteString("S :").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString("Daten Senden:").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_SEND, this );
|
||
BOOL bWasError = FALSE;
|
||
|
||
UINT32 nBuffer;
|
||
nBuffer = pDataStream->SeekRel(0) +1;
|
||
bWasError = pPacketHandler->TransferData( ((SvMemoryStream*)pDataStream)->GetData(), nBuffer, nProtocol ) != C_ERROR_NONE;
|
||
|
||
if ( bWasError )
|
||
{
|
||
INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_ERROR, this );
|
||
ShutdownCommunication();
|
||
}
|
||
return !bWasError;
|
||
}
|
||
|
||
BOOL CommunicationLink::TransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
|
||
{
|
||
aLastAccess = DateTime();
|
||
nTotalBytes += pDataStream->Seek( STREAM_SEEK_TO_END );
|
||
return DoTransferDataStream( pDataStream, nProtocol );
|
||
}
|
||
|
||
void CommunicationLink::SetApplication( const ByteString& aApp )
|
||
{
|
||
aApplication = aApp;
|
||
}
|
||
|
||
|
||
SimpleCommunicationLinkViaSocket::SimpleCommunicationLinkViaSocket( CommunicationManager *pMan, NAMESPACE_VOS(OStreamSocket) *pSocket )
|
||
: CommunicationLink( pMan )
|
||
, pStreamSocket( pSocket )
|
||
, pReceiveStream( NULL )
|
||
, aCommunicationPartner()
|
||
, aMyName()
|
||
, bIsRequestShutdownPending( FALSE )
|
||
{
|
||
pTCPIO = new TCPIO( pStreamSocket );
|
||
pPacketHandler = new PacketHandler( (ITransmiter*) pTCPIO, pTCPIO, pMyManager->IsMultiChannel() );
|
||
}
|
||
|
||
SimpleCommunicationLinkViaSocket::~SimpleCommunicationLinkViaSocket()
|
||
{
|
||
delete pPacketHandler;
|
||
pPacketHandler = NULL;
|
||
delete pTCPIO;
|
||
pTCPIO = NULL;
|
||
delete pStreamSocket;
|
||
pStreamSocket = NULL;
|
||
}
|
||
|
||
void SimpleCommunicationLinkViaSocket::SetStreamSocket( NAMESPACE_VOS(OStreamSocket)* pSocket )
|
||
{
|
||
if ( pTCPIO )
|
||
pTCPIO->SetStreamSocket( pSocket );
|
||
pStreamSocket = pSocket;
|
||
}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocket::StopCommunication()
|
||
{
|
||
CommunicationLinkRef rHold(this); // avoid deleting this link before the end of the method
|
||
if ( !IsCommunicationError() ) // Meaning that the Communication is still runnung
|
||
{
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
debug_printf("Sending REQUEST_ShutdownLink\n");
|
||
#endif
|
||
SendHandshake( CH_REQUEST_ShutdownLink );
|
||
}
|
||
WaitForShutdown();
|
||
return TRUE;
|
||
}
|
||
|
||
void SimpleCommunicationLinkViaSocket::SetFinalRecieveTimeout()
|
||
{
|
||
if ( !IsCommunicationError() )
|
||
{
|
||
TimeValue aTime = {30, 0}; // 30 seconds
|
||
pStreamSocket->setRecvTimeout( &aTime );
|
||
}
|
||
}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocket::IsCommunicationError()
|
||
{
|
||
return !pStreamSocket;
|
||
}
|
||
|
||
ByteString SimpleCommunicationLinkViaSocket::GetCommunicationPartner( CM_NameType eType )
|
||
{
|
||
if ( pStreamSocket )
|
||
{
|
||
switch ( eType )
|
||
{
|
||
case CM_DOTTED:
|
||
{
|
||
rtl::OUString aDotted;
|
||
NAMESPACE_VOS(OSocketAddr) *pPeerAdr = new NAMESPACE_VOS(OSocketAddr);
|
||
pStreamSocket->getPeerAddr( *pPeerAdr );
|
||
((NAMESPACE_VOS(OInetSocketAddr*))pPeerAdr)->getDottedAddr( aDotted );
|
||
delete pPeerAdr;
|
||
return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
|
||
}
|
||
break;
|
||
case CM_FQDN:
|
||
{
|
||
if ( !aCommunicationPartner.Len() )
|
||
{
|
||
rtl::OUString aFQDN;
|
||
pStreamSocket->getPeerHost( aFQDN );
|
||
aCommunicationPartner = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
|
||
}
|
||
return aCommunicationPartner;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return CByteString( "Unknown" );
|
||
}
|
||
|
||
ByteString SimpleCommunicationLinkViaSocket::GetMyName( CM_NameType eType )
|
||
{
|
||
if ( pStreamSocket )
|
||
{
|
||
switch ( eType )
|
||
{
|
||
case CM_DOTTED:
|
||
{
|
||
rtl::OUString aDotted;
|
||
NAMESPACE_VOS(OSocketAddr) *pPeerAdr = new NAMESPACE_VOS(OSocketAddr);
|
||
pStreamSocket->getLocalAddr( *pPeerAdr );
|
||
((NAMESPACE_VOS(OInetSocketAddr*))pPeerAdr)->getDottedAddr( aDotted );
|
||
delete pPeerAdr;
|
||
return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
|
||
}
|
||
break;
|
||
case CM_FQDN:
|
||
{
|
||
if ( !aMyName.Len() )
|
||
{
|
||
rtl::OUString aFQDN;
|
||
pStreamSocket->getLocalHost( aFQDN );
|
||
aMyName = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
|
||
}
|
||
return aMyName;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return CByteString( "Error" );
|
||
}
|
||
|
||
SvStream* SimpleCommunicationLinkViaSocket::GetBestCommunicationStream()
|
||
{
|
||
SvStream* pStream = new SvMemoryStream;
|
||
// pStream->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
|
||
return pStream;
|
||
}
|
||
|
||
#define READ_SOCKET( pBuffer, nLength )\
|
||
if ( !bWasError )\
|
||
{bWasError |= pTCPIO->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;}
|
||
|
||
#define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
|
||
READ_SOCKET( pBuffer, nLength );\
|
||
if ( !bWasError )\
|
||
{nTotal += nLength;}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocket::DoReceiveDataStream()
|
||
{
|
||
BOOL bWasError = FALSE;
|
||
char* pBuffer = NULL;
|
||
comm_UINT32 nLen;
|
||
bWasError = pPacketHandler->ReceiveData( (void* &)pBuffer, nLen ) != C_ERROR_NONE;
|
||
if ( !bWasError )
|
||
{
|
||
pReceiveStream = GetBestCommunicationStream();
|
||
DBG_ASSERT( pReceiveStream->IsA() == ID_MEMORYSTREAM, "CommunicationStream is not an SvMemoryStream. Communication has to be reimplemented here!")
|
||
if ( pReceiveStream->IsA() == ID_MEMORYSTREAM )
|
||
((SvMemoryStream*)pReceiveStream)->SetBuffer( pBuffer, nLen, TRUE, nLen );
|
||
DBG_ASSERT( pReceiveStream, "Datastream is NULL")
|
||
}
|
||
|
||
return !bWasError;
|
||
}
|
||
|
||
void SimpleCommunicationLinkViaSocket::SetApplication( const ByteString& aApp )
|
||
{
|
||
CommunicationLink::SetApplication( aApp );
|
||
SvStream* pData = GetBestCommunicationStream();
|
||
*pData << aApplication;
|
||
SendHandshake( CH_SetApplication, pData );
|
||
delete pData;
|
||
}
|
||
|
||
void SimpleCommunicationLinkViaSocket::SetNewPacketAsCurrent()
|
||
{
|
||
pServiceData = pReceiveStream;
|
||
nServiceProtocol = pPacketHandler->GetReceiveProtocol();
|
||
nServiceHeaderType = pPacketHandler->GetReceiveHeaderType();
|
||
}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocket::SendHandshake( HandshakeType aHandshakeType, SvStream* pData )
|
||
{
|
||
BOOL bWasError;
|
||
|
||
if ( pData )
|
||
{
|
||
UINT32 nBuffer;
|
||
nBuffer = pData->Seek( STREAM_SEEK_TO_END );
|
||
bWasError = !pPacketHandler->SendHandshake( aHandshakeType, ((SvMemoryStream*)pData)->GetData(), nBuffer );
|
||
}
|
||
else
|
||
bWasError = !pPacketHandler->SendHandshake( aHandshakeType );
|
||
|
||
|
||
if ( bWasError )
|
||
{
|
||
INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_ERROR, this );
|
||
ShutdownCommunication();
|
||
}
|
||
else
|
||
{ // set new status
|
||
switch ( aHandshakeType )
|
||
{
|
||
case CH_REQUEST_HandshakeAlive:
|
||
break;
|
||
case CH_RESPONSE_HandshakeAlive:
|
||
break;
|
||
case CH_REQUEST_ShutdownLink:
|
||
bIsRequestShutdownPending = TRUE;
|
||
break;
|
||
case CH_ShutdownLink:
|
||
break;
|
||
case CH_SUPPORT_OPTIONS:
|
||
break;
|
||
case CH_SetApplication:
|
||
break;
|
||
default:
|
||
DBG_ERROR("Unknown HandshakeType");
|
||
}
|
||
}
|
||
return !bWasError;
|
||
}
|
||
|
||
SimpleCommunicationLinkViaSocketWithReceiveCallbacks::SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, NAMESPACE_VOS(OStreamSocket) *pSocket )
|
||
: SimpleCommunicationLinkViaSocket( pMan, pSocket )
|
||
{
|
||
}
|
||
|
||
SimpleCommunicationLinkViaSocketWithReceiveCallbacks::~SimpleCommunicationLinkViaSocketWithReceiveCallbacks()
|
||
{
|
||
if ( pMyManager && pMyManager->IsLinkValid( this ) && !bIsRequestShutdownPending )
|
||
StopCommunication();
|
||
}
|
||
|
||
void SimpleCommunicationLinkViaSocketWithReceiveCallbacks::WaitForShutdown()
|
||
{
|
||
CommunicationLinkRef rHold(this); // avoid deleting this link before the end of the method
|
||
SetFinalRecieveTimeout();
|
||
while ( pMyManager && !IsCommunicationError() )
|
||
ReceiveDataStream();
|
||
}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ReceiveDataStream()
|
||
{
|
||
if ( DoReceiveDataStream() )
|
||
{
|
||
SetNewPacketAsCurrent();
|
||
StartCallback();
|
||
DataReceived();
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
StartCallback();
|
||
ShutdownCommunication();
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
BOOL SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ShutdownCommunication()
|
||
{
|
||
if ( GetStreamSocket() )
|
||
GetStreamSocket()->shutdown();
|
||
|
||
if ( GetStreamSocket() )
|
||
GetStreamSocket()->close();
|
||
|
||
NAMESPACE_VOS(OStreamSocket) *pTempSocket = GetStreamSocket();
|
||
SetStreamSocket( NULL );
|
||
delete pTempSocket;
|
||
|
||
ConnectionClosed();
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
CommunicationManager::CommunicationManager( BOOL bUseMultiChannel )
|
||
: bIsCommunicationRunning( FALSE )
|
||
, nInfoType( CM_NONE )
|
||
, bIsMultiChannel( bUseMultiChannel )
|
||
, aApplication("Unknown")
|
||
{
|
||
}
|
||
|
||
CommunicationManager::~CommunicationManager()
|
||
{
|
||
xLastNewLink.Clear();
|
||
}
|
||
|
||
ByteString CommunicationManager::GetMyName( CM_NameType eType )
|
||
{
|
||
rtl::OUString aHostname;
|
||
NAMESPACE_VOS(OSocketAddr)::getLocalHostname( aHostname );
|
||
return ByteString( UniString(aHostname), RTL_TEXTENCODING_UTF8 );
|
||
}
|
||
|
||
void CommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
|
||
{
|
||
pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
|
||
pCL->aStart = DateTime();
|
||
pCL->aLastAccess = pCL->aStart;
|
||
bIsCommunicationRunning = TRUE;
|
||
pCL->SetApplication( aApplication );
|
||
|
||
xLastNewLink = pCL;
|
||
|
||
INFO_MSG( CByteString("C+:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString("Verbindung aufgebaut: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_OPEN, pCL );
|
||
ConnectionOpened( pCL );
|
||
pCL->FinishCallback();
|
||
}
|
||
|
||
void CommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
|
||
{
|
||
pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
|
||
pCL->aLastAccess = DateTime();
|
||
|
||
INFO_MSG( CByteString("C-:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString("Verbindung abgebrochen: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_CLOSE, pCL );
|
||
ConnectionClosed( pCL );
|
||
|
||
if ( xLastNewLink == pCL )
|
||
xLastNewLink.Clear();
|
||
|
||
pCL->FinishCallback();
|
||
// delete pCL;
|
||
}
|
||
|
||
void CommunicationManager::CallDataReceived( CommunicationLink* pCL )
|
||
{
|
||
pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
|
||
pCL->aLastAccess = DateTime();
|
||
CommunicationLinkRef rHold(pCL); // H<>lt den Zeiger bis zum Ende des calls
|
||
|
||
// should be impossible but happens for mysterious reasons
|
||
if ( !pCL->pServiceData )
|
||
{
|
||
DBG_ERROR( "Datastream is NULL" )
|
||
pCL->FinishCallback();
|
||
return;
|
||
}
|
||
|
||
|
||
if ( CH_Handshake == pCL->nServiceHeaderType )
|
||
{
|
||
SvStream *pData = pCL->GetServiceData();
|
||
USHORT nType;
|
||
pData->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); // Unfortulately it is written this way :((
|
||
*pData >> nType;
|
||
pData->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
|
||
switch ( nType )
|
||
{
|
||
case CH_REQUEST_HandshakeAlive:
|
||
{
|
||
pCL->SendHandshake( CH_RESPONSE_HandshakeAlive );
|
||
}
|
||
break;
|
||
case CH_REQUEST_ShutdownLink:
|
||
{
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
debug_printf("Sending ShutdownLink\n");
|
||
#endif
|
||
pCL->SendHandshake( CH_ShutdownLink );
|
||
}
|
||
break;
|
||
case CH_ShutdownLink:
|
||
{
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
debug_printf("Executing ShutdownLink\n");
|
||
#endif
|
||
pCL->ShutdownCommunication();
|
||
}
|
||
break;
|
||
case CH_SetApplication:
|
||
{
|
||
ByteString aApplication;
|
||
*pData >> aApplication;
|
||
pCL->CommunicationLink::SetApplication( aApplication );
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
debug_printf( "Setting Application to " );
|
||
debug_printf( aApplication.GetBuffer() );
|
||
debug_printf( "\n" );
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
#if OSL_DEBUG_LEVEL > 1
|
||
default:
|
||
{
|
||
debug_printf("Unknown Handshake received\n");
|
||
}
|
||
#endif
|
||
}
|
||
delete pData;
|
||
}
|
||
else
|
||
{
|
||
if ( pCL->pServiceData )
|
||
{
|
||
pCL->nTotalBytes += pCL->pServiceData->Seek( STREAM_SEEK_TO_END );
|
||
pCL->pServiceData->Seek( STREAM_SEEK_TO_BEGIN );
|
||
}
|
||
|
||
INFO_MSG( CByteString("D :").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CByteString("Daten Empfangen:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
|
||
CM_RECEIVE, pCL );
|
||
DataReceived( pCL );
|
||
}
|
||
delete pCL->GetServiceData();
|
||
pCL->FinishCallback();
|
||
}
|
||
|
||
void CommunicationManager::CallInfoMsg( InfoString aMsg )
|
||
{
|
||
// Hier wird es wohl kein Housekeeping geben
|
||
InfoMsg( aMsg );
|
||
}
|
||
|
||
void CommunicationManager::SetApplication( const ByteString& aApp, BOOL bRunningLinks )
|
||
{
|
||
aApplication = aApp;
|
||
if ( bRunningLinks )
|
||
{
|
||
USHORT i;
|
||
for ( i = 0 ; i < GetCommunicationLinkCount() ; i++ )
|
||
GetCommunicationLink( i )->SetApplication( aApp );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
SingleCommunicationManager::SingleCommunicationManager( BOOL bUseMultiChannel )
|
||
: CommunicationManager( bUseMultiChannel )
|
||
{
|
||
xActiveLink = NULL;
|
||
pInactiveLink = NULL;
|
||
}
|
||
|
||
SingleCommunicationManager::~SingleCommunicationManager()
|
||
{
|
||
StopCommunication();
|
||
if ( pInactiveLink )
|
||
pInactiveLink->InvalidateManager();
|
||
}
|
||
|
||
BOOL SingleCommunicationManager::StopCommunication()
|
||
{
|
||
if ( xActiveLink.Is() )
|
||
{
|
||
BOOL bSuccess = xActiveLink->StopCommunication();
|
||
if ( pInactiveLink )
|
||
pInactiveLink->InvalidateManager();
|
||
pInactiveLink = xActiveLink;
|
||
xActiveLink.Clear();
|
||
return bSuccess;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL SingleCommunicationManager::IsLinkValid( CommunicationLink* pCL )
|
||
{
|
||
return &xActiveLink == pCL;
|
||
}
|
||
|
||
USHORT SingleCommunicationManager::GetCommunicationLinkCount()
|
||
{
|
||
return IsCommunicationRunning()?1:0;
|
||
}
|
||
|
||
CommunicationLinkRef SingleCommunicationManager::GetCommunicationLink( USHORT nNr )
|
||
{
|
||
return xActiveLink;
|
||
}
|
||
|
||
void SingleCommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
|
||
{
|
||
DBG_ASSERT( !xActiveLink.Is(), "Es ist bereits ein CommunicationLink aktiv");
|
||
if ( xActiveLink.Is() )
|
||
{
|
||
if ( pInactiveLink )
|
||
pInactiveLink->InvalidateManager();
|
||
pInactiveLink = xActiveLink;
|
||
xActiveLink->StopCommunication(); // Den alten Link brutal abw<62>rgen
|
||
}
|
||
xActiveLink = pCL;
|
||
CommunicationManager::CallConnectionOpened( pCL );
|
||
}
|
||
|
||
void SingleCommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
|
||
{
|
||
CommunicationManager::CallConnectionClosed( pCL );
|
||
|
||
DBG_ASSERT( pCL == xActiveLink, "SingleCommunicationManager::CallConnectionClosed mit fremdem Link");
|
||
if ( pInactiveLink )
|
||
pInactiveLink->InvalidateManager();
|
||
pInactiveLink = xActiveLink;
|
||
xActiveLink.Clear();
|
||
bIsCommunicationRunning = FALSE;
|
||
}
|
||
|
||
void SingleCommunicationManager::DestroyingLink( CommunicationLink *pCL )
|
||
{
|
||
pInactiveLink = NULL;
|
||
pCL->InvalidateManager();
|
||
}
|
||
|
||
|
||
SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( ByteString aHost, ULONG nPort, BOOL bUseMultiChannel )
|
||
: SingleCommunicationManager( bUseMultiChannel )
|
||
, aHostToTalk( aHost )
|
||
, nPortToTalk( nPort )
|
||
{
|
||
}
|
||
|
||
|
||
SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( BOOL bUseMultiChannel )
|
||
: SingleCommunicationManager( bUseMultiChannel )
|
||
, aHostToTalk()
|
||
, nPortToTalk( 0 )
|
||
{
|
||
}
|
||
|
||
|
||
BOOL CommonSocketFunctions::DoStartCommunication( CommunicationManager *pCM, ICommunicationManagerClient *pCMC, ByteString aHost, ULONG nPort )
|
||
{
|
||
NAMESPACE_VOS(OInetSocketAddr) Addr;
|
||
NAMESPACE_VOS(OConnectorSocket) *pConnSocket;
|
||
|
||
Addr.setAddr( rtl::OUString( UniString( aHost, RTL_TEXTENCODING_UTF8 ) ) );
|
||
Addr.setPort( nPort );
|
||
|
||
TimeValue aTV;
|
||
aTV.Seconds = 10; // Warte 10 Sekunden
|
||
aTV.Nanosec = 0;
|
||
do
|
||
{
|
||
pConnSocket = new NAMESPACE_VOS(OConnectorSocket)();
|
||
pConnSocket->setTcpNoDelay( 1 );
|
||
if ( pConnSocket->connect( Addr, &aTV ) == NAMESPACE_VOS(ISocketTypes::TResult_Ok) )
|
||
{
|
||
pConnSocket->setTcpNoDelay( 1 );
|
||
|
||
pCM->CallConnectionOpened( CreateCommunicationLink( pCM, pConnSocket ) );
|
||
return TRUE;
|
||
}
|
||
else
|
||
delete pConnSocket;
|
||
|
||
} while ( pCMC->RetryConnect() );
|
||
|
||
return FALSE;
|
||
}
|
||
|