1 /*=============================================================================|
2 |  PROJECT SNAP7                                                         1.3.0 |
3 |==============================================================================|
4 |  Copyright (C) 2013, 2015 Davide Nardella                                    |
5 |  All rights reserved.                                                        |
6 |==============================================================================|
7 |  SNAP7 is free software: you can redistribute it and/or modify               |
8 |  it under the terms of the Lesser GNU General Public License as published by |
9 |  the Free Software Foundation, either version 3 of the License, or           |
10 |  (at your option) any later version.                                         |
11 |                                                                              |
12 |  It means that you can distribute your commercial software linked with       |
13 |  SNAP7 without the requirement to distribute the source code of your         |
14 |  application and without the requirement that your application be itself     |
15 |  distributed under LGPL.                                                     |
16 |                                                                              |
17 |  SNAP7 is distributed in the hope that it will be useful,                    |
18 |  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
19 |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
20 |  Lesser GNU General Public License for more details.                         |
21 |                                                                              |
22 |  You should have received a copy of the GNU General Public License and a     |
23 |  copy of Lesser GNU General Public License along with Snap7.                 |
24 |  If not, see  http://www.gnu.org/licenses/                                   |
25 |=============================================================================*/
26 #ifndef s7_micro_client_h
27 #define s7_micro_client_h
28 //---------------------------------------------------------------------------
29 #include "s7_peer.h"
30 //---------------------------------------------------------------------------
31 
32 const longword errCliMask                   = 0xFFF00000;
33 const longword errCliBase                   = 0x000FFFFF;
34 
35 const longword errCliInvalidParams          = 0x00200000;
36 const longword errCliJobPending             = 0x00300000;
37 const longword errCliTooManyItems           = 0x00400000;
38 const longword errCliInvalidWordLen         = 0x00500000;
39 const longword errCliPartialDataWritten     = 0x00600000;
40 const longword errCliSizeOverPDU            = 0x00700000;
41 const longword errCliInvalidPlcAnswer       = 0x00800000;
42 const longword errCliAddressOutOfRange      = 0x00900000;
43 const longword errCliInvalidTransportSize   = 0x00A00000;
44 const longword errCliWriteDataSizeMismatch  = 0x00B00000;
45 const longword errCliItemNotAvailable       = 0x00C00000;
46 const longword errCliInvalidValue           = 0x00D00000;
47 const longword errCliCannotStartPLC         = 0x00E00000;
48 const longword errCliAlreadyRun             = 0x00F00000;
49 const longword errCliCannotStopPLC          = 0x01000000;
50 const longword errCliCannotCopyRamToRom     = 0x01100000;
51 const longword errCliCannotCompress         = 0x01200000;
52 const longword errCliAlreadyStop            = 0x01300000;
53 const longword errCliFunNotAvailable        = 0x01400000;
54 const longword errCliUploadSequenceFailed   = 0x01500000;
55 const longword errCliInvalidDataSizeRecvd   = 0x01600000;
56 const longword errCliInvalidBlockType       = 0x01700000;
57 const longword errCliInvalidBlockNumber     = 0x01800000;
58 const longword errCliInvalidBlockSize       = 0x01900000;
59 const longword errCliDownloadSequenceFailed = 0x01A00000;
60 const longword errCliInsertRefused          = 0x01B00000;
61 const longword errCliDeleteRefused          = 0x01C00000;
62 const longword errCliNeedPassword           = 0x01D00000;
63 const longword errCliInvalidPassword        = 0x01E00000;
64 const longword errCliNoPasswordToSetOrClear = 0x01F00000;
65 const longword errCliJobTimeout             = 0x02000000;
66 const longword errCliPartialDataRead        = 0x02100000;
67 const longword errCliBufferTooSmall         = 0x02200000;
68 const longword errCliFunctionRefused        = 0x02300000;
69 const longword errCliDestroying             = 0x02400000;
70 const longword errCliInvalidParamNumber     = 0x02500000;
71 const longword errCliCannotChangeParam      = 0x02600000;
72 
73 const time_t DeltaSecs = 441763200; // Seconds between 1970/1/1 (C time base) and 1984/1/1 (Siemens base)
74 
75 #pragma pack(1)
76 
77 // Read/Write Multivars
78 typedef struct{
79    int   Area;
80    int   WordLen;
81    int   Result;
82    int   DBNumber;
83    int   Start;
84    int   Amount;
85    void  *pdata;
86 } TS7DataItem, *PS7DataItem;
87 
88 typedef int TS7ResultItems[MaxVars];
89 typedef TS7ResultItems *PS7ResultItems;
90 
91 typedef struct {
92    int OBCount;
93    int FBCount;
94    int FCCount;
95    int SFBCount;
96    int SFCCount;
97    int DBCount;
98    int SDBCount;
99 } TS7BlocksList, *PS7BlocksList;
100 
101 typedef struct {
102    int BlkType;
103    int BlkNumber;
104    int BlkLang;
105    int BlkFlags;
106    int MC7Size;  // The real size in bytes
107    int LoadSize;
108    int LocalData;
109    int SBBLength;
110    int CheckSum;
111    int Version;
112    // Chars info
113    char CodeDate[11];
114    char IntfDate[11];
115    char Author[9];
116    char Family[9];
117    char Header[9];
118 } TS7BlockInfo, *PS7BlockInfo ;
119 
120 typedef word TS7BlocksOfType[0x2000];
121 typedef TS7BlocksOfType *PS7BlocksOfType;
122 
123 typedef struct {
124    char Code[21]; // Order Code
125    byte V1;       // Version V1.V2.V3
126    byte V2;
127    byte V3;
128 } TS7OrderCode, *PS7OrderCode;
129 
130 typedef struct {
131    char ModuleTypeName[33];
132    char SerialNumber[25];
133    char ASName[25];
134    char Copyright[27];
135    char ModuleName[25];
136 } TS7CpuInfo, *PS7CpuInfo;
137 
138 typedef struct {
139    int MaxPduLengt;
140    int MaxConnections;
141    int MaxMpiRate;
142    int MaxBusRate;
143 } TS7CpInfo, *PS7CpInfo;
144 
145 // See §33.1 of "System Software for S7-300/400 System and Standard Functions"
146 // and see SFC51 description too
147 typedef struct {
148    word LENTHDR;
149    word N_DR;
150 } SZL_HEADER, *PSZL_HEADER;
151 
152 typedef struct {
153    SZL_HEADER Header;
154    byte Data[0x4000-4];
155 } TS7SZL, *PS7SZL;
156 
157 // SZL List of available SZL IDs : same as SZL but List items are big-endian adjusted
158 typedef struct {
159    SZL_HEADER Header;
160    word List[0x2000-2];
161 } TS7SZLList, *PS7SZLList;
162 
163 // See §33.19 of "System Software for S7-300/400 System and Standard Functions"
164 typedef struct {
165    word  sch_schal;
166    word  sch_par;
167    word  sch_rel;
168    word  bart_sch;
169    word  anl_sch;
170 } TS7Protection, *PS7Protection;
171 
172 #define s7opNone               0
173 #define s7opReadArea           1
174 #define s7opWriteArea          2
175 #define s7opReadMultiVars      3
176 #define s7opWriteMultiVars     4
177 #define s7opDBGet              5
178 #define s7opUpload             6
179 #define s7opDownload           7
180 #define s7opDelete             8
181 #define s7opListBlocks         9
182 #define s7opAgBlockInfo       10
183 #define s7opListBlocksOfType  11
184 #define s7opReadSzlList       12
185 #define s7opReadSZL           13
186 #define s7opGetDateTime       14
187 #define s7opSetDateTime       15
188 #define s7opGetOrderCode      16
189 #define s7opGetCpuInfo        17
190 #define s7opGetCpInfo         18
191 #define s7opGetPlcStatus      19
192 #define s7opPlcHotStart       20
193 #define s7opPlcColdStart      21
194 #define s7opCopyRamToRom      22
195 #define s7opCompress          23
196 #define s7opPlcStop           24
197 #define s7opGetProtection     25
198 #define s7opSetPassword       26
199 #define s7opClearPassword     27
200 #define s7opDBFill            28
201 
202 // Param Number (to use with setparam)
203 
204 // Low level : change them to experiment new connections, their defaults normally work well
205 const int pc_iso_SendTimeout   = 6;
206 const int pc_iso_RecvTimeout   = 7;
207 const int pc_iso_ConnTimeout   = 8;
208 const int pc_iso_SrcRef        = 1;
209 const int pc_iso_DstRef        = 2;
210 const int pc_iso_SrcTSAP       = 3;
211 const int pc_iso_DstTSAP       = 4;
212 const int pc_iso_IsoPduSize    = 5;
213 
214 // Client Connection Type
215 const word CONNTYPE_PG         = 0x01;  // Connect to the PLC as a PG
216 const word CONNTYPE_OP         = 0x02;  // Connect to the PLC as an OP
217 const word CONNTYPE_BASIC      = 0x03;  // Basic connection
218 
219 #pragma pack()
220 
221 // Internal struct for operations
222 // Commands are not executed directly in the function such as "DBRead(...",
223 // but this struct is filled and then PerformOperation() is called.
224 // This allow us to implement async function very easily.
225 
226 struct TSnap7Job
227 {
228     int Op;        // Operation Code
229     int Result;    // Operation result
230     bool Pending;  // A Job is pending
231     longword Time; // Job Execution time
232     // Read/Write
233     int Area;      // Also used for Block type and Block of type
234     int Number;    // Used for DB Number, Block number
235     int Start;     // Offset start
236     int WordLen;   // Word length
237     // SZL
238     int ID;        // SZL ID
239     int Index;     // SZL Index
240     // ptr info
241     void * pData;  // User data pointer
242     int Amount;    // Items amount/Size in input
243     int *pAmount;  // Items amount/Size in output
244     // Generic
245     int IParam;   // Used for full upload and CopyRamToRom extended timeout
246 };
247 
248 class TSnap7MicroClient: public TSnap7Peer
249 {
250 private:
251     void FillTime(word SiemensTime, char *PTime);
252     byte BCDtoByte(byte B);
253     byte WordToBCD(word Value);
254     int opReadArea();
255     int opWriteArea();
256     int opReadMultiVars();
257     int opWriteMultiVars();
258     int opListBlocks();
259     int opListBlocksOfType();
260     int opAgBlockInfo();
261     int opDBGet();
262     int opDBFill();
263     int opUpload();
264     int opDownload();
265     int opDelete();
266     int opReadSZL();
267     int opReadSZLList();
268     int opGetDateTime();
269     int opSetDateTime();
270     int opGetOrderCode();
271     int opGetCpuInfo();
272     int opGetCpInfo();
273     int opGetPlcStatus();
274     int opPlcStop();
275     int opPlcHotStart();
276     int opPlcColdStart();
277     int opCopyRamToRom();
278     int opCompress();
279     int opGetProtection();
280     int opSetPassword();
281     int opClearPassword();
282     int CpuError(int Error);
283     longword DWordAt(void * P);
284     int CheckBlock(int BlockType, int BlockNum,  void *pBlock,  int Size);
285     int SubBlockToBlock(int SBB);
286 protected:
287     word ConnectionType;
288     longword JobStart;
289     TSnap7Job Job;
290     int DataSizeByte(int WordLength);
291     int opSize; // last operation size
292     int PerformOperation();
293 public:
294     TS7Buffer opData;
295 	TSnap7MicroClient();
296     ~TSnap7MicroClient();
297     int Reset(bool DoReconnect);
298     void SetConnectionParams(const char *RemAddress, word LocalTSAP, word RemoteTsap);
299     void SetConnectionType(word ConnType);
300 	int ConnectTo(const char *RemAddress, int Rack, int Slot);
301     int Connect();
302 	int Disconnect();
303 	int GetParam(int ParamNumber, void *pValue);
304 	int SetParam(int ParamNumber, void *pValue);
305     // Fundamental Data I/O functions
306     int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
307     int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void * pUsrData);
308     int ReadMultiVars(PS7DataItem Item, int ItemsCount);
309     int WriteMultiVars(PS7DataItem Item, int ItemsCount);
310     // Data I/O Helper functions
311     int DBRead(int DBNumber, int Start, int Size, void * pUsrData);
312     int DBWrite(int DBNumber, int Start, int Size, void * pUsrData);
313     int MBRead(int Start, int Size, void * pUsrData);
314     int MBWrite(int Start, int Size, void * pUsrData);
315     int EBRead(int Start, int Size, void * pUsrData);
316     int EBWrite(int Start, int Size, void * pUsrData);
317     int ABRead(int Start, int Size, void * pUsrData);
318     int ABWrite(int Start, int Size, void * pUsrData);
319     int TMRead(int Start, int Amount, void * pUsrData);
320     int TMWrite(int Start, int Amount, void * pUsrData);
321     int CTRead(int Start, int Amount, void * pUsrData);
322     int CTWrite(int Start, int Amount, void * pUsrData);
323     // Directory functions
324     int ListBlocks(PS7BlocksList pUsrData);
325     int GetAgBlockInfo(int BlockType, int BlockNum, PS7BlockInfo pUsrData);
326     int GetPgBlockInfo(void * pBlock, PS7BlockInfo pUsrData, int Size);
327     int ListBlocksOfType(int BlockType, TS7BlocksOfType *pUsrData, int & ItemsCount);
328     // Blocks functions
329     int Upload(int BlockType, int BlockNum, void * pUsrData, int & Size);
330     int FullUpload(int BlockType, int BlockNum, void * pUsrData, int & Size);
331     int Download(int BlockNum, void * pUsrData, int Size);
332     int Delete(int BlockType, int BlockNum);
333     int DBGet(int DBNumber, void * pUsrData, int & Size);
334     int DBFill(int DBNumber, int FillChar);
335     // Date/Time functions
336     int GetPlcDateTime(tm &DateTime);
337     int SetPlcDateTime(tm * DateTime);
338     int SetPlcSystemDateTime();
339     // System Info functions
340     int GetOrderCode(PS7OrderCode pUsrData);
341     int GetCpuInfo(PS7CpuInfo pUsrData);
342     int GetCpInfo(PS7CpInfo pUsrData);
343     int ReadSZL(int ID, int Index, PS7SZL pUsrData, int &Size);
344     int ReadSZLList(PS7SZLList pUsrData, int &ItemsCount);
345     // Control functions
346     int PlcHotStart();
347     int PlcColdStart();
348     int PlcStop();
349     int CopyRamToRom(int Timeout);
350     int Compress(int Timeout);
351     int GetPlcStatus(int &Status);
352     // Security functions
353     int GetProtection(PS7Protection pUsrData);
354     int SetSessionPassword(char *Password);
355     int ClearSessionPassword();
356     // Properties
Busy()357     bool Busy(){ return Job.Pending; };
Time()358     int Time(){ return int(Job.Time);}
359 };
360 
361 typedef TSnap7MicroClient *PSnap7MicroClient;
362 
363 //---------------------------------------------------------------------------
364 #endif // s7_micro_client_h
365