1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
//! Each packet transporting a request verification report shall be of service type 1.
use super::*;
use crate::error;
use crate::sp::{
    tm::{TmData, TmPacket, TmPacketHeader},
    Request, PEC_LEN,
};

const SERVICE_TYPE: u8 = 1;

/* Field sizes in terms of bytes */
const REQ_ID_LEN: usize = 4;
const STEP_ID_LEN: usize = 2;
const FAILURE_NOTICE_MIN_LEN: usize = 1;

/*---- Field Structs Of Messages Start ----*/

/// To Identify which request it is. Used in all TM[1,x] packs where x = {1,2,3,4,5,6,7,8,10}.
#[derive(Debug)]
pub struct RequestId {
    /// first 3 bits of the LSB are used.
    pub(crate) ver_no: u8,
    pub(crate) packet_type: bool,
    pub(crate) sec_header_flag: bool,
    /// first 11 bits of the LSB are used.
    pub(crate) apid: u16,
    pub(crate) seq_flags: (bool, bool),
    /// first 14 bits of the LSB are used.
    pub(crate) packet_seq_count: u16,
}
impl RequestId {
    fn to_bytes(&self) -> [u8; REQ_ID_LEN] {
        let mut bytes = [0; REQ_ID_LEN];
        let mut first_two_bytes = (self.ver_no as u16) << 13;
        if self.packet_type {
            first_two_bytes = first_two_bytes | 0b0001_0000_0000_0000;
        }
        if self.sec_header_flag {
            first_two_bytes = first_two_bytes | 0b0000_1000_0000_0000;
        }
        first_two_bytes += self.apid;
        let mut second_two_bytes = self.packet_seq_count;
        if self.seq_flags.0 {
            second_two_bytes = second_two_bytes | 0b1000_0000_0000_0000
        }
        if self.seq_flags.1 {
            second_two_bytes = second_two_bytes | 0b0100_0000_0000_0000
        }
        BigEndian::write_u16(&mut bytes[..2], first_two_bytes);
        BigEndian::write_u16(&mut bytes[2..], second_two_bytes);
        bytes
    }

    fn from_bytes(buffer: &[u8]) -> Result<Self, Error> {
        // TODO do other checks here
        if buffer.len() != REQ_ID_LEN {
            return Err(Error::InvalidPacket);
        };
        // first 3 bits
        let ver_no = buffer[0] >> 5;
        let packet_type = (buffer[0] & 0b0001_0000) != 0;
        let sec_header_flag = (buffer[0] & 0b0000_1000) != 0;
        let apid = buffer[1] as u16;
        let apid = apid + (((buffer[0] & 0b0000_0111) as u16) << 8);
        let seq_flags = (
            (0b1000_0000 & buffer[2] != 0),
            (0b0100_0000 & buffer[2] != 0),
        );
        let packet_seq_count = BigEndian::read_u16(&buffer[2..]);
        let packet_seq_count = packet_seq_count & 0b0011_1111_1111_1111;
        Ok(RequestId {
            ver_no,
            packet_type,
            sec_header_flag,
            apid,
            seq_flags,
            packet_seq_count,
        })
    }
}

/// Failure Notice Field Struct. Used in all fail response packs. TM[1,x] packs where x = {2,4,6,8,10}.
#[derive(Debug)]
struct FailureNotice {
    pub(crate) err_code: u8,
    pub(crate) err_data: Vec<u8>,
}
impl FailureNotice {
    /// Creates a Failure Notice Field Struct.
    /// TODO check values
    pub fn new(err_code: u8, err_data: Vec<u8>) -> Result<Self, Error> {
        Ok(FailureNotice { err_code, err_data })
    }
    pub fn from_bytes(buffer: &[u8]) -> Result<Self, Error> {
        if buffer.len() < FAILURE_NOTICE_MIN_LEN || (buffer[0] as usize) >= error::ERR_CODE_COUNT {
            return Err(Error::InvalidPacket);
        };
        let err_code = buffer[0];
        let err_data = buffer[1..].to_vec();
        Ok(FailureNotice { err_code, err_data })
    }
    pub fn to_byte(&self) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(self.err_data.len() + 1);
        bytes.push(self.err_code);
        bytes.extend(self.err_data.to_vec());
        bytes
    }
}
/// Step id field seen in TM[1,5] and TM[1,6]
#[derive(Debug)]
struct StepId {
    pub step_id: u16,
}
impl StepId {
    /// Creates a Step Id Field Struct.
    /// TODO learn context
    pub fn new(step_id: u16) -> Result<Self, Error> {
        Ok(StepId { step_id })
    }
    pub fn from_bytes(buffer: &[u8]) -> Result<Self, Error> {
        if buffer.len() != STEP_ID_LEN {
            return Err(Error::InvalidPacket);
        }
        let step_id = BigEndian::read_u16(&buffer);
        Ok(StepId { step_id })
    }
    pub fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = alloc::vec![0 as u8; STEP_ID_LEN];
        BigEndian::write_u16(&mut bytes, self.step_id);
        bytes
    }
}
/*---- Field Structs Of Messages End ----*/

