package org.etsi.its.adapter.ports; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.etsi.adapter.TERFactory; import org.etsi.common.ByteHelper; import org.etsi.ttcn.tci.CharstringValue; /** This class implements behaviour for Configuration Tester port. This port is used to access to the IUT management port * The Configuration tester entity in the SUT enables triggering Protocol functionalities by simulating primitives from * from SAPs * It is required to trigger the Protocol layer in the SUT to send Protocol specific messages, which are * resulting from management layer primitives */ public class ConfigTesterPort extends AdapterPort implements IPort, IObservable { private static final String SETTINGS_PATTERN = "(\\S+)\\:(\\d+)"; /** * Constructor * @param portName Name of the port * @param componentName Name of the component owning this port instance * @param localPortNumber Local port number for the UDP listener * @param remotePortNumber UDP port listener of remote UT application */ public ConfigTesterPort(final String portName, final String componentName) { super(portName, componentName); // UDP connection parameters String settings = ((CharstringValue)TERFactory.getInstance().getTaParameter("ConfigTesterSettings")).getString(); Matcher matcher = settingsPattern.matcher(settings); if (matcher.find()) { try { cfPeerAddress = InetAddress.getByName(matcher.group(1)); } catch (UnknownHostException e1) { e1.printStackTrace(); } cfPeerPort = Integer.parseInt(matcher.group(2)); } else { } running = true; // UDP socket for communication with UT try { cfSocket = new DatagramSocket(); cfThread = new UdpThread(cfSocket); cfThread.start(); } catch (Exception e) { e.printStackTrace(); } } @Override public boolean send(final byte[] message) { DatagramPacket packet = new DatagramPacket(message, message.length, cfPeerAddress, cfPeerPort); try { cfSocket.send(packet); } catch (IOException e) { e.printStackTrace(); return false; } return true; } @Override public void dispose() { if(running) { running = false; if(cfThread != null) { try { cfSocket.close(); cfThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } } private DatagramSocket cfSocket; private Thread cfThread; private InetAddress cfPeerAddress = null; private int cfPeerPort = 0; private Pattern settingsPattern = Pattern.compile(SETTINGS_PATTERN); /** * Indicates whether the port is still active. Setting this field to false will cause * the UDP communication with Config Tester to be stopped */ private volatile boolean running; private class UdpThread extends Thread { private DatagramSocket taSocket; public UdpThread(DatagramSocket taSocket) throws IOException { this.taSocket = taSocket; } @Override public void run() { while(running) { try { byte[] buf = new byte[4096]; // receive packet DatagramPacket packet = new DatagramPacket(buf, buf.length); taSocket.receive(packet); setChanged(); notifyObservers(new PortEvent(ByteHelper.extract(packet.getData(), packet.getOffset(), packet.getLength()), getPortName(), getComponentName())); } catch (IOException e) { running = false; } } taSocket.close(); } } } // End of class ConfigTesterPort