C2A_Core
tcp_to_m_pdu.c
[詳解]
1 #pragma section REPRO
7 #include "tcp_to_m_pdu.h"
8 // FIXME: CTP ではなく TSP を使ってしまっている.できれば抽象化するべき
10 
11 void T2M_initialize(TcpToMPdu* tcp_to_m_pdu)
12 {
13  // TC Packet Read Pointerの値を初期化
14  tcp_to_m_pdu->tcp_rp = 0;
15  tcp_to_m_pdu->m_pdu_wp = 0;
16  tcp_to_m_pdu->fhp_valid = 0;
17  // 強制送出待ち時間の初期値は10秒
18  // 32kbpsなら8VCDU/secの送信能力
19  tcp_to_m_pdu->flush_interval = OBCT_sec2cycle(10);
20  // 最終更新時刻は現在時刻に設定
21  tcp_to_m_pdu->last_updated = TMGR_get_master_total_cycle();
22 
23  return;
24 }
25 
26 T2M_ACK T2M_form_m_pdu(TcpToMPdu* tcp_to_m_pdu, PacketList* pl, M_PDU* m_pdu)
27 {
28  // M_PDUが完成する or TC Packetがなくなるまで実施
29  while (tcp_to_m_pdu->m_pdu_wp != M_PDU_DATA_SIZE)
30  {
31  const TlmSpacePacket* packet;
32  size_t tcp_len, tcp_left, m_pdu_left, write_len;
33 
34  if (PL_is_empty(pl))
35  {
36  // テレメトリQueueに送出すべきパケットがない場合
37  // 最終更新時刻からの経過時間を算出
38  cycle_t delta = TMGR_get_master_total_cycle() - tcp_to_m_pdu->last_updated;
39 
40  if (tcp_to_m_pdu->m_pdu_wp == 0)
41  {
42  // M_PDUのWrite Pointerが0で送出データがない場合
43  // 送出データなしとして処理打ち切り
44  return T2M_NO_DATA_TO_SEND;
45  }
46 
47  if (delta < tcp_to_m_pdu->flush_interval)
48  {
49  // 経過時間が強制送出間隔に達していない場合
50  // 処理を打ち切り、M_PDU未完成として0を返す
51  return T2M_INVALID_M_PDU;
52  }
53  else
54  {
55  // 強制送出のために埋めるべきデータ量を計算し、
56  // Fill Packetを生成、Queueに追加。
57  //
58  // M_PDUの残り領域がFill Packetのヘッダ長以下の場合、
59  // ユーザデータ長1のFill Packetが生成される。
60  // この場合、生成されたFill Packetは次M_PDUにまたがる。
61  // この状態で追加のテレメトリが生成されない場合は、Fill
62  // Packetのみで構成されたM_PDUが一度送出されることになる。
63  static TlmSpacePacket fill_; // サイズが大きいため静的確保(スタック保護)
64  size_t fill_size = M_PDU_DATA_SIZE - tcp_to_m_pdu->m_pdu_wp;
65  TSP_setup_fill_packet(&fill_, (uint16_t)fill_size);
66  PL_push_back(pl, &fill_);
67  }
68  }
69 
70  // Queue先頭のTC Packetを取得
71  // 有効パケットまたはFillパケットが必ず入っている。
72  packet = (const TlmSpacePacket*)(PL_get_head(pl)->packet); // FIXME: Space Packet 実装でなおす
73 
74  // 書き込むデータ長を計算
75  tcp_len = TSP_get_packet_len(packet);
76  tcp_left = tcp_len - tcp_to_m_pdu->tcp_rp;
77  m_pdu_left = M_PDU_DATA_SIZE - tcp_to_m_pdu->m_pdu_wp;
78  write_len = (tcp_left > m_pdu_left) ? m_pdu_left : tcp_left;
79 
80  // First Header Pointerが未設定かつ書き込み開始がパケット先頭
81  if ((tcp_to_m_pdu->fhp_valid != 1) && (tcp_to_m_pdu->tcp_rp == 0))
82  {
83  // First Header Pointerを現在のWrite Pointerの値に設定
84  M_PDU_set_1st_hdr_ptr(m_pdu, (uint16_t)tcp_to_m_pdu->m_pdu_wp);
85  // First Header Pointer設定済みを記録
86  tcp_to_m_pdu->fhp_valid = 1;
87  }
88 
89  // M_PDUデータの末尾にデータを追加
90  M_PDU_set_data(m_pdu,
91  &(packet->packet[tcp_to_m_pdu->tcp_rp]),
92  tcp_to_m_pdu->m_pdu_wp,
93  write_len);
94 
95  // TC Pacekt Read Pointerを更新
96  tcp_to_m_pdu->tcp_rp += write_len;
97  // M_PDU Write Pointerを更新
98  tcp_to_m_pdu->m_pdu_wp += write_len;
99  // 最終書き込み時刻を更新
100  tcp_to_m_pdu->last_updated = TMGR_get_master_total_cycle();
101 
102  // TC Packet全体をM_PDUに書き込み終わった場合
103  if (tcp_to_m_pdu->tcp_rp == tcp_len)
104  {
105  // 書き込み完了したTC PacketをQueueから破棄しRead Poineterの値を初期化
106  PL_drop_executed(pl);
107  tcp_to_m_pdu->tcp_rp = 0;
108  }
109  }
110 
111  // M_PDUを埋め終わったのにFirst Header Pointerが未設定の場合
112  // -> パケット先頭がM_PDUの中に含まれなかった場合
113  if (tcp_to_m_pdu->fhp_valid != 1)
114  {
115  // First Header Pointerを「ヘッダなし」に設定
117  // First Header Pointer設定済みを記録
118  tcp_to_m_pdu->fhp_valid = 1;
119  }
120 
121  // M_PDU Write Pointerの値をクリア
122  tcp_to_m_pdu->m_pdu_wp = 0;
123  // First Header Pointer状態を未設定に変更
124  tcp_to_m_pdu->fhp_valid = 0;
125 
126  return T2M_SUCCESS;
127 }
128 
129 #pragma section
void M_PDU_set_1st_hdr_ptr(M_PDU *m_pdu, uint16_t ptr)
Definition: m_pdu.c:73
void M_PDU_set_data(M_PDU *m_pdu, const uint8_t *data, size_t offset, size_t len)
Definition: m_pdu.c:84
#define M_PDU_DATA_SIZE
Definition: m_pdu.h:10
@ M_PDU_PTR_NO_HDR
Definition: m_pdu.h:21
cycle_t OBCT_sec2cycle(uint32_t sec)
秒を cycle に変換する
Definition: obc_time.c:107
uint32_t cycle_t
Definition: obc_time.h:10
const PL_Node * PL_get_head(const PacketList *pl)
PacketList の active な先頭 Node を取得
Definition: packet_list.c:150
PL_ACK PL_drop_executed(PacketList *pl)
先頭 Node を落とす
Definition: packet_list.c:236
PL_ACK PL_push_back(PacketList *pl, const void *packet)
PacketList の末尾に packet を挿入
Definition: packet_list.c:189
int PL_is_empty(const PacketList *pl)
PacketList が空かどうか
Definition: packet_list.c:138
Definition: m_pdu.h:14
void * packet
片方向リストに格納される packet. どのような型でも良いように, void.(基本的には CTCP, CTP, CCP を想定)
Definition: packet_list.h:60
パケットリスト本体
Definition: packet_list.h:73
TCPacket を M_PDU に変換するときに必要なパラメータ
Definition: tcp_to_m_pdu.h:33
cycle_t last_updated
Definition: tcp_to_m_pdu.h:38
size_t m_pdu_wp
Definition: tcp_to_m_pdu.h:35
cycle_t flush_interval
Definition: tcp_to_m_pdu.h:37
size_t tcp_rp
Definition: tcp_to_m_pdu.h:34
uint8_t fhp_valid
Definition: tcp_to_m_pdu.h:36
Space Packet (テレメ用)
uint8_t packet[TSP_MAX_LEN]
void T2M_initialize(TcpToMPdu *tcp_to_m_pdu)
T2M 構造体の初期化
Definition: tcp_to_m_pdu.c:11
T2M_ACK T2M_form_m_pdu(TcpToMPdu *tcp_to_m_pdu, PacketList *pl, M_PDU *m_pdu)
TCPacket を M_PDU に変換する
Definition: tcp_to_m_pdu.c:26
PacketList から TCPacket を取ってきてそれを送信可能な M_PDU へと変換する
T2M_ACK
T2M 関数の返り値
Definition: tcp_to_m_pdu.h:21
@ T2M_SUCCESS
Definition: tcp_to_m_pdu.h:22
@ T2M_NO_DATA_TO_SEND
Definition: tcp_to_m_pdu.h:23
@ T2M_INVALID_M_PDU
Definition: tcp_to_m_pdu.h:24
cycle_t TMGR_get_master_total_cycle(void)
現在の total_cycle を返す
Definition: time_manager.c:97
uint16_t TSP_get_packet_len(const TlmSpacePacket *tsp)
Packet Length を取得
void TSP_setup_fill_packet(TlmSpacePacket *tsp, uint16_t fill_size)
パケット全体を 0x00 クリアし, fill_size に等しいサイズのパケットを生成する
CCSDS で規定される Space Packet の テレメ版の実装