spandsp 3.0.0
private/sprt.h
Go to the documentation of this file.
1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * private/sprt.h - An implementation of the SPRT protocol defined in V.150.1
5 * Annex B, less the packet exchange part
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2022 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27/*! \file */
28
29#if !defined(_SPANDSP_PRIVATE_SPRT_H_)
30#define _SPANDSP_PRIVATE_SPRT_H_
31
32/* Timer TA01 is a buffering timer for ACKs. Start the timer when you buffer the first ACK.
33 If TA01 expires before you have three ACKs, or some data to send, send a packet with a
34 partically filled ACK section. Table B.3/V.150.1 in the spec implies there are separate
35 TA01 timers for the two types of reliable channel, although the suggested values are the
36 same. With ACKs for the two reliable channels being mixed in one packet, what would
37 different timers really mean?
38
39 Timer TA02 is a kind of keepalive timer for reliable packets. If there are no ACKs and
40 no data packets to send for TA02, an ACK only packet for the channel is sent, to keep
41 the BASE_SEQUENCE_NO updated. Each type of reliable channel can have a different value for
42 TA02, and the suggested values in the spec are different.
43
44 Timer TR03 is the retransmit timer for the reliable channels. Packets not acknowledged after
45 TR03 times out are retransmitted. */
46
47typedef struct
48{
49 bool active;
50
51 /* The maximum payload bytes is a per packet limit, which can be different for each
52 channel. For channel 0 it is unclear if this should be anything other than zero. */
53 int max_payload_bytes;
54 /* The window size is only relevant for the reliable channels - channels 1 and 2. */
55 int window_size;
56
57 /* TA02 is only relevant for the 2 reliable channels, but make it a per channel timeout */
58 int ta02_timeout;
59 /* TR03 is only relevant for the 2 reliable channels, but make it a per channel timeout.
60 There is a TR03 timeout for every slot in the window, but for each channel they all
61 use the same timeout value. */
62 int tr03_timeout;
63
64 /* There is a single TA02 timer for each reliable channel. */
65 span_timestamp_t ta02_timer;
66
67 /* The base sequence number should always be zero for the unreliable channels.
68 For the reliable channels it is the next sequence number to be delivered to
69 the application. */
70 uint16_t base_sequence_no;
71 /* This is the current sequence number for adding the next entry to the queue. */
72 uint16_t queuing_sequence_no;
73
74 uint8_t max_tries;
75
76 /* Only used for the reliable channels */
77 volatile int buff_in_ptr;
78 volatile int buff_acked_out_ptr;
79 uint8_t *buff;
80 uint16_t *buff_len;
81 span_timestamp_t *tr03_timer;
82 /* These are small buffers, so just make them statically the size of the largest possible
83 window */
84 uint8_t prev_in_time[SPRT_MAX_WINDOWS_SIZE];
85 uint8_t next_in_time[SPRT_MAX_WINDOWS_SIZE];
86 uint8_t remaining_tries[SPRT_MAX_WINDOWS_SIZE];
87
88 uint8_t first_in_time;
89 uint8_t last_in_time;
90
91 /* Busy indicates the application is congested, */
92 bool busy;
94
96{
97 sprt_tx_packet_handler_t tx_packet_handler;
98 void *tx_user_data;
99 sprt_rx_delivery_handler_t rx_delivery_handler;
100 void *rx_user_data;
101 sprt_timer_handler_t timer_handler;
102 void *timer_user_data;
103 span_modem_status_func_t status_handler;
104 void *status_user_data;
105
106 span_timestamp_t latest_timer;
107
108 struct
109 {
110 uint8_t subsession_id;
111 uint8_t payload_type;
112
113 sprt_chan_t chan[SPRT_CHANNELS];
114 } rx;
115 struct
116 {
117 uint8_t subsession_id;
118 uint8_t payload_type;
119
120 sprt_chan_t chan[SPRT_CHANNELS];
121
122 /* The ACK queue is shared across the reliable channels. */
123 volatile int ack_queue_ptr;
124 uint16_t ack_queue[3];
125
126 /* TA01 is not channel specific. */
127 int ta01_timeout;
128 span_timestamp_t ta01_timer;
129 /* The "immediate" timer is a special to get an immediate callback, without getting
130 deeper into nesting, with the protocol calling the app, calling protocol, ad
131 infinitum */
132 bool immediate_timer;
133 } tx;
134 /*! \brief Error and flow logging control */
136#if defined(SPANDSP_FULLY_DEFINE_SPRT_STATE_T)
137 /* TODO: This stuff is currently defined as the maximum possible sizes. It could be
138 allocated in a more adaptive manner. */
139 /*! \brief The data buffer, sized at the time the structure is created. */
140 /* TODO: make this buffer area adapt, rather than always being the maximum possible
141 size. */
142
143 /* Make these buffers statically as big as they could ever need to be. We may be using
144 smaller windows, or a limited maximum payload, and not need all this buffer space.
145 However, if we change these values after initialisation we could be in trouble if
146 we dynamically allocate just the amount of buffer space we need. */
147 uint8_t tc1_rx_buff[(SPRT_MAX_TC1_WINDOWS_SIZE + 1)*SPRT_MAX_TC1_PAYLOAD_BYTES];
148 uint16_t tc1_rx_buff_len[SPRT_MAX_TC1_WINDOWS_SIZE + 1];
149
150 uint8_t tc2_rx_buff[(SPRT_MAX_TC2_WINDOWS_SIZE + 1)*SPRT_MAX_TC2_PAYLOAD_BYTES];
151 uint16_t tc2_rx_buff_len[SPRT_MAX_TC2_WINDOWS_SIZE + 1];
152
153 /* Make these buffers statically as big as they could ever need to be. We may be using
154 smaller windows, or a limited maximum payload, and not need all this buffer space.
155 However, if we change these values after initialisation we could be in trouble if
156 we dynamically allocate just the amount of buffer space we need. */
157 uint8_t tc1_tx_buff[(SPRT_MAX_TC1_WINDOWS_SIZE + 1)*SPRT_MAX_TC1_PAYLOAD_BYTES];
158 uint16_t tc1_tx_buff_len[SPRT_MAX_TC1_WINDOWS_SIZE + 1];
159 span_timestamp_t tc1_tx_tr03_timer[SPRT_MAX_TC1_WINDOWS_SIZE + 1];
160
161 uint8_t tc2_tx_buff[(SPRT_MAX_TC2_WINDOWS_SIZE + 1)*SPRT_MAX_TC2_PAYLOAD_BYTES];
162 uint16_t tc2_tx_buff_len[SPRT_MAX_TC2_WINDOWS_SIZE + 1];
163 span_timestamp_t tc2_tx_tr03_timer[SPRT_MAX_TC2_WINDOWS_SIZE + 1];
164#endif
165};
166
167/* For packet buffer sizing purposes we need the maximum length of a constructed SPRT packet. */
168#define SPRT_MAX_PACKET_BYTES (12 + 256)
169
170#define SPRT_SEQ_NO_MASK 0x3FFF
171
172/* Used as the length of the data in a buffer slot when that slot is free */
173#define SPRT_LEN_SLOT_FREE 0xFFFF
174
175#define TR03_QUEUE_FREE_SLOT_TAG 0xFFU
176
177#endif
178/*- End of file ------------------------------------------------------------*/
void(* span_modem_status_func_t)(void *user_data, int status)
Definition async.h:131
struct logging_state_s logging_state_t
Definition logging.h:72
Definition private/sprt.h:48
Definition private/sprt.h:96
logging_state_t logging
Error and flow logging control.
Definition private/sprt.h:135