/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package testapplication;
import java.io.File;

import org.apache.log4j.Logger;
import org.llrp.ltk.generated.enumerations.StatusCode;
import org.llrp.ltk.generated.messages.ADD_ROSPEC_RESPONSE;
import org.llrp.ltk.generated.messages.CLOSE_CONNECTION;
import org.llrp.ltk.generated.messages.DELETE_ROSPEC;
import org.llrp.ltk.generated.messages.ENABLE_ROSPEC;
import org.llrp.ltk.generated.messages.RO_ACCESS_REPORT;
import org.llrp.ltk.generated.messages.START_ROSPEC;
import org.llrp.ltk.generated.parameters.EPC_96;
import org.llrp.ltk.generated.parameters.TagReportData;
import org.llrp.ltk.net.LLRPConnection;
import org.llrp.ltk.net.LLRPConnectionAttemptFailedException;
import org.llrp.ltk.net.LLRPConnector;
import org.llrp.ltk.net.LLRPEndpoint;
import org.llrp.ltk.types.LLRPMessage;
import org.llrp.ltk.types.UnsignedInteger;
import org.llrp.ltk.util.Util;

public class LTKJavaExample implements LLRPEndpoint {

	private LLRPConnection connection;
	private static Logger logger;

	public LTKJavaExample() {

                logger = Logger.getLogger(LTKJavaExample.class);
		configure();

	}

	private void configure() {

		// set IP address of RFID reader
		String READER_IP_ADDRESS = "127.0.0.1";

		// create client-initiated LLRP connection

		connection = new LLRPConnector(this, READER_IP_ADDRESS);

		// connect to reader
		// LLRPConnector.connect waits for successful
		// READER_EVENT_NOTIFICATION from reader

		try {
			logger.info("Initiate LLRP connection to reader");
			((LLRPConnector) connection).connect();
		} catch (LLRPConnectionAttemptFailedException e1) {
			e1.printStackTrace();
			System.exit(1);
		}



		LLRPMessage response;

		try {

			// delete ROSpec
			logger.info("Delete ROSPEC message ...");
			DELETE_ROSPEC del = new DELETE_ROSPEC();
			del.setROSpecID(new UnsignedInteger(1));
			response =  connection.transact(del, 10000);

			// load ADD_ROSPEC message
			logger.info("Loading ADD_ROSPEC message from file ADD_ROSPEC.xml ...");
			LLRPMessage addRospec = Util.loadXMLLLRPMessage(new File("D:/ADD_ROSPEC.xml"));



			// send message to LLRP reader and wait for response

			logger.info("Sending ADD_ROSPEC message ...");
			response =  connection.transact(addRospec, 10000);

			// check whether ROSpec addition was successful
			StatusCode status = ((ADD_ROSPEC_RESPONSE)response).getLLRPStatus().getStatusCode();
			if (status.equals(new StatusCode("M_Success"))) {
				logger.info("Addition of ROSPEC was successful");
			}
			else {
				logger.info(response.toXMLString());
				logger.info("Addition of ROSPEC was unsuccessful, exiting");
				System.exit(1);
			}

			logger.info("Enable ROSPEC ...");
			ENABLE_ROSPEC enable = new ENABLE_ROSPEC();
			enable.setROSpecID(new UnsignedInteger(1));
			response = connection.transact(enable, 10000);


			logger.info("Start ROSPEC ...");
			START_ROSPEC start = new START_ROSPEC();
			start.setROSpecID(new UnsignedInteger(1));
			response = connection.transact(start, 10000);

            try {
				Thread.sleep(5000);
			}
			catch (Exception ig) {}

			del.setROSpecID(new UnsignedInteger(1));
			response =  connection.transact(del, 10000);

			CLOSE_CONNECTION cc = new CLOSE_CONNECTION();
			response = connection.transact(cc, 10000);

			((LLRPConnector) connection).disconnect();

		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}


		logger.info("RO_ACCESS_REPORT will be arriving asynchronously ...");

	}

	// messageReceived method is called whenever a message is received
	// asynchronously on the LLRP connection.

	public void messageReceived(LLRPMessage message) {

		// convert all messages received to LTK-XML representation
		// and print them to the console

		logger.info("Received " + message.getName() + " message asychronously");

                if (message instanceof RO_ACCESS_REPORT) {

                    RO_ACCESS_REPORT rMsg = ((RO_ACCESS_REPORT)message);

                    for (TagReportData td : rMsg.getTagReportDataList()) {

                        logger.info(td.getEPCParameter().getClass());
                        logger.info(((EPC_96)td.getEPCParameter()).getEPC());
                    }
                }
	}

	public void errorOccured(String s) {

		logger.info("Error Occured: " + s);

	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {

		LTKJavaExample example = new LTKJavaExample();

	}

}