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