package org.yamcs; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.yamcs.ConfigurationException; import org.yamcs.StreamConfig.StandardStreamType; import org.yamcs.StreamConfig.StreamConfigEntry; import org.yamcs.archive.PacketWithTime; import org.yamcs.tctm.TmProviderAdapter; import org.yamcs.xtce.SequenceContainer; import org.yamcs.xtce.XtceDb; import org.yamcs.xtceproc.XtceDbFactory; import org.yamcs.yarch.Stream; import org.yamcs.yarch.StreamSubscriber; import org.yamcs.yarch.Tuple; import org.yamcs.yarch.YarchDatabase; import com.google.common.util.concurrent.AbstractService; /** * Receives packets from yamcs streams and sends them to the Processor/TmProcessor for extraction of parameters. * * Can read from multiple streams, each with its own root container used as start of XTCE packet processing * * @author nm * */ public class StreamTmPacketProvider extends AbstractService implements TmPacketProvider { Stream stream; TmProcessor tmProcessor; volatile boolean disabled=false; volatile long lastPacketTime; List<StreamReader> readers = new ArrayList<StreamReader>(); public StreamTmPacketProvider(String yamcsInstance, Map<String, Object> config) throws ConfigurationException { YarchDatabase ydb=YarchDatabase.getInstance(yamcsInstance); XtceDb xtcedb=XtceDbFactory.getInstance(yamcsInstance); if(!config.containsKey("streams")) throw new ConfigurationException("Cannot find key 'streams' in StreamTmPacketProvider"); StreamConfig streamConfig = StreamConfig.getInstance(yamcsInstance); List<String> streams = (List<String>) config.get("streams"); for(String streamName: streams) { StreamConfigEntry sce = streamConfig.getEntry(StandardStreamType.tm, streamName); SequenceContainer rootContainer; if(sce.getRootContainer()!=null) { rootContainer=sce.getRootContainer(); } else { rootContainer=xtcedb.getRootSequenceContainer(); if(rootContainer==null) throw new ConfigurationException("XtceDb does not have a root sequence container"); } Stream s=ydb.getStream(streamName); if(s==null) { throw new ConfigurationException("Cannot find stream '"+streamName+"'"); } StreamReader reader = new StreamReader(s, rootContainer); readers.add(reader); } } @Override public void init(Processor proc, TmProcessor tmProcessor) { this.tmProcessor=tmProcessor; } @Override protected void doStart() { for(StreamReader sr:readers) { sr.stream.addSubscriber(sr); } notifyStarted(); } @Override protected void doStop() { for(StreamReader sr:readers) { sr.stream.removeSubscriber(sr); } notifyStopped(); } @Override public boolean isArchiveReplay() { return false; } class StreamReader implements StreamSubscriber { Stream stream; SequenceContainer rootContainer; public StreamReader(Stream stream, SequenceContainer sc) { this.stream = stream; this.rootContainer = sc; } @Override public void onTuple(Stream s, Tuple tuple) { //the definition of tuple is in TmProviderAdapter long rectime = (Long)tuple.getColumn(TmProviderAdapter.RECTIME_COLUMN); long gentime = (Long)tuple.getColumn(TmProviderAdapter.GENTIME_COLUMN); byte[] packet=(byte[])tuple.getColumn(TmProviderAdapter.PACKET_COLUMN); PacketWithTime pwrt=new PacketWithTime(rectime, gentime, packet); lastPacketTime = gentime; tmProcessor.processPacket(pwrt); } @Override public void streamClosed(Stream s) { notifyStopped(); } } }