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> 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 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 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 73 void CommunicationLink::CallInfoMsg( InfoString aMsg ) 74 { 75 if ( pMyManager ) 76 pMyManager->InfoMsg( aMsg ); 77 }; 78 79 CM_InfoType CommunicationLink::GetInfoType() 80 { 81 if ( pMyManager ) 82 return pMyManager->GetInfoType(); 83 else 84 return CM_NO_TEXT; 85 } 86 87 IMPL_LINK( CommunicationLink, ConnectionClosed, void*, EMPTYARG ) 88 { 89 if ( pMyManager ) 90 pMyManager->CallConnectionClosed( this ); 91 return 1; 92 } 93 94 IMPL_LINK( CommunicationLink, DataReceived, void*, EMPTYARG ) 95 { 96 if ( pMyManager ) 97 pMyManager->CallDataReceived( this ); 98 return 1; 99 } 100 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 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 129 void CommunicationLink::SetApplication( const ByteString& aApp ) 130 { 131 maApplication = aApp; 132 } 133 134 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 147 SimpleCommunicationLinkViaSocket::~SimpleCommunicationLinkViaSocket() 148 { 149 delete pPacketHandler; 150 pPacketHandler = NULL; 151 delete pTCPIO; 152 pTCPIO = NULL; 153 delete pStreamSocket; 154 pStreamSocket = NULL; 155 } 156 157 void SimpleCommunicationLinkViaSocket::SetStreamSocket( vos::OStreamSocket* pSocket ) 158 { 159 if ( pTCPIO ) 160 pTCPIO->SetStreamSocket( pSocket ); 161 pStreamSocket = pSocket; 162 } 163 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 178 void SimpleCommunicationLinkViaSocket::SetFinalRecieveTimeout() 179 { 180 if ( !IsCommunicationError() ) 181 { 182 TimeValue aTime = {30, 0}; // 30 seconds 183 pStreamSocket->setRecvTimeout( &aTime ); 184 } 185 } 186 187 sal_Bool SimpleCommunicationLinkViaSocket::IsCommunicationError() 188 { 189 return !pStreamSocket; 190 } 191 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 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 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 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 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 299 void SimpleCommunicationLinkViaSocket::SetNewPacketAsCurrent() 300 { 301 pServiceData = pReceiveStream; 302 nServiceProtocol = pPacketHandler->GetReceiveProtocol(); 303 nServiceHeaderType = pPacketHandler->GetReceiveHeaderType(); 304 } 305 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 351 SimpleCommunicationLinkViaSocketWithReceiveCallbacks::SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, vos::OStreamSocket *pSocket ) 352 : SimpleCommunicationLinkViaSocket( pMan, pSocket ) 353 { 354 } 355 356 SimpleCommunicationLinkViaSocketWithReceiveCallbacks::~SimpleCommunicationLinkViaSocketWithReceiveCallbacks() 357 { 358 if ( pMyManager && pMyManager->IsLinkValid( this ) && !bIsRequestShutdownPending ) 359 StopCommunication(); 360 } 361 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 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 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 406 CommunicationManager::CommunicationManager( sal_Bool bUseMultiChannel ) 407 : nInfoType( CM_NONE ) 408 , bIsCommunicationRunning( sal_False ) 409 , maApplication("Unknown") 410 , bIsMultiChannel( bUseMultiChannel ) 411 { 412 } 413 414 CommunicationManager::~CommunicationManager() 415 { 416 xLastNewLink.Clear(); 417 } 418 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 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 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 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 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 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 558 void CommunicationManager::CallInfoMsg( InfoString aMsg ) 559 { 560 // Hier wird es wohl kein Housekeeping geben 561 InfoMsg( aMsg ); 562 } 563 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 577 SingleCommunicationManager::SingleCommunicationManager( sal_Bool bUseMultiChannel ) 578 : CommunicationManager( bUseMultiChannel ) 579 { 580 xActiveLink = NULL; 581 pInactiveLink = NULL; 582 } 583 584 SingleCommunicationManager::~SingleCommunicationManager() 585 { 586 StopCommunication(); 587 if ( pInactiveLink ) 588 pInactiveLink->InvalidateManager(); 589 } 590 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 605 sal_Bool SingleCommunicationManager::IsLinkValid( CommunicationLink* pCL ) 606 { 607 return &xActiveLink == pCL; 608 } 609 610 sal_uInt16 SingleCommunicationManager::GetCommunicationLinkCount() 611 { 612 return IsCommunicationRunning()?1:0; 613 } 614 615 CommunicationLinkRef SingleCommunicationManager::GetCommunicationLink( sal_uInt16 ) 616 { 617 return xActiveLink; 618 } 619 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 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 646 void SingleCommunicationManager::DestroyingLink( CommunicationLink *pCL ) 647 { 648 pInactiveLink = NULL; 649 pCL->InvalidateManager(); 650 } 651 652 653 SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel ) 654 : SingleCommunicationManager( bUseMultiChannel ) 655 , aHostToTalk( aHost ) 656 , nPortToTalk( nPort ) 657 { 658 } 659 660 661 SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel ) 662 : SingleCommunicationManager( bUseMultiChannel ) 663 , aHostToTalk() 664 , nPortToTalk( 0 ) 665 { 666 } 667 668 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