/*=============================================================================| | PROJECT SNAP7 1.3.0 | |==============================================================================| | Copyright (C) 2013, 2015 Davide Nardella | | All rights reserved. | |==============================================================================| | SNAP7 is free software: you can redistribute it and/or modify | | it under the terms of the Lesser GNU General Public License as published by | | the Free Software Foundation, either version 3 of the License, or | | (at your option) any later version. | | | | It means that you can distribute your commercial software linked with | | SNAP7 without the requirement to distribute the source code of your | | application and without the requirement that your application be itself | | distributed under LGPL. | | | | SNAP7 is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | Lesser GNU General Public License for more details. | | | | You should have received a copy of the GNU General Public License and a | | copy of Lesser GNU General Public License along with Snap7. | | If not, see http://www.gnu.org/licenses/ | |=============================================================================*/ #include "s7_peer.h" //--------------------------------------------------------------------------- TSnap7Peer::TSnap7Peer() { PDUH_out=PS7ReqHeader(&PDU.Payload); PDURequest=480; // Our request, FPDULength will contain the CPU answer LastError=0; cntword = 0; Destroying = false; } //--------------------------------------------------------------------------- TSnap7Peer::~TSnap7Peer() { Destroying = true; } //--------------------------------------------------------------------------- int TSnap7Peer::SetError(int Error) { if (Error==0) ClrError(); else LastError=Error | LastIsoError | LastTcpError; return Error; } //--------------------------------------------------------------------------- void TSnap7Peer::ClrError() { LastError=0; LastIsoError=0; LastTcpError=0; } //--------------------------------------------------------------------------- word TSnap7Peer::GetNextWord() { if (cntword==0xFFFF) cntword=0; return cntword++; } //--------------------------------------------------------------------------- int TSnap7Peer::NegotiatePDULength( ) { int Result, IsoSize = 0; PReqFunNegotiateParams ReqNegotiate; PResFunNegotiateParams ResNegotiate; PS7ResHeader23 Answer; ClrError(); // Setup Pointers ReqNegotiate = PReqFunNegotiateParams(pbyte(PDUH_out) + sizeof(TS7ReqHeader)); // Header PDUH_out->P = 0x32; // Always $32 PDUH_out->PDUType = PduType_request; // $01 PDUH_out->AB_EX = 0x0000; // Always $0000 PDUH_out->Sequence = GetNextWord(); // AutoInc PDUH_out->ParLen = SwapWord(sizeof(TReqFunNegotiateParams)); // 8 bytes PDUH_out->DataLen = 0x0000; // Params ReqNegotiate->FunNegotiate = pduNegotiate; ReqNegotiate->Unknown = 0x00; ReqNegotiate->ParallelJobs_1 = 0x0100; ReqNegotiate->ParallelJobs_2 = 0x0100; ReqNegotiate->PDULength = SwapWord(PDURequest); IsoSize = sizeof( TS7ReqHeader ) + sizeof( TReqFunNegotiateParams ); Result = isoExchangeBuffer(NULL, IsoSize); if ((Result == 0) && (IsoSize == int(sizeof(TS7ResHeader23) + sizeof(TResFunNegotiateParams)))) { // Setup pointers Answer = PS7ResHeader23(&PDU.Payload); ResNegotiate = PResFunNegotiateParams(pbyte(Answer) + sizeof(TS7ResHeader23)); if ( Answer->Error != 0 ) Result = SetError(errNegotiatingPDU); if ( Result == 0 ) PDULength = SwapWord(ResNegotiate->PDULength); } return Result; } //--------------------------------------------------------------------------- void TSnap7Peer::PeerDisconnect( ) { ClrError(); isoDisconnect(true); } //--------------------------------------------------------------------------- int TSnap7Peer::PeerConnect( ) { int Result; ClrError(); Result = isoConnect(); if (Result == 0) { Result = NegotiatePDULength(); if (Result != 0) PeerDisconnect(); } return Result; }