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 
47 typedef 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;
93 } sprt_chan_t;
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 ------------------------------------------------------------*/
Definition: private/sprt.h:47
Definition: private/sprt.h:95
void(* span_modem_status_func_t)(void *user_data, int status)
Definition: async.h:131
Definition: private/logging.h:33
logging_state_t logging
Error and flow logging control.
Definition: private/sprt.h:135