Skip to content

Commit

Permalink
Merge pull request #11 from wz2b/tag_struct_patch
Browse files Browse the repository at this point in the history
Struct/array tag patches
  • Loading branch information
kasemir authored Dec 15, 2016
2 parents a93500c + e26838d commit e6196a0
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 70 deletions.
9 changes: 7 additions & 2 deletions src/etherip/EtherNetIP.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,15 @@ private String getStringAttribute(final int attr) throws Exception
connection.execute(encap);
return attr_proto.getValue();
}

public CIPData readTag(final String tag) throws Exception
{
final MRChipReadProtocol cip_read = new MRChipReadProtocol(tag);
return readTag(tag, (short) 1);
}

public CIPData readTag(final String tag, short count) throws Exception
{
final MRChipReadProtocol cip_read = new MRChipReadProtocol(tag, count);
final Encapsulation encap =
new Encapsulation(SendRRData, connection.getSession(),
new SendRRDataProtocol(
Expand Down
55 changes: 37 additions & 18 deletions src/etherip/protocol/CIPReadDataProtocol.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package etherip.protocol;

import java.nio.ByteBuffer;

import etherip.types.CIPData;
import java.nio.ByteBuffer;

import etherip.types.CIPData;
import etherip.types.CNService;

/** Protocol body for {@link CNService#CIP_ReadData}
*
* @author Kay Kasemir
*
*/
public class CIPReadDataProtocol extends ProtocolAdapter
{
private CIPData data;
private final short count;


/**
* Create a read protocol message that requests a single element
*/
public CIPReadDataProtocol() {
count = 1;
}


/**
* Create a read protocol message that reqeusts one or more elements if request is an array
* @param count
*/
public CIPReadDataProtocol(short count) {
this.count = count;
}

@Override
public int getRequestSize()
Expand All @@ -29,20 +48,20 @@ public int getRequestSize()
@Override
public void encode(final ByteBuffer buf, final StringBuilder log)
{
buf.putShort((short) 1); // elements
buf.putShort(count); // elements
if (log != null)
log.append("USINT elements : 1\n");
}

@Override
public void decode(final ByteBuffer buf, final int available, final StringBuilder log) throws Exception
{
if (available <= 0)
{
data = null;
if (log != null)
log.append("USINT type, data : - nothing-\n");
return;
{
if (available <= 0)
{
data = null;
if (log != null)
log.append("USINT type, data : - nothing-\n");
return;
}
final CIPData.Type type = CIPData.Type.forCode(buf.getShort());
final byte[] raw = new byte[available - 2];
Expand Down
27 changes: 19 additions & 8 deletions src/etherip/protocol/MRChipReadProtocol.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package etherip.protocol;

import static etherip.types.CNPath.Symbol;
Expand All @@ -18,14 +18,25 @@ public class MRChipReadProtocol extends MessageRouterProtocol
{
final private CIPReadDataProtocol reader;

/** Initialize
/** Initialize. Note that if trying to read an arary this will only return the first item.
* @param tag Name of tag to read
*/
public MRChipReadProtocol(final String tag)
{
this(tag, new CIPReadDataProtocol());
}


/**
* Initialize. Only use this constructur if retrieving an array.
* @param tag Name of tag to read
* @param count Number of elements to read (if it is an array)
*/
public MRChipReadProtocol(final String tag, short count)
{
this(tag, new CIPReadDataProtocol(count));
}

/** Initialize
* @param tag Name of tag to read
* @param body Protocol embedded in the message request/response
Expand Down
23 changes: 18 additions & 5 deletions src/etherip/types/CIPData.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

import etherip.protocol.Connection;

Expand Down Expand Up @@ -46,13 +49,23 @@ public static enum Type

final private short code;
final private int element_size;


final private static Map<Short, Type> reverse;

static {
reverse = new HashMap<>();
for (Type t : EnumSet.allOf(Type.class)) {
reverse.put(t.code, t);
}
}

public static Type forCode(final short code) throws Exception
{
for (Type type : values())
if (type.code == code)
return type;
throw new Exception("Unknown CIP type code 0x" + Integer.toHexString(code));
Type t = reverse.get(code);
if (reverse == null) {
throw new Exception("Unknown CIP type code 0x" + Integer.toHexString(code));
}
return t;
}

private Type(final int code, final int element_size)
Expand Down
112 changes: 75 additions & 37 deletions src/etherip/types/CNSymbolPath.java
Original file line number Diff line number Diff line change
@@ -1,66 +1,104 @@
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
/*******************************************************************************
* Copyright (c) 2012 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package etherip.types;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** Control Net Path for element path
*
*
* <p>Example (with suitable static import):
* <p><code>CNPath path = Symbol.name("my_tag")</code>
* @author Kay Kasemir
*/
public class CNSymbolPath extends CNPath
{
private String symbol;
class PathAndIndex{
private String path;
private Integer index;
public PathAndIndex(String path, Integer index) {
this.path = path;
this.index = index;
}
public String getPath() {
return path;
}
public Integer getIndex() {
return index;
}

};

private final Pattern PATTERN_BRACKETS = Pattern.compile("\\[(\\d+)\\]");

private List<PathAndIndex> paths = new ArrayList<>();

/** Initialize
* @param symbol Name of symbol
*/
protected CNSymbolPath(final String symbol)
{
this.symbol = symbol;
for(String s:symbol.split("\\.")){
Matcher m = PATTERN_BRACKETS.matcher(s);
Integer index = null;
String path = s;
while(m.find()){
String match = m.group().replace("[","").replace("]", "");
index = Integer.parseInt(match);
path = path.replace("[" + match + "]", "");
}
paths.add(new PathAndIndex(path, index));
}
}
/** {@inheritDoc} */

/** {@inheritDoc} */
@Override
public int getRequestSize()
{ // End of string is padded if length is odd
return 2 + symbol.length() + (needPad() ? 1 : 0);
}

/** {@inheritDoc} */
public int getRequestSize()
{ // End of string is padded if length is odd
int count = 0;
for(PathAndIndex s:paths){
count += 2 + s.getPath().length() + (needPad(s.getPath()) ? 1 : 0);
if(s.getIndex()!=null)
count += 2;
}
return count;
}

/** {@inheritDoc} */
@Override
public void encode(final ByteBuffer buf, final StringBuilder log)
public void encode(final ByteBuffer buf, final StringBuilder log)
{
// spec 4 p.21: "ANSI extended symbol segment"
buf.put((byte) (getRequestSize() / 2));
buf.put((byte) 0x91);
buf.put((byte) symbol.length());
buf.put(symbol.getBytes());
if (needPad())
buf.put((byte) 0);
for(PathAndIndex pi:paths){
String s = pi.getPath();
buf.put((byte) 0x91);
buf.put((byte) s.length());
buf.put(s.getBytes());
if (needPad(s))
buf.put((byte) 0);
Integer index = pi.getIndex();
if(index!=null){
//Path Segment 28, from wireshark
buf.put((byte) 0x28);
buf.put(index.byteValue());
}
}

}

/** @return Is path of odd length, requiring a pad byte? */
private boolean needPad()
{
// Findbugs: x%2==1 fails for negative numbers
return (symbol.length() % 2) != 0;
}

@Override
public String toString()
private boolean needPad(String s)
{
final StringBuilder buf = new StringBuilder();
buf.append("Path Symbol(0x91) '").append(symbol).append("'");
if (needPad())
buf.append(", 0x00");
return buf.toString();
// Findbugs: x%2==1 fails for negative numbers
return (s.length() % 2) != 0;
}
}

0 comments on commit e6196a0

Please sign in to comment.