mirror of
https://github.com/thiagoralves/OpenPLC_v3.git
synced 2026-09-23 03:14:20 +08:00
Add files via upload
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,104 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_client_h
|
||||
#define s7_client_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "snap_threads.h"
|
||||
#include "s7_micro_client.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
typedef void (S7API *pfn_CliCompletion) (void * usrPtr, int opCode, int opResult);
|
||||
}
|
||||
class TSnap7Client;
|
||||
|
||||
class TClientThread: public TSnapThread
|
||||
{
|
||||
private:
|
||||
TSnap7Client * FClient;
|
||||
public:
|
||||
TClientThread(TSnap7Client *Client)
|
||||
{
|
||||
FClient = Client;
|
||||
}
|
||||
void Execute();
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
class TSnap7Client: public TSnap7MicroClient
|
||||
{
|
||||
private:
|
||||
TClientThread *FThread;
|
||||
bool ThreadCreated;
|
||||
void CloseThread();
|
||||
void OpenThread();
|
||||
void StartAsyncJob();
|
||||
protected:
|
||||
PSnapEvent EvtJob;
|
||||
PSnapEvent EvtComplete;
|
||||
pfn_CliCompletion CliCompletion;
|
||||
void *FUsrPtr;
|
||||
void DoCompletion();
|
||||
public:
|
||||
friend class TClientThread;
|
||||
TSnap7Client();
|
||||
~TSnap7Client();
|
||||
int Reset(bool DoReconnect);
|
||||
int SetAsCallback(pfn_CliCompletion pCompletion, void * usrPtr);
|
||||
int GetParam(int ParamNumber, void *pValue);
|
||||
int SetParam(int ParamNumber, void *pValue);
|
||||
// Async functions
|
||||
bool CheckAsCompletion( int & opResult);
|
||||
int WaitAsCompletion(unsigned long Timeout);
|
||||
int AsReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
|
||||
int AsWriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
|
||||
int AsListBlocksOfType(int BlockType, PS7BlocksOfType pUsrData, int & ItemsCount);
|
||||
int AsReadSZL(int ID, int Index, PS7SZL pUsrData, int & Size);
|
||||
int AsReadSZLList(PS7SZLList pUsrData, int &ItemsCount);
|
||||
int AsUpload(int BlockType, int BlockNum, void * pUsrData, int & Size);
|
||||
int AsFullUpload(int BlockType, int BlockNum, void * pUsrData, int & Size);
|
||||
int AsDownload(int BlockNum, void * pUsrData, int Size);
|
||||
int AsCopyRamToRom(int Timeout);
|
||||
int AsCompress(int Timeout);
|
||||
int AsDBRead(int DBNumber, int Start, int Size, void * pUsrData);
|
||||
int AsDBWrite(int DBNumber, int Start, int Size, void * pUsrData);
|
||||
int AsMBRead(int Start, int Size, void * pUsrData);
|
||||
int AsMBWrite(int Start, int Size, void * pUsrData);
|
||||
int AsEBRead(int Start, int Size, void * pUsrData);
|
||||
int AsEBWrite(int Start, int Size, void * pUsrData);
|
||||
int AsABRead(int Start, int Size, void * pUsrData);
|
||||
int AsABWrite(int Start, int Size, void * pUsrData);
|
||||
int AsTMRead(int Start, int Amount, void * pUsrData);
|
||||
int AsTMWrite(int Start, int Amount, void * pUsrData);
|
||||
int AsCTRead(int Start, int Amount, void * pUsrData);
|
||||
int AsCTWrite(int Start, int Amount, void * pUsrData);
|
||||
int AsDBGet(int DBNumber, void * pUsrData, int & Size);
|
||||
int AsDBFill(int DBNumber, int FillChar);
|
||||
};
|
||||
|
||||
typedef TSnap7Client *PSnap7Client;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // s7_client_h
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,271 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_isotcp_h
|
||||
#define s7_isotcp_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "snap_msgsock.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack(1)
|
||||
|
||||
#define isoTcpVersion 3 // RFC 1006
|
||||
#define isoTcpPort 102 // RFC 1006
|
||||
#define isoInvalidHandle 0
|
||||
#define MaxTSAPLength 16 // Max Lenght for Src and Dst TSAP
|
||||
#define MaxIsoFragments 64 // Max fragments
|
||||
#define IsoPayload_Size 4096 // Iso telegram Buffer size
|
||||
|
||||
#define noError 0
|
||||
|
||||
const longword errIsoMask = 0x000F0000;
|
||||
const longword errIsoBase = 0x0000FFFF;
|
||||
|
||||
const longword errIsoConnect = 0x00010000; // Connection error
|
||||
const longword errIsoDisconnect = 0x00020000; // Disconnect error
|
||||
const longword errIsoInvalidPDU = 0x00030000; // Bad format
|
||||
const longword errIsoInvalidDataSize = 0x00040000; // Bad Datasize passed to send/recv : buffer is invalid
|
||||
const longword errIsoNullPointer = 0x00050000; // Null passed as pointer
|
||||
const longword errIsoShortPacket = 0x00060000; // A short packet received
|
||||
const longword errIsoTooManyFragments = 0x00070000; // Too many packets without EoT flag
|
||||
const longword errIsoPduOverflow = 0x00080000; // The sum of fragments data exceded maximum packet size
|
||||
const longword errIsoSendPacket = 0x00090000; // An error occurred during send
|
||||
const longword errIsoRecvPacket = 0x000A0000; // An error occurred during recv
|
||||
const longword errIsoInvalidParams = 0x000B0000; // Invalid TSAP params
|
||||
const longword errIsoResvd_1 = 0x000C0000; // Unassigned
|
||||
const longword errIsoResvd_2 = 0x000D0000; // Unassigned
|
||||
const longword errIsoResvd_3 = 0x000E0000; // Unassigned
|
||||
const longword errIsoResvd_4 = 0x000F0000; // Unassigned
|
||||
|
||||
const longword ISO_OPT_TCP_NODELAY = 0x00000001; // Disable Nagle algorithm
|
||||
const longword ISO_OPT_INSIDE_MTU = 0x00000002; // Max packet size < MTU ethernet card
|
||||
|
||||
// TPKT Header - ISO on TCP - RFC 1006 (4 bytes)
|
||||
typedef struct{
|
||||
u_char Version; // Always 3 for RFC 1006
|
||||
u_char Reserved; // 0
|
||||
u_char HI_Lenght; // High part of packet lenght (entire frame, payload and TPDU included)
|
||||
u_char LO_Lenght; // Low part of packet lenght (entire frame, payload and TPDU included)
|
||||
} TTPKT; // Packet length : min 7 max 65535
|
||||
|
||||
typedef struct {
|
||||
u_char PduSizeCode;
|
||||
u_char PduSizeLen;
|
||||
u_char PduSizeVal;
|
||||
u_char TSAP[245]; // We don't know in advance these fields....
|
||||
} TCOPT_Params ;
|
||||
|
||||
// PDU Type constants - ISO 8073, not all are mentioned in RFC 1006
|
||||
// For our purposes we use only those labeled with **
|
||||
// These constants contains 4 low bit order 0 (credit nibble)
|
||||
//
|
||||
// $10 ED : Expedited Data
|
||||
// $20 EA : Expedited Data Ack
|
||||
// $40 UD : CLTP UD
|
||||
// $50 RJ : Reject
|
||||
// $70 AK : Ack data
|
||||
// ** $80 DR : Disconnect request (note : S7 doesn't use it)
|
||||
// ** $C0 DC : Disconnect confirm (note : S7 doesn't use it)
|
||||
// ** $D0 CC : Connection confirm
|
||||
// ** $E0 CR : Connection request
|
||||
// ** $F0 DT : Data
|
||||
//
|
||||
|
||||
// COTP Header for CONNECTION REQUEST/CONFIRM - DISCONNECT REQUEST/CONFIRM
|
||||
typedef struct {
|
||||
u_char HLength; // Header length : initialized to 6 (length without params - 1)
|
||||
// descending classes that add values in params field must update it.
|
||||
u_char PDUType; // 0xE0 Connection request
|
||||
// 0xD0 Connection confirm
|
||||
// 0x80 Disconnect request
|
||||
// 0xDC Disconnect confirm
|
||||
u_short DstRef; // Destination reference : Always 0x0000
|
||||
u_short SrcRef; // Source reference : Always 0x0000
|
||||
u_char CO_R; // If the telegram is used for Connection request/Confirm,
|
||||
// the meaning of this field is CLASS+OPTION :
|
||||
// Class (High 4 bits) + Option (Low 4 bits)
|
||||
// Class : Always 4 (0100) but is ignored in input (RFC States this)
|
||||
// Option : Always 0, also this in ignored.
|
||||
// If the telegram is used for Disconnect request,
|
||||
// the meaning of this field is REASON :
|
||||
// 1 Congestion at TSAP
|
||||
// 2 Session entity not attached to TSAP
|
||||
// 3 Address unknown (at TCP connect time)
|
||||
// 128+0 Normal disconnect initiated by the session
|
||||
// entity.
|
||||
// 128+1 Remote transport entity congestion at connect
|
||||
// request time
|
||||
// 128+3 Connection negotiation failed
|
||||
// 128+5 Protocol Error
|
||||
// 128+8 Connection request refused on this network
|
||||
// connection
|
||||
// Parameter data : depending on the protocol implementation.
|
||||
// ISO 8073 define several type of parameters, but RFC 1006 recognizes only
|
||||
// TSAP related parameters and PDU size. See RFC 0983 for more details.
|
||||
TCOPT_Params Params;
|
||||
/* Other params not used here, list only for completeness
|
||||
ACK_TIME = 0x85, 1000 0101 Acknowledge Time
|
||||
RES_ERROR = 0x86, 1000 0110 Residual Error Rate
|
||||
PRIORITY = 0x87, 1000 0111 Priority
|
||||
TRANSIT_DEL = 0x88, 1000 1000 Transit Delay
|
||||
THROUGHPUT = 0x89, 1000 1001 Throughput
|
||||
SEQ_NR = 0x8A, 1000 1010 Subsequence Number (in AK)
|
||||
REASSIGNMENT = 0x8B, 1000 1011 Reassignment Time
|
||||
FLOW_CNTL = 0x8C, 1000 1100 Flow Control Confirmation (in AK)
|
||||
TPDU_SIZE = 0xC0, 1100 0000 TPDU Size
|
||||
SRC_TSAP = 0xC1, 1100 0001 TSAP-ID / calling TSAP ( in CR/CC )
|
||||
DST_TSAP = 0xC2, 1100 0010 TSAP-ID / called TSAP
|
||||
CHECKSUM = 0xC3, 1100 0011 Checksum
|
||||
VERSION_NR = 0xC4, 1100 0100 Version Number
|
||||
PROTECTION = 0xC5, 1100 0101 Protection Parameters (user defined)
|
||||
OPT_SEL = 0xC6, 1100 0110 Additional Option Selection
|
||||
PROTO_CLASS = 0xC7, 1100 0111 Alternative Protocol Classes
|
||||
PREF_MAX_TPDU_SIZE = 0xF0, 1111 0000
|
||||
INACTIVITY_TIMER = 0xF2, 1111 0010
|
||||
ADDICC = 0xe0 1110 0000 Additional Information on Connection Clearing
|
||||
*/
|
||||
} TCOTP_CO ;
|
||||
typedef TCOTP_CO *PCOTP_CO;
|
||||
|
||||
// COTP Header for DATA EXCHANGE
|
||||
typedef struct {
|
||||
u_char HLength; // Header length : 3 for this header
|
||||
u_char PDUType; // 0xF0 for this header
|
||||
u_char EoT_Num; // EOT (bit 7) + PDU Number (bits 0..6)
|
||||
// EOT = 1 -> End of Trasmission Packet (This packet is complete)
|
||||
// PDU Number : Always 0
|
||||
} TCOTP_DT;
|
||||
typedef TCOTP_DT *PCOTP_DT;
|
||||
|
||||
// Info part of a PDU, only common parts. We use it to check the consistence
|
||||
// of a telegram regardless of it's nature (control or data).
|
||||
typedef struct {
|
||||
TTPKT TPKT; // TPKT Header
|
||||
// Common part of any COTP
|
||||
u_char HLength; // Header length : 3 for this header
|
||||
u_char PDUType; // Pdu type
|
||||
} TIsoHeaderInfo ;
|
||||
typedef TIsoHeaderInfo *PIsoHeaderInfo;
|
||||
|
||||
// PDU Type consts (Code + Credit)
|
||||
const byte pdu_type_CR = 0xE0; // Connection request
|
||||
const byte pdu_type_CC = 0xD0; // Connection confirm
|
||||
const byte pdu_type_DR = 0x80; // Disconnect request
|
||||
const byte pdu_type_DC = 0xC0; // Disconnect confirm
|
||||
const byte pdu_type_DT = 0xF0; // Data transfer
|
||||
|
||||
const byte pdu_EoT = 0x80; // End of Trasmission Packet (This packet is complete)
|
||||
|
||||
const longword DataHeaderSize = sizeof(TTPKT)+sizeof(TCOTP_DT);
|
||||
const longword IsoFrameSize = IsoPayload_Size+DataHeaderSize;
|
||||
|
||||
typedef struct {
|
||||
TTPKT TPKT; // TPKT Header
|
||||
TCOTP_CO COTP; // COPT Header for CONNECTION stuffs
|
||||
} TIsoControlPDU;
|
||||
typedef TIsoControlPDU *PIsoControlPDU;
|
||||
|
||||
typedef u_char TIsoPayload[IsoPayload_Size];
|
||||
|
||||
typedef struct {
|
||||
TTPKT TPKT; // TPKT Header
|
||||
TCOTP_DT COTP; // COPT Header for DATA EXCHANGE
|
||||
TIsoPayload Payload; // Payload
|
||||
} TIsoDataPDU ;
|
||||
|
||||
typedef TIsoDataPDU *PIsoDataPDU;
|
||||
typedef TIsoPayload *PIsoPayload;
|
||||
|
||||
typedef enum {
|
||||
pkConnectionRequest,
|
||||
pkDisconnectRequest,
|
||||
pkEmptyFragment,
|
||||
pkInvalidPDU,
|
||||
pkUnrecognizedType,
|
||||
pkValidData
|
||||
} TPDUKind ;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
void ErrIsoText(int Error, char *Msg, int len);
|
||||
|
||||
class TIsoTcpSocket : public TMsgSocket
|
||||
{
|
||||
private:
|
||||
|
||||
TIsoControlPDU FControlPDU;
|
||||
int IsoMaxFragments; // max fragments allowed for an ISO telegram
|
||||
// Checks the PDU format
|
||||
int CheckPDU(void *pPDU, u_char PduTypeExpected);
|
||||
// Receives the next fragment
|
||||
int isoRecvFragment(void *From, int Max, int &Size, bool &EoT);
|
||||
protected:
|
||||
TIsoDataPDU PDU;
|
||||
int SetIsoError(int Error);
|
||||
// Builds the control PDU starting from address properties
|
||||
virtual int BuildControlPDU();
|
||||
// Calcs the PDU size
|
||||
int PDUSize(void *pPDU);
|
||||
// Parses the connection request PDU to extract TSAP and PDU size info
|
||||
virtual void IsoParsePDU(TIsoControlPDU PDU);
|
||||
// Confirms the connection, override this method for special pourpose
|
||||
// By default it checks the PDU format and resend it changing the pdu type
|
||||
int IsoConfirmConnection(u_char PDUType);
|
||||
void ClrIsoError();
|
||||
virtual void FragmentSkipped(int Size);
|
||||
public:
|
||||
word SrcTSap; // Source TSAP
|
||||
word DstTSap; // Destination TSAP
|
||||
word SrcRef; // Source Reference
|
||||
word DstRef; // Destination Reference
|
||||
int IsoPDUSize;
|
||||
int LastIsoError;
|
||||
//--------------------------------------------------------------------------
|
||||
TIsoTcpSocket();
|
||||
~TIsoTcpSocket();
|
||||
// HIGH Level functions (work on payload hiding the underlying protocol)
|
||||
// Connects with a peer, the connection PDU is automatically built starting from address scheme (see below)
|
||||
int isoConnect();
|
||||
// Disconnects from a peer, if OnlyTCP = true, only a TCP disconnect is performed,
|
||||
// otherwise a disconnect PDU is built and send.
|
||||
int isoDisconnect(bool OnlyTCP);
|
||||
// Sends a buffer, a valid header is created
|
||||
int isoSendBuffer(void *Data, int Size);
|
||||
// Receives a buffer
|
||||
int isoRecvBuffer(void *Data, int & Size);
|
||||
// Exchange cycle send->receive
|
||||
int isoExchangeBuffer(void *Data, int & Size);
|
||||
// A PDU is ready (at least its header) to be read
|
||||
bool IsoPDUReady();
|
||||
// Same as isoSendBuffer, but the entire PDU has to be provided (in any case a check is performed)
|
||||
int isoSendPDU(PIsoDataPDU Data);
|
||||
// Same as isoRecvBuffer, but it returns the entire PDU, automatically enques the fragments
|
||||
int isoRecvPDU(PIsoDataPDU Data);
|
||||
// Same as isoExchangeBuffer, but the entire PDU has to be provided (in any case a check is performed)
|
||||
int isoExchangePDU(PIsoDataPDU Data);
|
||||
// Peeks an header info to know which kind of telegram is incoming
|
||||
void IsoPeek(void *pPDU, TPDUKind &PduKind);
|
||||
};
|
||||
|
||||
#endif // s7_isotcp_h
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,364 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_micro_client_h
|
||||
#define s7_micro_client_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "s7_peer.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const longword errCliMask = 0xFFF00000;
|
||||
const longword errCliBase = 0x000FFFFF;
|
||||
|
||||
const longword errCliInvalidParams = 0x00200000;
|
||||
const longword errCliJobPending = 0x00300000;
|
||||
const longword errCliTooManyItems = 0x00400000;
|
||||
const longword errCliInvalidWordLen = 0x00500000;
|
||||
const longword errCliPartialDataWritten = 0x00600000;
|
||||
const longword errCliSizeOverPDU = 0x00700000;
|
||||
const longword errCliInvalidPlcAnswer = 0x00800000;
|
||||
const longword errCliAddressOutOfRange = 0x00900000;
|
||||
const longword errCliInvalidTransportSize = 0x00A00000;
|
||||
const longword errCliWriteDataSizeMismatch = 0x00B00000;
|
||||
const longword errCliItemNotAvailable = 0x00C00000;
|
||||
const longword errCliInvalidValue = 0x00D00000;
|
||||
const longword errCliCannotStartPLC = 0x00E00000;
|
||||
const longword errCliAlreadyRun = 0x00F00000;
|
||||
const longword errCliCannotStopPLC = 0x01000000;
|
||||
const longword errCliCannotCopyRamToRom = 0x01100000;
|
||||
const longword errCliCannotCompress = 0x01200000;
|
||||
const longword errCliAlreadyStop = 0x01300000;
|
||||
const longword errCliFunNotAvailable = 0x01400000;
|
||||
const longword errCliUploadSequenceFailed = 0x01500000;
|
||||
const longword errCliInvalidDataSizeRecvd = 0x01600000;
|
||||
const longword errCliInvalidBlockType = 0x01700000;
|
||||
const longword errCliInvalidBlockNumber = 0x01800000;
|
||||
const longword errCliInvalidBlockSize = 0x01900000;
|
||||
const longword errCliDownloadSequenceFailed = 0x01A00000;
|
||||
const longword errCliInsertRefused = 0x01B00000;
|
||||
const longword errCliDeleteRefused = 0x01C00000;
|
||||
const longword errCliNeedPassword = 0x01D00000;
|
||||
const longword errCliInvalidPassword = 0x01E00000;
|
||||
const longword errCliNoPasswordToSetOrClear = 0x01F00000;
|
||||
const longword errCliJobTimeout = 0x02000000;
|
||||
const longword errCliPartialDataRead = 0x02100000;
|
||||
const longword errCliBufferTooSmall = 0x02200000;
|
||||
const longword errCliFunctionRefused = 0x02300000;
|
||||
const longword errCliDestroying = 0x02400000;
|
||||
const longword errCliInvalidParamNumber = 0x02500000;
|
||||
const longword errCliCannotChangeParam = 0x02600000;
|
||||
|
||||
const time_t DeltaSecs = 441763200; // Seconds between 1970/1/1 (C time base) and 1984/1/1 (Siemens base)
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// Read/Write Multivars
|
||||
typedef struct{
|
||||
int Area;
|
||||
int WordLen;
|
||||
int Result;
|
||||
int DBNumber;
|
||||
int Start;
|
||||
int Amount;
|
||||
void *pdata;
|
||||
} TS7DataItem, *PS7DataItem;
|
||||
|
||||
typedef int TS7ResultItems[MaxVars];
|
||||
typedef TS7ResultItems *PS7ResultItems;
|
||||
|
||||
typedef struct {
|
||||
int OBCount;
|
||||
int FBCount;
|
||||
int FCCount;
|
||||
int SFBCount;
|
||||
int SFCCount;
|
||||
int DBCount;
|
||||
int SDBCount;
|
||||
} TS7BlocksList, *PS7BlocksList;
|
||||
|
||||
typedef struct {
|
||||
int BlkType;
|
||||
int BlkNumber;
|
||||
int BlkLang;
|
||||
int BlkFlags;
|
||||
int MC7Size; // The real size in bytes
|
||||
int LoadSize;
|
||||
int LocalData;
|
||||
int SBBLength;
|
||||
int CheckSum;
|
||||
int Version;
|
||||
// Chars info
|
||||
char CodeDate[11];
|
||||
char IntfDate[11];
|
||||
char Author[9];
|
||||
char Family[9];
|
||||
char Header[9];
|
||||
} TS7BlockInfo, *PS7BlockInfo ;
|
||||
|
||||
typedef word TS7BlocksOfType[0x2000];
|
||||
typedef TS7BlocksOfType *PS7BlocksOfType;
|
||||
|
||||
typedef struct {
|
||||
char Code[21]; // Order Code
|
||||
byte V1; // Version V1.V2.V3
|
||||
byte V2;
|
||||
byte V3;
|
||||
} TS7OrderCode, *PS7OrderCode;
|
||||
|
||||
typedef struct {
|
||||
char ModuleTypeName[33];
|
||||
char SerialNumber[25];
|
||||
char ASName[25];
|
||||
char Copyright[27];
|
||||
char ModuleName[25];
|
||||
} TS7CpuInfo, *PS7CpuInfo;
|
||||
|
||||
typedef struct {
|
||||
int MaxPduLengt;
|
||||
int MaxConnections;
|
||||
int MaxMpiRate;
|
||||
int MaxBusRate;
|
||||
} TS7CpInfo, *PS7CpInfo;
|
||||
|
||||
// See §33.1 of "System Software for S7-300/400 System and Standard Functions"
|
||||
// and see SFC51 description too
|
||||
typedef struct {
|
||||
word LENTHDR;
|
||||
word N_DR;
|
||||
} SZL_HEADER, *PSZL_HEADER;
|
||||
|
||||
typedef struct {
|
||||
SZL_HEADER Header;
|
||||
byte Data[0x4000-4];
|
||||
} TS7SZL, *PS7SZL;
|
||||
|
||||
// SZL List of available SZL IDs : same as SZL but List items are big-endian adjusted
|
||||
typedef struct {
|
||||
SZL_HEADER Header;
|
||||
word List[0x2000-2];
|
||||
} TS7SZLList, *PS7SZLList;
|
||||
|
||||
// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
|
||||
typedef struct {
|
||||
word sch_schal;
|
||||
word sch_par;
|
||||
word sch_rel;
|
||||
word bart_sch;
|
||||
word anl_sch;
|
||||
} TS7Protection, *PS7Protection;
|
||||
|
||||
#define s7opNone 0
|
||||
#define s7opReadArea 1
|
||||
#define s7opWriteArea 2
|
||||
#define s7opReadMultiVars 3
|
||||
#define s7opWriteMultiVars 4
|
||||
#define s7opDBGet 5
|
||||
#define s7opUpload 6
|
||||
#define s7opDownload 7
|
||||
#define s7opDelete 8
|
||||
#define s7opListBlocks 9
|
||||
#define s7opAgBlockInfo 10
|
||||
#define s7opListBlocksOfType 11
|
||||
#define s7opReadSzlList 12
|
||||
#define s7opReadSZL 13
|
||||
#define s7opGetDateTime 14
|
||||
#define s7opSetDateTime 15
|
||||
#define s7opGetOrderCode 16
|
||||
#define s7opGetCpuInfo 17
|
||||
#define s7opGetCpInfo 18
|
||||
#define s7opGetPlcStatus 19
|
||||
#define s7opPlcHotStart 20
|
||||
#define s7opPlcColdStart 21
|
||||
#define s7opCopyRamToRom 22
|
||||
#define s7opCompress 23
|
||||
#define s7opPlcStop 24
|
||||
#define s7opGetProtection 25
|
||||
#define s7opSetPassword 26
|
||||
#define s7opClearPassword 27
|
||||
#define s7opDBFill 28
|
||||
|
||||
// Param Number (to use with setparam)
|
||||
|
||||
// Low level : change them to experiment new connections, their defaults normally work well
|
||||
const int pc_iso_SendTimeout = 6;
|
||||
const int pc_iso_RecvTimeout = 7;
|
||||
const int pc_iso_ConnTimeout = 8;
|
||||
const int pc_iso_SrcRef = 1;
|
||||
const int pc_iso_DstRef = 2;
|
||||
const int pc_iso_SrcTSAP = 3;
|
||||
const int pc_iso_DstTSAP = 4;
|
||||
const int pc_iso_IsoPduSize = 5;
|
||||
|
||||
// Client Connection Type
|
||||
const word CONNTYPE_PG = 0x01; // Connect to the PLC as a PG
|
||||
const word CONNTYPE_OP = 0x02; // Connect to the PLC as an OP
|
||||
const word CONNTYPE_BASIC = 0x03; // Basic connection
|
||||
|
||||
#pragma pack()
|
||||
|
||||
// Internal struct for operations
|
||||
// Commands are not executed directly in the function such as "DBRead(...",
|
||||
// but this struct is filled and then PerformOperation() is called.
|
||||
// This allow us to implement async function very easily.
|
||||
|
||||
struct TSnap7Job
|
||||
{
|
||||
int Op; // Operation Code
|
||||
int Result; // Operation result
|
||||
bool Pending; // A Job is pending
|
||||
longword Time; // Job Execution time
|
||||
// Read/Write
|
||||
int Area; // Also used for Block type and Block of type
|
||||
int Number; // Used for DB Number, Block number
|
||||
int Start; // Offset start
|
||||
int WordLen; // Word length
|
||||
// SZL
|
||||
int ID; // SZL ID
|
||||
int Index; // SZL Index
|
||||
// ptr info
|
||||
void * pData; // User data pointer
|
||||
int Amount; // Items amount/Size in input
|
||||
int *pAmount; // Items amount/Size in output
|
||||
// Generic
|
||||
int IParam; // Used for full upload and CopyRamToRom extended timeout
|
||||
};
|
||||
|
||||
class TSnap7MicroClient: public TSnap7Peer
|
||||
{
|
||||
private:
|
||||
void FillTime(word SiemensTime, char *PTime);
|
||||
byte BCDtoByte(byte B);
|
||||
byte WordToBCD(word Value);
|
||||
int opReadArea();
|
||||
int opWriteArea();
|
||||
int opReadMultiVars();
|
||||
int opWriteMultiVars();
|
||||
int opListBlocks();
|
||||
int opListBlocksOfType();
|
||||
int opAgBlockInfo();
|
||||
int opDBGet();
|
||||
int opDBFill();
|
||||
int opUpload();
|
||||
int opDownload();
|
||||
int opDelete();
|
||||
int opReadSZL();
|
||||
int opReadSZLList();
|
||||
int opGetDateTime();
|
||||
int opSetDateTime();
|
||||
int opGetOrderCode();
|
||||
int opGetCpuInfo();
|
||||
int opGetCpInfo();
|
||||
int opGetPlcStatus();
|
||||
int opPlcStop();
|
||||
int opPlcHotStart();
|
||||
int opPlcColdStart();
|
||||
int opCopyRamToRom();
|
||||
int opCompress();
|
||||
int opGetProtection();
|
||||
int opSetPassword();
|
||||
int opClearPassword();
|
||||
int CpuError(int Error);
|
||||
longword DWordAt(void * P);
|
||||
int CheckBlock(int BlockType, int BlockNum, void *pBlock, int Size);
|
||||
int SubBlockToBlock(int SBB);
|
||||
protected:
|
||||
word ConnectionType;
|
||||
longword JobStart;
|
||||
TSnap7Job Job;
|
||||
int DataSizeByte(int WordLength);
|
||||
int opSize; // last operation size
|
||||
int PerformOperation();
|
||||
public:
|
||||
TS7Buffer opData;
|
||||
TSnap7MicroClient();
|
||||
~TSnap7MicroClient();
|
||||
int Reset(bool DoReconnect);
|
||||
void SetConnectionParams(const char *RemAddress, word LocalTSAP, word RemoteTsap);
|
||||
void SetConnectionType(word ConnType);
|
||||
int ConnectTo(const char *RemAddress, int Rack, int Slot);
|
||||
int Connect();
|
||||
int Disconnect();
|
||||
int GetParam(int ParamNumber, void *pValue);
|
||||
int SetParam(int ParamNumber, void *pValue);
|
||||
// Fundamental Data I/O functions
|
||||
int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
|
||||
int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
|
||||
int ReadMultiVars(PS7DataItem Item, int ItemsCount);
|
||||
int WriteMultiVars(PS7DataItem Item, int ItemsCount);
|
||||
// Data I/O Helper functions
|
||||
int DBRead(int DBNumber, int Start, int Size, void * pUsrData);
|
||||
int DBWrite(int DBNumber, int Start, int Size, void * pUsrData);
|
||||
int MBRead(int Start, int Size, void * pUsrData);
|
||||
int MBWrite(int Start, int Size, void * pUsrData);
|
||||
int EBRead(int Start, int Size, void * pUsrData);
|
||||
int EBWrite(int Start, int Size, void * pUsrData);
|
||||
int ABRead(int Start, int Size, void * pUsrData);
|
||||
int ABWrite(int Start, int Size, void * pUsrData);
|
||||
int TMRead(int Start, int Amount, void * pUsrData);
|
||||
int TMWrite(int Start, int Amount, void * pUsrData);
|
||||
int CTRead(int Start, int Amount, void * pUsrData);
|
||||
int CTWrite(int Start, int Amount, void * pUsrData);
|
||||
// Directory functions
|
||||
int ListBlocks(PS7BlocksList pUsrData);
|
||||
int GetAgBlockInfo(int BlockType, int BlockNum, PS7BlockInfo pUsrData);
|
||||
int GetPgBlockInfo(void * pBlock, PS7BlockInfo pUsrData, int Size);
|
||||
int ListBlocksOfType(int BlockType, TS7BlocksOfType *pUsrData, int & ItemsCount);
|
||||
// Blocks functions
|
||||
int Upload(int BlockType, int BlockNum, void * pUsrData, int & Size);
|
||||
int FullUpload(int BlockType, int BlockNum, void * pUsrData, int & Size);
|
||||
int Download(int BlockNum, void * pUsrData, int Size);
|
||||
int Delete(int BlockType, int BlockNum);
|
||||
int DBGet(int DBNumber, void * pUsrData, int & Size);
|
||||
int DBFill(int DBNumber, int FillChar);
|
||||
// Date/Time functions
|
||||
int GetPlcDateTime(tm &DateTime);
|
||||
int SetPlcDateTime(tm * DateTime);
|
||||
int SetPlcSystemDateTime();
|
||||
// System Info functions
|
||||
int GetOrderCode(PS7OrderCode pUsrData);
|
||||
int GetCpuInfo(PS7CpuInfo pUsrData);
|
||||
int GetCpInfo(PS7CpInfo pUsrData);
|
||||
int ReadSZL(int ID, int Index, PS7SZL pUsrData, int &Size);
|
||||
int ReadSZLList(PS7SZLList pUsrData, int &ItemsCount);
|
||||
// Control functions
|
||||
int PlcHotStart();
|
||||
int PlcColdStart();
|
||||
int PlcStop();
|
||||
int CopyRamToRom(int Timeout);
|
||||
int Compress(int Timeout);
|
||||
int GetPlcStatus(int &Status);
|
||||
// Security functions
|
||||
int GetProtection(PS7Protection pUsrData);
|
||||
int SetSessionPassword(char *Password);
|
||||
int ClearSessionPassword();
|
||||
// Properties
|
||||
bool Busy(){ return Job.Pending; };
|
||||
int Time(){ return int(Job.Time);}
|
||||
};
|
||||
|
||||
typedef TSnap7MicroClient *PSnap7MicroClient;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // s7_micro_client_h
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,284 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_partner_h
|
||||
#define s7_partner_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "snap_threads.h"
|
||||
#include "s7_peer.h"
|
||||
//---------------------------------------------------------------------------
|
||||
using namespace std;
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define MaxPartners 256
|
||||
#define MaxAdapters 256
|
||||
#define csTimeout 1500 // Connection server destruction timeout
|
||||
|
||||
const int par_stopped = 0; // stopped
|
||||
const int par_connecting = 1; // running and active connecting
|
||||
const int par_waiting = 2; // running and waiting for a connection
|
||||
const int par_linked = 3; // running and connected
|
||||
const int par_sending = 4; // sending data
|
||||
const int par_receiving = 5; // receiving data
|
||||
const int par_binderror = 6; // error starting passive partner
|
||||
|
||||
const longword errParMask = 0xFFF00000;
|
||||
const longword errParBase = 0x000FFFFF;
|
||||
|
||||
const longword errParAddressInUse = 0x00200000;
|
||||
const longword errParNoRoom = 0x00300000;
|
||||
const longword errServerNoRoom = 0x00400000;
|
||||
const longword errParInvalidParams = 0x00500000;
|
||||
const longword errParNotLinked = 0x00600000;
|
||||
const longword errParBusy = 0x00700000;
|
||||
const longword errParFrameTimeout = 0x00800000;
|
||||
const longword errParInvalidPDU = 0x00900000;
|
||||
const longword errParSendTimeout = 0x00A00000;
|
||||
const longword errParRecvTimeout = 0x00B00000;
|
||||
const longword errParSendRefused = 0x00C00000;
|
||||
const longword errParNegotiatingPDU = 0x00D00000;
|
||||
const longword errParSendingBlock = 0x00E00000;
|
||||
const longword errParRecvingBlock = 0x00F00000;
|
||||
const longword errParBindError = 0x01000000;
|
||||
const longword errParDestroying = 0x01100000;
|
||||
const longword errParInvalidParamNumber = 0x01200000; // Invalid param (par_get/set_param)
|
||||
const longword errParCannotChangeParam = 0x01300000; // Cannot change because running
|
||||
const longword errParBufferTooSmall = 0x01400000; // Raised by LabVIEW wrapper
|
||||
|
||||
class TSnap7Partner;
|
||||
typedef TSnap7Partner *PSnap7Partner;
|
||||
|
||||
class TConnectionServer;
|
||||
typedef TConnectionServer *PConnectionServer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CONNECTION SERVERS MANAGER
|
||||
//------------------------------------------------------------------------------
|
||||
class TServersManager
|
||||
{
|
||||
private:
|
||||
PConnectionServer Servers[MaxAdapters];
|
||||
TSnapCriticalSection *cs;
|
||||
void Lock();
|
||||
void Unlock();
|
||||
int CreateServer(longword BindAddress, PConnectionServer &Server);
|
||||
void AddServer(PConnectionServer Server);
|
||||
public:
|
||||
int ServersCount;
|
||||
TServersManager();
|
||||
~TServersManager();
|
||||
|
||||
int GetServer(longword BindAddress, PConnectionServer &Server);
|
||||
void RemovePartner(PConnectionServer Server, PSnap7Partner Partner);
|
||||
|
||||
};
|
||||
typedef TServersManager *PServersManager;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CONNECTION SERVER (Don't inherit from TcpSrv to avoid dependence)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class TConnListenerThread : public TSnapThread
|
||||
{
|
||||
private:
|
||||
TMsgSocket *FListener;
|
||||
TConnectionServer *FServer;
|
||||
public:
|
||||
TConnListenerThread(TMsgSocket *Listener, TConnectionServer *Server)
|
||||
{
|
||||
FServer=Server;
|
||||
FListener=Listener;
|
||||
FreeOnTerminate=false;
|
||||
};
|
||||
void Execute();
|
||||
};
|
||||
typedef TConnListenerThread *PConnListenerThread;
|
||||
|
||||
|
||||
class TConnectionServer
|
||||
{
|
||||
private:
|
||||
TSnapCriticalSection *cs;
|
||||
bool FRunning;
|
||||
// Bind Address
|
||||
char FLocalAddress[16];
|
||||
// Server listener
|
||||
PConnListenerThread ServerThread;
|
||||
// Socket listener
|
||||
PMsgSocket SockListener;
|
||||
// Finds a partner bound to the address
|
||||
PSnap7Partner FindPartner(longword Address);
|
||||
// Locks the Partner list
|
||||
void Lock();
|
||||
// Unlocks the Partner list
|
||||
void Unlock();
|
||||
protected:
|
||||
// Workers list
|
||||
PSnap7Partner Partners[MaxPartners];
|
||||
bool Destroying;
|
||||
void Incoming(socket_t Sock);
|
||||
int Start();
|
||||
int FirstFree();
|
||||
public:
|
||||
int PartnersCount;
|
||||
longword LocalBind;
|
||||
TConnectionServer();
|
||||
~TConnectionServer();
|
||||
|
||||
int StartTo(const char *Address);
|
||||
void Stop();
|
||||
int RegisterPartner(PSnap7Partner Partner);
|
||||
void RemovePartner(PSnap7Partner Partner);
|
||||
friend class TConnListenerThread;
|
||||
};
|
||||
typedef TConnectionServer * PConnectionServer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PARTNER THREAD
|
||||
//------------------------------------------------------------------------------
|
||||
class TPartnerThread : public TSnapThread
|
||||
{
|
||||
private:
|
||||
TSnap7Partner *FPartner;
|
||||
longword FRecoveryTime;
|
||||
longword FKaElapsed;
|
||||
protected:
|
||||
void Execute();
|
||||
public:
|
||||
TPartnerThread(TSnap7Partner *Partner, longword RecoveryTime)
|
||||
{
|
||||
FPartner = Partner;
|
||||
FRecoveryTime =RecoveryTime;
|
||||
FreeOnTerminate =false;
|
||||
};
|
||||
~TPartnerThread(){};
|
||||
};
|
||||
typedef TPartnerThread *PPartnerThread;
|
||||
//------------------------------------------------------------------------------
|
||||
// S7 PARTNER
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef struct{
|
||||
bool First;
|
||||
bool Done;
|
||||
uintptr_t Offset;
|
||||
longword TotalLength;
|
||||
longword In_R_ID;
|
||||
longword Elapsed;
|
||||
byte Seq_Out;
|
||||
}TRecvStatus;
|
||||
|
||||
typedef struct{
|
||||
bool Done;
|
||||
int Size;
|
||||
int Result;
|
||||
longword R_ID;
|
||||
longword Count;
|
||||
}TRecvLast;
|
||||
|
||||
extern "C" {
|
||||
typedef void (S7API *pfn_ParBRecvCallBack)(void * usrPtr, int opResult, longword R_ID, void *pdata, int Size);
|
||||
typedef void (S7API *pfn_ParBSendCompletion)(void * usrPtr, int opResult);
|
||||
}
|
||||
|
||||
class TSnap7Partner : public TSnap7Peer
|
||||
{
|
||||
private:
|
||||
PS7ReqHeader PDUH_in;
|
||||
void *FRecvUsrPtr;
|
||||
void *FSendUsrPtr;
|
||||
PSnapEvent SendEvt;
|
||||
PSnapEvent RecvEvt;
|
||||
PConnectionServer FServer;
|
||||
PPartnerThread FWorkerThread;
|
||||
bool FSendPending;
|
||||
bool FRecvPending;
|
||||
TRecvStatus FRecvStatus;
|
||||
TRecvLast FRecvLast;
|
||||
TPendingBuffer TxBuffer;
|
||||
TPendingBuffer RxBuffer;
|
||||
longword FSendElapsed;
|
||||
bool BindError;
|
||||
byte NextByte;
|
||||
pfn_ParBRecvCallBack OnBRecv;
|
||||
pfn_ParBSendCompletion OnBSend;
|
||||
void ClearRecv();
|
||||
byte GetNextByte();
|
||||
void CloseWorker();
|
||||
bool BlockSend();
|
||||
bool PickData();
|
||||
bool BlockRecv();
|
||||
bool ConnectionConfirm();
|
||||
protected:
|
||||
bool Stopping;
|
||||
bool Execute();
|
||||
void Disconnect();
|
||||
bool ConnectToPeer();
|
||||
bool PerformFunctionNegotiate();
|
||||
public:
|
||||
bool Active;
|
||||
bool Running;
|
||||
longword PeerAddress;
|
||||
longword SrcAddress;
|
||||
int BRecvTimeout;
|
||||
int BSendTimeout;
|
||||
longword SendTime;
|
||||
longword RecvTime;
|
||||
longword RecoveryTime;
|
||||
longword KeepAliveTime;
|
||||
longword BytesSent;
|
||||
longword BytesRecv;
|
||||
longword SendErrors;
|
||||
longword RecvErrors;
|
||||
// The partner is linked when the init sequence is terminated
|
||||
//(TCP connection + ISO connection + PDU Length negotiation)
|
||||
bool Linked;
|
||||
TSnap7Partner(bool CreateActive);
|
||||
~TSnap7Partner();
|
||||
// Control
|
||||
int Start();
|
||||
int StartTo(const char *LocAddress, const char *RemAddress, word LocTsap, word RemTsap);
|
||||
int Stop();
|
||||
int Status();
|
||||
int GetParam(int ParamNumber, void * pValue);
|
||||
int SetParam(int ParamNumber, void * pValue);
|
||||
// Block send
|
||||
int BSend(longword R_ID, void *pUsrData, int Size);
|
||||
int AsBSend(longword R_ID, void *pUsrData, int Size);
|
||||
bool CheckAsBSendCompletion(int &opResult);
|
||||
int WaitAsBSendCompletion(longword Timeout);
|
||||
int SetSendCallback(pfn_ParBSendCompletion pCompletion, void *usrPtr);
|
||||
// Block recv
|
||||
int BRecv(longword &R_ID, void *pData, int &Size, longword Timeout);
|
||||
bool CheckAsBRecvCompletion(int &opResult, longword &R_ID,
|
||||
void *pData, int &Size);
|
||||
int SetRecvCallback(pfn_ParBRecvCallBack pCompletion, void *usrPtr);
|
||||
|
||||
friend class TConnectionServer;
|
||||
friend class TPartnerThread;
|
||||
};
|
||||
|
||||
|
||||
#endif // s7_partner_h
|
||||
@@ -0,0 +1,122 @@
|
||||
/*=============================================================================|
|
||||
| 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;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_peer_h
|
||||
#define s7_peer_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "s7_types.h"
|
||||
#include "s7_isotcp.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const longword errPeerMask = 0xFFF00000;
|
||||
const longword errPeerBase = 0x000FFFFF;
|
||||
const longword errNegotiatingPDU = 0x00100000;
|
||||
|
||||
class TSnap7Peer: public TIsoTcpSocket
|
||||
{
|
||||
private:
|
||||
word cntword;
|
||||
protected:
|
||||
bool Destroying;
|
||||
PS7ReqHeader PDUH_out;
|
||||
word GetNextWord();
|
||||
int SetError(int Error);
|
||||
int NegotiatePDULength();
|
||||
void ClrError();
|
||||
public:
|
||||
int LastError;
|
||||
int PDULength;
|
||||
int PDURequest;
|
||||
TSnap7Peer();
|
||||
~TSnap7Peer();
|
||||
void PeerDisconnect();
|
||||
int PeerConnect();
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_server_h
|
||||
#define s7_server_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "snap_tcpsrvr.h"
|
||||
#include "s7_types.h"
|
||||
#include "s7_isotcp.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Maximum number of DB, change it to increase/decrease the limit.
|
||||
// The DB table size is 12*MaxDB bytes
|
||||
|
||||
#define MaxDB 2048 // Like a S7 318
|
||||
#define MinPduSize 240
|
||||
#define CPU315PduSize 240
|
||||
//---------------------------------------------------------------------------
|
||||
// Server Interface errors
|
||||
const longword errSrvDBNullPointer = 0x00200000; // Pssed null as PData
|
||||
const longword errSrvAreaAlreadyExists = 0x00300000; // Area Re-registration
|
||||
const longword errSrvUnknownArea = 0x00400000; // Unknown area
|
||||
const longword errSrvInvalidParams = 0x00500000; // Invalid param(s) supplied
|
||||
const longword errSrvTooManyDB = 0x00600000; // Cannot register DB
|
||||
const longword errSrvInvalidParamNumber = 0x00700000; // Invalid param (srv_get/set_param)
|
||||
const longword errSrvCannotChangeParam = 0x00800000; // Cannot change because running
|
||||
|
||||
// Server Area ID (use with Register/unregister - Lock/unlock Area)
|
||||
const int srvAreaPE = 0;
|
||||
const int srvAreaPA = 1;
|
||||
const int srvAreaMK = 2;
|
||||
const int srvAreaCT = 3;
|
||||
const int srvAreaTM = 4;
|
||||
const int srvAreaDB = 5;
|
||||
|
||||
typedef struct{
|
||||
word Number; // Number (only for DB)
|
||||
word Size; // Area size (in bytes)
|
||||
pbyte PData; // Pointer to area
|
||||
PSnapCriticalSection cs;
|
||||
}TS7Area, *PS7Area;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ISOTCP WORKER CLASS
|
||||
//------------------------------------------------------------------------------
|
||||
class TIsoTcpWorker : public TIsoTcpSocket
|
||||
{
|
||||
protected:
|
||||
virtual bool IsoPerformCommand(int &Size);
|
||||
virtual bool ExecuteSend();
|
||||
virtual bool ExecuteRecv();
|
||||
public:
|
||||
TIsoTcpWorker(){};
|
||||
~TIsoTcpWorker(){};
|
||||
// Worker execution
|
||||
bool Execute();
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
// S7 WORKER CLASS
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// SZL frame
|
||||
typedef struct{
|
||||
TS7Answer17 Answer;
|
||||
PReqFunReadSZLFirst ReqParams;
|
||||
PS7ReqSZLData ReqData;
|
||||
PS7ResParams7 ResParams;
|
||||
pbyte ResData;
|
||||
int ID;
|
||||
int Index;
|
||||
bool SZLDone;
|
||||
}TSZL;
|
||||
|
||||
// Current Event Info
|
||||
typedef struct{
|
||||
word EvRetCode;
|
||||
word EvArea;
|
||||
word EvIndex;
|
||||
word EvStart;
|
||||
word EvSize;
|
||||
}TEv;
|
||||
|
||||
// Current Block info
|
||||
typedef struct{
|
||||
PReqFunGetBlockInfo ReqParams;
|
||||
PResFunGetBlockInfo ResParams;
|
||||
TS7Answer17 Answer;
|
||||
word evError;
|
||||
word DataLength;
|
||||
}TCB;
|
||||
|
||||
class TSnap7Server; // forward declaration
|
||||
|
||||
class TS7Worker : public TIsoTcpWorker
|
||||
{
|
||||
private:
|
||||
PS7ReqHeader PDUH_in;
|
||||
int DBCnt;
|
||||
byte LastBlk;
|
||||
TSZL SZL;
|
||||
byte BCD(word Value);
|
||||
// Checks the consistence of the incoming PDU
|
||||
bool CheckPDU_in(int PayloadSize);
|
||||
void FillTime(PS7Time PTime);
|
||||
protected:
|
||||
int DataSizeByte(int WordLength);
|
||||
bool ExecuteRecv();
|
||||
void DoEvent(longword Code, word RetCode, word Param1, word Param2,
|
||||
word Param3, word Param4);
|
||||
void DoReadEvent(longword Code, word RetCode, word Param1, word Param2,
|
||||
word Param3, word Param4);
|
||||
void FragmentSkipped(int Size);
|
||||
// Entry parse
|
||||
bool IsoPerformCommand(int &Size);
|
||||
// First stage parse
|
||||
bool PerformPDUAck(int &Size);
|
||||
bool PerformPDURequest(int &Size);
|
||||
bool PerformPDUUsrData(int &Size);
|
||||
// Second stage parse : PDU Request
|
||||
PS7Area GetArea(byte S7Code, word index);
|
||||
// Group Read Area
|
||||
bool PerformFunctionRead();
|
||||
// Subfunctions Read Data
|
||||
word ReadArea(PResFunReadItem ResItemData, PReqFunReadItem ReqItemPar,
|
||||
int &PDURemainder,TEv &EV);
|
||||
word RA_NotFound(PResFunReadItem ResItem, TEv &EV);
|
||||
word RA_OutOfRange(PResFunReadItem ResItem, TEv &EV);
|
||||
word RA_SizeOverPDU(PResFunReadItem ResItem, TEv &EV);
|
||||
// Group Write Area
|
||||
bool PerformFunctionWrite();
|
||||
// Subfunctions Write Data
|
||||
byte WriteArea(PReqFunWriteDataItem ReqItemData, PReqFunWriteItem ReqItemPar,
|
||||
TEv &EV);
|
||||
byte WA_NotFound(TEv &EV);
|
||||
byte WA_InvalidTransportSize(TEv &EV);
|
||||
byte WA_OutOfRange(TEv &EV);
|
||||
byte WA_DataSizeMismatch(TEv &EV);
|
||||
// Negotiate PDU Length
|
||||
bool PerformFunctionNegotiate();
|
||||
// Control
|
||||
bool PerformFunctionControl(byte PduFun);
|
||||
// Up/Download
|
||||
bool PerformFunctionUpload();
|
||||
bool PerformFunctionDownload();
|
||||
// Second stage parse : PDU User data
|
||||
bool PerformGroupProgrammer();
|
||||
bool PerformGroupCyclicData();
|
||||
bool PerformGroupSecurity();
|
||||
// Group Block(s) Info
|
||||
bool PerformGroupBlockInfo();
|
||||
// Subfunctions Block info
|
||||
void BLK_ListAll(TCB &CB);
|
||||
void BLK_ListBoT(byte BlockType, bool Start, TCB &CB);
|
||||
void BLK_NoResource_ListBoT(PDataFunGetBot Data, TCB &CB);
|
||||
void BLK_GetBlkInfo(TCB &CB);
|
||||
void BLK_NoResource_GetBlkInfo(PResDataBlockInfo Data, TCB &CB);
|
||||
void BLK_GetBlockNum_GetBlkInfo(int &BlkNum, PReqDataBlockInfo ReqData);
|
||||
void BLK_DoBlockInfo_GetBlkInfo(PS7Area DB, PResDataBlockInfo Data, TCB &CB);
|
||||
// Clock Group
|
||||
bool PerformGetClock();
|
||||
bool PerformSetClock();
|
||||
// SZL Group
|
||||
bool PerformGroupSZL();
|
||||
// Subfunctions (called by PerformGroupSZL)
|
||||
void SZLNotAvailable();
|
||||
void SZLSystemState();
|
||||
void SZLData(void *P, int len);
|
||||
void SZL_ID424();
|
||||
void SZL_ID131_IDX003();
|
||||
public:
|
||||
TSnap7Server *FServer;
|
||||
int FPDULength;
|
||||
TS7Worker();
|
||||
~TS7Worker(){};
|
||||
};
|
||||
|
||||
typedef TS7Worker *PS7Worker;
|
||||
//------------------------------------------------------------------------------
|
||||
// S7 SERVER CLASS
|
||||
//------------------------------------------------------------------------------
|
||||
extern "C"
|
||||
{
|
||||
typedef int (S7API *pfn_RWAreaCallBack)(void *usrPtr, int Sender, int Operation, PS7Tag PTag, void *pUsrData);
|
||||
}
|
||||
const int OperationRead = 0;
|
||||
const int OperationWrite = 1;
|
||||
|
||||
class TSnap7Server : public TCustomMsgServer
|
||||
{
|
||||
private:
|
||||
// Read Callback related
|
||||
pfn_SrvCallBack OnReadEvent;
|
||||
pfn_RWAreaCallBack OnRWArea;
|
||||
// Critical section to lock Read/Write Hook Area
|
||||
PSnapCriticalSection CSRWHook;
|
||||
void *FReadUsrPtr;
|
||||
void *FRWAreaUsrPtr;
|
||||
void DisposeAll();
|
||||
int FindFirstFreeDB();
|
||||
int IndexOfDB(word DBNumber);
|
||||
protected:
|
||||
int DBCount;
|
||||
int DBLimit;
|
||||
PS7Area DB[MaxDB]; // DB
|
||||
PS7Area HA[5]; // MK,PE,PA,TM,CT
|
||||
PS7Area FindDB(word DBNumber);
|
||||
PWorkerSocket CreateWorkerSocket(socket_t Sock);
|
||||
bool ResourceLess;
|
||||
word ForcePDU;
|
||||
int RegisterDB(word Number, void *pUsrData, word Size);
|
||||
int RegisterSys(int AreaCode, void *pUsrData, word Size);
|
||||
int UnregisterDB(word DBNumber);
|
||||
int UnregisterSys(int AreaCode);
|
||||
// The Read event
|
||||
void DoReadEvent(int Sender, longword Code, word RetCode, word Param1,
|
||||
word Param2, word Param3, word Param4);
|
||||
bool DoReadArea(int Sender, int Area, int DBNumber, int Start, int Size, int WordLen, void *pUsrData);
|
||||
bool DoWriteArea(int Sender, int Area, int DBNumber, int Start, int Size, int WordLen, void *pUsrData);
|
||||
public:
|
||||
int WorkInterval;
|
||||
byte CpuStatus;
|
||||
TSnap7Server();
|
||||
~TSnap7Server();
|
||||
int StartTo(const char *Address);
|
||||
int GetParam(int ParamNumber, void *pValue);
|
||||
int SetParam(int ParamNumber, void *pValue);
|
||||
int RegisterArea(int AreaCode, word Index, void *pUsrData, word Size);
|
||||
int UnregisterArea(int AreaCode, word Index);
|
||||
int LockArea(int AreaCode, word DBNumber);
|
||||
int UnlockArea(int AreaCode, word DBNumber);
|
||||
// Sets Event callback
|
||||
int SetReadEventsCallBack(pfn_SrvCallBack PCallBack, void *UsrPtr);
|
||||
int SetRWAreaCallBack(pfn_RWAreaCallBack PCallBack, void *UsrPtr);
|
||||
friend class TS7Worker;
|
||||
};
|
||||
typedef TSnap7Server *PSnap7Server;
|
||||
|
||||
#endif // s7_server_h
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
/*=============================================================================|
|
||||
| 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/ |
|
||||
|=============================================================================*/
|
||||
#ifndef s7_text_h
|
||||
#define s7_text_h
|
||||
//---------------------------------------------------------------------------
|
||||
#include "s7_micro_client.h"
|
||||
#include "s7_server.h"
|
||||
#include "s7_partner.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const int errLibInvalidParam = -1;
|
||||
const int errLibInvalidObject = -2;
|
||||
// Errors areas definition
|
||||
const longword ErrTcpMask = 0x0000FFFF;
|
||||
const longword ErrIsoMask = 0x000F0000;
|
||||
const longword ErrS7Mask = 0xFFF00000;
|
||||
|
||||
char* ErrCliText(int Error, char* Result, int TextLen);
|
||||
char* ErrSrvText(int Error, char* Result, int TextLen);
|
||||
char* ErrParText(int Error, char* Result, int TextLen);
|
||||
char* EvtSrvText(TSrvEvent &Event, char* Result, int TextLen);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user