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 46cdf0e10cSrcweir PacketHandler::PacketHandler( ITransmiter* pTransmitter_, IReceiver* pReceiver_, comm_BOOL bMC ) 47cdf0e10cSrcweir : pTransmitter( pTransmitter_ ) 48cdf0e10cSrcweir , pReceiver( pReceiver_ ) 49cdf0e10cSrcweir , bMultiChannel( bMC ) 50cdf0e10cSrcweir { 51cdf0e10cSrcweir } 52cdf0e10cSrcweir 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 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 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 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