mirror of https://github.com/wb2osz/direwolf.git
147 lines
4.2 KiB
C
147 lines
4.2 KiB
C
//
|
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
|
//
|
|
// Copyright (C) 2021 John Langner, WB2OSZ
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "direwolf.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#include "il2p.h"
|
|
#include "textcolor.h"
|
|
#include "audio.h"
|
|
#include "gen_tone.h"
|
|
|
|
|
|
static int number_of_bits_sent[MAX_CHANS]; // Count number of bits sent by "il2p_send_frame"
|
|
|
|
static void send_bytes (int chan, unsigned char *b, int count, int polarity);
|
|
static void send_bit (int chan, int b, int polarity);
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------
|
|
*
|
|
* Name: il2p_send_frame
|
|
*
|
|
* Purpose: Convert frames to a stream of bits in IL2P format.
|
|
*
|
|
* Inputs: chan - Audio channel number, 0 = first.
|
|
*
|
|
* pp - Pointer to packet object.
|
|
*
|
|
* max_fec - 1 to force 16 parity symbols for each payload block.
|
|
* 0 for automatic depending on block size.
|
|
*
|
|
* polarity - 0 for normal. 1 to invert signal.
|
|
* 2 special case for testing - introduce some errors to test FEC.
|
|
*
|
|
* Outputs: Bits are shipped out by calling tone_gen_put_bit().
|
|
*
|
|
* Returns: Number of bits sent including
|
|
* - Preamble (01010101...)
|
|
* - 3 byte Sync Word.
|
|
* - 15 bytes for Header.
|
|
* - Optional payload.
|
|
* The required time can be calculated by dividing this
|
|
* number by the transmit rate of bits/sec.
|
|
* -1 is returned for failure.
|
|
*
|
|
* Description: Generate an IL2P encoded frame.
|
|
*
|
|
* Assumptions: It is assumed that the tone_gen module has been
|
|
* properly initialized so that bits sent with
|
|
* tone_gen_put_bit() are processed correctly.
|
|
*
|
|
* Errors: Return -1 for error. Probably frame too large.
|
|
*
|
|
* Note: Inconsistency here. ax25 version has just a byte array
|
|
* and length going in. Here we need the full packet object.
|
|
*
|
|
*--------------------------------------------------------------*/
|
|
|
|
int il2p_send_frame (int chan, packet_t pp, int max_fec, int polarity)
|
|
{
|
|
unsigned char encoded[IL2P_MAX_PACKET_SIZE];
|
|
|
|
encoded[0] = ( IL2P_SYNC_WORD >> 16 ) & 0xff;
|
|
encoded[1] = ( IL2P_SYNC_WORD >> 8 ) & 0xff;
|
|
encoded[2] = ( IL2P_SYNC_WORD ) & 0xff;
|
|
|
|
int elen = il2p_encode_frame (pp, max_fec, encoded + IL2P_SYNC_WORD_SIZE);
|
|
if (elen <= 0) {
|
|
text_color_set(DW_COLOR_ERROR);
|
|
dw_printf ("IL2P: Unable to encode frame into IL2P.\n");
|
|
return (-1);
|
|
}
|
|
|
|
elen += IL2P_SYNC_WORD_SIZE;
|
|
|
|
number_of_bits_sent[chan] = 0;
|
|
|
|
if (il2p_get_debug() >= 1) {
|
|
text_color_set(DW_COLOR_DEBUG);
|
|
dw_printf ("IL2P frame, max_fec = %d, %d encoded bytes total\n", max_fec, elen);
|
|
fx_hex_dump (encoded, elen);
|
|
}
|
|
|
|
// Clobber some bytes for testing.
|
|
if (polarity >= 2) {
|
|
for (int j = 10; j < elen; j+=100) {
|
|
encoded[j] = ~ encoded[j];
|
|
}
|
|
}
|
|
|
|
// Send bits to modulator.
|
|
|
|
static unsigned char preamble = IL2P_PREAMBLE;
|
|
|
|
send_bytes (chan, &preamble, 1, polarity);
|
|
send_bytes (chan, encoded, elen, polarity);
|
|
|
|
return (number_of_bits_sent[chan]);
|
|
}
|
|
|
|
|
|
static void send_bytes (int chan, unsigned char *b, int count, int polarity)
|
|
{
|
|
for (int j = 0; j < count; j++) {
|
|
unsigned int x = b[j];
|
|
for (int k = 0; k < 8; k++) {
|
|
send_bit (chan, (x & 0x80) != 0, polarity);
|
|
x <<= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// NRZI would be applied for AX.25 but IL2P does not use it.
|
|
// However we do have an option to invert the signal.
|
|
// The direwolf receive implementation will automatically compensate
|
|
// for either polarity but other implementations might not.
|
|
|
|
static void send_bit (int chan, int b, int polarity)
|
|
{
|
|
tone_gen_put_bit (chan, (b ^ polarity) & 1);
|
|
number_of_bits_sent[chan]++;
|
|
}
|
|
|
|
|
|
|
|
// end il2p_send.c
|