/*
* 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.net;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.log4j.Logger;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import kr.ac.kaist.resl.ltk.generated.messages.KEEPALIVE;
import kr.ac.kaist.resl.ltk.generated.messages.KEEPALIVE_ACK;
import kr.ac.kaist.resl.ltk.generated.messages.READER_EVENT_NOTIFICATION;
import kr.ac.kaist.resl.ltk.generated.parameters.ConnectionAttemptEvent;
import org.llrp.ltk.types.LLRPMessage;
/**
*
* LLRPIoHandlerAdapterImpl is the default implementation of the LLRPIoHandlerAdapter.
* It handles incoming messages: routes incoming asynchronous messages
* to the LLRPEndpoint registered, replies to KEEP_ALIVE messages and handles incoming READER_NOTIFICATION
* messages and responses to synchronous calls.
*
*/
public class LLRPIoHandlerAdapterImpl extends LLRPIoHandlerAdapter{
private Logger log = Logger.getLogger(LLRPIoHandlerAdapterImpl.class);
private LLRPConnection connection;
private BlockingQueue<LLRPMessage> synMessageQueue = new LinkedBlockingQueue<LLRPMessage>();
private BlockingQueue<ConnectionAttemptEvent> connectionAttemptEventQueue = new LinkedBlockingQueue<ConnectionAttemptEvent>(1);
private boolean keepAliveAck = true;
private boolean keepAliveForward = false;
public LLRPIoHandlerAdapterImpl(LLRPConnection connection) {
this.connection = connection;
}
public LLRPIoHandlerAdapterImpl() {
}
/**
* {@inheritDoc}
*/
public void sessionOpened(IoSession session) throws Exception {
log.debug("session is opened:"+session);
this.connection.session = session;
}
/**
* is called whenever an LLRP Message is received. The method replies to incoming
* KEEP_ALIVE messages by sending an KEEP_ALIVE_ACK when the keepAliveAck flag is set.
* ConnectionAttemptEvents of incoming are stored in a queue that can be retrieved using
* the getConnectionAttemptEventQueue method. messageReceived also checks whether the
* incoming message is a response to previously method sent via the LLRPConnection.transact
* method. Matching messages are stored in a queue that can be retrieved via the
* getSynMessageQueue() method. All incoming messages except KEEP_ALIVE and those identified
* as synchronous responses to the LLRPConnection.transact method are passed to the
* LLRPEndpoint registered.
*/
public void messageReceived(IoSession session, Object message)
throws Exception {
LLRPMessage llrpMessage = (LLRPMessage) message;
log.info("message "+message.getClass()+" received in session "+session);
if (log.isDebugEnabled()) {
log.debug(llrpMessage.toXMLString());
}
if(message instanceof KEEPALIVE){
if (keepAliveForward) {
connection.getEndpoint().messageReceived(llrpMessage);
}
if(keepAliveAck){
session.write(new KEEPALIVE_ACK());
return;
}
}
if (llrpMessage instanceof READER_EVENT_NOTIFICATION) {
ConnectionAttemptEvent connectionAttemptEvent = ((READER_EVENT_NOTIFICATION)message).getReaderEventNotificationData().getConnectionAttemptEvent();
if(connectionAttemptEvent != null){
connectionAttemptEventQueue.add(connectionAttemptEvent);
connection.getEndpoint().messageReceived(llrpMessage);
return;
}
}
String expectedSyncMessage = (String) session.getAttribute(LLRPConnection.SYNC_MESSAGE_ANSWER);
// send message only if not already handled by synchronous call
if (!llrpMessage.getName().equals(expectedSyncMessage)){
log.debug("Calling messageReceived of endpoint ... "+session);
connection.getEndpoint().messageReceived(llrpMessage);
}else{
synMessageQueue.add(llrpMessage);
log.debug("Adding message "+message.getClass()+" to transaction queue "+session);
}
}
/**
* {@inheritDoc}
*/
public void messageSent(IoSession session, Object message) throws java.lang.Exception {
if (log.isInfoEnabled()) {
log.info( "Message " + ((LLRPMessage)message).getName() + " successfully transmitted");
}
if (log.isDebugEnabled()) {
log.debug(((LLRPMessage)message).toXMLString());
}
}
/**
* {@inheritDoc}
*/
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
connection.getEndpoint().errorOccured(cause.getClass().getName());
}
/**
* {@inheritDoc}
*/
public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
{
System.out.println( "IDLE " + session.getIdleCount( status ));
}
/**
* {@inheritDoc}
*/
public BlockingQueue<LLRPMessage> getSynMessageQueue() {
return synMessageQueue;
}
/**
* {@inheritDoc}
*/
public BlockingQueue<ConnectionAttemptEvent> getConnectionAttemptEventQueue() {
return connectionAttemptEventQueue;
}
/**
* {@inheritDoc}
*/
public boolean isKeepAliveAck() {
return keepAliveAck;
}
/**
* {@inheritDoc}
*/
public void setKeepAliveAck(boolean keepAliveAck) {
this.keepAliveAck = keepAliveAck;
}
/**
* {@inheritDoc}
*/
public boolean isKeepAliveForward() {
return keepAliveForward;
}
/**
* {@inheritDoc}
*/
public void setKeepAliveForward(boolean keepAliveForward) {
this.keepAliveForward = keepAliveForward;
}
/**
* {@inheritDoc}
*/
public LLRPConnection getConnection() {
return connection;
}
/**
* {@inheritDoc}
*/
public void setConnection(LLRPConnection connection) {
this.connection = connection;
}
}