| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| #ifndef _SIMPLECM_HXX |
| #define _SIMPLECM_HXX |
| |
| #include <tools/link.hxx> |
| #include <tools/string.hxx> |
| #include <tools/stream.hxx> |
| #include <vos/socket.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/datetime.hxx> |
| |
| #include <automation/commdefines.hxx> |
| |
| // CM steht für CommunicationManager |
| #define CM_UNLIMITED_CONNECTIONS 0xffff |
| |
| typedef sal_uInt16 CM_NameType; |
| #define CM_DOTTED ( (CM_NameType) 01 ) |
| #define CM_FQDN ( (CM_NameType) 02 ) |
| |
| typedef sal_uInt16 CM_InfoType; |
| // nur eines dieser 3 defines darf verwendet werden |
| #define CM_NO_TEXT ( (CM_InfoType) 01 ) |
| #define CM_SHORT_TEXT ( (CM_InfoType) 02 ) |
| #define CM_VERBOSE_TEXT ( (CM_InfoType) 03 ) |
| |
| #define CM_OPEN ( (CM_InfoType) 0x0004 ) |
| #define CM_CLOSE ( (CM_InfoType) 0x0008 ) |
| #define CM_RECEIVE ( (CM_InfoType) 0x0010 ) |
| #define CM_SEND ( (CM_InfoType) 0x0020 ) |
| #define CM_ERROR ( (CM_InfoType) 0x0040 ) |
| #define CM_MISC ( (CM_InfoType) 0x0080 ) |
| |
| #define CM_USER_1 ( (CM_InfoType) 0x0100 ) |
| #define CM_USER_2 ( (CM_InfoType) 0x0200 ) |
| #define CM_USER_3 ( (CM_InfoType) 0x0400 ) |
| #define CM_USER_4 ( (CM_InfoType) 0x0800 ) |
| |
| #define CM_ALL ( CM_OPEN | CM_CLOSE | CM_RECEIVE | CM_SEND | CM_ERROR | CM_MISC ) |
| #define CM_NONE ( 0 ) |
| |
| #define CByteString( constAsciiStr ) ByteString( RTL_CONSTASCII_STRINGPARAM ( constAsciiStr ) ) |
| |
| #define INFO_MSG( Short, Long, Type, CLink ) \ |
| { \ |
| if ( (Type & GetInfoType()) > 0 ) \ |
| { \ |
| switch ( GetInfoType() & 03 ) \ |
| { \ |
| case CM_NO_TEXT: \ |
| { \ |
| ByteString aByteString; \ |
| CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ |
| } \ |
| break; \ |
| case CM_SHORT_TEXT: \ |
| { \ |
| ByteString aByteString( Short ); \ |
| CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ |
| } \ |
| break; \ |
| case CM_VERBOSE_TEXT: \ |
| { \ |
| ByteString aByteString( Long ); \ |
| CallInfoMsg( InfoString( aByteString, Type, CLink ) ); \ |
| } \ |
| break; \ |
| default: \ |
| break; \ |
| } \ |
| } \ |
| }\ |
| |
| class CommunicationLink; |
| |
| /*#undef PRV_SV_DECL_REF_LOCK |
| #define PRV_SV_DECL_REF_LOCK(ClassName, Ref) \ |
| protected: \ |
| ClassName * pObj; \ |
| public: \ |
| PRV_SV_DECL_REF_SIGNATURE(ClassName, Ref) \ |
| inline ClassName##Ref( void * pObjP ){ClassName##Ref ((ClassName *) pObjP);} \ |
| */ |
| |
| SV_DECL_REF( CommunicationLink ) |
| |
| class InfoString : public ByteString |
| { |
| public: |
| InfoString( ByteString &nMsg, CM_InfoType nIT, CommunicationLink *pCL = NULL ): ByteString( nMsg ), nInfoType( nIT ), pCommLink( pCL ) {;} |
| CM_InfoType GetInfoType(){ return nInfoType; } |
| CommunicationLinkRef GetCommunicationLink(){ return pCommLink; } |
| private: |
| CM_InfoType nInfoType; |
| CommunicationLinkRef pCommLink; |
| }; |
| |
| class PacketHandler; |
| class CommunicationManager; |
| class SingleCommunicationManager; |
| class MultiCommunicationManager; |
| class CommunicationManagerServerAcceptThread; |
| class CommunicationLink : public SvRefBase |
| { |
| protected: |
| friend class CommunicationManager; |
| friend class SingleCommunicationManager; |
| friend class MultiCommunicationManager; |
| friend class CommunicationManagerServerAcceptThread; |
| // Darf nicht abgeräumt werden zwischen Empfang des Streams und ende des Callbacks |
| |
| protected: // so daß nur über Ref gelöscht werden kann |
| virtual ~CommunicationLink(); |
| void InvalidateManager() { pMyManager = NULL; } |
| |
| PacketHandler* pPacketHandler; |
| |
| public: |
| CommunicationLink( CommunicationManager *pMan ); |
| |
| virtual sal_Bool StopCommunication()=0; |
| virtual sal_Bool IsCommunicationError()=0; |
| CommunicationManager* GetCommunicationManager(){ return pMyManager; } |
| |
| // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren |
| virtual ByteString GetCommunicationPartner( CM_NameType eType )=0; |
| |
| // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren |
| virtual ByteString GetMyName( CM_NameType eType )=0; |
| |
| // Liefert einen neuen Stream zum Versenden von Daten. |
| virtual SvStream* GetBestCommunicationStream()=0; |
| |
| /** will call virtual function DoTransferDataStream to do actual work |
| Purpos is to allow housekeeping |
| **/ |
| sal_Bool TransferDataStream( SvStream *pDataStream, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE ); |
| |
| // Liefert die ID, die vom Sender angegeben wurde. |
| // Dadurch lassen sich virtuelle Kommunikationen über einen physikalischen Link realisiren. |
| // Da die Kommunikation zu älteren Versionen kompatibel bleiben muß, muß der Empfänger raten, |
| // die neue oder die alte verwendet wird, da sich der Kopf eines Auftrages dann ändert. |
| sal_uInt16 GetProtocol(){ return nServiceProtocol; } |
| |
| // Der Stream wird hier übergeben. Der Aufrufer ist für dessen Löschung zuständig |
| // Die Methode MUSS gerufen werden, da sonst keine weiteren Daten empfangen werden. |
| SvStream* GetServiceData(){ SvStream *pTemp = pServiceData; pServiceData = NULL; return pTemp; } |
| |
| /// Ermöglicht das Auslösen des nächsten Callbacks. Wird auch Implizit gerufen. |
| void FinishCallback(){ bIsInsideCallback = sal_False; } |
| |
| /// Syncrones Empfangen der Daten. Nur für Kommandozeile, sonst leer implementiert |
| virtual sal_Bool ReceiveDataStream(){ return sal_False; } |
| |
| /// Statistics |
| DateTime GetStart() { return aStart; } |
| sal_uLong GetTotalBytes() { return nTotalBytes; } |
| DateTime GetLastAccess() { return aLastAccess; } |
| const ByteString& GetApplication() { return maApplication; } |
| virtual void SetApplication( const ByteString& aApp ); |
| |
| protected: |
| void CallInfoMsg( InfoString aMsg ); |
| CM_InfoType GetInfoType(); |
| CommunicationManager *pMyManager; |
| // Diese Methoden werden im Main Kontext gerufen und an den Manager weitergereicht. |
| virtual DECL_LINK( ConnectionClosed, void* = NULL ); |
| virtual DECL_LINK( DataReceived, void* = NULL ); |
| |
| virtual sal_Bool DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE ); |
| |
| SvStream *pServiceData; |
| sal_uInt16 nServiceProtocol; |
| sal_uInt16 nServiceHeaderType; |
| |
| /// Verhindert das vorzeitige Auslösen des nächsten Callbacks. |
| void StartCallback(){ bIsInsideCallback = sal_True; } |
| sal_Bool bIsInsideCallback; |
| |
| virtual sal_Bool SendHandshake( HandshakeType aHandshakeType, SvStream* pData = NULL)=0; |
| |
| virtual sal_Bool ShutdownCommunication() = 0; /// Really stop the Communication |
| |
| /// Statistics |
| DateTime aStart; |
| sal_uLong nTotalBytes; |
| DateTime aLastAccess; |
| |
| private: |
| ByteString maApplication; |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| public: |
| // misc (debuging) purposes |
| sal_Bool bFlag; |
| sal_uLong nSomething; |
| #endif |
| |
| }; |
| |
| SV_IMPL_REF( CommunicationLink ); |
| |
| class CommonSocketFunctions; |
| class CommunicationManager |
| { |
| friend class CommunicationLink; |
| friend class CommonSocketFunctions; |
| public: |
| CommunicationManager( sal_Bool bUseMultiChannel = sal_False ); |
| virtual ~CommunicationManager(); |
| |
| virtual sal_Bool StartCommunication()=0; |
| virtual sal_Bool StartCommunication( String aApp, String aParams ); |
| virtual sal_Bool StartCommunication( ByteString aHost, sal_uLong nPort ); |
| virtual sal_Bool StopCommunication()=0; // Hält alle CommunicationLinks an |
| virtual sal_Bool IsCommunicationRunning() { return bIsCommunicationRunning; } |
| // virtual sal_Bool IsCommunicationError(); |
| |
| // Der Name oder die IP-Adresse oder sonstwas um den Communikationspartner zu identifizieren |
| virtual ByteString GetMyName( CM_NameType eType ); |
| |
| virtual sal_Bool IsLinkValid( CommunicationLink* pCL )=0; // Notwendig für call im Destruktor |
| |
| virtual sal_uInt16 GetCommunicationLinkCount()=0; |
| virtual CommunicationLinkRef GetCommunicationLink( sal_uInt16 nNr )=0; |
| |
| // Liefert den letzten neuen Link oder NULL wenn dieser schon wieder geschlossen ist. |
| CommunicationLinkRef GetLastNewLink() { return xLastNewLink; } |
| |
| void SetConnectionOpenedHdl( Link lConnectionOpened ){ mlConnectionOpened = lConnectionOpened; } |
| void SetConnectionClosedHdl( Link lConnectionClosed ){ mlConnectionClosed = lConnectionClosed; } |
| void SetDataReceivedHdl( Link lDataReceived ){ mlDataReceived = lDataReceived; } |
| void SetInfoMsgHdl( Link lInfoMsg ){ mlInfoMsg = lInfoMsg; } |
| |
| void SetInfoType( CM_InfoType nIT ){ nInfoType = nIT; } |
| CM_InfoType GetInfoType(){ return nInfoType; } |
| |
| sal_Bool IsMultiChannel(){ return bIsMultiChannel; } |
| void SetApplication( const ByteString& aApp, sal_Bool bRunningLinks = sal_False ); |
| const ByteString& GetApplication() { return maApplication; } |
| |
| protected: |
| // Diese Methoden werden innerhalb gerufen. Sie erledigen eventuelles Housekeeping |
| // und rufen dann die entsprechende Methode |
| virtual void CallConnectionOpened( CommunicationLink* pCL ); |
| virtual void CallConnectionClosed( CommunicationLink* pCL ); |
| void CallDataReceived( CommunicationLink* pCL ); |
| void CallInfoMsg( InfoString aMsg ); |
| |
| CM_InfoType nInfoType; |
| |
| // Diese Routinen rufen den Link oder sind überladen |
| virtual void ConnectionOpened( CommunicationLink* pCL ){ mlConnectionOpened.Call( pCL ); } |
| virtual void ConnectionClosed( CommunicationLink* pCL ){ mlConnectionClosed.Call( pCL ); } |
| virtual void DataReceived( CommunicationLink* pCL ){ mlDataReceived.Call( pCL ); } |
| virtual void InfoMsg( InfoString aMsg ){ mlInfoMsg.Call( &aMsg ); } |
| |
| sal_Bool bIsCommunicationRunning; |
| |
| virtual void DestroyingLink( CommunicationLink *pCL )=0; // Link trägt sich im Destruktor aus |
| |
| private: |
| ByteString maApplication; |
| Link mlConnectionOpened; |
| Link mlConnectionClosed; |
| Link mlDataReceived; |
| Link mlInfoMsg; |
| CommunicationLinkRef xLastNewLink; |
| |
| sal_Bool bIsMultiChannel; |
| }; |
| |
| class SingleCommunicationManager : public CommunicationManager |
| { |
| public: |
| SingleCommunicationManager( sal_Bool bUseMultiChannel = sal_False ); |
| virtual ~SingleCommunicationManager(); |
| virtual sal_Bool StopCommunication(); // Hält alle CommunicationLinks an |
| virtual sal_Bool IsLinkValid( CommunicationLink* pCL ); |
| virtual sal_uInt16 GetCommunicationLinkCount(); |
| virtual CommunicationLinkRef GetCommunicationLink( sal_uInt16 nNr ); |
| |
| protected: |
| virtual void CallConnectionOpened( CommunicationLink* pCL ); |
| virtual void CallConnectionClosed( CommunicationLink* pCL ); |
| CommunicationLinkRef xActiveLink; |
| CommunicationLink *pInactiveLink; |
| virtual void DestroyingLink( CommunicationLink *pCL ); // Link trägt sich im Destruktor aus |
| }; |
| |
| class ICommunicationManagerClient |
| { |
| friend class CommonSocketFunctions; |
| protected: |
| virtual sal_Bool RetryConnect() { return sal_False; } // Kann dann eventuell die Applikation starten |
| }; |
| |
| class TCPIO; |
| class SimpleCommunicationLinkViaSocket : public CommunicationLink |
| { |
| public: |
| virtual sal_Bool IsCommunicationError(); |
| virtual sal_Bool StopCommunication(); |
| |
| virtual ByteString GetCommunicationPartner( CM_NameType eType ); |
| virtual ByteString GetMyName( CM_NameType eType ); |
| virtual SvStream* GetBestCommunicationStream(); |
| virtual void SetApplication( const ByteString& aApp ); |
| |
| private: |
| ByteString aCommunicationPartner; |
| ByteString aMyName; |
| |
| TCPIO* pTCPIO; |
| vos::OStreamSocket *pStreamSocket; |
| |
| protected: |
| SimpleCommunicationLinkViaSocket( CommunicationManager *pMan, vos::OStreamSocket *pSocket ); |
| virtual ~SimpleCommunicationLinkViaSocket(); |
| |
| vos::OStreamSocket* GetStreamSocket() { return pStreamSocket; } |
| void SetStreamSocket( vos::OStreamSocket* pSocket ); |
| |
| SvStream *pReceiveStream; |
| sal_Bool DoReceiveDataStream(); /// Recieve DataPacket from Socket |
| virtual sal_Bool SendHandshake( HandshakeType aHandshakeType, SvStream* pData = NULL); |
| void SetFinalRecieveTimeout(); |
| sal_Bool bIsRequestShutdownPending; |
| virtual void WaitForShutdown()=0; |
| void SetNewPacketAsCurrent(); |
| }; |
| |
| class SimpleCommunicationLinkViaSocketWithReceiveCallbacks : public SimpleCommunicationLinkViaSocket |
| { |
| public: |
| SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, vos::OStreamSocket *pSocket ); |
| ~SimpleCommunicationLinkViaSocketWithReceiveCallbacks(); |
| virtual sal_Bool ReceiveDataStream(); |
| protected: |
| virtual sal_Bool ShutdownCommunication(); /// Really stop the Communication |
| virtual void WaitForShutdown(); |
| }; |
| |
| class CommonSocketFunctions |
| { |
| public: |
| sal_Bool DoStartCommunication( CommunicationManager *pCM, ICommunicationManagerClient *pCMC, ByteString aHost, sal_uLong nPort ); |
| protected: |
| virtual CommunicationLink *CreateCommunicationLink( CommunicationManager *pCM, vos::OConnectorSocket *pCS )=0; |
| }; |
| |
| class SingleCommunicationManagerClientViaSocket : public SingleCommunicationManager, public ICommunicationManagerClient, CommonSocketFunctions |
| { |
| public: |
| using CommunicationManager::StartCommunication; |
| |
| SingleCommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel = sal_False ); |
| SingleCommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel = sal_False ); |
| virtual sal_Bool StartCommunication(){ return DoStartCommunication( this, (ICommunicationManagerClient*) this, aHostToTalk, nPortToTalk );} |
| virtual sal_Bool StartCommunication( ByteString aHost, sal_uLong nPort ){ return DoStartCommunication( this, (ICommunicationManagerClient*) this, aHost, nPort );} |
| private: |
| ByteString aHostToTalk; |
| sal_uLong nPortToTalk; |
| protected: |
| virtual CommunicationLink *CreateCommunicationLink( CommunicationManager *pCM, vos::OConnectorSocket *pCS ){ return new SimpleCommunicationLinkViaSocketWithReceiveCallbacks( pCM, pCS ); } |
| }; |
| |
| #endif |