package org.etsi.its.adapter.layers; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.etsi.adapter.TERFactory; import org.etsi.common.ByteHelper; import org.etsi.its.adapter.IManagementLayers; import org.etsi.ttcn.tci.CharstringValue; public class UdpIpLayer extends Layer { private static final String SETTINGS_PATTERN = "(\\S+)\\:(\\d+)\\:(\\d+)"; // FIXME The second port shall be optional if the same port shall be used for server and client private Pattern settingsPattern = Pattern.compile(SETTINGS_PATTERN); public UdpIpLayer(IManagementLayers management, Stack lowerStack) { super(management, lowerStack); } /* (non-Javadoc) * @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map) */ @Override public boolean send(byte[] message, Map params) { DatagramPacket packet = new DatagramPacket(message, message.length, iutAddress, iutClientPort); try { iutSocket.send(packet); } catch (IOException e) { e.printStackTrace(); } return true; } /* (non-Javadoc) * @see org.etsi.its.adapter.layers.Layer#register(org.etsi.its.adapter.layers.Layer) */ @Override public void register(Layer upperLayer) { if(registeredUpperLayer == null) { super.register(upperLayer); try { // UDP connection parameters String settings = ((CharstringValue)TERFactory.getInstance().getTaParameter("LowerTesterSettings")).getString(); Matcher matcher = settingsPattern.matcher(settings); if (matcher.find()) { iutAddress = InetAddress.getByName(matcher.group(1)); iutClientPort = Integer.parseInt(matcher.group(2)); if (matcher.group(3) != null) { iutServerPort = Integer.parseInt(matcher.group(3)); } else { iutServerPort = iutClientPort; } } else { System.err.println("No pattern matching"); } // UDP server socket for communication with UT iutSocket = new DatagramSocket(iutServerPort); iutThread = new UdpThread(iutSocket); iutThread.start(); } catch (Exception e) { e.printStackTrace(); } } } /* (non-Javadoc) * @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer) */ @Override public void unregister(Layer upperLayer) { iutSocket.close(); iutThread.interrupt(); try { iutThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } super.unregister(upperLayer); } private DatagramSocket iutSocket; private InetAddress iutAddress; private int iutClientPort; private int iutServerPort; private Thread iutThread; private class UdpThread extends Thread { private DatagramSocket taSocket; private boolean running = true; public UdpThread(DatagramSocket taSocket) throws IOException { this.taSocket = taSocket; } @Override public void run() { while(running) { try { byte[] buf = new byte[4096]; Map lowerInfo = new HashMap(); // receive packet DatagramPacket packet = new DatagramPacket(buf, buf.length); taSocket.receive(packet); lowerInfo.put(Layer.RECEPTION_TIMESTAMP, System.currentTimeMillis()); receive(ByteHelper.extract(packet.getData(), packet.getOffset(), packet.getLength()), lowerInfo); } catch (IOException e) { running = false; } } } } }