REDERNAME Module.java

From RifidiWiki

Jump to: navigation, search

The readerModule is the constructor for the reader. Every reader needs one of these classes. The class needs to extend AbstractPowerModule and implement ReaderModule.

READERNAMEModule

This is the main constructor for the reader There should actually be two constructors. One is an empty constructor that is needed for jaxb to automatically create the reader. It should look like this:

	public SymbolReaderModule(){
	}

The readermodule also needs a main constructor with this signature:

	public SymbolReaderModule(ControlSignal<Boolean> powerControlSignal,GeneralReaderPropertyHolder properties);

Arguments

  1. powerControlSignal - The power control signal for the entire reader. It is used to turn the reader on and off as well as to suspend and resume the reader. See information on the power states in the module package for more explanation of this.
  2. properties - These are the properties that the reader creation wizzard constructed. The GeneralReaderPropertyHolder contains the information required by the emulator.xml.

Reference Implementation

This is the constructor for the SymbolReaderModule.

	public SymbolReaderModule(ControlSignal<Boolean> powerControlSignal,
			GeneralReaderPropertyHolder properties) {

always start out with a call to the super class

                super(SymbolReaderModuleOffPowerState.getInstance(),powerControlSignal);

write some basic information to the console to let the user know that the reader is starting. Note that we are getting some information from the generalRederProperyHolder

		consoleLogger = LogFactory.getLog("console."
				+ properties.getReaderName());
		consoleLogger.info(SymbolReaderModule.startupText
				+ "Instantiated Symbol Reader with name: "
				+ properties.getReaderName());
		consoleLogger.info(SymbolReaderModule.startupText
				+ properties.getReaderName() + " IP Address: "
				+ properties.getProperty("byte_address"));
		consoleLogger.info(SymbolReaderModule.startupText
				+ properties.getReaderName() + " has "
				+ properties.getNumAntennas() + " antennas");

set the name of the reader equal to the name given in the generalReaderPropertyHolder

		this.name = properties.getReaderName();

Initialize the digester and read in the command hander methods supplied in the reader.xml file

		digester = new CommandXMLDigester();
		digester.parseToCommand(this.getClass().getClassLoader()
				.getResourceAsStream(XMLLOCATION + "reader.xml"));

Create a new tag memory, create antennas, create a new radio and supply the tagMemory and antennas to the radio

		SymbolTagMemory tagMemory = new SymbolTagMemory();

		HashMap<Integer, Antenna> antennaList = new HashMap<Integer, Antenna>();
		for (int i = 0; i < properties.getNumAntennas(); i++) {
			logger.debug("creating an antenna: " + i);
			antennaList.put(i, new Antenna(i));
		}

		/* Make a Radio for the reader */
		GenericRadio genericRadio = new GenericRadio(antennaList, 25, tagMemory);

The symbol reader has two different IP addresses being used. One is for byte commands, and the other is for HTTP commands. parse out the IPs and ports from the GeneralReaderPropertyHolder

		String byte_address = ((String) properties.getProperty("byte_address"))
				.split(":")[0];
		int byte_port = Integer.parseInt(((String) properties
				.getProperty("byte_address")).split(":")[1]);

		String http_address = ((String) properties.getProperty("http_address"))
				.split(":")[0];
		int http_port = Integer.parseInt(((String) properties
				.getProperty("http_address")).split(":")[1]);

create the shared resources and supply necessary information to it

		this.srsr = new SymbolReaderSharedResources(genericRadio, tagMemory,
				new ControlSignal<Boolean>(false), name, null, digester,
				new ControlSignal<Boolean>(false), new ControlSignal<Boolean>(
						false), new ControlSignal<Boolean>(false),
				new ControlSignal<Boolean>(false), antennaList.size());

Create the communication objects. In this case, we need two communication objects (one for bytes, and one for http), however, most readers will probably only need one. Notice that this is where we supply the reader with the Protocol, Stream Reader, and Log Formatter

		this.httpComm = new TCPServerCommunication(new RawProtocol(), this.srsr
				.getInteractiveHttpPowerSignal(), this.srsr
				.getInteractiveHttpConnectionSignal(), http_address, http_port,
				this.name, GenericByteStreamReader.class, new GenericByteLogFormatter());

		this.byteComm = new TCPServerCommunication(new RawProtocol(), this.srsr
				.getInteractiveBytePowerSignal(), this.srsr
				.getInteractiveByteConnectionSignal(), byte_address, byte_port,
				this.name, GenericByteStreamReader.class, new GenericByteLogFormatter());

Build the adapters for this reader. Again, because the Symbol reader has two ways of communicating, we need two adapters. See Command Flow for more information about the adapter. This is where we supply the reader with the CommandFormatter and the ExceptionHandler

		this.interactiveBitAdapter = new ReflectiveCommandAdapter(
				"Interactive", new SymbolBitCommandFormatter(), new SymbolBitExceptionHandler(),
				this.srsr, new RawCommandSearcher());

		this.interactiveHttpAdapter = new ReflectiveCommandAdapter(
				"Interactive", null, new SymbolBitExceptionHandler(), this.srsr, new RawCommandSearcher());

Build the controllers.

		this.interactiveBitController = new InteractiveCommandController(
				new LoginAuthenticatedCommandControllerOperatingState(
						interactiveBitAdapter), this.srsr
						.getInteractiveBytePowerSignal(), this.srsr
						.getInteractiveByteConnectionSignal(), this.byteComm);

		this.interactiveHttpController = new InteractiveCommandController(
				new LoginAuthenticatedCommandControllerOperatingState(
						interactiveHttpAdapter), this.srsr
						.getInteractiveHttpPowerSignal(), this.srsr
						.getInteractiveHttpConnectionSignal(), this.httpComm);
	}

Other Notes

Here is an example from the Thing Magic reader:

		this.RQLComm = new TCPServerCommunication(new ThingMagicProtocol(), this.tmsr
				.getInteractiveRQLPowerSignal(), this.tmsr
				.getInteractiveRQLConnectionSignal(), rql_address, rql_port,
				this.name, GenericCharStreamReader.class, new GenericStringLogFormatter());

Notice the difference of this from the Symbol example. We are using GenericCharStreamReader and GenericStringLogFormatter instead. These are used when a client can be a standard telnet connection (another example of this is the Alien reader).

In addition, if you need to override the default command searcher, RawCommandSearcher, then replace this class with a different implementation and pass it to ReflectiveCommandAdapter instead of the default one.


Also, one can add a few more parameters to ones implementation of the shared resources if it that information (object or primitive type) if it is needed across different areas of the reader (including its accessors and mutators if needed).

Other Methods

The ReaderModule will also need to implement some other methods required by the interface that it implements, however, these methods should be nearly identical to similar methods in the other readers. Please see the other readers and follow examples there for more information.

Personal tools