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