Промежуточные изменения
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "group_fec.h"
|
||||
#include "frame_tx.h"
|
||||
|
||||
// Параметры передатчика по умолчанию
|
||||
#define DEFAULT_GAIN -30.0 // Усиление передатчика: -30 дБ
|
||||
@@ -18,73 +19,9 @@
|
||||
// Внешняя переменная флага завершения (определена в common.c)
|
||||
extern volatile sig_atomic_t stop;
|
||||
|
||||
// Кодирование и отправка одного кадра: CRC-поверх-RS (техдолг #3) → заголовок
|
||||
// 12 Б → OFDM-сборка → push_partial → пауза. hdr11 несёт флаги group-FEC
|
||||
// (0 для legacy). pl/n — полезная нагрузка (данные ≤1024 или паритет 1026).
|
||||
static void tx_frame(ofdmflexframegen fg, struct iio_buffer *buf, fec enc,
|
||||
uint32_t seq, uint8_t hdr11,
|
||||
const uint8_t *pl, size_t n, float amp, int pause_us) {
|
||||
uint8_t *tx_payload = NULL;
|
||||
size_t tx_len = 0;
|
||||
uint8_t hdr[HDR_SIZE] = {0};
|
||||
|
||||
if (enc) {
|
||||
// CRC32 поверх исходных данных ДО RS: fec_decode() liquid не сообщает о
|
||||
// неисправимых блоках — единственный надёжный критерий на RX (техдолг #3).
|
||||
uint8_t framed[GF_PAR_PAY + 4]; // ≥ данные+4 и ≥ паритет 1026+4
|
||||
memcpy(framed, pl, n);
|
||||
// liquid crc_generate_key() не помечает вход const (API-огрех), хотя
|
||||
// только читает буфер — снимаем const кастом, чтобы -Wextra был чист.
|
||||
unsigned int crc = crc_generate_key(LIQUID_CRC_32, (unsigned char *)pl, n);
|
||||
framed[n] = (crc >> 24) & 0xFF;
|
||||
framed[n + 1] = (crc >> 16) & 0xFF;
|
||||
framed[n + 2] = (crc >> 8) & 0xFF;
|
||||
framed[n + 3] = crc & 0xFF;
|
||||
size_t framed_n = n + 4;
|
||||
|
||||
size_t total_blocks = (framed_n + RS_DATA - 1) / RS_DATA;
|
||||
tx_len = total_blocks * RS_ENC;
|
||||
tx_payload = malloc(tx_len);
|
||||
for (size_t b = 0; b < total_blocks; b++) {
|
||||
uint8_t blk[RS_DATA] = {0};
|
||||
size_t bytes = (b == total_blocks - 1) ? framed_n - b * RS_DATA : RS_DATA;
|
||||
memcpy(blk, framed + b * RS_DATA, bytes);
|
||||
fec_encode(enc, RS_DATA, blk, tx_payload + b * RS_ENC);
|
||||
}
|
||||
hdr[8] = (total_blocks >> 8) & 0xFF; hdr[9] = total_blocks & 0xFF;
|
||||
hdr[10] = framed_n % RS_DATA;
|
||||
} else {
|
||||
tx_len = n;
|
||||
tx_payload = malloc(tx_len);
|
||||
memcpy(tx_payload, pl, n);
|
||||
}
|
||||
|
||||
hdr[0] = HDR_SIGNATURE_0; hdr[1] = HDR_SIGNATURE_1;
|
||||
hdr[2] = (seq >> 24) & 0xFF; hdr[3] = (seq >> 16) & 0xFF;
|
||||
hdr[4] = (seq >> 8) & 0xFF; hdr[5] = seq & 0xFF;
|
||||
hdr[6] = (n >> 8) & 0xFF; hdr[7] = n & 0xFF;
|
||||
hdr[11] = hdr11; // group-FEC флаги (0 = legacy)
|
||||
|
||||
ofdmflexframegen_assemble(fg, hdr, tx_payload, tx_len);
|
||||
free(tx_payload);
|
||||
|
||||
int16_t *out = (int16_t *)iio_buffer_start(buf);
|
||||
memset(out, 0, BUF_SAMPLES * 2 * sizeof(int16_t));
|
||||
int idx = 0, done = 0;
|
||||
float complex symb[OFDM_M + OFDM_CP];
|
||||
while (!done && (idx + OFDM_M + OFDM_CP) <= BUF_SAMPLES) {
|
||||
done = ofdmflexframegen_write(fg, symb, OFDM_M + OFDM_CP);
|
||||
for (int i = 0; i < OFDM_M + OFDM_CP; i++) {
|
||||
out[2 * idx] = (int16_t)(crealf(symb[i]) * 32767 * amp);
|
||||
out[2 * idx + 1] = (int16_t)(cimagf(symb[i]) * 32767 * amp);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
// Только фактически заполненные idx сэмплов (техдолг #5): иначе мёртвый эфир
|
||||
// и сбитый межкадровый тайминг. push_partial даёт ту же длину, что write.
|
||||
if (idx > 0) iio_buffer_push_partial(buf, idx);
|
||||
if (pause_us > 0) usleep(pause_us);
|
||||
}
|
||||
// Сигнатура кадров данных/паритета GF (см. frame_tx.h — тип кадра различает
|
||||
// hdr[0..1]; END/STATUS обратного канала используют другие сигнатуры, §10 п.7).
|
||||
static const uint8_t SIG_DATA[2] = { HDR_SIGNATURE_0, HDR_SIGNATURE_1 };
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Инициализация параметров
|
||||
@@ -188,7 +125,7 @@ int main(int argc, char *argv[]) {
|
||||
usleep(10000);
|
||||
continue;
|
||||
}
|
||||
tx_frame(fg, buf, enc, seq++, 0, raw, n, amp, pause_us);
|
||||
phy_tx_frame(fg, buf, BUF_SAMPLES, enc, SIG_DATA, seq++, 0, raw, n, amp, pause_us);
|
||||
frames++; bytes_tx += n;
|
||||
if (time(NULL) > last) {
|
||||
fprintf(stderr, "\r📤 Передано: %llu кадров, %llu байт",
|
||||
@@ -216,7 +153,7 @@ int main(int argc, char *argv[]) {
|
||||
if (k == GF_K || (done_reading && k > 0)) {
|
||||
// k кадров данных: idx=0..k-1
|
||||
for (int i = 0; i < k; i++) {
|
||||
tx_frame(fg, buf, enc, seq++, GF_FLAG_MODE | i,
|
||||
phy_tx_frame(fg, buf, BUF_SAMPLES, enc, SIG_DATA, seq++, GF_FLAG_MODE | i,
|
||||
gdata[i], glen[i], amp, pause_us);
|
||||
frames++; bytes_tx += glen[i];
|
||||
}
|
||||
@@ -226,10 +163,10 @@ int main(int argc, char *argv[]) {
|
||||
uint16_t meta = GF_META_PACK(k, glen[k - 1]);
|
||||
par[0] = meta >> 8; par[1] = meta & 0xFF;
|
||||
memcpy(par + GF_META, P, GF_CHUNK);
|
||||
tx_frame(fg, buf, enc, seq++, GF_FLAG_MODE | GF_FLAG_PAR | k,
|
||||
phy_tx_frame(fg, buf, BUF_SAMPLES, enc, SIG_DATA, seq++, GF_FLAG_MODE | GF_FLAG_PAR | k,
|
||||
par, GF_PAR_PAY, amp, pause_us);
|
||||
memcpy(par + GF_META, Q, GF_CHUNK);
|
||||
tx_frame(fg, buf, enc, seq++, GF_FLAG_MODE | GF_FLAG_PAR | GF_FLAG_Q | (k + 1),
|
||||
phy_tx_frame(fg, buf, BUF_SAMPLES, enc, SIG_DATA, seq++, GF_FLAG_MODE | GF_FLAG_PAR | GF_FLAG_Q | (k + 1),
|
||||
par, GF_PAR_PAY, amp, pause_us);
|
||||
frames += 2;
|
||||
k = 0;
|
||||
|
||||
Reference in New Issue
Block a user