/*=============================================================================| | 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