package org.opennaas.extensions.roadm.wonesys.transports.rawsocket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.net.InetSocketAddress; import java.net.Socket; import java.util.ArrayList; import java.util.Date; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.opennaas.core.events.EventFilter; import org.opennaas.core.resources.ActivatorException; import org.opennaas.extensions.roadm.wonesys.protocols.WonesysProtocolBundleActivator; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; /** * Creates a Socket and uses it to send and receive messages. Messages to send are expected to be HexStrings. Received messages are expected to be * byte chunks , and will be transformed to HexString. * * Notifies listeners when a message is received, connection is closed or an error occurs during reading from socket. * * Notice it uses osgi events without using EventManager * * @author isart * */ public class RawSocketTransport { /* Event topic */ public static final String ALL_EVENTS_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/*"; public static final String MSG_RCVD_EVENT_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/MESSAGE_RCV"; public static final String MSG_SENT_EVENT_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/MESSAGE_SENT"; public static final String CONNECTION_CLOSED_EVENT_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/CONNECTION_CLOSED"; public static final String CONNECTION_CLOSED_BY_USER_EVENT_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/CONNECTION_CLOSED_BY_USER"; public static final String ERROR_EVENT_TOPIC = "net/i2cat/luminis/transports/wonesys/rawsocket/ERROR"; public static final String MESSAGE_PROPERTY_NAME = "message"; public static final String ERROR_PROPERTY_NAME = "error"; public static final String TRANSPORT_ID_PROPERTY_NAME = "transportid"; public static final String ARRIVAL_TIME_PROPERTY_NAME = "arrivalTime"; public static final int DEFAULT_PORT = 27773; public static final int DEFAULT_TIMEOUT = 1000; private Socket sock; private List<EventHandler> listeners = new ArrayList<EventHandler>(); Log log = LogFactory.getLog(RawSocketTransport.class); private final String transportID; private static AtomicInteger inc = new AtomicInteger(0); public RawSocketTransport() { sock = new Socket(); transportID = generateTransportID(); } private String generateTransportID() { return String.valueOf(inc.getAndIncrement()); } public void connectSocket(String ip) throws IOException { connectSocket(ip, DEFAULT_PORT); } public void connectSocket(String ip, int port) throws IOException { int timeout = DEFAULT_TIMEOUT; // Bind to a local ephemeral port sock.bind(null); sock.connect(new InetSocketAddress(ip, port), timeout); // attach reader to receive async msgs SocketReader reader = new SocketReader(); reader.start(); } public void disconnectSocket() throws IOException { if (!sock.isClosed()) { sock.close(); notifyListeners(createEvent(CONNECTION_CLOSED_BY_USER_EVENT_TOPIC, null)); } } public void sendAsyncToSocket(String message) throws IOException { byte[] bts = new BigInteger(message, 16).toByteArray(); OutputStream out = sock.getOutputStream(); out.write(bts); out.flush(); } // public int registerListener(EventHandler listener) throws WonesysTransportException { // // EventFilter allMyEventsFilter = createAllMyEventsFilter(); // try { // return Activator.getEventManagerService().registerEventHandler(listener, allMyEventsFilter); // } catch (ActivatorException e) { // throw new WonesysTransportException("Unable to register listener", e); // } // // // if (listener != null && !listeners.contains(listener)) // // listeners.add(listener); // } // // public void unregisterListener(int registrationNum) throws WonesysTransportException { // try { // Activator.getEventManagerService().unregisterHandler(registrationNum); // } catch (ActivatorException e) { // throw new WonesysTransportException("Unable to unregister listener", e); // } // // listeners.remove(listener); // } public void notifyListeners(Event ev) { try { WonesysProtocolBundleActivator.getEventManagerService().publishEvent(ev); } catch (ActivatorException e) { log.error("Could not notify transport listeners.", e); log.error("Received event will be lost. Event: " + ev.toString()); } // for (int i = listeners.size() - 1; i >= 0; i--) { // listeners.get(i).handleEvent(ev); // } } protected Event createEvent(String eventTopic, String message) { Dictionary<String, Object> properties = new Hashtable<String, Object>(); properties.put(RawSocketTransport.TRANSPORT_ID_PROPERTY_NAME, getTransportID()); properties.put(RawSocketTransport.ARRIVAL_TIME_PROPERTY_NAME, new Date().getTime()); if (message != null) properties.put(MESSAGE_PROPERTY_NAME, message); return new Event(eventTopic, properties); } protected Event createErrorEvent(String eventTopic, Exception err) { Dictionary<String, Object> properties = new Hashtable<String, Object>(); properties.put(RawSocketTransport.TRANSPORT_ID_PROPERTY_NAME, getTransportID()); properties.put(RawSocketTransport.ARRIVAL_TIME_PROPERTY_NAME, new Date().getTime()); if (err != null) properties.put(ERROR_PROPERTY_NAME, err); return new Event(eventTopic, properties); } protected EventFilter createAllMyEventsFilter() { String topic = RawSocketTransport.ALL_EVENTS_TOPIC; Properties properties = new Properties(); properties.setProperty(RawSocketTransport.TRANSPORT_ID_PROPERTY_NAME, getTransportID()); return new EventFilter(new String[] { topic }, properties); } public String getTransportID() { return transportID.toString(); } /** * Thread that listens the socket for messages arrival, until socket is closed. * * When a message arrives, listeners are notified. * * @author isart * */ class SocketReader extends Thread { public void run() { try { InputStream in = sock.getInputStream(); while (!sock.isClosed()) { String message = readMessage(in); if (!message.equals("")) { log.debug("Message received: " + message); notifyListeners(createEvent(MSG_RCVD_EVENT_TOPIC, message)); } } } catch (IOException e1) { notifyListeners(createErrorEvent(ERROR_EVENT_TOPIC, e1)); } } private String readMessage(InputStream in) throws IOException { String outS = ""; byte[] buffer = new byte[256]; // while ((i = in.read(buffer)) != 0){ int i = in.read(buffer); String salida = ""; //$NON-NLS-1$ for (int j = 0; j < i; j++) { byte o = buffer[j]; if ((o < 0x10) && (o >= 0)) salida += "0"; //$NON-NLS-1$ String bite = Integer.toHexString(o); if (bite.length() > 2) salida += bite.substring(bite.length() - 2); else salida += bite; } outS += salida; // } return outS; } } }