#ifndef PACKET_MOD #define PACKET_MOD #include #include #include #include "results.h" typedef enum { NOT_STARTED, DATA_RAW, DATA_CODED, DATA_MODULATED, HEADER_ADDED, PREAMBLE_ADDED, } packet_mod_state_t; typedef struct { unsigned char *pkt_bytes; float complex *pkt_symbols; packet_mod_state_t state; modem modem; fec fec; uint16_t raw_data_crc; size_t length; } packet_mod_ctx_t; /*!\brief Initialize the packet modulator context. * * \param[inout] ctx The context to initialize. * \returns An result code (see results.h). */ result_t packet_mod_init(packet_mod_ctx_t *ctx); /*!\brief Free all resources in the given context. * * \param[inout] ctx The context to free. * \returns An result code (see results.h). */ result_t packet_mod_free(packet_mod_ctx_t *ctx); /*!\brief Set the raw packet data. * * In this step, the CRC of the data is calculated. * * This is the first step in packet processing. The context must be freshly * initialized. * * The stored data can be retrieved for verification using \ref * packet_mod_get_result_b(). * * \param[inout] ctx The context to use for this operation. * \returns An result code (see results.h). */ result_t packet_mod_set_data(packet_mod_ctx_t *ctx, const unsigned char *data, size_t length); /*!\brief Channel-code the stored packet data. * * This can only be called after \ref packet_mod_set_data(). * * The resulting data can be retrieved for verification using \ref * packet_mod_get_result_b(). * * \param[inout] ctx The context to use for this operation. * \returns An result code (see results.h). */ result_t packet_mod_encode(packet_mod_ctx_t *ctx); /*!\brief Modulate the packet data. * * This can be called after \ref packet_mod_set_data() or \ref * packet_mod_encode(). * * The resulting data can be retrieved for verification using \ref * packet_mod_get_result_cf(). * * \param[inout] ctx The context to use for this operation. * \returns An result code (see results.h). */ result_t packet_mod_modulate(packet_mod_ctx_t *ctx); /*!\brief Add a channel-coded and modulated packet header. * * The header contains the length of the data part (in symbols) and the CRC of * the original raw data. The channel coding scheme and modulation are * different than for the actual packet data, see \ref HEADER_CHANNEL_CODING * and \ref HEADER_MODULATION. These settings should be chosen to be slightly * more robust than the actual data encoding and modulation. * * This can only be called after \ref packet_mod_modulate(). * * The resulting data can be retrieved for verification using \ref * packet_mod_get_result_cf(). * * \param[inout] ctx The context to use for this operation. * \returns An result code (see results.h). */ result_t packet_mod_add_header(packet_mod_ctx_t *ctx); /*!\brief Add the preamble to the packet. * * The preamble is one cycle of a m-sequence, modulated using BPSK. Adding such * a preamble allows to find the packet start time and further signal * parameters such as phase offset using cross-correlation at the receiver. * * This can only be called after \ref packet_mod_add_header(). * * The resulting data can be retrieved using \ref packet_mod_get_result_cf(). * * \param[inout] ctx The context to use for this operation. * \returns An result code (see results.h). */ result_t packet_mod_add_preamble(packet_mod_ctx_t *ctx); /*!\brief Dump the internal data to the given file. * * The format of the resulting file depends on the current state of the packet * modulation context. * * \param[in] ctx The context to use for this operation. * \param[in] filename Name of the file to write to. * \returns An result code (see results.h). */ result_t packet_mod_dump(packet_mod_ctx_t *ctx, const char *filename); /*!\brief Get the result data as raw bytes. * * Raw bytes can be retrieved after \ref packet_mod_set_data() and \ref * packet_mod_encode(). In all other states, this returns ERR_INVALID_STATE. * * \param[in] ctx The context to use for this operation. * \param[out] data A pointer to the memory location where the data should be written. * \param[inout length A pointer to the data length (in array items). The * value shall be set to the size of the data buffer. * After the call, it is set to the required buffer size * (if \ref data is NULL or the length is not sufficient) * or the number of items actually written to \ref data. * \retval OK If the data was copied successfully or \ref data was * NULL. In the latter case, only \ref length is modified * to the required buffer size. * \retval ERR_NO_MEM If the \ref length was not sufficient for the data. * \retval ERR_INVALID_STATE If byte data is unavailable in the current state. */ result_t packet_mod_get_result_b(packet_mod_ctx_t *ctx, unsigned char *data, size_t *length); /*!\brief Get the result data as complex numbers. * * Complex numbers can be retrieved after \ref packet_mod_modulate(), \ref * packet_mod_add_header() and \ref packet_mod_add_preamble(). In all other * states, this returns ERR_INVALID_STATE. * * \param[in] ctx The context to use for this operation. * \param[out] data A pointer to the memory location where the data should be written. * \param[inout length A pointer to the data length (in array items). The * value shall be set to the size of the data buffer. * After the call, it is set to the required buffer size * (if \ref data is NULL or the length is not sufficient) * or the number of items actually written to \ref data. * \retval OK If the data was copied successfully or \ref data was * NULL. In the latter case, only \ref length is modified * to the required buffer size. * \retval ERR_NO_MEM If the \ref length was not sufficient for the data. * \retval ERR_INVALID_STATE If byte data is unavailable in the current state. */ result_t packet_mod_get_result_cf(packet_mod_ctx_t *ctx, float complex *data, size_t *length); #endif // PACKET_MOD