1*9d1279ecSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9d1279ecSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9d1279ecSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9d1279ecSAndrew Rist * distributed with this work for additional information
6*9d1279ecSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9d1279ecSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9d1279ecSAndrew Rist * "License"); you may not use this file except in compliance
9*9d1279ecSAndrew Rist * with the License. You may obtain a copy of the License at
10*9d1279ecSAndrew Rist *
11*9d1279ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*9d1279ecSAndrew Rist *
13*9d1279ecSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9d1279ecSAndrew Rist * software distributed under the License is distributed on an
15*9d1279ecSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9d1279ecSAndrew Rist * KIND, either express or implied. See the License for the
17*9d1279ecSAndrew Rist * specific language governing permissions and limitations
18*9d1279ecSAndrew Rist * under the License.
19*9d1279ecSAndrew Rist *
20*9d1279ecSAndrew Rist *************************************************************/
21*9d1279ecSAndrew Rist
22*9d1279ecSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_automation.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir /*************************************************************************
28cdf0e10cSrcweir *
29cdf0e10cSrcweir * ATTENTION
30cdf0e10cSrcweir * This file is intended to work inside and outside the StarOffice environment.
31cdf0e10cSrcweir * Only adaption of file commtypes.hxx should be necessary. Else it is a bug!
32cdf0e10cSrcweir *
33cdf0e10cSrcweir ************************************************************************/
34cdf0e10cSrcweir
35cdf0e10cSrcweir #include "packethandler.hxx"
36cdf0e10cSrcweir #include <automation/commtypes.hxx>
37cdf0e10cSrcweir #include <automation/commdefines.hxx>
38cdf0e10cSrcweir #include "communiio.hxx"
39cdf0e10cSrcweir
40cdf0e10cSrcweir /**
41cdf0e10cSrcweir Forces switch to multichannel headers even for old communication Method
42cdf0e10cSrcweir **/
43cdf0e10cSrcweir #define FORCE_MULTI_CHANNEL_HEADERS
44cdf0e10cSrcweir
45cdf0e10cSrcweir
PacketHandler(ITransmiter * pTransmitter_,IReceiver * pReceiver_,comm_BOOL bMC)46cdf0e10cSrcweir PacketHandler::PacketHandler( ITransmiter* pTransmitter_, IReceiver* pReceiver_, comm_BOOL bMC )
47cdf0e10cSrcweir : pTransmitter( pTransmitter_ )
48cdf0e10cSrcweir , pReceiver( pReceiver_ )
49cdf0e10cSrcweir , bMultiChannel( bMC )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir }
52cdf0e10cSrcweir
CalcCheckByte(comm_UINT32 nBytes)53cdf0e10cSrcweir unsigned char PacketHandler::CalcCheckByte( comm_UINT32 nBytes )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir comm_UINT16 nRes = 0;
56cdf0e10cSrcweir nRes += HIBYTE( HIWORD( nBytes ) ) ^ 0xf0;
57cdf0e10cSrcweir nRes += LOBYTE( HIWORD( nBytes ) ) ^ 0x0f;
58cdf0e10cSrcweir nRes += HIBYTE( LOWORD( nBytes ) ) ^ 0xf0;
59cdf0e10cSrcweir nRes += LOBYTE( LOWORD( nBytes ) ) ^ 0x0f;
60cdf0e10cSrcweir
61cdf0e10cSrcweir nRes ^= HIBYTE( nRes );
62cdf0e10cSrcweir
63cdf0e10cSrcweir return LOBYTE( nRes );
64cdf0e10cSrcweir }
65cdf0e10cSrcweir
66cdf0e10cSrcweir
67cdf0e10cSrcweir #define READ_SOCKET( pBuffer, nLength )\
68cdf0e10cSrcweir if ( !bWasError )\
69cdf0e10cSrcweir {\
70cdf0e10cSrcweir bWasError |= pReceiver->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;\
71cdf0e10cSrcweir }
72cdf0e10cSrcweir
73cdf0e10cSrcweir #define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
74cdf0e10cSrcweir READ_SOCKET( pBuffer, nLength );\
75cdf0e10cSrcweir if ( !bWasError )\
76cdf0e10cSrcweir {nTotal += nLength;}
77cdf0e10cSrcweir
ReceiveData(void * & pData,comm_UINT32 & nLen)78cdf0e10cSrcweir comm_BOOL PacketHandler::ReceiveData( void* &pData, comm_UINT32 &nLen )
79cdf0e10cSrcweir {
80cdf0e10cSrcweir DBG_ASSERT( !pData, "pData should be NULL -> memory leak" );
81cdf0e10cSrcweir
82cdf0e10cSrcweir nLen = 0;
83cdf0e10cSrcweir pData = NULL;
84cdf0e10cSrcweir comm_BOOL bWasError = sal_False;
85cdf0e10cSrcweir comm_BOOL bForceMultiChannelThisPacket = sal_False;
86cdf0e10cSrcweir if ( pReceiver )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir comm_UINT32 nBytes = 0;
89cdf0e10cSrcweir nReceiveProtocol = CM_PROTOCOL_OLDSTYLE;
90cdf0e10cSrcweir nReceiveHeaderType = CH_NoHeader;
91cdf0e10cSrcweir
92cdf0e10cSrcweir READ_SOCKET( &nBytes, sizeof(nBytes) )
93cdf0e10cSrcweir if ( bWasError )
94cdf0e10cSrcweir return sal_False;
95cdf0e10cSrcweir
96cdf0e10cSrcweir if ( 0xFFFFFFFF == nBytes ) // Expliziter Request f�r dieses Datenpaket auf MultiChannel umzuschalten
97cdf0e10cSrcweir {
98cdf0e10cSrcweir READ_SOCKET( &nBytes, sizeof(nBytes) )
99cdf0e10cSrcweir if ( bWasError )
100cdf0e10cSrcweir return sal_False;
101cdf0e10cSrcweir bForceMultiChannelThisPacket = sal_True;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir
104cdf0e10cSrcweir nBytes = NETDWORD( nBytes );
105cdf0e10cSrcweir
106cdf0e10cSrcweir if ( bMultiChannel || bForceMultiChannelThisPacket )
107cdf0e10cSrcweir {
108cdf0e10cSrcweir comm_ULONG nReadSoFar = 0;
109cdf0e10cSrcweir comm_ULONG nHeaderReadSoFar = 0;
110cdf0e10cSrcweir
111cdf0e10cSrcweir // Pr�fbyte f�r L�ngenangabe
112cdf0e10cSrcweir unsigned char nLenCheck = 0;
113cdf0e10cSrcweir READ_SOCKET_LEN( &nLenCheck, 1, nReadSoFar );
114cdf0e10cSrcweir // Stimmt das Pr�fbyte?
115cdf0e10cSrcweir bWasError |= nLenCheck != CalcCheckByte( nBytes );
116cdf0e10cSrcweir
117cdf0e10cSrcweir
118cdf0e10cSrcweir comm_UINT16 nHeaderBytes;
119cdf0e10cSrcweir READ_SOCKET_LEN( &nHeaderBytes, 2, nReadSoFar );
120cdf0e10cSrcweir nHeaderBytes = NETWORD( nHeaderBytes );
121cdf0e10cSrcweir // reicht der Header �ber das Ende hinaus?
122cdf0e10cSrcweir bWasError |= !(nBytes >= nReadSoFar + nHeaderBytes);
123cdf0e10cSrcweir
124cdf0e10cSrcweir READ_SOCKET_LEN( &nReceiveHeaderType, 2, nHeaderReadSoFar );
125cdf0e10cSrcweir nReceiveHeaderType = NETWORD( nReceiveHeaderType );
126cdf0e10cSrcweir
127cdf0e10cSrcweir switch ( nReceiveHeaderType )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir case CH_SimpleMultiChannel:
130cdf0e10cSrcweir {
131cdf0e10cSrcweir READ_SOCKET_LEN( &nReceiveProtocol, 2, nHeaderReadSoFar );
132cdf0e10cSrcweir nReceiveProtocol = NETWORD( nReceiveProtocol );
133cdf0e10cSrcweir }
134cdf0e10cSrcweir break;
135cdf0e10cSrcweir case CH_Handshake:
136cdf0e10cSrcweir {
137cdf0e10cSrcweir }
138cdf0e10cSrcweir break;
139cdf0e10cSrcweir default:
140cdf0e10cSrcweir {
141cdf0e10cSrcweir DBG_ERROR("Unbekannter Headertyp in der Kommunikation");
142cdf0e10cSrcweir bWasError = sal_True;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir
145cdf0e10cSrcweir }
146cdf0e10cSrcweir
147cdf0e10cSrcweir if ( bWasError )
148cdf0e10cSrcweir return sal_False;
149cdf0e10cSrcweir
150cdf0e10cSrcweir /// L�ngen anpassen und ggf restheader �berlesen.
151cdf0e10cSrcweir while ( nHeaderBytes > nHeaderReadSoFar )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir unsigned char nDummy;
154cdf0e10cSrcweir READ_SOCKET_LEN( &nDummy, 1, nHeaderReadSoFar );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
157cdf0e10cSrcweir nReadSoFar += nHeaderReadSoFar;
158cdf0e10cSrcweir nBytes -= nReadSoFar;
159cdf0e10cSrcweir
160cdf0e10cSrcweir }
161cdf0e10cSrcweir
162cdf0e10cSrcweir /* @@@ Notes @@@
163cdf0e10cSrcweir *
164cdf0e10cSrcweir * 1) a 'void*' allocated via 'new char[]' is always deallocated
165cdf0e10cSrcweir * via plain 'delete()', not via array 'delete[]()'; it's just
166cdf0e10cSrcweir * raw memory.
167cdf0e10cSrcweir *
168cdf0e10cSrcweir * 2) as the caller of this routine later-on changes ownership
169cdf0e10cSrcweir * of 'pData' via 'SvMemoryStream::SetBuffer()' (in 'simplecm.cxx',
170cdf0e10cSrcweir * 'SimpleCommunicationLinkViaSocket::DoReceiveDataStream()'),
171cdf0e10cSrcweir * the allocator used here for 'void* pData' must match the
172cdf0e10cSrcweir * deallocator used in 'SvMemoryStream::FreeMemory()', i.e.
173cdf0e10cSrcweir * '::operator delete()'.
174cdf0e10cSrcweir */
175cdf0e10cSrcweir pData = ::operator new(nBytes);
176cdf0e10cSrcweir READ_SOCKET( pData, nBytes )
177cdf0e10cSrcweir if ( bWasError )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir ::operator delete(pData), pData = 0;
180cdf0e10cSrcweir return sal_False;
181cdf0e10cSrcweir }
182cdf0e10cSrcweir nLen = nBytes;
183cdf0e10cSrcweir }
184cdf0e10cSrcweir else
185cdf0e10cSrcweir bWasError = sal_True;
186cdf0e10cSrcweir
187cdf0e10cSrcweir return !bWasError;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
190cdf0e10cSrcweir /*#define WRITE_SOCKET( pBuffer, nLength )\
191cdf0e10cSrcweir if ( !bWasError )\
192cdf0e10cSrcweir bWasError |= !pStreamSocket || (pStreamSocket->write( pBuffer, nLength ) != nLength)*/
193cdf0e10cSrcweir
194cdf0e10cSrcweir #define WRITE_SOCKET( pBuffer, nLength )\
195cdf0e10cSrcweir if ( !bWasError )\
196cdf0e10cSrcweir {bWasError |= pTransmitter->TransferBytes( pBuffer, nLength ) != C_ERROR_NONE;}
197cdf0e10cSrcweir
198cdf0e10cSrcweir
199cdf0e10cSrcweir
TransferData(const void * pData,comm_UINT32 nLen,CMProtocol nProtocol)200cdf0e10cSrcweir comm_BOOL PacketHandler::TransferData( const void* pData, comm_UINT32 nLen, CMProtocol nProtocol )
201cdf0e10cSrcweir {
202cdf0e10cSrcweir comm_UINT32 nBuffer = nLen;
203cdf0e10cSrcweir comm_BOOL bWasError = sal_False;
204cdf0e10cSrcweir
205cdf0e10cSrcweir #ifndef FORCE_MULTI_CHANNEL_HEADERS
206cdf0e10cSrcweir if ( bMultiChannel )
207cdf0e10cSrcweir #endif
208cdf0e10cSrcweir nBuffer += 1+2+2+2; // f�r einen CH_SimpleMultiChannel
209cdf0e10cSrcweir
210cdf0e10cSrcweir #ifdef FORCE_MULTI_CHANNEL_HEADERS
211cdf0e10cSrcweir if ( !bMultiChannel )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir comm_UINT32 n32;
214cdf0e10cSrcweir n32 = 0xffffffff; // Umschalten auf MultiChannel
215cdf0e10cSrcweir n32 = NETDWORD( n32 );
216cdf0e10cSrcweir WRITE_SOCKET( &n32, 4 );
217cdf0e10cSrcweir }
218cdf0e10cSrcweir #endif
219cdf0e10cSrcweir
220cdf0e10cSrcweir
221cdf0e10cSrcweir comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
222cdf0e10cSrcweir WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
223cdf0e10cSrcweir
224cdf0e10cSrcweir
225cdf0e10cSrcweir #ifndef FORCE_MULTI_CHANNEL_HEADERS
226cdf0e10cSrcweir if ( bMultiChannel )
227cdf0e10cSrcweir #endif
228cdf0e10cSrcweir {
229cdf0e10cSrcweir comm_UINT16 n16;
230cdf0e10cSrcweir unsigned char c;
231cdf0e10cSrcweir
232cdf0e10cSrcweir c = CalcCheckByte( nBuffer );
233cdf0e10cSrcweir WRITE_SOCKET( &c, 1 );
234cdf0e10cSrcweir
235cdf0e10cSrcweir n16 = 4; // L�nge des Headers f�r einen CH_SimpleMultiChannel
236cdf0e10cSrcweir n16 = NETWORD( n16 );
237cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
238cdf0e10cSrcweir
239cdf0e10cSrcweir n16 = CH_SimpleMultiChannel; // Typ des Headers
240cdf0e10cSrcweir n16 = NETWORD( n16 );
241cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
242cdf0e10cSrcweir
243cdf0e10cSrcweir nProtocol = NETWORD( nProtocol );
244cdf0e10cSrcweir WRITE_SOCKET( &nProtocol, 2 );
245cdf0e10cSrcweir }
246cdf0e10cSrcweir
247cdf0e10cSrcweir WRITE_SOCKET( pData, nLen );
248cdf0e10cSrcweir return !bWasError;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
SendHandshake(HandshakeType aHandshakeType,const void * pData,comm_UINT32 nLen)251cdf0e10cSrcweir comm_BOOL PacketHandler::SendHandshake( HandshakeType aHandshakeType, const void* pData, comm_UINT32 nLen )
252cdf0e10cSrcweir {
253cdf0e10cSrcweir comm_BOOL bWasError = sal_False;
254cdf0e10cSrcweir
255cdf0e10cSrcweir comm_UINT32 nBuffer = 0;
256cdf0e10cSrcweir
257cdf0e10cSrcweir // if ( pMyManager->IsMultiChannel() ) Wir senden immer FFFFFFFF vorweg -> immer MultiChannel (Oder GPF bei �lteren)
258cdf0e10cSrcweir nBuffer += 1+2+2; // f�r einen CH_Handshake
259cdf0e10cSrcweir
260cdf0e10cSrcweir nBuffer += 2; // f�r den Typ des Handshakes
261cdf0e10cSrcweir
262cdf0e10cSrcweir switch ( aHandshakeType )
263cdf0e10cSrcweir {
264cdf0e10cSrcweir case CH_REQUEST_HandshakeAlive:
265cdf0e10cSrcweir nBuffer += 0; // Keine extra Daten
266cdf0e10cSrcweir break;
267cdf0e10cSrcweir case CH_RESPONSE_HandshakeAlive:
268cdf0e10cSrcweir nBuffer += 0; // Keine extra Daten
269cdf0e10cSrcweir break;
270cdf0e10cSrcweir case CH_REQUEST_ShutdownLink:
271cdf0e10cSrcweir nBuffer += 0; // Keine extra Daten
272cdf0e10cSrcweir break;
273cdf0e10cSrcweir case CH_ShutdownLink:
274cdf0e10cSrcweir nBuffer += 0; // Keine extra Daten
275cdf0e10cSrcweir break;
276cdf0e10cSrcweir case CH_SUPPORT_OPTIONS:
277cdf0e10cSrcweir nBuffer += 2 ; // one word extradata for options
278cdf0e10cSrcweir break;
279cdf0e10cSrcweir case CH_SetApplication:
280cdf0e10cSrcweir nBuffer += 0 ; // one word extradata for options
281cdf0e10cSrcweir break;
282cdf0e10cSrcweir default:
283cdf0e10cSrcweir DBG_ERROR("Unknown HandshakeType");
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir if ( pData )
287cdf0e10cSrcweir nBuffer += nLen; // Extra data in Buffer
288cdf0e10cSrcweir
289cdf0e10cSrcweir comm_UINT32 n32;
290cdf0e10cSrcweir n32 = 0xffffffff; // Umschalten auf MultiChannel
291cdf0e10cSrcweir n32 = NETDWORD( n32 );
292cdf0e10cSrcweir WRITE_SOCKET( &n32, 4 );
293cdf0e10cSrcweir
294cdf0e10cSrcweir comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
295cdf0e10cSrcweir WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
296cdf0e10cSrcweir
297cdf0e10cSrcweir
298cdf0e10cSrcweir comm_UINT16 n16;
299cdf0e10cSrcweir unsigned char c;
300cdf0e10cSrcweir
301cdf0e10cSrcweir c = CalcCheckByte( nBuffer );
302cdf0e10cSrcweir WRITE_SOCKET( &c, 1 );
303cdf0e10cSrcweir
304cdf0e10cSrcweir n16 = 2; // L�nge des Headers f�r einen CH_Handshake
305cdf0e10cSrcweir n16 = NETWORD( n16 );
306cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
307cdf0e10cSrcweir
308cdf0e10cSrcweir n16 = CH_Handshake; // Typ des Headers
309cdf0e10cSrcweir n16 = NETWORD( n16 );
310cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
311cdf0e10cSrcweir
312cdf0e10cSrcweir n16 = aHandshakeType; // Typ des Handshakes
313cdf0e10cSrcweir n16 = NETWORD( n16 );
314cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
315cdf0e10cSrcweir
316cdf0e10cSrcweir
317cdf0e10cSrcweir switch ( aHandshakeType )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir case CH_SUPPORT_OPTIONS:
320cdf0e10cSrcweir n16 = OPT_USE_SHUTDOWN_PROTOCOL;
321cdf0e10cSrcweir n16 = NETWORD( n16 );
322cdf0e10cSrcweir WRITE_SOCKET( &n16, 2 );
323cdf0e10cSrcweir break;
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
326cdf0e10cSrcweir if ( pData )
327cdf0e10cSrcweir WRITE_SOCKET( pData, nLen );
328cdf0e10cSrcweir
329cdf0e10cSrcweir return !bWasError;
330cdf0e10cSrcweir }
331