/*---- PUS TM[1,1], TM[1,3] and TM[1,7] Packets Declaration Start ----*/
#[derive(Debug)]
pub struct ServiceSuccess {
    request_id: RequestId,
}
// Getting TmData Trait
impl TmData for ServiceSuccess {
    /* Empty */
}

/// Source data for PUS TM[1,1] packet.
/// PUS TM[1,1] successful acceptance verification report
pub type Service1_1 = ServiceSuccess;
/// Source data for PUS TM[1,3] packet.
/// PUS TM[1,3] successful start of execution verification report
pub type Service1_3 = ServiceSuccess;
/// Source data for PUS TM[1,7] packet.
/// PUS TM[1,7] successful completion of execution verification report
pub type Service1_7 = ServiceSuccess;
/*---- PUS TM[1,1], TM[1,3] and TM[1,7] Packets Declaration End ----*/

/*---- PUS TM[1,2], TM[1,4], TM[1,8]and TM[1,10] Packets Declaration Start ----*/
#[derive(Debug)]
pub struct ServiceFail {
    request_id: RequestId,
    failure_notice: FailureNotice,
}
// Getting TmData Trait
impl TmData for ServiceFail {
    /* Empty */
}
/// Source data for PUS TM[1,2] packet.
/// PUS TM[1,2] failed acceptance verification report
pub type Service1_2 = ServiceFail;
/// Source data for PUS TM[1,4] packet.
/// TM[1,4] failed start of execut<<ion verification report
pub type Service1_4 = ServiceFail;
/// Source data for PUS TM[1,8] packet.
/// PUS TM[1,8] failed completion of execution verification report
pub type Service1_8 = ServiceFail;
/// Source data for PUS TM[1,10] packet.
/// PUS TM[1,10] failed routing verification report
pub type Service1_10 = ServiceFail;
/*---- PUS TM[1,2], TM[1,4], TM[1,8]and TM[1,10] Packets Declaration End ----*/

/*---- PUS TM[1,5] Packet Declaration Start ----*/
#[derive(Debug)]
pub struct ServiceSuccessStep {
    request_id: RequestId,
    step_id: StepId,
}
// Getting TmData Trait
impl TmData for ServiceSuccessStep {
    /* Empty */
}

/// Source data for PUS TM[1,5] packet.
/// PUS TM[1,5] successful progress of execution verification report
pub type Service1_5 = ServiceSuccessStep;
/*---- PUS TM[1,5] Packet Declaration End ----*/

/*---- PUS TM[1,6] Packet Declaration Start ----*/
#[derive(Debug)]
pub struct ServiceFailStep {
    request_id: RequestId,
    step_id: StepId,
    failure_notice: FailureNotice,
}
// Getting TmData Trait
impl TmData for ServiceFailStep {
    /* Empty */
}
/// Source data for PUS TM[1,6] packet.
/// PUS TM[1,6] failed progress of execution verification report
pub type Service1_6 = ServiceFailStep;
/*---- PUS TM[1,6] Packet Declaration End ----*/

pub mod service_fail;
pub mod service_fail_step;
pub mod service_success;
pub mod service_success_step;

// TODO: improve aliases