# Svc::Ccsds::TmFramer

The `Svc::Ccsds::TmFramer` is an implementation of the [FramerInterface](../../../Interfaces/docs/sdd.md) for the CCSDS [TM Space Data Link Protocol](https://ccsds.org/Pubs/132x0b3.pdf). 

It receives payload data (such as a Space Packet or a VCA_SDU) on input and produces a TM frame on its output port as a result. Please refer to the CCSDS [TM specification (CCSDS 132.0-B-3)](https://ccsds.org/Pubs/132x0b3.pdf) for details on the frame format and protocol.

The `Svc::Ccsds::TmFramer` is designed to work in the common F Prime telemetry stack, receiving data from an upstream [`Svc::ComQueue`](../../../ComQueue/docs/sdd.md) and passing frames to a [Communications Adapter](../../../Interfaces/docs/sdd.md), such as a Radio manager component or [`Svc::ComStub`](../../../ComStub/docs/sdd.md), for transmission on the wire. It is commonly coupled with the [`Svc::Ccsds::SpacePacketFramer`](../../SpacePacketFramer/docs/sdd.md) to wrap CCSDS Space Packets into TM frames.

## Internals

The TM protocol specifies a fixed frame size. This can be configured in the `config/ComCfg.fpp` file.

The `Svc::Ccsds::TmFramer` uses an internal (member) buffer to hold the fixed size frame. The buffer **must** be returned to the TmFramer via the `dataReturnIn` port once it has been used or consumed. When the buffer returns to the TmFramer it will reuse the buffer for the next frame. Should a component want to use the frame data past the time it is returned to the TmFramer, data should be copied before the original buffer is returned to the TmFramer via the `dataReturnIn` port. 

## Usage Examples

The `Svc::Ccsds::TmFramer` component, as well as the rest of the CCSDS communications stack, is used in the [`Ref/`](https://github.com/nasa/fprime/tree/devel/Ref) example application. It is also generated by the `fprime-util new --deployment` command.

## CCSDS Header Fields

For each frame generated, the `Svc::Ccsds::TmFramer` will populate the CCSDS TM Primary Header fields as follows:

| Field | Value | Notes |
|---|---|---|
| Transfer Frame Version Number | 0 | As per protocol 4.1.2.2 |
| Spacecraft ID | Configured in `config/ComCfg.fpp` | Set in the project configuration |
| Virtual Channel ID | Uses value passed in the `context` argument (defaults to 0) | Set by an upstream component |
| Operational Control Field Flag | 0 | Unsupported |
| Master Channel Frame Count | Incremented for each frame | Managed internally by TmFramer |
| Virtual Channel Frame Count | Incremented for each frame | Managed internally by TmFramer. One TmFramer instance can only keep count of a single VCID. |
| Transfer Frame Secondary Header Flag | 0 | F Prime does not formally use secondary headers |
| Synchronization Flag | 0 | 0 as Packets are inserted |
| Packet Order Flag | 0 | As per protocol 4.1.2.7.4 |
| Segment Length Identifier | 0b11 | As per protocol 4.1.2.7.5 |
| First Header Pointer | 0 | F Prime packets are limited in length and always sent in a single frame, aligned to the start of the frame. |

## Port Descriptions

| Kind | Name | Port Type | Description |
|---|---|---|---|
| sync input | dataIn | Svc.ComDataWithContext | Receives data to frame, in a Fw::Buffer with optional context |
| output | dataOut | Svc.ComDataWithContext | Outputs framed data with optional context |
| output | dataReturnOut | Svc.ComDataWithContext | Returns ownership of the incoming Fw::Buffer to its sender once framing is handled |
| sync input | dataReturnIn | Svc.ComDataWithContext | Receives buffer from a deallocate call in a ComDriver component |
| sync input | comStatusIn | Fw.SuccessCondition | Receives status from downstream communication adapter per the [Communication Adapter Protocol](../../../../docs/reference/communication-adapter-interface.md#communication-adapter-protocol) |
| output | comStatusOut | Fw.SuccessCondition | Passes status through to upstream `Svc::ComQueue` per the [Framer Status Protocol](../../../../docs/reference/communication-adapter-interface.md#framer-status-protocol) |

## Requirements

| Name | Description | Validation |
|---|---|---|
| SVC-Ccsds-TM-FRAMER-001 | The TmFramer shall implement the `Svc.FramerInterface`. | Inspection, Unit Test |
| SVC-Ccsds-TM-FRAMER-002 | The TmFramer shall construct CCSDS Telemetry (TM) Transfer Frames compliant with the CCSDS 132.0-B-3 standard. | Unit Test, Inspection |
| SVC-Ccsds-TM-FRAMER-002 | The TmFramer shall use a fixed frame size that is configurable by the project. | Unit Test, Inspection |
| SVC-Ccsds-TM-FRAMER-003 | The TmFramer shall accept payload data (Space Packets or VCA_SDU) to be framed via its `dataIn` port. | Unit Test |
| SVC-Ccsds-TM-FRAMER-004 | The TmFramer shall output the constructed TM Transfer Frame via its `dataOut` port. | Unit Test |
| SVC-Ccsds-TM-FRAMER-005 | The TmFramer shall return ownership of the input buffer via the `dataReturnOut` port after the framing process is complete. | Unit Test |
| SVC-Ccsds-TM-FRAMER-006 | The TmFramer shall accept returned buffers (previously sent via `dataOut`) through the `dataReturnIn` port for deallocation or reuse. | Unit Test |
| SVC-Ccsds-TM-FRAMER-007 | The TmFramer shall receive communication status from downstream components via the `comStatusIn` port and pass it through to `comStatusOut`, including the initial start-up `Fw::Success::SUCCESS`, per-message statuses, and any recovery `Fw::Success::SUCCESS` after a `Fw::Success::FAILURE`, per the [Framer Status Protocol](../../../../docs/reference/communication-adapter-interface.md#framer-status-protocol) | Unit Test, Integration Test |
| SVC-Ccsds-TM-FRAMER-008 | The TmFramer shall use exactly one Virtual Channel. | Unit Test, Integration Test |
| SVC-Ccsds-TM-FRAMER-009 | The TmFramer shall correctly populate all mandatory fields of the TM Transfer Frame Primary Header, including Transfer Frame Version Number, Spacecraft Identifier, Virtual Channel Identifier, Operational Control Field Flag, Master Channel Frame Count, Virtual Channel Frame Count, Transfer Frame Secondary Header Flag, Synchronization Flag, Packet Order Flag, Segment Length Identifier, and First Header Pointer. | Unit Test, Inspection |
| SVC-Ccsds-TM-FRAMER-010 | The TmFramer shall be configurable with a Spacecraft Identifier. | Inspection, Unit Test |
| SVC-Ccsds-TM-FRAMER-011 | The TmFramer shall use the Virtual Channel Identifier passed in the `context` object on `dataIn`. | Unit Test |
| SVC-Ccsds-TM-FRAMER-012 | The TmFramer shall manage Master Channel Frame Count and Virtual Channel Frame Count. | Unit Test |
| SVC-Ccsds-TM-FRAMER-013 | The TmFramer shall fill the data field of the TM Transfer Frame with the payload data received on `dataIn`, and fill up the rest of the fixed-size frame with a single Idle Packet as defined by the protocol. | Unit Test |
