package org.etsi.its.tool.elvior; import java.io.IOException; import java.util.Properties; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; import org.elvior.ttcn.tritci.ChannelEventHandler; import org.elvior.ttcn.tritci.TciProvider; import org.elvior.ttcn.tritci.TriTciChannel; import org.etsi.codec.ITCIRequired; import org.etsi.codec.ITciCDWrapper; import org.etsi.codec.TciCDWrapperFactory; import org.etsi.tool.elvior.TciCDWrapper; import org.etsi.ttcn.codec.CodecFactory; import org.etsi.ttcn.tci.TciCDProvided; import org.etsi.ttcn.tci.Type; import org.etsi.ttcn.tci.Value; import org.etsi.ttcn.tri.TriMessage; public class Its_CodecProvider implements TciCDProvided, ChannelEventHandler, ITCIRequired { private static Properties _properties = new Properties(); /** * Logger instance */ private final static Logger _logger = Logger.getLogger("org.etsi.its"); private ITciCDWrapper _cdReq; private CodecFactory _cf; public Its_CodecProvider() { //_logger.entering("Its_CodecProvider", "Its_CodecProvider"); // Load Codec settings _cdReq = null; _cf = null; try { _properties.load(MainCodec.class.getResourceAsStream("/org/etsi/its/tool/elvior/res/codec.properties")); } catch (IOException e) { e.printStackTrace(); } String debugLevel = _properties.getProperty("DEBUG_ENABLED", "OFF"); Level level = Level.OFF; if (debugLevel.equalsIgnoreCase("ALL")) { level = Level.ALL; } else if (debugLevel.equalsIgnoreCase("INFO")) { level = Level.INFO; } else if (debugLevel.equalsIgnoreCase("SEVERE")) { level = Level.SEVERE; } else if (!debugLevel.equalsIgnoreCase("OFF")) { // FIXME //TERFactory.getInstance().logError("Unsupported logging level: " + debugLevel); level = Level.OFF; } //_logger.addHandler(new ConsoleHandler()); //_logger.setLevel(level); //_logger.getHandlers()[0].setLevel(level); // Register this object as the instance implementing the TCI-CD Provided interface TciProvider.getInstance().setTciCDProvided(this); TriTciChannel channel = TriTciChannel.getInstance(); // Set application name that will be displayed in the TestCast log channel.setApplicationName("ItsCodec"); // Register this object as the receiver of events generated by TestCast framework channel.setEventHandler(this); initializeCodecs(); } private void initializeCodecs() { TciCDWrapperFactory.getInstance().setImpl(new TciCDWrapper()); _cdReq = TciCDWrapperFactory.getTciCDInstance(); // Register External codecs _cf = CodecFactory.getInstance(); // TODO Reuse Build-in codec here String[] asn1Codecs = _properties.getProperty("ASN.1Codecs", "").split(","); for (String codec : asn1Codecs) { String[] paths = _properties.getProperty(codec, "").split(","); try { _cf.setExternalCodec(paths[0], (TciCDProvided) Class.forName(paths[1]).newInstance()); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } } // End of 'for' loop try { // This comes with 'with encode () "UpperTester"' for all UtxxxTrigger/UtxxxUpdate messages _cf.setExternalCodec("per-basic-unaligned:1997", LibIts_asn1.class.newInstance()); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { //_logger.entering("Its_CodecProvider", "run"); // Attempt to connect to TestCast if (TriTciChannel.getInstance().open()) { try { synchronized(this) { wait(); } } catch (InterruptedException e) { } } //_logger.exiting("Its_CodecProvider", "run"); } @Override public void onConnectionClosed() { //_logger.entering("Its_CodecProvider", "onConnectionClosed"); synchronized(this) { notify(); } } @Override public void onConnectionEstablished() { //_logger.entering("Its_CodecProvider", "onConnectionEstablished"); } @Override public void onError(String error) { //_logger.entering("Its_CodecProvider", "onError", error); } @Override public Value decode(TriMessage message, Type decodingHypothesis) { /*_logger.entering( "decode", String.format("%s - %s - %s", decodingHypothesis.getName(), decodingHypothesis.getTypeEncoding(), decodingHypothesis.getTypeClass()));*/ String encodingName = decodingHypothesis.getTypeEncoding(); if (encodingName != null) { encodingName = decodingHypothesis.getDefiningModule().getModuleName(); } else { // Use basic codec encodingName = ""; } TciCDProvided codec = getCodec(encodingName); if (codec == null) { return null; } Value value = codec.decode(message, decodingHypothesis); //_logger.exiting("Its_CodecProvider.decode", (value != null) ? GetValueStructure.getValueStructure(value) : "(null)"); return value; } @Override public TriMessage encode(Value value) { /*_logger.entering( "encode", String.format( ">>> encode: %s - %s - %s - %s - %s - %s - %s - %s - %s", value.getType().getName(), value.getType().getDefiningModule(), value.getType().getDefiningModule().getModuleName(), value.getType().getTypeExtension(), value.getType().getTypeEncoding(), value.getType().getTypeEncodingVariant(), value.getValueEncoding(), value.getValueEncodingVariant(), (value.notPresent() == true) ? "true" : "false" ) );*/ // TERFactory.getInstance().logDebug(">>> encode: " + value.getType().getName()); String encodingName = value.getType().getTypeEncoding(); if ((encodingName != null) && !encodingName.startsWith("Lib")) { encodingName = value.getType().getDefiningModule().getModuleName(); } else if (encodingName == null) { // Use basic codec encodingName = ""; } TciCDProvided codec = getCodec(encodingName); if (codec == null) { return null; } //_logger.info("Value to encode: " + GetValueStructure.getValueStructure(value)); TriMessage res = codec.encode(value); //_logger.exiting("encode", res.toString()); return res; } /** * This method provides the codec associated to the specified encoding identifier * * @param rb TTwb Runtime reference * @param encodingName The name of the encoding, specified by the TTCN-3 key words 'with/encode' * @return The codec associated to the specified encoding identifier */ @Override public TciCDProvided getCodec(final String encodingName) { // FIXME Remove argument here and in the interface ITCIRequired return new Codec(); } private class Codec implements TciCDProvided { @Override public Value decode(TriMessage message, Type decodingHypothesis) { //_logger.entering("Codec", "decode", decodingHypothesis.getName()); org.etsi.ttcn.codec.MainCodec codec = new org.etsi.ttcn.codec.MainCodec(_cdReq); Value v = null; try { v = codec.triDecode(message, decodingHypothesis); } catch(Exception e) { e.printStackTrace(); } return v; } @Override public TriMessage encode(Value value) { //_logger.entering("Codec", "encode"); org.etsi.ttcn.codec.MainCodec codec = new org.etsi.ttcn.codec.MainCodec(_cdReq); TriMessage m = null; try { m = codec.triEncode(value); } catch(Exception e) { e.printStackTrace(); } return m; } } } // End of class Its_CodecProvider