我们正在尝试使用LLRP工具包代码连接FX9500。我们希望一旦进入范围就会收到读取标记。从消息看起来所有添加/设置配置都已正确完成,但无法接收事件。
附加了正在交换的消息的代码和XML输出。 XML消息位于:http://gadgetnapps.blogspot.in/2016/02/llrp-xml-messages.html
提前致谢。
public class LLRPHelloWorld {
private static String ipAddress = null;
private static int readerPort = -1;
private Socket connection;
private DataOutputStream out;
private static int ROSPEC_ID = 999;
private static Logger logger;
private ReadThread rt = null;
static AppCtx ctxMain;
public static void rfidMain(String ipAdString, int port, AppCtx ctx) {
logger = Logger.getLogger(LLRPHelloWorld.class);
ipAddress = ipAdString;
readerPort = port;
ctxMain = ctx;
try {
new LLRPHelloWorld();
logger.info("LLRP Hello World has terminated");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* The constructor creates a connection to the reader and sends LLRP
* messages. It first sends a GET_READER_CAPABILIITIES message and a
* SET_READER_CONFIG message. Then it creates an ROSpec with null start and
* stop triggers. After it enables and starts the ROSpec. It waits for a few
* seconds to receive tag reads before it disables and deletes the ROSpec.
* Finally it ends the LLRP connection.
*
* @param ctx
*
* @throws IOException
*/
public LLRPHelloWorld() throws IOException {
// Try to establish a connection to the reader
connection = new Socket(ipAddress, readerPort);
out = new DataOutputStream(connection.getOutputStream());
// Start up the ReaderThread to read messages form socket to Console
rt = new ReadThread(connection);
rt.start();
// Wait for the NotificationEvent the Reader sends whenever a
// connection attempt is made
pause(250);
LLRPMessage m = rt.getNextMessage();
READER_EVENT_NOTIFICATION readerEventNotification = (READER_EVENT_NOTIFICATION) m;
ReaderEventNotificationData red = readerEventNotification
.getReaderEventNotificationData();
if (red.getConnectionAttemptEvent() != null) {
logger.info("Connection attempt was successful");
} else {
logger.error("Connection attempt was unsucessful");
System.exit(-1);
}
// Create a GET_READER_CAPABILITIES Message and send it to the reader
GET_READER_CAPABILITIES getReaderCap = new GET_READER_CAPABILITIES();
getReaderCap.setRequestedData(new GetReaderCapabilitiesRequestedData(
GetReaderCapabilitiesRequestedData.All));
write(getReaderCap, "GET_READER_CAPABILITIES");
pause(250);
// Create a SET_READER_CONFIG Message and send it to the reader
SET_READER_CONFIG setReaderConfig = createSetReaderConfig();
write(setReaderConfig, "SET_READER_CONFIG");
pause(250);
// CREATE an ADD_ROSPEC Message and send it to the reader
ADD_ROSPEC addROSpec = new ADD_ROSPEC();
addROSpec.setROSpec(createROSpec());
write(addROSpec, "ADD_ROSPEC");
pause(250);
// Create an ENABLE_ROSPEC message and send it to the reader
ENABLE_ROSPEC enableROSpec = new ENABLE_ROSPEC();
enableROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
write(enableROSpec, "ENABLE_ROSPEC");
pause(250);
boolean flg = true;
START_ROSPEC startROSpec = new START_ROSPEC();
startROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
write(startROSpec, "START_ROSPEC");
while (flg) {
// Create a START_ROSPEC message and send it to the reader
LLRPMessage msg = rt.getNextMessage();
try {
System.err.println(msg+"--->"+msg.toXMLString());
} catch (InvalidLLRPMessageException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// pause(4000);
// System.err.println("main test 4s");
// Create a STOP_ROSPEC message and send it to the reader
// STOP_ROSPEC stopROSpec = new STOP_ROSPEC();
// stopROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
// write(stopROSpec, "STOP_ROSPEC");
//
// pause(4000);
// startROSpec = new START_ROSPEC();
// startROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
// write(startROSpec, "START_ROSPEC");
//
}
// Create a DISABLE_ROSPEC message and send it to the reader
DISABLE_ROSPEC disableROSpec = new DISABLE_ROSPEC();
disableROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
write(disableROSpec, "DISABLE_ROSPEC");
pause(250);
// Create a DELTE_ROSPEC message and send it to the reader
DELETE_ROSPEC deleteROSpec = new DELETE_ROSPEC();
deleteROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
write(deleteROSpec, "DELETE_ROSPEC");
pause(250);
// wait for one second before closing the connection
pause(1000);
// Create a CLOSE_CONNECTION message and send it to the reader
CLOSE_CONNECTION cc = new CLOSE_CONNECTION();
write(cc, "CloseConnection");
synchronized (rt) {
try {
logger.debug("Wait for the Reader to close the Connection");
rt.wait();
// KEEPALIVE_ACK
} catch (InterruptedException e) {
// Quit the Program
}
}
}
/**
* This method creates a ROSpec with null start and stop triggers
*
* @return
*/
private ROSpec createROSpec() {
// create a new rospec
ROSpec roSpec = new ROSpec();
roSpec.setPriority(new UnsignedByte(0));
roSpec.setCurrentState(new ROSpecState(ROSpecState.Disabled));//rathi
roSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
// set up ROBoundary (start and stop triggers)
ROBoundarySpec roBoundarySpec = new ROBoundarySpec();
ROSpecStartTrigger startTrig = new ROSpecStartTrigger();
startTrig.setROSpecStartTriggerType(new ROSpecStartTriggerType(
ROSpecStartTriggerType.Immediate));
// PeriodicTriggerValue pt =new PeriodicTriggerValue();
// pt.setPeriod(new UnsignedInteger(1));
// pt.setOffset(new UnsignedInteger(0));
// startTrig.setPeriodicTriggerValue(pt);
roBoundarySpec.setROSpecStartTrigger(startTrig);
ROSpecStopTrigger stopTrig = new ROSpecStopTrigger();
stopTrig.setDurationTriggerValue(new UnsignedInteger(0));
stopTrig.setROSpecStopTriggerType(new ROSpecStopTriggerType(
ROSpecStopTriggerType.Null));
roBoundarySpec.setROSpecStopTrigger(stopTrig);
roSpec.setROBoundarySpec(roBoundarySpec);
// Add an AISpec
AISpec aispec = new AISpec();
// set AI Stop trigger to null
AISpecStopTrigger aiStopTrigger = new AISpecStopTrigger();
aiStopTrigger.setAISpecStopTriggerType(new AISpecStopTriggerType(
AISpecStopTriggerType.Null));//null
aiStopTrigger.setDurationTrigger(new UnsignedInteger(0));
aispec.setAISpecStopTrigger(aiStopTrigger);
UnsignedShortArray antennaIDs = new UnsignedShortArray();
antennaIDs.add(new UnsignedShort(0));
aispec.setAntennaIDs(antennaIDs);
InventoryParameterSpec inventoryParam = new InventoryParameterSpec();
inventoryParam.setProtocolID(new AirProtocols(
AirProtocols.EPCGlobalClass1Gen2));
inventoryParam.setInventoryParameterSpecID(new UnsignedShort(1));
aispec.addToInventoryParameterSpecList(inventoryParam);
roSpec.addToSpecParameterList(aispec);
return roSpec;
}
/**
* This method creates a SET_READER_CONFIG method
*
* @return
*/
private SET_READER_CONFIG createSetReaderConfig() {
SET_READER_CONFIG setReaderConfig = new SET_READER_CONFIG();
// Create a default RoReportSpec so that reports are sent at the end of
// ROSpecs
ROReportSpec roReportSpec = new ROReportSpec();
roReportSpec.setN(new UnsignedShort(0));
roReportSpec.setROReportTrigger(new ROReportTriggerType(
ROReportTriggerType.Upon_N_Tags_Or_End_Of_ROSpec));
//Enable keep alive
// KeepaliveSpec ka = new KeepaliveSpec();
// KeepaliveTriggerType ktype = new KeepaliveTriggerType();
// ktype.set(KeepaliveTriggerType.Periodic);
// ka.setPeriodicTriggerValue(new UnsignedInteger(100));
// ka.setKeepaliveTriggerType(ktype);
// setReaderConfig.setKeepaliveSpec(ka);
//
TagReportContentSelector tagReportContentSelector = new TagReportContentSelector();
tagReportContentSelector.setEnableAccessSpecID(new Bit(0));
tagReportContentSelector.setEnableAntennaID(new Bit(1));
tagReportContentSelector.setEnableChannelIndex(new Bit(0));
tagReportContentSelector.setEnableFirstSeenTimestamp(new Bit(0));
tagReportContentSelector.setEnableInventoryParameterSpecID(new Bit(1));
tagReportContentSelector.setEnableLastSeenTimestamp(new Bit(0));
tagReportContentSelector.setEnablePeakRSSI(new Bit(0));
tagReportContentSelector.setEnableROSpecID(new Bit(1));
tagReportContentSelector.setEnableSpecIndex(new Bit(0));
tagReportContentSelector.setEnableTagSeenCount(new Bit(0));
// tagReport.
C1G2EPCMemorySelector epcMemSel = new C1G2EPCMemorySelector();
epcMemSel.setEnableCRC(new Bit(0));
epcMemSel.setEnablePCBits(new Bit(0));
tagReportContentSelector
.addToAirProtocolEPCMemorySelectorList(epcMemSel);
roReportSpec.setTagReportContentSelector(tagReportContentSelector);
setReaderConfig.setROReportSpec(roReportSpec);
// Set default AccessReportSpec
AccessReportSpec accessReportSpec = new AccessReportSpec();
accessReportSpec.setAccessReportTrigger(new AccessReportTriggerType(
AccessReportTriggerType.End_Of_AccessSpec));
setReaderConfig.setAccessReportSpec(accessReportSpec);
// Set up reporting for AISpec events, ROSpec events, and GPI Events
ReaderEventNotificationSpec eventNoteSpec = new ReaderEventNotificationSpec();
EventNotificationState noteState = new EventNotificationState();
noteState.setEventType(new NotificationEventType(
NotificationEventType.AISpec_Event));
noteState.setNotificationState(new Bit(1));
eventNoteSpec.addToEventNotificationStateList(noteState);
noteState = new EventNotificationState();
noteState.setEventType(new NotificationEventType(
NotificationEventType.ROSpec_Event));
noteState.setNotificationState(new Bit(1));
eventNoteSpec.addToEventNotificationStateList(noteState);
noteState = new EventNotificationState();
noteState.setEventType(new NotificationEventType(
NotificationEventType.GPI_Event));
noteState.setNotificationState(new Bit(1));
eventNoteSpec.addToEventNotificationStateList(noteState);
noteState = new EventNotificationState();
noteState.setEventType(new NotificationEventType(
NotificationEventType.Antenna_Event));
noteState.setNotificationState(new Bit(1));
eventNoteSpec.addToEventNotificationStateList(noteState);
setReaderConfig.setReaderEventNotificationSpec(eventNoteSpec);
setReaderConfig.setResetToFactoryDefault(new Bit(0));
return setReaderConfig;
}
/**
* This method causes the calling thread to sleep for a specified number of
* milliseconds
*
* @param ms
*/
private void pause(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Send a llrp message to the reader
*
* @param msg
* Message to be send
* @param message
* Description for output purposes
*/
private void write(LLRPMessage msg, String message) {
try {
logger.info(" Sending message: \n" + msg.toXMLString());
out.write(msg.encodeBinary());
} catch (IOException e) {
logger.error("Couldn't send Command ", e);
} catch (InvalidLLRPMessageException e) {
logger.error("Couldn't send Command", e);
}
}
/**
*
* This class is a allows LLRP messages to be read on a separate thread
*
* @author Kyle Neumeier
* @author Andreas Huebner
*
*/
class ReadThread extends Thread {
/**
* The incoming data stream from the LLRP reader connection
*/
private DataInputStream inStream = null;
/**
* The socket for the connection to the LLRP Reader
*/
private Socket socket = null;
/**
* A queue to store incoming LLRP Messages
*/
private LinkedBlockingQueue<LLRPMessage> queue = null;
/**
* Thread for constant reading of the stream
*
* @param inStream
*/
public ReadThread(Socket socket) {
this.socket = socket;
this.queue = new LinkedBlockingQueue<LLRPMessage>();
try {
this.inStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
logger.error("Cannot get input stream", e);
}
}
@Override
public void run() {
int i = 0;
super.run();
if (socket.isConnected()) {
while (!socket.isClosed()) {
LLRPMessage message = null;
try {
message = read();
if (message != null) {
queue.put(message);
logger.info("Received Message: \n"
+ message);//.toXMLString());
if (message instanceof org.llrp.ltk.generated.messages.RO_ACCESS_REPORT) {
// logger.info("Received Message: \n"
// + message.toXMLString());
RO_ACCESS_REPORT re = (RO_ACCESS_REPORT) message;
java.util.List<TagReportData> list = re
.getTagReportDataList();
for (TagReportData tagReportData : list) {
if (tagReportData.getEPCParameter() instanceof EPC_96) {
EPC_96 epc = (EPC_96) tagReportData
.getEPCParameter();
System.err
.println("=====================================>>>>>>>>>>>>>>>>>"
+ epc.getEPC());
// sendWebMessage(epc.getEPC(),i++);
}
}
}
} else {
logger.info("closing socket");
socket.close();
}
} catch (IOException e) {
logger.error("Error while reading message", e);
} catch (InvalidLLRPMessageException e) {
logger.error("Error while reading message", e);
} catch (InterruptedException e) {
logger.error("Error while reading message", e);
}
}
}
}
private void sendWebMessage(Integer96_HEX epc, int i)
throws InterruptedException {
WebMessage cmd = new WebMessage();
String url;
if (i % 2 == 0)
url = ctxMain.getWorker().getAddLogUrl() + "/" + epc;
else
url = ctxMain.getWorker().getTransationUrl() + "/" + epc;
cmd.setUrl(url);
System.out.println(" id " + url);
cmd.setMessage(new String("{}"));
ctxMain.sendWebMessage(cmd);
}
/**
* Read everything from the stream until the socket is closed
*
* @throws InvalidLLRPMessageException
*/
public LLRPMessage read() throws IOException,
InvalidLLRPMessageException {
LLRPMessage m = null;
// The message header
byte[] first = new byte[6];
// the complete message
byte[] msg;
// Read in the message header. If -1 is read, there is no more
// data available, so close the socket
if (inStream.read(first, 0, 6) == -1) {
return null;
}
int msgLength = 0;
try {
// calculate message length
msgLength = calculateLLRPMessageLength(first);
} catch (IllegalArgumentException e) {
throw new IOException("Incorrect Message Length");
}
/*
* the rest of bytes of the message will be stored in here before
* they are put in the accumulator. If the message is short, all
* messageLength-6 bytes will be read in here at once. If it is
* long, the data might not be available on the socket all at once,
* so it make take a couple of iterations to read in all the bytes
*/
byte[] temp = new byte[msgLength - 6];
// all the rest of the bytes will be put into the accumulator
ArrayList<Byte> accumulator = new ArrayList<Byte>();
// add the first six bytes to the accumulator so that it will
// contain all the bytes at the end
for (byte b : first) {
accumulator.add(b);
}
// the number of bytes read on the last call to read()
int numBytesRead = 0;
// read from the input stream and put bytes into the accumulator
// while there are still bytes left to read on the socket and
// the entire message has not been read
while (((msgLength - accumulator.size()) != 0)
&& numBytesRead != -1) {
numBytesRead = inStream.read(temp, 0,
msgLength - accumulator.size());
for (int i = 0; i < numBytesRead; i++) {
accumulator.add(temp[i]);
}
}
if ((msgLength - accumulator.size()) != 0) {
throw new IOException("Error: Discrepency between message size"
+ " in header and actual number of bytes read");
}
msg = new byte[msgLength];
// copy all bytes in the accumulator to the msg byte array
for (int i = 0; i < accumulator.size(); i++) {
msg[i] = accumulator.get(i);
}
// turn the byte array into an LLRP Message Object
m = LLRPMessageFactory.createLLRPMessage(msg);
return m;
}
/**
* Send in the first 6 bytes of an LLRP Message
*
* @param bytes
* @return
*/
private int calculateLLRPMessageLength(byte[] bytes)
throws IllegalArgumentException {
long msgLength = 0;
int num1 = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
num1 = ((unsignedByteToInt(bytes[2])));
num1 = num1 << 32;
if (num1 > 127) {
throw new RuntimeException(
"Cannot construct a message greater than "
+ "2147483647 bytes (2^31 - 1), due to the fact that there are "
+ "no unsigned ints in java");
}
num2 = ((unsignedByteToInt(bytes[3])));
num2 = num2 << 16;
num3 = ((unsignedByteToInt(bytes[4])));
num3 = num3 << 8;
num4 = (unsignedByteToInt(bytes[5]));
msgLength = num1 + num2 + num3 + num4;
if (msgLength < 0) {
throw new IllegalArgumentException(
"LLRP message length is less than 0");
} else {
return (int) msgLength;
}
}
/**
* From http://www.rgagnon.com/javadetails/java-0026.html
*
* @param b
* @return
*/
private int unsignedByteToInt(byte b) {
return (int) b & 0xFF;
}
/**
* Receive the next Message
*
* @return returns the Message form the Queue and removes it. It blocks
* if there is no Message.
*/
public LLRPMessage getNextMessage() {
LLRPMessage m = null;
try {
m = queue.take();
} catch (InterruptedException e) {
// nothing
}
return m;
}
}
}
答案 0 :(得分:1)
你必须在startRoSpec之后编写报告,然后才能获得tagids。
> START_ROSPEC startROSpec = new START_ROSPEC();
> startROSpec.setROSpecID(new UnsignedInteger(ROSPEC_ID));
> write(startROSpec, "START_ROSPEC"); //wait for five seconds for tag
> reads pause(5000);
ENABLE_EVENTS_AND_REPORTS report = new ENABLE_EVENTS_AND_REPORTS();
write(report, "ENABLE_EVENTS_AND_REPORTS");
上课