1 /** 2 * This module contains bindings to types and functions from the nodave C header <nodavesimple.h>. 3 */ 4 5 module dinodave.nodave; 6 7 import std.stdio; 8 import core.stdc.stdio; 9 import core.stdc.stdlib; 10 11 enum daveProtoISOTCP = 122; /** ISO over TCP */ 12 13 /** ProfiBus/MPI speed constants to be used with newInterface */ 14 enum daveSpeed9k = 0; 15 enum daveSpeed19k = 1; 16 enum daveSpeed187k = 2; 17 enum daveSpeed500k = 3; 18 enum daveSpeed1500k = 4; 19 enum daveSpeed45k = 5; 20 enum daveSpeed93k = 6; 21 22 enum daveP = 0x80; 23 enum daveInputs = 0x81; 24 enum daveOutputs = 0x82; 25 enum daveFlags = 0x83; 26 enum daveDB = 0x84; /** Data blocks */ 27 enum daveDI = 0x85; /** Instance data blocks */ 28 enum daveLocal = 0x86; /* not tested */ 29 enum daveV = 0x87; /* don't know what it is */ 30 enum daveCounter = 28; /** S7 counters */ 31 enum daveTimer = 29; /** S7 timers */ 32 enum daveCounter200 = 30; /* IEC counters (200 family) */ 33 enum daveTimer200 = 31; /* IEC timers (200 family) */ 34 35 extern (C): 36 37 alias daveConnection = _daveConnection; 38 alias daveInterface = _daveInterface; 39 40 struct _daveOSserialType { 41 int rfd; 42 int wfd; 43 } 44 45 struct PDU { 46 ubyte* header; 47 ubyte* param; 48 ubyte* data; 49 ubyte* udata; 50 int hlen; 51 int plen; 52 int dlen; 53 int udlen; 54 } 55 56 /** 57 * A structure representing the physical connection to a PLC or a network of PLCs (e.g. like MPI). 58 * daveInterface stores all those properties that are common to a network of PLCs: 59 * - The local address used by your computer. 60 * - The speed used in this network. 61 * - The protocol type used in this network. 62 * - A name which is used when printing out debug messages. 63 * 64 * The structure daveInterface is created and initialized by daveNewInterface: 65 * 66 * -------------------- 67 * daveInterface* di; 68 * di = daveNewInterface(fds, "IF1", localMPI, daveProtoXXX, daveSpeedYYY); 69 * -------------------- 70 * 71 * or in D 72 * -------------------- 73 * auto sock = new TcpSocket(new InternetAddress(ip, to!(ushort)(port))); 74 * fds.wfd = fds.rfd = sock.handle; 75 * daveInterface* di = daveNewInterface(fds, "IF1", 0, daveProtoISOTCP, daveSpeed9k); 76 * -------------------- 77 */ 78 struct _daveInterface { 79 int _timeout; 80 } 81 82 /** 83 * A structure representing the physical connection to a single PLC. 84 * daveConnection stores all properties that are unique to a single PLC: 85 * - The MPI address of this PLC. 86 * - The rack the PLC is in. 87 * - The slot the PLC is in. 88 */ 89 struct _daveConnection { 90 int AnswLen; 91 ubyte* resultPointer; 92 int maxPDUlength; 93 } 94 95 struct daveBlockTypeEntry { 96 ubyte[2] type; 97 ushort count; 98 } 99 100 struct daveBlockEntry { 101 ushort number; 102 ubyte[2] type; 103 } 104 105 struct daveResult { 106 int error; 107 int length; 108 ubyte* bytes; 109 } 110 111 struct daveResultSet { 112 int numResults; 113 daveResult* results; 114 } 115 116 // helper 117 // --------- 118 int daveGetS8from(ubyte* b); 119 int daveGetU8from(ubyte* b); 120 int daveGetS16from(ubyte* b); 121 int daveGetU16from(ubyte* b); 122 int daveGetS32from(ubyte* b); 123 uint daveGetU32from(ubyte* b); 124 float daveGetFloatfrom(ubyte* b); 125 126 ubyte* davePut8(ubyte* b, int v); 127 ubyte* davePut16(ubyte* b, int v); 128 ubyte* davePut32(ubyte* b, int v); 129 ubyte* davePutFloat(ubyte* b, float v); 130 void davePut8At(ubyte* b, int pos, int v); 131 void davePut16At(ubyte* b, int pos, int v); 132 void davePut32At(ubyte* b, int pos, int v); 133 void davePutFloatAt(ubyte* b, int pos, float v); 134 135 ubyte daveToBCD(ubyte i); 136 ubyte daveFromBCD(ubyte i); 137 138 // plc 139 // --------- 140 int daveGetS8(daveConnection* dc); 141 int daveGetU8(daveConnection* dc); 142 int daveGetS16(daveConnection* dc); 143 int daveGetU16(daveConnection* dc); 144 int daveGetS32(daveConnection* dc); 145 uint daveGetU32(daveConnection* dc); 146 float daveGetFloat(daveConnection* dc); 147 148 int daveGetS8At(daveConnection* dc, int pos); 149 int daveGetU8At(daveConnection* dc, int pos); 150 int daveGetS16At(daveConnection* dc, int pos); 151 int daveGetU16At(daveConnection* dc, int pos); 152 int daveGetS32At(daveConnection* dc, int pos); 153 uint daveGetU32At(daveConnection* dc, int pos); 154 float daveGetFloatAt(daveConnection* dc, int pos); 155 156 int daveSetBit(daveConnection* dc, int area, int DB, int byteAdr, int bitAdr); 157 int daveClrBit(daveConnection* dc, int area, int DB, int byteAdr, int bitAdr); 158 159 /** 160 * Read len bytes from the PLC. 161 * 162 * Params: 163 * dc = A daveConnection 164 * area = Denotes whether the data comes from FLAGS, DATA BLOCKS, 165 * DB = The number of the data block to be used. Set it to zero 166 * start = First byte. 167 * len = Number of bytes to read 168 * buffer = Pointer to a memory block provided by the calling program. 169 * If the pointer is not NULL, the result data will be copied thereto. 170 * Hence it must be big enough to take up the result. 171 * 172 */ 173 int daveReadBytes(daveConnection* dc, int area, int DB, int start, int len, void* buffer); 174 int daveWriteBytes(daveConnection* dc, int area, int DB, int start, int len, void* buffer); 175 176 int daveReadPLCTime(daveConnection* dc); 177 // --------- 178 179 180 /** 181 * Get time in seconds from current read position 182 */ 183 float daveGetSeconds(daveConnection* dc); 184 185 /** 186 * Get time in seconds from random position 187 * 188 * Params: 189 * dc = a daveConnection 190 * pos = Position in bytes 191 * 192 * Examples: 193 * -------------------- 194 * // read 4 timers: each timer has 2 bytes 195 * const(int) res = daveReadBytes(dc, daveTimer, 0, 0, 4, null); 196 * // read second of timer 2 197 * float d = daveGetSecondsAt(dc, 4); 198 * // 4 because: 199 * // | pos | timer | 200 * // | 0 | timer 0 | 201 * // | 1 | timer 0 | 202 * // | 2 | timer 1 | 203 * // | 3 | timer 1 | 204 * // | 4 | timer 2 | <---- 205 * // | 5 | timer 2 | 206 * -------------------- 207 */ 208 float daveGetSecondsAt(daveConnection* dc, int pos); 209 int daveGetCounterValue(daveConnection* dc); 210 int daveGetCounterValueAt(daveConnection* dc, int pos); 211 void _daveConstructUpload(PDU* p, char blockType, int blockNr); 212 void _daveConstructDoUpload(PDU* p, int uploadID); 213 void _daveConstructEndUpload(PDU* p, int uploadID); 214 215 int daveGetOrderCode(daveConnection* dc, char* buf); 216 int daveReadManyBytes(daveConnection* dc, int area, int DBnum, int start, int len, void* buffer); 217 int daveWriteManyBytes(daveConnection* dc, int area, int DB, int start, int len, void* buffer); 218 int daveReadBits(daveConnection* dc, int area, int DB, int start, int len, void* buffer); 219 int daveWriteBits(daveConnection* dc, int area, int DB, int start, int len, void* buffer); 220 221 int daveReadSZL(daveConnection* dc, int ID, int index, void* buf, int buflen); 222 int daveListBlocksOfType(daveConnection* dc, ubyte type, daveBlockEntry* buf); 223 int daveListBlocks(daveConnection* dc, daveBlockTypeEntry* buf); 224 int initUpload(daveConnection* dc, char blockType, int blockNr, int* uploadID); 225 int doUpload(daveConnection* dc, int* more, ubyte** buffer, int* len, int uploadID); 226 int endUpload(daveConnection* dc, int uploadID); 227 int daveGetProgramBlock(daveConnection* dc, int blockType, int number, char* buffer, int* length); 228 int daveStop(daveConnection* dc); 229 int daveStart(daveConnection* dc); 230 int daveCopyRAMtoROM(daveConnection* dc); 231 int daveForce200(daveConnection* dc, int area, int start, int val); 232 void davePrepareReadRequest(daveConnection* dc, PDU* p); 233 void daveAddVarToReadRequest(PDU* p, int area, int DBnum, int start, int bytes); 234 int daveExecReadRequest(daveConnection* dc, PDU* p, daveResultSet* rl); 235 int daveUseResult(daveConnection* dc, daveResultSet* rl, int n); 236 void daveFreeResults(daveResultSet* rl); 237 void daveAddBitVarToReadRequest(PDU* p, int area, int DBnum, int start, int byteCount); 238 void davePrepareWriteRequest(daveConnection* dc, PDU* p); 239 void daveAddVarToWriteRequest(PDU* p, int area, int DBnum, int start, int bytes, void* buffer); 240 void daveAddBitVarToWriteRequest(PDU* p, int area, int DBnum, int start, int byteCount, void* buffer); 241 int daveExecWriteRequest(daveConnection* dc, PDU* p, daveResultSet* rl); 242 int daveInitAdapter(daveInterface* di); 243 int daveConnectPLC(daveConnection* dc); 244 int daveDisconnectPLC(daveConnection* dc); 245 int daveDisconnectAdapter(daveInterface* di); 246 int daveListReachablePartners(daveInterface* di, char* buf); 247 void daveSetTimeout(daveInterface* di, int tmo); 248 int daveGetTimeout(daveInterface* di); 249 char* daveGetName(daveInterface* di); 250 int daveGetMPIAdr(daveConnection* dc); 251 int daveGetAnswLen(daveConnection* dc); 252 int daveGetMaxPDULen(daveConnection* dc); 253 //daveResultSet* daveNewResultSet(...); 254 255 // FIX: void daveFree(void* dc); 256 257 //PDU* daveNewPDU(...); 258 int daveGetErrorOfResult(daveResultSet*, int number); 259 int daveForceDisconnectIBH(daveInterface* di, int src, int dest, int mpi); 260 int daveResetIBH(daveInterface* di); 261 int daveGetProgramBlock(daveConnection* dc, int blockType, int number, char* buffer, int* length); 262 263 int daveSetPLCTime(daveConnection* dc, ubyte* ts); 264 int daveSetPLCTimeToSystime(daveConnection* dc); 265 266 char* daveStrerror(int code); 267 void daveStringCopy(char* intString, char* extString); 268 void daveSetDebug(int nDebug); 269 int daveGetDebug(); 270 271 /** 272 * Create a daveInterface structure. 273 * 274 * Params: 275 * nfd = A _daveOSserialType 276 * nname = Interface name 277 * localMPI = The address used by your computer/adapter (only meaningful for MPI and PPI) 278 * protocol = A constant specifying the protocol to be used on this interface 279 * speed = A constant specifying the speed to be used on this interface. (only meaningful for MPI and Profibus) 280 */ 281 daveInterface* daveNewInterface(_daveOSserialType nfd, const(char)* nname, int localMPI, int protocol, int speed); 282 283 /** 284 * Setup a new connection structure using an initialized 285 * daveInterface and PLC's MPI address. 286 * 287 * Params: 288 * di = A daveInterface 289 * MPI = The address of the PLC (only meaningful for MPI and PPI). 290 * rack = The rack the CPU is mounted in (normally 0, only meaningful for ISO over TCP). 291 * slot = The slot number the CPU is mounted in (normally 2, only meaningful for ISO over TCP) 292 */ 293 daveConnection* daveNewConnection(daveInterface* di, int MPI, int rack, int slot); 294 int daveGetResponse(daveConnection* dc); 295 int daveSendMessage(daveConnection* dc, PDU* p); 296 void _daveDumpPDU(PDU* p); 297 void _daveDump(char* name, ubyte* b, int len); 298 char* daveBlockName(ubyte bn); 299 char* daveAreaName(ubyte n); 300 301 short daveSwapIed_16(short ff); 302 int daveSwapIed_32(int ff); 303 float toPLCfloat(float ff); 304 int daveToPLCfloat(float ff);