• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

WindhoverLabs / yamcs-cfs / #157

25 Nov 2024 11:22PM UTC coverage: 0.0%. Remained the same
#157

push

web-flow
Merge 096a65ddf into e64813ef2

0 of 18 new or added lines in 13 files covered. (0.0%)

1 existing line in 1 file now uncovered.

0 of 6640 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/com/windhoverlabs/yamcs/tctm/ccsds/StreamTcFrameLink.java
1
package com.windhoverlabs.yamcs.tctm.ccsds;
2

3
import com.google.common.util.concurrent.RateLimiter;
4
import java.util.Arrays;
5
import java.util.Map;
6
import java.util.concurrent.ConcurrentHashMap;
7
import java.util.concurrent.TimeUnit;
8
import org.yamcs.ConfigurationException;
9
import org.yamcs.YConfiguration;
10
import org.yamcs.commanding.PreparedCommand;
11
import org.yamcs.tctm.ccsds.AbstractTcFrameLink;
12
import org.yamcs.tctm.ccsds.TcTransferFrame;
13
import org.yamcs.utils.StringConverter;
14
import org.yamcs.yarch.ColumnDefinition;
15
import org.yamcs.yarch.DataType;
16
import org.yamcs.yarch.Stream;
17
import org.yamcs.yarch.Tuple;
18
import org.yamcs.yarch.TupleDefinition;
19
import org.yamcs.yarch.YarchDatabase;
20
import org.yamcs.yarch.YarchDatabaseInstance;
21

22
/**
23
 * Send command fames via serial interface.
24
 *
25
 * @author Mathew Benson (mbenson@windhoverlabs.com)
26
 */
27
public class StreamTcFrameLink extends AbstractTcFrameLink implements Runnable {
×
28
  RateLimiter rateLimiter;
29
  protected String deviceName;
30
  protected String syncSymbol;
31
  protected Stream stream;
32

33
  Map<Integer, TcTransferFrame> pendingFrames = new ConcurrentHashMap<>();
×
34

35
  Thread thread;
36

37
  static TupleDefinition gftdef;
38

39
  static final String RECTIME_CNAME = "rectime";
40
  static final String DATA_CNAME = "data";
41

42
  static {
43
    gftdef = new TupleDefinition();
×
44
    gftdef.addColumn(new ColumnDefinition(PreparedCommand.CNAME_GENTIME, DataType.TIMESTAMP));
×
45
    gftdef.addColumn(new ColumnDefinition(DATA_CNAME, DataType.BINARY));
×
46
  }
×
47

48
  /**
49
   * Creates a new Serial Frame Data Link
50
   *
51
   * @throws ConfigurationException if port is not defined in the configuration
52
   */
53
  public void init(String instance, String name, YConfiguration config)
54
      throws ConfigurationException {
55
    super.init(instance, name, config);
×
56

57
    if (config.containsKey("frameMaxRate")) {
×
58
      rateLimiter = RateLimiter.create(config.getDouble("frameMaxRate"), 1, TimeUnit.SECONDS);
×
59
    }
60

61
    this.syncSymbol = config.getString("syncSymbol", "");
×
62

63
    String streamName = config.getString("stream");
×
64

65
    YarchDatabaseInstance ydb = YarchDatabase.getInstance(instance);
×
66
    this.stream = getStream(ydb, streamName);
×
67
  }
×
68

69
  private static Stream getStream(YarchDatabaseInstance ydb, String streamName) {
70
    Stream stream = ydb.getStream(streamName);
×
71
    if (stream == null) {
×
72
      try {
73
        ydb.execute("create stream " + streamName + gftdef.getStringDefinition());
×
74
        // ydb.execute("create stream " + streamName);
75
      } catch (Exception e) {
×
76
        throw new ConfigurationException(e);
×
77
      }
×
78
      stream = ydb.getStream(streamName);
×
79
    }
80
    return stream;
×
81
  }
82

83
  @Override
84
  public void run() {
85
    while (isRunningAndEnabled()) {
×
86

87
      if (rateLimiter != null) {
×
88
        rateLimiter.acquire();
×
89
      }
90
      TcTransferFrame tf = multiplexer.getFrame();
×
91
      if (tf != null) {
×
92
        long rectime = tf.getGenerationTime();
×
93
        byte[] data = tf.getData();
×
94
        if (log.isTraceEnabled()) {
×
95
          log.trace("Outgoing frame data: {}", StringConverter.arrayToHexString(data, true));
×
96
        }
97

98
        if (cltuGenerator != null) {
×
99
          data = cltuGenerator.makeCltu(data, false);
×
100
          if (log.isTraceEnabled()) {
×
101
            log.trace("Outgoing CLTU: {}", StringConverter.arrayToHexString(data, true));
×
102
          }
103
        }
104

105
        if (tf.isBypass()) {
×
106
          ackBypassFrame(tf);
×
107
        }
108

109
        this.stream.emitTuple(new Tuple(gftdef, Arrays.asList(rectime, data)));
×
110

111
        frameCount++;
×
112
      }
113
    }
×
114
  }
×
115

116
  @Override
117
  protected void doDisable() throws Exception {
118
    if (thread != null) {
×
119
      thread.interrupt();
×
120
    }
121
  }
×
122

123
  @Override
124
  protected void doEnable() throws Exception {
125
    thread = new Thread(this);
×
126
    thread.start();
×
127
  }
×
128

129
  @Override
130
  protected void doStart() {
131
    try {
132
      if (!isDisabled()) {}
×
133

134
      doEnable();
×
135
      notifyStarted();
×
136
    } catch (Exception e) {
×
137
      log.warn("Exception starting link", e);
×
138
      notifyFailed(e);
×
139
    }
×
140
  }
×
141

142
  @Override
143
  protected void doStop() {
144
    try {
145
      doDisable();
×
146
      multiplexer.quit();
×
147
      notifyStopped();
×
148
    } catch (Exception e) {
×
149
      log.warn("Exception stopping link", e);
×
150
      notifyFailed(e);
×
151
    }
×
152
  }
×
153

154
  @Override
155
  protected Status connectionStatus() {
156
    return Status.OK;
×
157
  }
158

159
  @Override
160
  public boolean sendCommand(PreparedCommand pc) {
161
    // Not used when framing commands.
NEW
162
    return true;
×
163
  }
164
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc