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