package javaforce.controls.ab;
import javaforce.LE;
/** EtherNet/IP (Industrial Protocol)
*
* @author pquiring
*/
public class ENIP {
//header (24 bytes)
public short cmd; //cmd type
public short len; //following command data below
public int session; //random ID for connection
public int status; //0 = success
public long context; //increments per packet
public int options; //0
//CMD_RR_DATA (16 bytes)
public int ihandle; //0
public short timeout; //0
public short count = 2;
public short type_1 = 0x0000;
public short len_1 = 0x0000;
public short type_2 = 0x00b2;
public short len_2 = 0x0000; //length of CIP packet in bytes
//CMD_GET_SESSION (4 bytes)
public short protocol = 0x0001;
public short flags = 0x0000;
public static final short CMD_RR_DATA = 0x6f;
public static final short CMD_GET_SESSION = 0x65;
public ENIP() {}
public ENIP(short _cmd) {
cmd = _cmd;
}
public int size() {
switch (cmd) {
case CMD_RR_DATA: return 24 + 16; //40
case CMD_GET_SESSION: return 24 + 4; //28
}
return -1;
}
public void read(byte data[], int offset) throws Exception {
cmd = (short)LE.getuint16(data, offset); offset += 2;
len = (short)LE.getuint16(data, offset); offset += 2;
session = LE.getuint32(data, offset); offset += 4;
status = LE.getuint32(data, offset); offset += 4;
context = LE.getuint64(data, offset); offset += 8;
options = LE.getuint32(data, offset); offset += 4;
switch (cmd) {
case CMD_RR_DATA:
ihandle = LE.getuint32(data, offset); offset += 4;
timeout = (short)LE.getuint16(data, offset); offset += 2;
count = (short)LE.getuint16(data, offset); offset += 2;
if (count != 2) throw new Exception("ab:bad ip packet");
type_1 = (short)LE.getuint16(data, offset); offset += 2;
len_1 = (short)LE.getuint16(data, offset); offset += 2;
type_2 = (short)LE.getuint16(data, offset); offset += 2;
len_2 = (short)LE.getuint16(data, offset); offset += 2;
break;
case CMD_GET_SESSION:
protocol = (short)LE.getuint16(data, offset); offset += 2;
flags = (short)LE.getuint16(data, offset); offset += 2;
break;
}
}
public void setSizes(int size) {
switch (cmd) {
case CMD_RR_DATA:
len = (short)(16 + size);
len_2 = (short)size;
break;
case CMD_GET_SESSION:
len = 4;
break;
}
}
public void write(byte data[], int offset, ABContext abcontext) {
session = abcontext.session;
context = abcontext.context;
abcontext.increment();
LE.setuint16(data, offset, cmd); offset += 2;
LE.setuint16(data, offset, len); offset += 2;
LE.setuint32(data, offset, session); offset += 4;
LE.setuint32(data, offset, status); offset += 4;
LE.setuint64(data, offset, context); offset += 8;
LE.setuint32(data, offset, options); offset += 4;
switch (cmd) {
case CMD_RR_DATA:
LE.setuint32(data, offset, ihandle); offset += 4;
LE.setuint16(data, offset, timeout); offset += 2;
LE.setuint16(data, offset, count); offset += 2;
LE.setuint16(data, offset, type_1); offset += 2;
LE.setuint16(data, offset, len_1); offset += 2;
LE.setuint16(data, offset, type_2); offset += 2;
LE.setuint16(data, offset, len_2); offset += 2;
break;
case CMD_GET_SESSION:
LE.setuint16(data, offset, protocol); offset += 2;
LE.setuint16(data, offset, flags); offset += 2;
break;
}
}
}