xref: /trunk/main/automation/source/simplecm/simplecm.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_automation.hxx"
30 
31 
32 #define ENABLE_BYTESTRING_STREAM_OPERATORS
33 #include <tools/solar.h>
34 #include <automation/simplecm.hxx>
35 
36 #include <automation/commdefines.hxx>
37 #include "packethandler.hxx"
38 #include "tcpio.hxx"
39 
40 #if OSL_DEBUG_LEVEL > 1
41 #include <stdio.h>
42 void debug_printf( const char *chars )
43 {
44     static sal_Bool bPrint = (getenv("DEBUG") != NULL);
45     if ( bPrint )
46     {
47         printf( chars );
48         fflush( stdout );
49     }
50 }
51 #endif
52 
53 CommunicationLink::CommunicationLink( CommunicationManager *pMan )
54 : pMyManager(pMan)
55 , pServiceData(NULL)
56 , nServiceProtocol( 0 )
57 , bIsInsideCallback( sal_False )
58 , nTotalBytes( 0 )
59 , maApplication("Undefined")
60 #if OSL_DEBUG_LEVEL > 1
61 , bFlag( sal_False )
62 , nSomething( 0 )
63 #endif
64 {
65 }
66 
67 CommunicationLink::~CommunicationLink()
68 {
69 #if OSL_DEBUG_LEVEL > 1
70     if ( !bFlag )    // bFlag will be set if deletion is expected else we can set a breakpoint
71         bFlag = sal_False;
72 #endif
73     if ( pMyManager )
74         pMyManager->DestroyingLink( this );
75 }
76 
77 void CommunicationLink::CallInfoMsg( InfoString aMsg )
78 {
79     if ( pMyManager )
80         pMyManager->InfoMsg( aMsg );
81 };
82 
83 CM_InfoType CommunicationLink::GetInfoType()
84 {
85     if ( pMyManager )
86         return pMyManager->GetInfoType();
87     else
88         return CM_NO_TEXT;
89 }
90 
91 IMPL_LINK( CommunicationLink, ConnectionClosed, void*, EMPTYARG )
92 {
93     if ( pMyManager )
94         pMyManager->CallConnectionClosed( this );
95     return 1;
96 }
97 
98 IMPL_LINK( CommunicationLink, DataReceived, void*, EMPTYARG )
99 {
100     if ( pMyManager )
101         pMyManager->CallDataReceived( this );
102     return 1;
103 }
104 
105 sal_Bool CommunicationLink::DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
106 {
107     INFO_MSG( CByteString("S :").Append( GetCommunicationPartner( CM_FQDN ) ),
108         CByteString("Daten Senden:").Append( GetCommunicationPartner( CM_FQDN ) ),
109         CM_SEND, this );
110     sal_Bool bWasError = sal_False;
111 
112     sal_uInt32 nBuffer;
113     nBuffer = pDataStream->SeekRel(0) +1;
114     bWasError = pPacketHandler->TransferData( ((SvMemoryStream*)pDataStream)->GetData(), nBuffer, nProtocol ) != C_ERROR_NONE;
115 
116     if ( bWasError )
117     {
118         INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
119             CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
120             CM_ERROR, this );
121         ShutdownCommunication();
122     }
123     return !bWasError;
124 }
125 
126 sal_Bool CommunicationLink::TransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
127 {
128     aLastAccess = DateTime();
129     nTotalBytes += pDataStream->Seek( STREAM_SEEK_TO_END );
130     return DoTransferDataStream( pDataStream, nProtocol );
131 }
132 
133 void CommunicationLink::SetApplication( const ByteString& aApp )
134 {
135     maApplication = aApp;
136 }
137 
138 
139 SimpleCommunicationLinkViaSocket::SimpleCommunicationLinkViaSocket( CommunicationManager *pMan, vos::OStreamSocket *pSocket )
140 : CommunicationLink( pMan )
141 , aCommunicationPartner()
142 , aMyName()
143 , pStreamSocket( pSocket )
144 , pReceiveStream( NULL )
145 , bIsRequestShutdownPending( sal_False )
146 {
147     pTCPIO = new TCPIO( pStreamSocket );
148     pPacketHandler = new PacketHandler( (ITransmiter*) pTCPIO, pTCPIO, pMyManager->IsMultiChannel() );
149 }
150 
151 SimpleCommunicationLinkViaSocket::~SimpleCommunicationLinkViaSocket()
152 {
153     delete pPacketHandler;
154     pPacketHandler = NULL;
155     delete pTCPIO;
156     pTCPIO = NULL;
157     delete pStreamSocket;
158     pStreamSocket = NULL;
159 }
160 
161 void SimpleCommunicationLinkViaSocket::SetStreamSocket( vos::OStreamSocket* pSocket )
162 {
163     if ( pTCPIO )
164         pTCPIO->SetStreamSocket( pSocket );
165     pStreamSocket = pSocket;
166 }
167 
168 sal_Bool SimpleCommunicationLinkViaSocket::StopCommunication()
169 {
170     CommunicationLinkRef rHold(this);       // avoid deleting this link before the end of the method
171     if ( !IsCommunicationError() )  // Meaning that the Communication is still runnung
172     {
173 #if OSL_DEBUG_LEVEL > 1
174         debug_printf("Sending REQUEST_ShutdownLink\n");
175 #endif
176         SendHandshake( CH_REQUEST_ShutdownLink );
177     }
178     WaitForShutdown();
179     return sal_True;
180 }
181 
182 void SimpleCommunicationLinkViaSocket::SetFinalRecieveTimeout()
183 {
184     if ( !IsCommunicationError() )
185     {
186         TimeValue aTime = {30, 0};   // 30 seconds
187         pStreamSocket->setRecvTimeout( &aTime );
188     }
189 }
190 
191 sal_Bool SimpleCommunicationLinkViaSocket::IsCommunicationError()
192 {
193     return !pStreamSocket;
194 }
195 
196 ByteString SimpleCommunicationLinkViaSocket::GetCommunicationPartner( CM_NameType eType )
197 {
198     if ( pStreamSocket )
199     {
200         switch ( eType )
201         {
202             case CM_DOTTED:
203                 {
204                     rtl::OUString aDotted;
205                     vos::OSocketAddr *pPeerAdr = new vos::OSocketAddr;
206                     pStreamSocket->getPeerAddr( *pPeerAdr );
207                     ((vos::OInetSocketAddr*)pPeerAdr)->getDottedAddr( aDotted );
208                     delete pPeerAdr;
209                     return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
210                 }
211                 //break;
212             case CM_FQDN:
213                 {
214                     if ( !aCommunicationPartner.Len() )
215                     {
216                         rtl::OUString aFQDN;
217                         pStreamSocket->getPeerHost( aFQDN );
218                         aCommunicationPartner = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
219                     }
220                     return aCommunicationPartner;
221                 }
222                 //break;
223         }
224     }
225     return CByteString( "Unknown" );
226 }
227 
228 ByteString SimpleCommunicationLinkViaSocket::GetMyName( CM_NameType eType )
229 {
230     if ( pStreamSocket )
231     {
232         switch ( eType )
233         {
234             case CM_DOTTED:
235                 {
236                     rtl::OUString aDotted;
237                     vos::OSocketAddr *pPeerAdr = new vos::OSocketAddr;
238                     pStreamSocket->getLocalAddr( *pPeerAdr );
239                     ((vos::OInetSocketAddr*)pPeerAdr)->getDottedAddr( aDotted );
240                     delete pPeerAdr;
241                     return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
242                 }
243                 //break;
244             case CM_FQDN:
245                 {
246                     if ( !aMyName.Len() )
247                     {
248                         rtl::OUString aFQDN;
249                         pStreamSocket->getLocalHost( aFQDN );
250                         aMyName = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
251                     }
252                     return aMyName;
253                 }
254                 //break;
255         }
256     }
257     return CByteString( "Error" );
258 }
259 
260 SvStream* SimpleCommunicationLinkViaSocket::GetBestCommunicationStream()
261 {
262     SvStream* pStream = new SvMemoryStream;
263 //  pStream->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
264     return pStream;
265 }
266 
267 #define READ_SOCKET( pBuffer, nLength )\
268     if ( !bWasError )\
269         {bWasError |= pTCPIO->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;}
270 
271 #define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
272     READ_SOCKET( pBuffer, nLength );\
273     if ( !bWasError )\
274         {nTotal += nLength;}
275 
276 sal_Bool SimpleCommunicationLinkViaSocket::DoReceiveDataStream()
277 {
278     sal_Bool bWasError = sal_False;
279     void* pBuffer = NULL;
280     comm_UINT32 nLen;
281     bWasError = pPacketHandler->ReceiveData( pBuffer, nLen ) != C_ERROR_NONE;
282     if ( !bWasError )
283     {
284         pReceiveStream = GetBestCommunicationStream();
285         DBG_ASSERT( pReceiveStream->IsA() == ID_MEMORYSTREAM, "CommunicationStream is not an SvMemoryStream. Communication has to be reimplemented here!");
286         if ( pReceiveStream->IsA() == ID_MEMORYSTREAM )
287             ((SvMemoryStream*)pReceiveStream)->SetBuffer( pBuffer, nLen, sal_True, nLen );
288         DBG_ASSERT( pReceiveStream, "Datastream is NULL");
289     }
290 
291     return !bWasError;
292 }
293 
294 void SimpleCommunicationLinkViaSocket::SetApplication( const ByteString& aApp )
295 {
296     CommunicationLink::SetApplication( aApp );
297     SvStream* pData = GetBestCommunicationStream();
298     *pData << aApp;
299     SendHandshake( CH_SetApplication, pData );
300     delete pData;
301 }
302 
303 void SimpleCommunicationLinkViaSocket::SetNewPacketAsCurrent()
304 {
305     pServiceData = pReceiveStream;
306     nServiceProtocol = pPacketHandler->GetReceiveProtocol();
307     nServiceHeaderType = pPacketHandler->GetReceiveHeaderType();
308 }
309 
310 sal_Bool SimpleCommunicationLinkViaSocket::SendHandshake( HandshakeType aHandshakeType, SvStream* pData )
311 {
312     sal_Bool bWasError;
313 
314     if ( pData )
315     {
316         sal_uInt32 nBuffer;
317         nBuffer = pData->Seek( STREAM_SEEK_TO_END );
318         bWasError = !pPacketHandler->SendHandshake( aHandshakeType, ((SvMemoryStream*)pData)->GetData(), nBuffer );
319     }
320     else
321         bWasError = !pPacketHandler->SendHandshake( aHandshakeType );
322 
323 
324     if ( bWasError )
325     {
326         INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
327             CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
328             CM_ERROR, this );
329         ShutdownCommunication();
330     }
331     else
332     {   // set new status
333         switch ( aHandshakeType )
334         {
335             case CH_REQUEST_HandshakeAlive:
336                 break;
337             case CH_RESPONSE_HandshakeAlive:
338                 break;
339             case CH_REQUEST_ShutdownLink:
340                 bIsRequestShutdownPending = sal_True;
341                 break;
342             case CH_ShutdownLink:
343                 break;
344             case CH_SUPPORT_OPTIONS:
345                 break;
346             case CH_SetApplication:
347                 break;
348             default:
349                 DBG_ERROR("Unknown HandshakeType");
350         }
351     }
352     return !bWasError;
353 }
354 
355 SimpleCommunicationLinkViaSocketWithReceiveCallbacks::SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, vos::OStreamSocket *pSocket )
356 : SimpleCommunicationLinkViaSocket( pMan, pSocket )
357 {
358 }
359 
360 SimpleCommunicationLinkViaSocketWithReceiveCallbacks::~SimpleCommunicationLinkViaSocketWithReceiveCallbacks()
361 {
362     if ( pMyManager && pMyManager->IsLinkValid( this ) && !bIsRequestShutdownPending )
363         StopCommunication();
364 }
365 
366 void SimpleCommunicationLinkViaSocketWithReceiveCallbacks::WaitForShutdown()
367 {
368     CommunicationLinkRef rHold(this);       // avoid deleting this link before the end of the method
369     SetFinalRecieveTimeout();
370     while ( pMyManager && !IsCommunicationError() )
371         ReceiveDataStream();
372 }
373 
374 sal_Bool SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ReceiveDataStream()
375 {
376     if ( DoReceiveDataStream() )
377     {
378         SetNewPacketAsCurrent();
379         StartCallback();
380         DataReceived();
381         return sal_True;
382     }
383     else
384     {
385         StartCallback();
386         ShutdownCommunication();
387         return sal_False;
388     }
389 }
390 
391 sal_Bool SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ShutdownCommunication()
392 {
393     if ( GetStreamSocket() )
394         GetStreamSocket()->shutdown();
395 
396     if ( GetStreamSocket() )
397         GetStreamSocket()->close();
398 
399     vos::OStreamSocket *pTempSocket = GetStreamSocket();
400     SetStreamSocket( NULL );
401     delete pTempSocket;
402 
403     ConnectionClosed();
404 
405     return sal_True;
406 }
407 
408 
409 
410 CommunicationManager::CommunicationManager( sal_Bool bUseMultiChannel )
411 : nInfoType( CM_NONE )
412 , bIsCommunicationRunning( sal_False )
413 , maApplication("Unknown")
414 , bIsMultiChannel( bUseMultiChannel )
415 {
416 }
417 
418 CommunicationManager::~CommunicationManager()
419 {
420     xLastNewLink.Clear();
421 }
422 
423 sal_Bool CommunicationManager::StartCommunication( String aApp, String aParams )
424 {
425     (void) aApp; /* avoid warning about unused parameter */
426     (void) aParams; /* avoid warning about unused parameter */
427     return sal_False;
428 }
429 
430 sal_Bool CommunicationManager::StartCommunication( ByteString aHost, sal_uLong nPort )
431 {
432     (void) aHost; /* avoid warning about unused parameter */
433     (void) nPort; /* avoid warning about unused parameter */
434     return sal_False;
435 }
436 
437 ByteString CommunicationManager::GetMyName( CM_NameType )
438 {
439     rtl::OUString aHostname;
440     vos::OSocketAddr::getLocalHostname( aHostname );
441     return ByteString( UniString(aHostname), RTL_TEXTENCODING_UTF8 );
442 }
443 
444 void CommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
445 {
446     pCL->StartCallback();       // Sollte bereits vor dem Aufruf gerufen werden
447     pCL->aStart = DateTime();
448     pCL->aLastAccess = pCL->aStart;
449     bIsCommunicationRunning = sal_True;
450     pCL->SetApplication( GetApplication() );
451 
452     xLastNewLink = pCL;
453 
454     INFO_MSG( CByteString("C+:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
455         CByteString("Verbindung aufgebaut: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
456         CM_OPEN, pCL );
457     ConnectionOpened( pCL );
458     pCL->FinishCallback();
459 }
460 
461 void CommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
462 {
463     pCL->StartCallback();       // Sollte bereits vor dem Aufruf gerufen werden
464     pCL->aLastAccess = DateTime();
465 
466     INFO_MSG( CByteString("C-:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
467         CByteString("Verbindung abgebrochen: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
468         CM_CLOSE, pCL );
469     ConnectionClosed( pCL );
470 
471     if ( xLastNewLink == pCL )
472         xLastNewLink.Clear();
473 
474     pCL->FinishCallback();
475 //  delete pCL;
476 }
477 
478 void CommunicationManager::CallDataReceived( CommunicationLink* pCL )
479 {
480     pCL->StartCallback();       // Sollte bereits vor dem Aufruf gerufen werden
481     pCL->aLastAccess = DateTime();
482     CommunicationLinkRef rHold(pCL);    // H�lt den Zeiger bis zum Ende des calls
483 
484     // should be impossible but happens for mysterious reasons
485     if ( !pCL->pServiceData )
486     {
487         DBG_ERROR( "Datastream is NULL" );
488         pCL->FinishCallback();
489         return;
490     }
491 
492 
493     if ( CH_Handshake == pCL->nServiceHeaderType )
494     {
495         SvStream *pData = pCL->GetServiceData();
496         sal_uInt16 nType;
497         pData->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );    // Unfortulately it is written this way :((
498         *pData >> nType;
499         pData->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
500         switch ( nType )
501         {
502             case CH_REQUEST_HandshakeAlive:
503                 {
504                     pCL->SendHandshake( CH_RESPONSE_HandshakeAlive );
505                 }
506                 break;
507             case CH_REQUEST_ShutdownLink:
508                 {
509 #if OSL_DEBUG_LEVEL > 1
510                     debug_printf("Sending ShutdownLink\n");
511 #endif
512                     pCL->SendHandshake( CH_ShutdownLink );
513                 }
514                 break;
515             case CH_ShutdownLink:
516                 {
517 #if OSL_DEBUG_LEVEL > 1
518                     debug_printf("Executing ShutdownLink\n");
519 #endif
520                     pCL->ShutdownCommunication();
521                 }
522                 break;
523             case CH_SetApplication:
524                 {
525                     ByteString aApplication;
526                     *pData >> aApplication;
527                     pCL->CommunicationLink::SetApplication( aApplication );
528 #if OSL_DEBUG_LEVEL > 1
529                     debug_printf( "Setting Application to " );
530                     debug_printf( aApplication.GetBuffer() );
531                     debug_printf( "\n" );
532 #endif
533                 }
534                 break;
535 
536 #if OSL_DEBUG_LEVEL > 1
537             default:
538                 {
539                     debug_printf("Unknown Handshake received\n");
540                 }
541 #endif
542         }
543         delete pData;
544     }
545     else
546     {
547         if ( pCL->pServiceData )
548         {
549             pCL->nTotalBytes += pCL->pServiceData->Seek( STREAM_SEEK_TO_END );
550             pCL->pServiceData->Seek( STREAM_SEEK_TO_BEGIN );
551         }
552 
553         INFO_MSG( CByteString("D :").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
554             CByteString("Daten Empfangen:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
555             CM_RECEIVE, pCL );
556         DataReceived( pCL );
557     }
558     delete pCL->GetServiceData();
559     pCL->FinishCallback();
560 }
561 
562 void CommunicationManager::CallInfoMsg( InfoString aMsg )
563 {
564     // Hier wird es wohl kein Housekeeping geben
565     InfoMsg( aMsg );
566 }
567 
568 void CommunicationManager::SetApplication( const ByteString& aApp, sal_Bool bRunningLinks )
569 {
570     maApplication = aApp;
571     if ( bRunningLinks )
572     {
573         sal_uInt16 i;
574         for ( i = 0 ; i < GetCommunicationLinkCount() ; i++ )
575             GetCommunicationLink( i )->SetApplication( aApp );
576     }
577 }
578 
579 
580 
581 SingleCommunicationManager::SingleCommunicationManager( sal_Bool bUseMultiChannel )
582 : CommunicationManager( bUseMultiChannel )
583 {
584     xActiveLink = NULL;
585     pInactiveLink = NULL;
586 }
587 
588 SingleCommunicationManager::~SingleCommunicationManager()
589 {
590     StopCommunication();
591     if ( pInactiveLink )
592         pInactiveLink->InvalidateManager();
593 }
594 
595 sal_Bool SingleCommunicationManager::StopCommunication()
596 {
597     if ( xActiveLink.Is() )
598     {
599         sal_Bool bSuccess = xActiveLink->StopCommunication();
600         if ( pInactiveLink )
601             pInactiveLink->InvalidateManager();
602         pInactiveLink = xActiveLink;
603         xActiveLink.Clear();
604         return bSuccess;
605     }
606     return sal_True;
607 }
608 
609 sal_Bool SingleCommunicationManager::IsLinkValid( CommunicationLink* pCL )
610 {
611     return &xActiveLink == pCL;
612 }
613 
614 sal_uInt16 SingleCommunicationManager::GetCommunicationLinkCount()
615 {
616     return IsCommunicationRunning()?1:0;
617 }
618 
619 CommunicationLinkRef SingleCommunicationManager::GetCommunicationLink( sal_uInt16 )
620 {
621     return xActiveLink;
622 }
623 
624 void SingleCommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
625 {
626     DBG_ASSERT( !xActiveLink.Is(), "Es ist bereits ein CommunicationLink aktiv");
627     if ( xActiveLink.Is() )
628     {
629         if ( pInactiveLink )
630             pInactiveLink->InvalidateManager();
631         pInactiveLink = xActiveLink;
632         xActiveLink->StopCommunication();   // Den alten Link brutal abw�rgen
633     }
634     xActiveLink = pCL;
635     CommunicationManager::CallConnectionOpened( pCL );
636 }
637 
638 void SingleCommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
639 {
640     CommunicationManager::CallConnectionClosed( pCL );
641 
642     DBG_ASSERT( pCL == xActiveLink, "SingleCommunicationManager::CallConnectionClosed mit fremdem Link");
643     if ( pInactiveLink )
644         pInactiveLink->InvalidateManager();
645     pInactiveLink = xActiveLink;
646     xActiveLink.Clear();
647     bIsCommunicationRunning = sal_False;
648 }
649 
650 void SingleCommunicationManager::DestroyingLink( CommunicationLink *pCL )
651 {
652     pInactiveLink = NULL;
653     pCL->InvalidateManager();
654 }
655 
656 
657 SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel )
658 : SingleCommunicationManager( bUseMultiChannel )
659 , aHostToTalk( aHost )
660 , nPortToTalk( nPort )
661 {
662 }
663 
664 
665 SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel )
666 : SingleCommunicationManager( bUseMultiChannel )
667 , aHostToTalk()
668 , nPortToTalk( 0 )
669 {
670 }
671 
672 
673 sal_Bool CommonSocketFunctions::DoStartCommunication( CommunicationManager *pCM, ICommunicationManagerClient *pCMC, ByteString aHost, sal_uLong nPort )
674 {
675     vos::OInetSocketAddr Addr;
676     vos::OConnectorSocket *pConnSocket;
677 
678     Addr.setAddr( rtl::OUString( UniString( aHost, RTL_TEXTENCODING_UTF8 ) ) );
679     Addr.setPort( nPort );
680 
681     TimeValue aTV;
682     aTV.Seconds = 10;       // Warte 10 Sekunden
683     aTV.Nanosec = 0;
684     do
685     {
686         pConnSocket = new vos::OConnectorSocket();
687         pConnSocket->setTcpNoDelay( 1 );
688         if ( pConnSocket->connect( Addr, &aTV ) == vos::ISocketTypes::TResult_Ok )
689         {
690             pConnSocket->setTcpNoDelay( 1 );
691 
692             pCM->CallConnectionOpened( CreateCommunicationLink( pCM, pConnSocket ) );
693             return sal_True;
694         }
695         else
696             delete pConnSocket;
697 
698     } while ( pCMC->RetryConnect() );
699 
700     return sal_False;
701 }
702 
703