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 #ifndef _SIMPLECM_HXX 24 #define _SIMPLECM_HXX 25 26 #include <tools/link.hxx> 27 #include <tools/string.hxx> 28 #include <tools/stream.hxx> 29 #include <vos/socket.hxx> 30 #include <tools/debug.hxx> 31 #include <tools/datetime.hxx> 32 33 #include <automation/commdefines.hxx> 34 35 // CM steht f�r CommunicationManager 36 #define CM_UNLIMITED_CONNECTIONS 0xffff 37 38 typedef sal_uInt16 CM_NameType; 39 #define CM_DOTTED ( (CM_NameType) 01 ) 40 #define CM_FQDN ( (CM_NameType) 02 ) 41 42 typedef sal_uInt16 CM_InfoType; 43 // nur eines dieser 3 defines darf verwendet werden 44 #define CM_NO_TEXT ( (CM_InfoType) 01 ) 45 #define CM_SHORT_TEXT ( (CM_InfoType) 02 ) 46 #define CM_VERBOSE_TEXT ( (CM_InfoType) 03 ) 47 48 #define CM_OPEN ( (CM_InfoType) 0x0004 ) 49 #define CM_CLOSE ( (CM_InfoType) 0x0008 ) 50 #define CM_RECEIVE ( (CM_InfoType) 0x0010 ) 51 #define CM_SEND ( (CM_InfoType) 0x0020 ) 52 #define CM_ERROR ( (CM_InfoType) 0x0040 ) 53 #define CM_MISC ( (CM_InfoType) 0x0080 ) 54 55 #define CM_USER_1 ( (CM_InfoType) 0x0100 ) 56 #define CM_USER_2 ( (CM_InfoType) 0x0200 ) 57 #define CM_USER_3 ( (CM_InfoType) 0x0400 ) 58 #define CM_USER_4 ( (CM_InfoType) 0x0800 ) 59 60 #define CM_ALL ( CM_OPEN | CM_CLOSE | CM_RECEIVE | CM_SEND | CM_ERROR | CM_MISC ) 61 #define CM_NONE ( 0 ) 62 63 #define CByteString( constAsciiStr ) ByteString( RTL_CONSTASCII_STRINGPARAM ( constAsciiStr ) ) 64 65 #define INFO_MSG( Short, Long, Type, CLink ) \ 66 { \ 67 if ( (Type & GetInfoType()) > 0 ) \ 68 { \ 69 switch ( GetInfoType() & 03 ) \ 70 { \ 71 case CM_NO_TEXT: \ 72 { \ 73 ByteString aByteString; \ 74 CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ 75 } \ 76 break; \ 77 case CM_SHORT_TEXT: \ 78 { \ 79 ByteString aByteString( Short ); \ 80 CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ 81 } \ 82 break; \ 83 case CM_VERBOSE_TEXT: \ 84 { \ 85 ByteString aByteString( Long ); \ 86 CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ 87 } \ 88 break; \ 89 default: \ 90 break; \ 91 } \ 92 } \ 93 }\ 94 95 class CommunicationLink; 96 97 /*#undef PRV_SV_DECL_REF_LOCK 98 #define PRV_SV_DECL_REF_LOCK(ClassName, Ref) \ 99 protected: \ 100 ClassName * pObj; \ 101 public: \ 102 PRV_SV_DECL_REF_SIGNATURE(ClassName, Ref) \ 103 inline ClassName##Ref( void * pObjP ){ClassName##Ref ((ClassName *) pObjP);} \ 104 */ 105 106 SV_DECL_REF( CommunicationLink ) 107 108 class InfoString : public ByteString 109 { 110 public: InfoString(ByteString & nMsg,CM_InfoType nIT,CommunicationLink * pCL=NULL)111 InfoString( ByteString &nMsg, CM_InfoType nIT, CommunicationLink *pCL = NULL ): ByteString( nMsg ), nInfoType( nIT ), pCommLink( pCL ) {;} GetInfoType()112 CM_InfoType GetInfoType(){ return nInfoType; } GetCommunicationLink()113 CommunicationLinkRef GetCommunicationLink(){ return pCommLink; } 114 private: 115 CM_InfoType nInfoType; 116 CommunicationLinkRef pCommLink; 117 }; 118 119 class PacketHandler; 120 class CommunicationManager; 121 class SingleCommunicationManager; 122 class MultiCommunicationManager; 123 class CommunicationManagerServerAcceptThread; 124 class CommunicationLink : public SvRefBase 125 { 126 protected: 127 friend class CommunicationManager; 128 friend class SingleCommunicationManager; 129 friend class MultiCommunicationManager; 130 friend class CommunicationManagerServerAcceptThread; 131 // Darf nicht abger�umt werden zwischen Empfang des Streams und ende des Callbacks 132 133 protected: // so da� nur �ber Ref gel�scht werden kann 134 virtual ~CommunicationLink(); InvalidateManager()135 void InvalidateManager() { pMyManager = NULL; } 136 137 PacketHandler* pPacketHandler; 138 139 public: 140 CommunicationLink( CommunicationManager *pMan ); 141 142 virtual sal_Bool StopCommunication()=0; 143 virtual sal_Bool IsCommunicationError()=0; GetCommunicationManager()144 CommunicationManager* GetCommunicationManager(){ return pMyManager; } 145 146 // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren 147 virtual ByteString GetCommunicationPartner( CM_NameType eType )=0; 148 149 // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren 150 virtual ByteString GetMyName( CM_NameType eType )=0; 151 152 // Liefert einen neuen Stream zum Versenden von Daten. 153 virtual SvStream* GetBestCommunicationStream()=0; 154 155 /** will call virtual function DoTransferDataStream to do actual work 156 Purpos is to allow housekeeping 157 **/ 158 sal_Bool TransferDataStream( SvStream *pDataStream, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE ); 159 160 // Liefert die ID, die vom Sender angegeben wurde. 161 // Dadurch lassen sich virtuelle Kommunikationen �ber einen physikalischen Link realisiren. 162 // Da die Kommunikation zu �lteren Versionen kompatibel bleiben mu�, mu� der Empf�nger raten, 163 // die neue oder die alte verwendet wird, da sich der Kopf eines Auftrages dann �ndert. GetProtocol()164 sal_uInt16 GetProtocol(){ return nServiceProtocol; } 165 166 // Der Stream wird hier �bergeben. Der Aufrufer ist f�r dessen L�schung zust�ndig 167 // Die Methode MUSS gerufen werden, da sonst keine weiteren Daten empfangen werden. GetServiceData()168 SvStream* GetServiceData(){ SvStream *pTemp = pServiceData; pServiceData = NULL; return pTemp; } 169 170 /// Erm�glicht das Ausl�sen des n�chsten Callbacks. Wird auch Implizit gerufen. FinishCallback()171 void FinishCallback(){ bIsInsideCallback = sal_False; } 172 173 /// Syncrones Empfangen der Daten. Nur f�r Kommandozeile, sonst leer implementiert ReceiveDataStream()174 virtual sal_Bool ReceiveDataStream(){ return sal_False; } 175 176 /// Statistics GetStart()177 DateTime GetStart() { return aStart; } GetTotalBytes()178 sal_uLong GetTotalBytes() { return nTotalBytes; } GetLastAccess()179 DateTime GetLastAccess() { return aLastAccess; } GetApplication()180 const ByteString& GetApplication() { return maApplication; } 181 virtual void SetApplication( const ByteString& aApp ); 182 183 protected: 184 void CallInfoMsg( InfoString aMsg ); 185 CM_InfoType GetInfoType(); 186 CommunicationManager *pMyManager; 187 // Diese Methoden werden im Main Kontext gerufen und an den Manager weitergereicht. 188 virtual DECL_LINK( ConnectionClosed, void* = NULL ); 189 virtual DECL_LINK( DataReceived, void* = NULL ); 190 191 virtual sal_Bool DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE ); 192 193 SvStream *pServiceData; 194 sal_uInt16 nServiceProtocol; 195 sal_uInt16 nServiceHeaderType; 196 197 /// Verhindert das vorzeitige Ausl�sen des n�chsten Callbacks. StartCallback()198 void StartCallback(){ bIsInsideCallback = sal_True; } 199 sal_Bool bIsInsideCallback; 200 201 virtual sal_Bool SendHandshake( HandshakeType aHandshakeType, SvStream* pData = NULL)=0; 202 203 virtual sal_Bool ShutdownCommunication() = 0; /// Really stop the Communication 204 205 /// Statistics 206 DateTime aStart; 207 sal_uLong nTotalBytes; 208 DateTime aLastAccess; 209 210 private: 211 ByteString maApplication; 212 213 #if OSL_DEBUG_LEVEL > 1 214 public: 215 // misc (debuging) purposes 216 sal_Bool bFlag; 217 sal_uLong nSomething; 218 #endif 219 220 }; 221 222 SV_IMPL_REF( CommunicationLink ); 223 224 class CommonSocketFunctions; 225 class CommunicationManager 226 { 227 friend class CommunicationLink; 228 friend class CommonSocketFunctions; 229 public: 230 CommunicationManager( sal_Bool bUseMultiChannel = sal_False ); 231 virtual ~CommunicationManager(); 232 233 virtual sal_Bool StartCommunication()=0; 234 virtual sal_Bool StartCommunication( String aApp, String aParams ); 235 virtual sal_Bool StartCommunication( ByteString aHost, sal_uLong nPort ); 236 virtual sal_Bool StopCommunication()=0; // H�lt alle CommunicationLinks an IsCommunicationRunning()237 virtual sal_Bool IsCommunicationRunning() { return bIsCommunicationRunning; } 238 // virtual sal_Bool IsCommunicationError(); 239 240 // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren 241 virtual ByteString GetMyName( CM_NameType eType ); 242 243 virtual sal_Bool IsLinkValid( CommunicationLink* pCL )=0; // Notwendig f�r call im Destruktor 244 245 virtual sal_uInt16 GetCommunicationLinkCount()=0; 246 virtual CommunicationLinkRef GetCommunicationLink( sal_uInt16 nNr )=0; 247 248 // Liefert den letzten neuen Link oder NULL wenn dieser schon wieder geschlossen ist. GetLastNewLink()249 CommunicationLinkRef GetLastNewLink() { return xLastNewLink; } 250 SetConnectionOpenedHdl(Link lConnectionOpened)251 void SetConnectionOpenedHdl( Link lConnectionOpened ){ mlConnectionOpened = lConnectionOpened; } SetConnectionClosedHdl(Link lConnectionClosed)252 void SetConnectionClosedHdl( Link lConnectionClosed ){ mlConnectionClosed = lConnectionClosed; } SetDataReceivedHdl(Link lDataReceived)253 void SetDataReceivedHdl( Link lDataReceived ){ mlDataReceived = lDataReceived; } SetInfoMsgHdl(Link lInfoMsg)254 void SetInfoMsgHdl( Link lInfoMsg ){ mlInfoMsg = lInfoMsg; } 255 SetInfoType(CM_InfoType nIT)256 void SetInfoType( CM_InfoType nIT ){ nInfoType = nIT; } GetInfoType()257 CM_InfoType GetInfoType(){ return nInfoType; } 258 IsMultiChannel()259 sal_Bool IsMultiChannel(){ return bIsMultiChannel; } 260 void SetApplication( const ByteString& aApp, sal_Bool bRunningLinks = sal_False ); GetApplication()261 const ByteString& GetApplication() { return maApplication; } 262 263 protected: 264 // Diese Methoden werden innerhalb gerufen. Sie erledigen eventuelles Housekeeping 265 // und rufen dann die entsprechende Methode 266 virtual void CallConnectionOpened( CommunicationLink* pCL ); 267 virtual void CallConnectionClosed( CommunicationLink* pCL ); 268 void CallDataReceived( CommunicationLink* pCL ); 269 void CallInfoMsg( InfoString aMsg ); 270 271 CM_InfoType nInfoType; 272 273 // Diese Routinen rufen den Link oder sind �berladen ConnectionOpened(CommunicationLink * pCL)274 virtual void ConnectionOpened( CommunicationLink* pCL ){ mlConnectionOpened.Call( pCL ); } ConnectionClosed(CommunicationLink * pCL)275 virtual void ConnectionClosed( CommunicationLink* pCL ){ mlConnectionClosed.Call( pCL ); } DataReceived(CommunicationLink * pCL)276 virtual void DataReceived( CommunicationLink* pCL ){ mlDataReceived.Call( pCL ); } InfoMsg(InfoString aMsg)277 virtual void InfoMsg( InfoString aMsg ){ mlInfoMsg.Call( &aMsg ); } 278 279 sal_Bool bIsCommunicationRunning; 280 281 virtual void DestroyingLink( CommunicationLink *pCL )=0; // Link tr�gt sich im Destruktor aus 282 283 private: 284 ByteString maApplication; 285 Link mlConnectionOpened; 286 Link mlConnectionClosed; 287 Link mlDataReceived; 288 Link mlInfoMsg; 289 CommunicationLinkRef xLastNewLink; 290 291 sal_Bool bIsMultiChannel; 292 }; 293 294 class SingleCommunicationManager : public CommunicationManager 295 { 296 public: 297 SingleCommunicationManager( sal_Bool bUseMultiChannel = sal_False ); 298 virtual ~SingleCommunicationManager(); 299 virtual sal_Bool StopCommunication(); // H�lt alle CommunicationLinks an 300 virtual sal_Bool IsLinkValid( CommunicationLink* pCL ); 301 virtual sal_uInt16 GetCommunicationLinkCount(); 302 virtual CommunicationLinkRef GetCommunicationLink( sal_uInt16 nNr ); 303 304 protected: 305 virtual void CallConnectionOpened( CommunicationLink* pCL ); 306 virtual void CallConnectionClosed( CommunicationLink* pCL ); 307 CommunicationLinkRef xActiveLink; 308 CommunicationLink *pInactiveLink; 309 virtual void DestroyingLink( CommunicationLink *pCL ); // Link tr�gt sich im Destruktor aus 310 }; 311 312 class ICommunicationManagerClient 313 { 314 friend class CommonSocketFunctions; 315 protected: RetryConnect()316 virtual sal_Bool RetryConnect() { return sal_False; } // Kann dann eventuell die Applikation starten 317 }; 318 319 class TCPIO; 320 class SimpleCommunicationLinkViaSocket : public CommunicationLink 321 { 322 public: 323 virtual sal_Bool IsCommunicationError(); 324 virtual sal_Bool StopCommunication(); 325 326 virtual ByteString GetCommunicationPartner( CM_NameType eType ); 327 virtual ByteString GetMyName( CM_NameType eType ); 328 virtual SvStream* GetBestCommunicationStream(); 329 virtual void SetApplication( const ByteString& aApp ); 330 331 private: 332 ByteString aCommunicationPartner; 333 ByteString aMyName; 334 335 TCPIO* pTCPIO; 336 vos::OStreamSocket *pStreamSocket; 337 338 protected: 339 SimpleCommunicationLinkViaSocket( CommunicationManager *pMan, vos::OStreamSocket *pSocket ); 340 virtual ~SimpleCommunicationLinkViaSocket(); 341 GetStreamSocket()342 vos::OStreamSocket* GetStreamSocket() { return pStreamSocket; } 343 void SetStreamSocket( vos::OStreamSocket* pSocket ); 344 345 SvStream *pReceiveStream; 346 sal_Bool DoReceiveDataStream(); /// Recieve DataPacket from Socket 347 virtual sal_Bool SendHandshake( HandshakeType aHandshakeType, SvStream* pData = NULL); 348 void SetFinalRecieveTimeout(); 349 sal_Bool bIsRequestShutdownPending; 350 virtual void WaitForShutdown()=0; 351 void SetNewPacketAsCurrent(); 352 }; 353 354 class SimpleCommunicationLinkViaSocketWithReceiveCallbacks : public SimpleCommunicationLinkViaSocket 355 { 356 public: 357 SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, vos::OStreamSocket *pSocket ); 358 ~SimpleCommunicationLinkViaSocketWithReceiveCallbacks(); 359 virtual sal_Bool ReceiveDataStream(); 360 protected: 361 virtual sal_Bool ShutdownCommunication(); /// Really stop the Communication 362 virtual void WaitForShutdown(); 363 }; 364 365 class CommonSocketFunctions 366 { 367 public: 368 sal_Bool DoStartCommunication( CommunicationManager *pCM, ICommunicationManagerClient *pCMC, ByteString aHost, sal_uLong nPort ); 369 protected: 370 virtual CommunicationLink *CreateCommunicationLink( CommunicationManager *pCM, vos::OConnectorSocket *pCS )=0; 371 }; 372 373 class SingleCommunicationManagerClientViaSocket : public SingleCommunicationManager, public ICommunicationManagerClient, CommonSocketFunctions 374 { 375 public: 376 using CommunicationManager::StartCommunication; 377 378 SingleCommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel = sal_False ); 379 SingleCommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel = sal_False ); StartCommunication()380 virtual sal_Bool StartCommunication(){ return DoStartCommunication( this, (ICommunicationManagerClient*) this, aHostToTalk, nPortToTalk );} StartCommunication(ByteString aHost,sal_uLong nPort)381 virtual sal_Bool StartCommunication( ByteString aHost, sal_uLong nPort ){ return DoStartCommunication( this, (ICommunicationManagerClient*) this, aHost, nPort );} 382 private: 383 ByteString aHostToTalk; 384 sal_uLong nPortToTalk; 385 protected: CreateCommunicationLink(CommunicationManager * pCM,vos::OConnectorSocket * pCS)386 virtual CommunicationLink *CreateCommunicationLink( CommunicationManager *pCM, vos::OConnectorSocket *pCS ){ return new SimpleCommunicationLinkViaSocketWithReceiveCallbacks( pCM, pCS ); } 387 }; 388 389 #endif 390