-
Notifications
You must be signed in to change notification settings - Fork 314
/
Copy pathil2p_send.c
147 lines (120 loc) · 4.17 KB
/
il2p_send.c
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
//
// 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