/* * * This file was generated by LLRP Code Generator * see http://llrp-toolkit.cvs.sourceforge.net/llrp-toolkit * for more information * Generated on: Mon Mar 10 14:26:48 KST 2014; * */ /* * Copyright 2007 ETH Zurich * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions * and limitations under the License. * */ package kr.ac.kaist.resl.ltk.generated.parameters; import org.apache.log4j.Logger; import org.jdom.Content; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.llrp.ltk.exceptions.InvalidLLRPMessageException; import org.llrp.ltk.exceptions.MissingParameterException; import kr.ac.kaist.resl.ltk.generated.LLRPConstants; import kr.ac.kaist.resl.ltk.generated.interfaces.Timestamp; import kr.ac.kaist.resl.ltk.generated.parameters.AISpecEvent; import kr.ac.kaist.resl.ltk.generated.parameters.AntennaEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ConnectionAttemptEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ConnectionCloseEvent; import kr.ac.kaist.resl.ltk.generated.parameters.Custom; import kr.ac.kaist.resl.ltk.generated.parameters.GPIEvent; import kr.ac.kaist.resl.ltk.generated.parameters.HoppingEvent; import kr.ac.kaist.resl.ltk.generated.parameters.RFSurveyEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ROSpecEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ReaderExceptionEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ReportBufferLevelWarningEvent; import kr.ac.kaist.resl.ltk.generated.parameters.ReportBufferOverflowErrorEvent; import kr.ac.kaist.resl.ltk.generated.parameters.UTCTimestamp; import kr.ac.kaist.resl.ltk.generated.parameters.Uptime; import org.llrp.ltk.types.LLRPBitList; import org.llrp.ltk.types.LLRPMessage; import org.llrp.ltk.types.SignedShort; import org.llrp.ltk.types.TLVParameter; import org.llrp.ltk.types.TVParameter; import org.llrp.ltk.types.UnsignedShort; import java.util.LinkedList; import java.util.List; /** * This parameter describes the contents of the event notification sent by the Reader, and defines the events that cause the notification to be sent. Event notification messages may be sent by the Reader due to connection establishment/closing event, critical events such as hopping, fault-detection in a Reader functional block, buffer overflow, due to the activation of a Reader accessory trigger input (e.g. motion detection), or due to performance monitoring events such as abnormalities in the RF environment.Timestamp is the time that the events reported occurred.LLRP assumes a reliable stream transport mechanism. Messages sent through LLRP will arrive in the order that they were sent over the transport and binding utilized. Status events within the same message SHALL be ordered chronologically.Status events delivered by reader event notifications are useful, especially in conjunction with the tag report data. The following describes the requirements of the reader event notifications ordering with respect to the ordering of tag reports and Reader Event Notifications. The following requirements are made on the ordering of Event Parameters with respect to each other and to tag report Parameters. These statements apply if the respective status events and report triggers are enabled. If the start of an ROSpec is triggered by a GPI, the GPIEvent Parameter SHALL be sent before the ROSpecEvent Parameter signaling the start of the ROSpec.If the end of an ROSpec is triggered by a GPI, the GPIEvent Parameter SHALL be sent before the ROSpecEvent Parameter signaling the end of the ROSpec.If an ROSpec contains one or more AISpecs, the ROSpecEvent parameter signaling the end of an ROSpec SHALL be sent after the AISpecEvent Parameter signaling the end of the last AISpec within that ROSpec.If one ROSpec pre-empts another ROSpec, the ROSpecEvent parameter signaling the preemption of the first ROSpec SHALL be sent before the ROSpecEvent parameter signaling the start of the next ROSpec.Tag data received during an ROSpec execution SHALL be sent between the ROSpecEvent parameter signaling the start of the ROSpec and the ROSpecEvent parameter signaling the end or preemption of the ROSpec if the ROReportTrigger is not set to "None".Tag data received during an AISpec execution SHALL be sent before the AISpecEvent Parameter signaling the end of the AISpec if the ROReportTrigger is not "None" or "end of RO Spec"Tag data received during the time on a channel SHALL be sent after the HoppingEvent parameter that announced this channel and before the next HoppingEvent parameter when the ROReportTrigger is not "None" and N=1. See also {@link <a href="http://www.epcglobalinc.org/standards/llrp/llrp_1_0_1-standard-20070813.pdf#page=86&view=fit">LLRP Specification Section 13.2.6</a>} and {@link <a href="http://www.epcglobalinc.org/standards/llrp/llrp_1_0_1-standard-20070813.pdf#page=148&view=fit">LLRP Specification Section 16.2.7.6</a>} */ /** * This parameter describes the contents of the event notification sent by the Reader, and defines the events that cause the notification to be sent. Event notification messages may be sent by the Reader due to connection establishment/closing event, critical events such as hopping, fault-detection in a Reader functional block, buffer overflow, due to the activation of a Reader accessory trigger input (e.g. motion detection), or due to performance monitoring events such as abnormalities in the RF environment.Timestamp is the time that the events reported occurred.LLRP assumes a reliable stream transport mechanism. Messages sent through LLRP will arrive in the order that they were sent over the transport and binding utilized. Status events within the same message SHALL be ordered chronologically.Status events delivered by reader event notifications are useful, especially in conjunction with the tag report data. The following describes the requirements of the reader event notifications ordering with respect to the ordering of tag reports and Reader Event Notifications. The following requirements are made on the ordering of Event Parameters with respect to each other and to tag report Parameters. These statements apply if the respective status events and report triggers are enabled. If the start of an ROSpec is triggered by a GPI, the GPIEvent Parameter SHALL be sent before the ROSpecEvent Parameter signaling the start of the ROSpec.If the end of an ROSpec is triggered by a GPI, the GPIEvent Parameter SHALL be sent before the ROSpecEvent Parameter signaling the end of the ROSpec.If an ROSpec contains one or more AISpecs, the ROSpecEvent parameter signaling the end of an ROSpec SHALL be sent after the AISpecEvent Parameter signaling the end of the last AISpec within that ROSpec.If one ROSpec pre-empts another ROSpec, the ROSpecEvent parameter signaling the preemption of the first ROSpec SHALL be sent before the ROSpecEvent parameter signaling the start of the next ROSpec.Tag data received during an ROSpec execution SHALL be sent between the ROSpecEvent parameter signaling the start of the ROSpec and the ROSpecEvent parameter signaling the end or preemption of the ROSpec if the ROReportTrigger is not set to "None".Tag data received during an AISpec execution SHALL be sent before the AISpecEvent Parameter signaling the end of the AISpec if the ROReportTrigger is not "None" or "end of RO Spec"Tag data received during the time on a channel SHALL be sent after the HoppingEvent parameter that announced this channel and before the next HoppingEvent parameter when the ROReportTrigger is not "None" and N=1. See also {@link <a href="http://www.epcglobalinc.org/standards/llrp/llrp_1_0_1-standard-20070813.pdf#page=86&view=fit">LLRP Specification Section 13.2.6</a>} and {@link <a href="http://www.epcglobalinc.org/standards/llrp/llrp_1_0_1-standard-20070813.pdf#page=148&view=fit">LLRP Specification Section 16.2.7.6</a>} . */ public class ReaderEventNotificationData extends TLVParameter { public static final SignedShort TYPENUM = new SignedShort(246); private static final Logger LOGGER = Logger.getLogger(ReaderEventNotificationData.class); protected Timestamp timestamp; protected HoppingEvent hoppingEvent; protected GPIEvent gPIEvent; protected ROSpecEvent rOSpecEvent; protected ReportBufferLevelWarningEvent reportBufferLevelWarningEvent; protected ReportBufferOverflowErrorEvent reportBufferOverflowErrorEvent; protected ReaderExceptionEvent readerExceptionEvent; protected RFSurveyEvent rFSurveyEvent; protected AISpecEvent aISpecEvent; protected AntennaEvent antennaEvent; protected ConnectionAttemptEvent connectionAttemptEvent; protected ConnectionCloseEvent connectionCloseEvent; protected List<Custom> customList = new LinkedList<Custom>(); /** * empty constructor to create new parameter. */ public ReaderEventNotificationData() { } /** * Constructor to create parameter from binary encoded parameter * calls decodeBinary to decode parameter. * @param list to be decoded */ public ReaderEventNotificationData(LLRPBitList list) { decodeBinary(list); } /** * Constructor to create parameter from xml encoded parameter * calls decodeXML to decode parameter. * @param element to be decoded */ public ReaderEventNotificationData(Element element) throws InvalidLLRPMessageException { decodeXML(element); } /** * {@inheritDoc} */ public LLRPBitList encodeBinarySpecific() { LLRPBitList resultBits = new LLRPBitList(); if (timestamp == null) { // single parameter, may not be null LOGGER.warn(" timestamp not set"); throw new MissingParameterException(" timestamp not set"); } else { resultBits.append(timestamp.encodeBinary()); } if (hoppingEvent == null) { // optional parameter, may be null LOGGER.info(" hoppingEvent not set"); } else { resultBits.append(hoppingEvent.encodeBinary()); } if (gPIEvent == null) { // optional parameter, may be null LOGGER.info(" gPIEvent not set"); } else { resultBits.append(gPIEvent.encodeBinary()); } if (rOSpecEvent == null) { // optional parameter, may be null LOGGER.info(" rOSpecEvent not set"); } else { resultBits.append(rOSpecEvent.encodeBinary()); } if (reportBufferLevelWarningEvent == null) { // optional parameter, may be null LOGGER.info(" reportBufferLevelWarningEvent not set"); } else { resultBits.append(reportBufferLevelWarningEvent.encodeBinary()); } if (reportBufferOverflowErrorEvent == null) { // optional parameter, may be null LOGGER.info(" reportBufferOverflowErrorEvent not set"); } else { resultBits.append(reportBufferOverflowErrorEvent.encodeBinary()); } if (readerExceptionEvent == null) { // optional parameter, may be null LOGGER.info(" readerExceptionEvent not set"); } else { resultBits.append(readerExceptionEvent.encodeBinary()); } if (rFSurveyEvent == null) { // optional parameter, may be null LOGGER.info(" rFSurveyEvent not set"); } else { resultBits.append(rFSurveyEvent.encodeBinary()); } if (aISpecEvent == null) { // optional parameter, may be null LOGGER.info(" aISpecEvent not set"); } else { resultBits.append(aISpecEvent.encodeBinary()); } if (antennaEvent == null) { // optional parameter, may be null LOGGER.info(" antennaEvent not set"); } else { resultBits.append(antennaEvent.encodeBinary()); } if (connectionAttemptEvent == null) { // optional parameter, may be null LOGGER.info(" connectionAttemptEvent not set"); } else { resultBits.append(connectionAttemptEvent.encodeBinary()); } if (connectionCloseEvent == null) { // optional parameter, may be null LOGGER.info(" connectionCloseEvent not set"); } else { resultBits.append(connectionCloseEvent.encodeBinary()); } if (customList == null) { //just warn - it is optional LOGGER.info(" customList not set"); } else { for (Custom field : customList) { resultBits.append(field.encodeBinary()); } } return resultBits; } /** * {@inheritDoc} */ public Content encodeXML(String name, Namespace ns) { // element in namespace defined by parent element Element element = new Element(name, ns); // child element are always in default LLRP namespace ns = Namespace.getNamespace("llrp", LLRPConstants.LLRPNAMESPACE); //parameters if (timestamp == null) { LOGGER.info("timestamp not set"); throw new MissingParameterException("timestamp not set"); } else { element.addContent(timestamp.encodeXML(timestamp.getClass() .getSimpleName(), ns)); } if (hoppingEvent == null) { LOGGER.info("hoppingEvent not set"); } else { element.addContent(hoppingEvent.encodeXML( hoppingEvent.getClass().getSimpleName(), ns)); } if (gPIEvent == null) { LOGGER.info("gPIEvent not set"); } else { element.addContent(gPIEvent.encodeXML(gPIEvent.getClass() .getSimpleName(), ns)); } if (rOSpecEvent == null) { LOGGER.info("rOSpecEvent not set"); } else { element.addContent(rOSpecEvent.encodeXML(rOSpecEvent.getClass() .getSimpleName(), ns)); } if (reportBufferLevelWarningEvent == null) { LOGGER.info("reportBufferLevelWarningEvent not set"); } else { element.addContent(reportBufferLevelWarningEvent.encodeXML( reportBufferLevelWarningEvent.getClass().getSimpleName(), ns)); } if (reportBufferOverflowErrorEvent == null) { LOGGER.info("reportBufferOverflowErrorEvent not set"); } else { element.addContent(reportBufferOverflowErrorEvent.encodeXML( reportBufferOverflowErrorEvent.getClass().getSimpleName(), ns)); } if (readerExceptionEvent == null) { LOGGER.info("readerExceptionEvent not set"); } else { element.addContent(readerExceptionEvent.encodeXML( readerExceptionEvent.getClass().getSimpleName(), ns)); } if (rFSurveyEvent == null) { LOGGER.info("rFSurveyEvent not set"); } else { element.addContent(rFSurveyEvent.encodeXML( rFSurveyEvent.getClass().getSimpleName(), ns)); } if (aISpecEvent == null) { LOGGER.info("aISpecEvent not set"); } else { element.addContent(aISpecEvent.encodeXML(aISpecEvent.getClass() .getSimpleName(), ns)); } if (antennaEvent == null) { LOGGER.info("antennaEvent not set"); } else { element.addContent(antennaEvent.encodeXML( antennaEvent.getClass().getSimpleName(), ns)); } if (connectionAttemptEvent == null) { LOGGER.info("connectionAttemptEvent not set"); } else { element.addContent(connectionAttemptEvent.encodeXML( connectionAttemptEvent.getClass().getSimpleName(), ns)); } if (connectionCloseEvent == null) { LOGGER.info("connectionCloseEvent not set"); } else { element.addContent(connectionCloseEvent.encodeXML( connectionCloseEvent.getClass().getSimpleName(), ns)); } if (customList == null) { LOGGER.info("customList not set"); } else { for (Custom field : customList) { element.addContent(field.encodeXML(field.getClass().getName() .replaceAll(field.getClass() .getPackage() .getName() + ".", ""), ns)); } } return element; } /** * {@inheritDoc} */ protected void decodeBinarySpecific(LLRPBitList binary) { int position = 0; int tempByteLength; int tempLength = 0; int count; SignedShort type; int fieldCount; Custom custom; // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.warn( "ReaderEventNotificationData misses non optional parameter of type Timestamp"); throw new MissingParameterException( "ReaderEventNotificationData misses non optional parameter of type Timestamp"); } boolean found = false; LOGGER.debug("decoding choice type Timestamp "); //if first bit is 1 it is a TV Parameter if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = UTCTimestamp.length(); } if ((type != null) && type.equals(UTCTimestamp.TYPENUM)) { timestamp = new UTCTimestamp(binary.subList(position, tempLength)); LOGGER.debug(" timestamp instatiated to UTCTimestamp with length " + tempLength); position += tempLength; found = true; } //if first bit is 1 it is a TV Parameter if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = Uptime.length(); } if ((type != null) && type.equals(Uptime.TYPENUM)) { timestamp = new Uptime(binary.subList(position, tempLength)); LOGGER.debug(" timestamp instatiated to Uptime with length " + tempLength); position += tempLength; found = true; } if (!found) { LOGGER.warn( "encoded message misses non optional parameter timestamp"); throw new MissingParameterException( "ReaderEventNotificationData misses non optional parameter of type Timestamp"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type HoppingEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = hoppingEvent.length(); } if ((type != null) && type.equals(HoppingEvent.TYPENUM)) { hoppingEvent = new HoppingEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug( " hoppingEvent is instantiated with HoppingEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type HoppingEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type GPIEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = gPIEvent.length(); } if ((type != null) && type.equals(GPIEvent.TYPENUM)) { gPIEvent = new GPIEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug(" gPIEvent is instantiated with GPIEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type GPIEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ROSpecEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = rOSpecEvent.length(); } if ((type != null) && type.equals(ROSpecEvent.TYPENUM)) { rOSpecEvent = new ROSpecEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug( " rOSpecEvent is instantiated with ROSpecEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ROSpecEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReportBufferLevelWarningEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = reportBufferLevelWarningEvent.length(); } if ((type != null) && type.equals(ReportBufferLevelWarningEvent.TYPENUM)) { reportBufferLevelWarningEvent = new ReportBufferLevelWarningEvent(binary.subList( position, tempLength)); position += tempLength; LOGGER.debug( " reportBufferLevelWarningEvent is instantiated with ReportBufferLevelWarningEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReportBufferLevelWarningEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReportBufferOverflowErrorEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = reportBufferOverflowErrorEvent.length(); } if ((type != null) && type.equals(ReportBufferOverflowErrorEvent.TYPENUM)) { reportBufferOverflowErrorEvent = new ReportBufferOverflowErrorEvent(binary.subList( position, tempLength)); position += tempLength; LOGGER.debug( " reportBufferOverflowErrorEvent is instantiated with ReportBufferOverflowErrorEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReportBufferOverflowErrorEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReaderExceptionEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = readerExceptionEvent.length(); } if ((type != null) && type.equals(ReaderExceptionEvent.TYPENUM)) { readerExceptionEvent = new ReaderExceptionEvent(binary.subList( position, tempLength)); position += tempLength; LOGGER.debug( " readerExceptionEvent is instantiated with ReaderExceptionEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ReaderExceptionEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type RFSurveyEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = rFSurveyEvent.length(); } if ((type != null) && type.equals(RFSurveyEvent.TYPENUM)) { rFSurveyEvent = new RFSurveyEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug( " rFSurveyEvent is instantiated with RFSurveyEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type RFSurveyEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type AISpecEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = aISpecEvent.length(); } if ((type != null) && type.equals(AISpecEvent.TYPENUM)) { aISpecEvent = new AISpecEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug( " aISpecEvent is instantiated with AISpecEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type AISpecEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type AntennaEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = antennaEvent.length(); } if ((type != null) && type.equals(AntennaEvent.TYPENUM)) { antennaEvent = new AntennaEvent(binary.subList(position, tempLength)); position += tempLength; LOGGER.debug( " antennaEvent is instantiated with AntennaEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type AntennaEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ConnectionAttemptEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = connectionAttemptEvent.length(); } if ((type != null) && type.equals(ConnectionAttemptEvent.TYPENUM)) { connectionAttemptEvent = new ConnectionAttemptEvent(binary.subList( position, tempLength)); position += tempLength; LOGGER.debug( " connectionAttemptEvent is instantiated with ConnectionAttemptEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ConnectionAttemptEvent"); } // look ahead to see type // may be optional or exactly once type = null; tempByteLength = 0; tempLength = 0; try { // if first bit is one it is a TV Parameter if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } } catch (IllegalArgumentException le) { // if an IllegalArgumentException is thrown, list was not long enough so the parameter is missing LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ConnectionCloseEvent"); } if (binary.get(position)) { // length can statically be determined for TV Parameters tempLength = connectionCloseEvent.length(); } if ((type != null) && type.equals(ConnectionCloseEvent.TYPENUM)) { connectionCloseEvent = new ConnectionCloseEvent(binary.subList( position, tempLength)); position += tempLength; LOGGER.debug( " connectionCloseEvent is instantiated with ConnectionCloseEvent with length" + tempLength); } else { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type ConnectionCloseEvent"); } // list of parameters customList = new LinkedList<Custom>(); LOGGER.debug("decoding parameter customList "); while (position < binary.length()) { // store if one parameter matched boolean atLeastOnce = false; // look ahead to see type if (binary.get(position)) { // do not take the first bit as it is always 1 type = new SignedShort(binary.subList(position + 1, 7)); } else { type = new SignedShort(binary.subList(position + RESERVEDLENGTH, TYPENUMBERLENGTH)); tempByteLength = new UnsignedShort(binary.subList(position + RESERVEDLENGTH + TYPENUMBERLENGTH, UnsignedShort.length())).toShort(); tempLength = 8 * tempByteLength; } // custom if ((type != null) && type.equals(Custom.TYPENUM)) { Custom cus = new Custom(binary.subList(position, tempLength)); // custom parameters for this parameter // ReaderEventNotificationData //end parameters //if none matched continue wasn't called and we add just cus as we found no specific vendor implementation customList.add(cus); position += tempLength; atLeastOnce = true; } if (!atLeastOnce) { //no parameter matched therefore we jump out of the loop break; } } //if list is still empty no parameter matched if (customList.isEmpty()) { LOGGER.info( "encoded message does not contain parameter for optional customList"); } } /** * {@inheritDoc} */ public void decodeXML(Element element) throws InvalidLLRPMessageException { List<Element> tempList = null; boolean atLeastOnce = false; Custom custom; Element temp = null; // child element are always in default LLRP namespace Namespace ns = Namespace.getNamespace(LLRPConstants.LLRPNAMESPACE); //choices - must check all possible subtypes boolean found = false; LOGGER.debug("decoding choice type Timestamp "); // try to get child for each possible subtype temp = element.getChild("UTCTimestamp", ns); if (temp != null) { timestamp = new UTCTimestamp(temp); LOGGER.debug(" timestamp instatiated to UTCTimestamp with"); found = true; } element.removeChild("UTCTimestamp", ns); // try to get child for each possible subtype temp = element.getChild("Uptime", ns); if (temp != null) { timestamp = new Uptime(temp); LOGGER.debug(" timestamp instatiated to Uptime with"); found = true; } element.removeChild("Uptime", ns); if (!found) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type timestampList"); } //parameter - not choices - no special actions needed temp = element.getChild("HoppingEvent", ns); if (temp != null) { hoppingEvent = new HoppingEvent(temp); LOGGER.info( "setting parameter hoppingEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type hoppingEvent"); } element.removeChild("HoppingEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("GPIEvent", ns); if (temp != null) { gPIEvent = new GPIEvent(temp); LOGGER.info( "setting parameter gPIEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type gPIEvent"); } element.removeChild("GPIEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ROSpecEvent", ns); if (temp != null) { rOSpecEvent = new ROSpecEvent(temp); LOGGER.info( "setting parameter rOSpecEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type rOSpecEvent"); } element.removeChild("ROSpecEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ReportBufferLevelWarningEvent", ns); if (temp != null) { reportBufferLevelWarningEvent = new ReportBufferLevelWarningEvent(temp); LOGGER.info( "setting parameter reportBufferLevelWarningEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type reportBufferLevelWarningEvent"); } element.removeChild("ReportBufferLevelWarningEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ReportBufferOverflowErrorEvent", ns); if (temp != null) { reportBufferOverflowErrorEvent = new ReportBufferOverflowErrorEvent(temp); LOGGER.info( "setting parameter reportBufferOverflowErrorEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type reportBufferOverflowErrorEvent"); } element.removeChild("ReportBufferOverflowErrorEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ReaderExceptionEvent", ns); if (temp != null) { readerExceptionEvent = new ReaderExceptionEvent(temp); LOGGER.info( "setting parameter readerExceptionEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type readerExceptionEvent"); } element.removeChild("ReaderExceptionEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("RFSurveyEvent", ns); if (temp != null) { rFSurveyEvent = new RFSurveyEvent(temp); LOGGER.info( "setting parameter rFSurveyEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type rFSurveyEvent"); } element.removeChild("RFSurveyEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("AISpecEvent", ns); if (temp != null) { aISpecEvent = new AISpecEvent(temp); LOGGER.info( "setting parameter aISpecEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type aISpecEvent"); } element.removeChild("AISpecEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("AntennaEvent", ns); if (temp != null) { antennaEvent = new AntennaEvent(temp); LOGGER.info( "setting parameter antennaEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type antennaEvent"); } element.removeChild("AntennaEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ConnectionAttemptEvent", ns); if (temp != null) { connectionAttemptEvent = new ConnectionAttemptEvent(temp); LOGGER.info( "setting parameter connectionAttemptEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type connectionAttemptEvent"); } element.removeChild("ConnectionAttemptEvent", ns); //parameter - not choices - no special actions needed temp = element.getChild("ConnectionCloseEvent", ns); if (temp != null) { connectionCloseEvent = new ConnectionCloseEvent(temp); LOGGER.info( "setting parameter connectionCloseEvent for parameter ReaderEventNotificationData"); } if (temp == null) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type connectionCloseEvent"); } element.removeChild("ConnectionCloseEvent", ns); //parameter - not choices - no special actions needed //we expect a list of parameters customList = new LinkedList<Custom>(); tempList = element.getChildren("Custom", ns); if ((tempList == null) || tempList.isEmpty()) { LOGGER.info( "ReaderEventNotificationData misses optional parameter of type customList"); } else { for (Element e : tempList) { customList.add(new Custom(e)); LOGGER.debug("adding Custom to customList "); } } element.removeChildren("Custom", ns); //custom parameter tempList = element.getChildren("Custom", ns); for (Element e : tempList) { customList.add(new Custom(e)); atLeastOnce = true; LOGGER.debug("adding custom parameter"); } element.removeChildren("Custom", ns); //end custom if (element.getChildren().size() > 0) { String message = "ReaderEventNotificationData has unknown element " + ((Element) element.getChildren().get(0)).getName(); throw new InvalidLLRPMessageException(message); } } //setters /** * set timestamp of type Timestamp. * @param timestamp to be set */ public void setTimestamp(final Timestamp timestamp) { this.timestamp = timestamp; } /** * set hoppingEvent of type HoppingEvent. * @param hoppingEvent to be set */ public void setHoppingEvent(final HoppingEvent hoppingEvent) { this.hoppingEvent = hoppingEvent; } /** * set gPIEvent of type GPIEvent. * @param gPIEvent to be set */ public void setGPIEvent(final GPIEvent gPIEvent) { this.gPIEvent = gPIEvent; } /** * set rOSpecEvent of type ROSpecEvent. * @param rOSpecEvent to be set */ public void setROSpecEvent(final ROSpecEvent rOSpecEvent) { this.rOSpecEvent = rOSpecEvent; } /** * set reportBufferLevelWarningEvent of type ReportBufferLevelWarningEvent. * @param reportBufferLevelWarningEvent to be set */ public void setReportBufferLevelWarningEvent( final ReportBufferLevelWarningEvent reportBufferLevelWarningEvent) { this.reportBufferLevelWarningEvent = reportBufferLevelWarningEvent; } /** * set reportBufferOverflowErrorEvent of type ReportBufferOverflowErrorEvent. * @param reportBufferOverflowErrorEvent to be set */ public void setReportBufferOverflowErrorEvent( final ReportBufferOverflowErrorEvent reportBufferOverflowErrorEvent) { this.reportBufferOverflowErrorEvent = reportBufferOverflowErrorEvent; } /** * set readerExceptionEvent of type ReaderExceptionEvent. * @param readerExceptionEvent to be set */ public void setReaderExceptionEvent( final ReaderExceptionEvent readerExceptionEvent) { this.readerExceptionEvent = readerExceptionEvent; } /** * set rFSurveyEvent of type RFSurveyEvent. * @param rFSurveyEvent to be set */ public void setRFSurveyEvent(final RFSurveyEvent rFSurveyEvent) { this.rFSurveyEvent = rFSurveyEvent; } /** * set aISpecEvent of type AISpecEvent. * @param aISpecEvent to be set */ public void setAISpecEvent(final AISpecEvent aISpecEvent) { this.aISpecEvent = aISpecEvent; } /** * set antennaEvent of type AntennaEvent. * @param antennaEvent to be set */ public void setAntennaEvent(final AntennaEvent antennaEvent) { this.antennaEvent = antennaEvent; } /** * set connectionAttemptEvent of type ConnectionAttemptEvent. * @param connectionAttemptEvent to be set */ public void setConnectionAttemptEvent( final ConnectionAttemptEvent connectionAttemptEvent) { this.connectionAttemptEvent = connectionAttemptEvent; } /** * set connectionCloseEvent of type ConnectionCloseEvent. * @param connectionCloseEvent to be set */ public void setConnectionCloseEvent( final ConnectionCloseEvent connectionCloseEvent) { this.connectionCloseEvent = connectionCloseEvent; } /** * set customList of type List <Custom>. * @param customList to be set */ public void setCustomList(final List<Custom> customList) { this.customList = customList; } // end setter //getters /** * get timestamp of type Timestamp . * @return Timestamp */ public Timestamp getTimestamp() { return timestamp; } /** * get hoppingEvent of type HoppingEvent . * @return HoppingEvent */ public HoppingEvent getHoppingEvent() { return hoppingEvent; } /** * get gPIEvent of type GPIEvent . * @return GPIEvent */ public GPIEvent getGPIEvent() { return gPIEvent; } /** * get rOSpecEvent of type ROSpecEvent . * @return ROSpecEvent */ public ROSpecEvent getROSpecEvent() { return rOSpecEvent; } /** * get reportBufferLevelWarningEvent of type ReportBufferLevelWarningEvent . * @return ReportBufferLevelWarningEvent */ public ReportBufferLevelWarningEvent getReportBufferLevelWarningEvent() { return reportBufferLevelWarningEvent; } /** * get reportBufferOverflowErrorEvent of type ReportBufferOverflowErrorEvent . * @return ReportBufferOverflowErrorEvent */ public ReportBufferOverflowErrorEvent getReportBufferOverflowErrorEvent() { return reportBufferOverflowErrorEvent; } /** * get readerExceptionEvent of type ReaderExceptionEvent . * @return ReaderExceptionEvent */ public ReaderExceptionEvent getReaderExceptionEvent() { return readerExceptionEvent; } /** * get rFSurveyEvent of type RFSurveyEvent . * @return RFSurveyEvent */ public RFSurveyEvent getRFSurveyEvent() { return rFSurveyEvent; } /** * get aISpecEvent of type AISpecEvent . * @return AISpecEvent */ public AISpecEvent getAISpecEvent() { return aISpecEvent; } /** * get antennaEvent of type AntennaEvent . * @return AntennaEvent */ public AntennaEvent getAntennaEvent() { return antennaEvent; } /** * get connectionAttemptEvent of type ConnectionAttemptEvent . * @return ConnectionAttemptEvent */ public ConnectionAttemptEvent getConnectionAttemptEvent() { return connectionAttemptEvent; } /** * get connectionCloseEvent of type ConnectionCloseEvent . * @return ConnectionCloseEvent */ public ConnectionCloseEvent getConnectionCloseEvent() { return connectionCloseEvent; } /** * get customList of type List <Custom> . * @return List <Custom> */ public List<Custom> getCustomList() { return customList; } // end getters //add methods /** * add element custom of type Custom . * @param custom of type Custom */ public void addToCustomList(Custom custom) { if (this.customList == null) { this.customList = new LinkedList<Custom>(); } this.customList.add(custom); } // end add /** * For TLV Parameter length can not be determined at compile time. This method therefore always returns 0. * @return Integer always zero */ public static Integer length() { return 0; } /** * {@inheritDoc} */ public SignedShort getTypeNum() { return TYPENUM; } /** * {@inheritDoc} */ public String getName() { return "ReaderEventNotificationData"; } /** * return string representation. All field values but no parameters are included * @return String */ public String toString() { String result = "ReaderEventNotificationData: "; result = result.replaceFirst(", ", ""); return result; } }