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_server_h 27 #define s7_server_h 28 //--------------------------------------------------------------------------- 29 #include "snap_tcpsrvr.h" 30 #include "s7_types.h" 31 #include "s7_isotcp.h" 32 //--------------------------------------------------------------------------- 33 34 // Maximum number of DB, change it to increase/decrease the limit. 35 // The DB table size is 12*MaxDB bytes 36 37 #define MaxDB 2048 // Like a S7 318 38 #define MinPduSize 240 39 #define CPU315PduSize 240 40 //--------------------------------------------------------------------------- 41 // Server Interface errors 42 const longword errSrvDBNullPointer = 0x00200000; // Pssed null as PData 43 const longword errSrvAreaAlreadyExists = 0x00300000; // Area Re-registration 44 const longword errSrvUnknownArea = 0x00400000; // Unknown area 45 const longword errSrvInvalidParams = 0x00500000; // Invalid param(s) supplied 46 const longword errSrvTooManyDB = 0x00600000; // Cannot register DB 47 const longword errSrvInvalidParamNumber = 0x00700000; // Invalid param (srv_get/set_param) 48 const longword errSrvCannotChangeParam = 0x00800000; // Cannot change because running 49 50 // Server Area ID (use with Register/unregister - Lock/unlock Area) 51 const int srvAreaPE = 0; 52 const int srvAreaPA = 1; 53 const int srvAreaMK = 2; 54 const int srvAreaCT = 3; 55 const int srvAreaTM = 4; 56 const int srvAreaDB = 5; 57 58 typedef struct{ 59 word Number; // Number (only for DB) 60 word Size; // Area size (in bytes) 61 pbyte PData; // Pointer to area 62 PSnapCriticalSection cs; 63 }TS7Area, *PS7Area; 64 65 //------------------------------------------------------------------------------ 66 // ISOTCP WORKER CLASS 67 //------------------------------------------------------------------------------ 68 class TIsoTcpWorker : public TIsoTcpSocket 69 { 70 protected: 71 virtual bool IsoPerformCommand(int &Size); 72 virtual bool ExecuteSend(); 73 virtual bool ExecuteRecv(); 74 public: TIsoTcpWorker()75 TIsoTcpWorker(){}; ~TIsoTcpWorker()76 ~TIsoTcpWorker(){}; 77 // Worker execution 78 bool Execute(); 79 }; 80 //------------------------------------------------------------------------------ 81 // S7 WORKER CLASS 82 //------------------------------------------------------------------------------ 83 84 // SZL frame 85 typedef struct{ 86 TS7Answer17 Answer; 87 PReqFunReadSZLFirst ReqParams; 88 PS7ReqSZLData ReqData; 89 PS7ResParams7 ResParams; 90 pbyte ResData; 91 int ID; 92 int Index; 93 bool SZLDone; 94 }TSZL; 95 96 // Current Event Info 97 typedef struct{ 98 word EvRetCode; 99 word EvArea; 100 word EvIndex; 101 word EvStart; 102 word EvSize; 103 }TEv; 104 105 // Current Block info 106 typedef struct{ 107 PReqFunGetBlockInfo ReqParams; 108 PResFunGetBlockInfo ResParams; 109 TS7Answer17 Answer; 110 word evError; 111 word DataLength; 112 }TCB; 113 114 class TSnap7Server; // forward declaration 115 116 class TS7Worker : public TIsoTcpWorker 117 { 118 private: 119 PS7ReqHeader PDUH_in; 120 int DBCnt; 121 byte LastBlk; 122 TSZL SZL; 123 byte BCD(word Value); 124 // Checks the consistence of the incoming PDU 125 bool CheckPDU_in(int PayloadSize); 126 void FillTime(PS7Time PTime); 127 protected: 128 int DataSizeByte(int WordLength); 129 bool ExecuteRecv(); 130 void DoEvent(longword Code, word RetCode, word Param1, word Param2, 131 word Param3, word Param4); 132 void DoReadEvent(longword Code, word RetCode, word Param1, word Param2, 133 word Param3, word Param4); 134 void FragmentSkipped(int Size); 135 // Entry parse 136 bool IsoPerformCommand(int &Size); 137 // First stage parse 138 bool PerformPDUAck(int &Size); 139 bool PerformPDURequest(int &Size); 140 bool PerformPDUUsrData(int &Size); 141 // Second stage parse : PDU Request 142 PS7Area GetArea(byte S7Code, word index); 143 // Group Read Area 144 bool PerformFunctionRead(); 145 // Subfunctions Read Data 146 word ReadArea(PResFunReadItem ResItemData, PReqFunReadItem ReqItemPar, 147 int &PDURemainder,TEv &EV); 148 word RA_NotFound(PResFunReadItem ResItem, TEv &EV); 149 word RA_OutOfRange(PResFunReadItem ResItem, TEv &EV); 150 word RA_SizeOverPDU(PResFunReadItem ResItem, TEv &EV); 151 // Group Write Area 152 bool PerformFunctionWrite(); 153 // Subfunctions Write Data 154 byte WriteArea(PReqFunWriteDataItem ReqItemData, PReqFunWriteItem ReqItemPar, 155 TEv &EV); 156 byte WA_NotFound(TEv &EV); 157 byte WA_InvalidTransportSize(TEv &EV); 158 byte WA_OutOfRange(TEv &EV); 159 byte WA_DataSizeMismatch(TEv &EV); 160 // Negotiate PDU Length 161 bool PerformFunctionNegotiate(); 162 // Control 163 bool PerformFunctionControl(byte PduFun); 164 // Up/Download 165 bool PerformFunctionUpload(); 166 bool PerformFunctionDownload(); 167 // Second stage parse : PDU User data 168 bool PerformGroupProgrammer(); 169 bool PerformGroupCyclicData(); 170 bool PerformGroupSecurity(); 171 // Group Block(s) Info 172 bool PerformGroupBlockInfo(); 173 // Subfunctions Block info 174 void BLK_ListAll(TCB &CB); 175 void BLK_ListBoT(byte BlockType, bool Start, TCB &CB); 176 void BLK_NoResource_ListBoT(PDataFunGetBot Data, TCB &CB); 177 void BLK_GetBlkInfo(TCB &CB); 178 void BLK_NoResource_GetBlkInfo(PResDataBlockInfo Data, TCB &CB); 179 void BLK_GetBlockNum_GetBlkInfo(int &BlkNum, PReqDataBlockInfo ReqData); 180 void BLK_DoBlockInfo_GetBlkInfo(PS7Area DB, PResDataBlockInfo Data, TCB &CB); 181 // Clock Group 182 bool PerformGetClock(); 183 bool PerformSetClock(); 184 // SZL Group 185 bool PerformGroupSZL(); 186 // Subfunctions (called by PerformGroupSZL) 187 void SZLNotAvailable(); 188 void SZLSystemState(); 189 void SZLData(void *P, int len); 190 void SZL_ID424(); 191 void SZL_ID131_IDX003(); 192 public: 193 TSnap7Server *FServer; 194 int FPDULength; 195 TS7Worker(); ~TS7Worker()196 ~TS7Worker(){}; 197 }; 198 199 typedef TS7Worker *PS7Worker; 200 //------------------------------------------------------------------------------ 201 // S7 SERVER CLASS 202 //------------------------------------------------------------------------------ 203 extern "C" 204 { 205 typedef int (S7API *pfn_RWAreaCallBack)(void *usrPtr, int Sender, int Operation, PS7Tag PTag, void *pUsrData); 206 } 207 const int OperationRead = 0; 208 const int OperationWrite = 1; 209 210 class TSnap7Server : public TCustomMsgServer 211 { 212 private: 213 // Read Callback related 214 pfn_SrvCallBack OnReadEvent; 215 pfn_RWAreaCallBack OnRWArea; 216 // Critical section to lock Read/Write Hook Area 217 PSnapCriticalSection CSRWHook; 218 void *FReadUsrPtr; 219 void *FRWAreaUsrPtr; 220 void DisposeAll(); 221 int FindFirstFreeDB(); 222 int IndexOfDB(word DBNumber); 223 protected: 224 int DBCount; 225 int DBLimit; 226 PS7Area DB[MaxDB]; // DB 227 PS7Area HA[5]; // MK,PE,PA,TM,CT 228 PS7Area FindDB(word DBNumber); 229 PWorkerSocket CreateWorkerSocket(socket_t Sock); 230 bool ResourceLess; 231 word ForcePDU; 232 int RegisterDB(word Number, void *pUsrData, word Size); 233 int RegisterSys(int AreaCode, void *pUsrData, word Size); 234 int UnregisterDB(word DBNumber); 235 int UnregisterSys(int AreaCode); 236 // The Read event 237 void DoReadEvent(int Sender, longword Code, word RetCode, word Param1, 238 word Param2, word Param3, word Param4); 239 bool DoReadArea(int Sender, int Area, int DBNumber, int Start, int Size, int WordLen, void *pUsrData); 240 bool DoWriteArea(int Sender, int Area, int DBNumber, int Start, int Size, int WordLen, void *pUsrData); 241 public: 242 int WorkInterval; 243 byte CpuStatus; 244 TSnap7Server(); 245 ~TSnap7Server(); 246 int StartTo(const char *Address); 247 int GetParam(int ParamNumber, void *pValue); 248 int SetParam(int ParamNumber, void *pValue); 249 int RegisterArea(int AreaCode, word Index, void *pUsrData, word Size); 250 int UnregisterArea(int AreaCode, word Index); 251 int LockArea(int AreaCode, word DBNumber); 252 int UnlockArea(int AreaCode, word DBNumber); 253 // Sets Event callback 254 int SetReadEventsCallBack(pfn_SrvCallBack PCallBack, void *UsrPtr); 255 int SetRWAreaCallBack(pfn_RWAreaCallBack PCallBack, void *UsrPtr); 256 friend class TS7Worker; 257 }; 258 typedef TSnap7Server *PSnap7Server; 259 260 #endif // s7_server_h 261 262