update dev300-m58
[ooovba.git] / automation / source / simplecm / packethandler.cxx
blobc0143a681e988c2703a086ba9a2da5b6991a2c48
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: packethandler.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_automation.hxx"
34 /*************************************************************************
36 * ATTENTION
37 * This file is intended to work inside and outside the StarOffice environment.
38 * Only adaption of file commtypes.hxx should be necessary. Else it is a bug!
40 ************************************************************************/
42 #include "packethandler.hxx"
43 #include <automation/commtypes.hxx>
44 #include <automation/commdefines.hxx>
45 #include "communiio.hxx"
47 /**
48 Forces switch to multichannel headers even for old communication Method
49 **/
50 #define FORCE_MULTI_CHANNEL_HEADERS
53 PacketHandler::PacketHandler( ITransmiter* pTransmitter_, IReceiver* pReceiver_, comm_BOOL bMC )
54 : pTransmitter( pTransmitter_ )
55 , pReceiver( pReceiver_ )
56 , bMultiChannel( bMC )
60 unsigned char PacketHandler::CalcCheckByte( comm_UINT32 nBytes )
62 comm_UINT16 nRes = 0;
63 nRes += HIBYTE( HIWORD( nBytes ) ) ^ 0xf0;
64 nRes += LOBYTE( HIWORD( nBytes ) ) ^ 0x0f;
65 nRes += HIBYTE( LOWORD( nBytes ) ) ^ 0xf0;
66 nRes += LOBYTE( LOWORD( nBytes ) ) ^ 0x0f;
68 nRes ^= HIBYTE( nRes );
70 return LOBYTE( nRes );
74 #define READ_SOCKET( pBuffer, nLength )\
75 if ( !bWasError )\
77 bWasError |= pReceiver->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;\
80 #define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
81 READ_SOCKET( pBuffer, nLength );\
82 if ( !bWasError )\
83 {nTotal += nLength;}
85 comm_BOOL PacketHandler::ReceiveData( void* &pData, comm_UINT32 &nLen )
87 DBG_ASSERT( !pData, "pData should be NULL -> memory leak" );
89 nLen = 0;
90 pData = NULL;
91 comm_BOOL bWasError = FALSE;
92 comm_BOOL bForceMultiChannelThisPacket = FALSE;
93 if ( pReceiver )
95 comm_UINT32 nBytes = 0;
96 nReceiveProtocol = CM_PROTOCOL_OLDSTYLE;
97 nReceiveHeaderType = CH_NoHeader;
99 READ_SOCKET( &nBytes, sizeof(nBytes) )
100 if ( bWasError )
101 return FALSE;
103 if ( 0xFFFFFFFF == nBytes ) // Expliziter Request für dieses Datenpaket auf MultiChannel umzuschalten
105 READ_SOCKET( &nBytes, sizeof(nBytes) )
106 if ( bWasError )
107 return FALSE;
108 bForceMultiChannelThisPacket = TRUE;
111 nBytes = NETDWORD( nBytes );
113 if ( bMultiChannel || bForceMultiChannelThisPacket )
115 comm_ULONG nReadSoFar = 0;
116 comm_ULONG nHeaderReadSoFar = 0;
118 // Prüfbyte für Längenangabe
119 unsigned char nLenCheck = 0;
120 READ_SOCKET_LEN( &nLenCheck, 1, nReadSoFar );
121 // Stimmt das Prüfbyte?
122 bWasError |= nLenCheck != CalcCheckByte( nBytes );
125 comm_UINT16 nHeaderBytes;
126 READ_SOCKET_LEN( &nHeaderBytes, 2, nReadSoFar );
127 nHeaderBytes = NETWORD( nHeaderBytes );
128 // reicht der Header über das Ende hinaus?
129 bWasError |= !(nBytes >= nReadSoFar + nHeaderBytes);
131 READ_SOCKET_LEN( &nReceiveHeaderType, 2, nHeaderReadSoFar );
132 nReceiveHeaderType = NETWORD( nReceiveHeaderType );
134 switch ( nReceiveHeaderType )
136 case CH_SimpleMultiChannel:
138 READ_SOCKET_LEN( &nReceiveProtocol, 2, nHeaderReadSoFar );
139 nReceiveProtocol = NETWORD( nReceiveProtocol );
141 break;
142 case CH_Handshake:
145 break;
146 default:
148 DBG_ERROR("Unbekannter Headertyp in der Kommunikation");
149 bWasError = TRUE;
154 if ( bWasError )
155 return FALSE;
157 /// Längen anpassen und ggf restheader überlesen.
158 while ( nHeaderBytes > nHeaderReadSoFar )
160 unsigned char nDummy;
161 READ_SOCKET_LEN( &nDummy, 1, nHeaderReadSoFar );
164 nReadSoFar += nHeaderReadSoFar;
165 nBytes -= nReadSoFar;
169 /* @@@ Notes @@@
171 * 1) a 'void*' allocated via 'new char[]' is always deallocated
172 * via plain 'delete()', not via array 'delete[]()'; it's just
173 * raw memory.
175 * 2) as the caller of this routine later-on changes ownership
176 * of 'pData' via 'SvMemoryStream::SetBuffer()' (in 'simplecm.cxx',
177 * 'SimpleCommunicationLinkViaSocket::DoReceiveDataStream()'),
178 * the allocator used here for 'void* pData' must match the
179 * deallocator used in 'SvMemoryStream::FreeMemory()', i.e.
180 * '::operator delete()'.
182 pData = ::operator new(nBytes);
183 READ_SOCKET( pData, nBytes )
184 if ( bWasError )
186 ::operator delete(pData), pData = 0;
187 return FALSE;
189 nLen = nBytes;
191 else
192 bWasError = TRUE;
194 return !bWasError;
197 /*#define WRITE_SOCKET( pBuffer, nLength )\
198 if ( !bWasError )\
199 bWasError |= !pStreamSocket || (pStreamSocket->write( pBuffer, nLength ) != nLength)*/
201 #define WRITE_SOCKET( pBuffer, nLength )\
202 if ( !bWasError )\
203 {bWasError |= pTransmitter->TransferBytes( pBuffer, nLength ) != C_ERROR_NONE;}
207 comm_BOOL PacketHandler::TransferData( const void* pData, comm_UINT32 nLen, CMProtocol nProtocol )
209 comm_UINT32 nBuffer = nLen;
210 comm_BOOL bWasError = FALSE;
212 #ifndef FORCE_MULTI_CHANNEL_HEADERS
213 if ( bMultiChannel )
214 #endif
215 nBuffer += 1+2+2+2; // für einen CH_SimpleMultiChannel
217 #ifdef FORCE_MULTI_CHANNEL_HEADERS
218 if ( !bMultiChannel )
220 comm_UINT32 n32;
221 n32 = 0xffffffff; // Umschalten auf MultiChannel
222 n32 = NETDWORD( n32 );
223 WRITE_SOCKET( &n32, 4 );
225 #endif
228 comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
229 WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
232 #ifndef FORCE_MULTI_CHANNEL_HEADERS
233 if ( bMultiChannel )
234 #endif
236 comm_UINT16 n16;
237 unsigned char c;
239 c = CalcCheckByte( nBuffer );
240 WRITE_SOCKET( &c, 1 );
242 n16 = 4; // Länge des Headers für einen CH_SimpleMultiChannel
243 n16 = NETWORD( n16 );
244 WRITE_SOCKET( &n16, 2 );
246 n16 = CH_SimpleMultiChannel; // Typ des Headers
247 n16 = NETWORD( n16 );
248 WRITE_SOCKET( &n16, 2 );
250 nProtocol = NETWORD( nProtocol );
251 WRITE_SOCKET( &nProtocol, 2 );
254 WRITE_SOCKET( pData, nLen );
255 return !bWasError;
258 comm_BOOL PacketHandler::SendHandshake( HandshakeType aHandshakeType, const void* pData, comm_UINT32 nLen )
260 comm_BOOL bWasError = FALSE;
262 comm_UINT32 nBuffer = 0;
264 // if ( pMyManager->IsMultiChannel() ) Wir senden immer FFFFFFFF vorweg -> immer MultiChannel (Oder GPF bei älteren)
265 nBuffer += 1+2+2; // für einen CH_Handshake
267 nBuffer += 2; // für den Typ des Handshakes
269 switch ( aHandshakeType )
271 case CH_REQUEST_HandshakeAlive:
272 nBuffer += 0; // Keine extra Daten
273 break;
274 case CH_RESPONSE_HandshakeAlive:
275 nBuffer += 0; // Keine extra Daten
276 break;
277 case CH_REQUEST_ShutdownLink:
278 nBuffer += 0; // Keine extra Daten
279 break;
280 case CH_ShutdownLink:
281 nBuffer += 0; // Keine extra Daten
282 break;
283 case CH_SUPPORT_OPTIONS:
284 nBuffer += 2 ; // one word extradata for options
285 break;
286 case CH_SetApplication:
287 nBuffer += 0 ; // one word extradata for options
288 break;
289 default:
290 DBG_ERROR("Unknown HandshakeType");
293 if ( pData )
294 nBuffer += nLen; // Extra data in Buffer
296 comm_UINT32 n32;
297 n32 = 0xffffffff; // Umschalten auf MultiChannel
298 n32 = NETDWORD( n32 );
299 WRITE_SOCKET( &n32, 4 );
301 comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
302 WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
305 comm_UINT16 n16;
306 unsigned char c;
308 c = CalcCheckByte( nBuffer );
309 WRITE_SOCKET( &c, 1 );
311 n16 = 2; // Länge des Headers für einen CH_Handshake
312 n16 = NETWORD( n16 );
313 WRITE_SOCKET( &n16, 2 );
315 n16 = CH_Handshake; // Typ des Headers
316 n16 = NETWORD( n16 );
317 WRITE_SOCKET( &n16, 2 );
319 n16 = aHandshakeType; // Typ des Handshakes
320 n16 = NETWORD( n16 );
321 WRITE_SOCKET( &n16, 2 );
324 switch ( aHandshakeType )
326 case CH_SUPPORT_OPTIONS:
327 n16 = OPT_USE_SHUTDOWN_PROTOCOL;
328 n16 = NETWORD( n16 );
329 WRITE_SOCKET( &n16, 2 );
330 break;
333 if ( pData )
334 WRITE_SOCKET( pData, nLen );
336 return !bWasError;