365 lines
13 KiB
C++
365 lines
13 KiB
C++
/*=============================================================================|
|
|
| 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
|