File: s7_server.h

package info (click to toggle)
snap7 1.4.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 14,928 kB
  • sloc: cpp: 16,151; pascal: 5,295; cs: 2,246; ansic: 726; makefile: 271; xml: 2
file content (261 lines) | stat: -rw-r--r-- 10,189 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
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