Bug Summary

File:src/v150_1_sse.c
Warning:line 975, column 9
Value stored to 'f' is never read

Annotated Source Code

1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * v150_1_sse.c - An implementation of the state signaling events (SSE),
5 * protocol defined in V.150.1 Annex C, less the packet
6 * exchange part
7 *
8 * Written by Steve Underwood <steveu@coppice.org>
9 *
10 * Copyright (C) 2022, 2023 Steve Underwood
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2, as
16 * published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#if defined(HAVE_CONFIG_H1)
29#include "config.h"
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <sys/types.h>
35#include <inttypes.h>
36#include <memory.h>
37#if defined(HAVE_STDBOOL_H1)
38#include <stdbool.h>
39#else
40#include <spandsp/stdbool.h>
41#endif
42
43#define SPANDSP_FULLY_DEFINE_SPRT_STATE_T
44
45#include "spandsp/telephony.h"
46#include "spandsp/alloc.h"
47#include "spandsp/unaligned.h"
48#include "spandsp/logging.h"
49#include "spandsp/async.h"
50#include "spandsp/sprt.h"
51#include "spandsp/v150_1.h"
52#include "spandsp/v150_1_sse.h"
53
54#include "spandsp/private/logging.h"
55#include "spandsp/private/sprt.h"
56#include "spandsp/private/v150_1_sse.h"
57#include "spandsp/private/v150_1.h"
58
59#include "v150_1_local.h"
60
61/*
62If the explicit acknowledgement procedure is being used for a call, the endpoints shall execute the
63following procedures.
64
65When an endpoint's MoIP application goes to a new mode, it:
66 sends an SSE message containing the current value of the variables local_media_state and remote_media_state
67 to the other endpoint, with the must respond flag set to FALSE
68 sets counter n0 to the value n0count
69 sets timer t0 to t0interval (even if it was non-zero)
70 sets timer t1 to t1interval (even if it was non-zero)
71
72
73
74 if timer t0 decrements to 0
75 and
76 counter n0 is not equal to 0
77 and
78 the value of local_media_state is not equal to the value of remote_ack
79 then
80 The endpoint sends an SSE message to the other endpoint exactly as above except
81 o counter n0 is decremented rather than set to n0count
82 o timer t1 is not set
83 o the must respond flag is set to TRUE if the value of timer t1 is zero.
84
85NOTE - If timer t0 decrements to 0 and counter n0 is equal to zero, no action is taken until timer t1
86 decrements to 0.
87
88
89
90 if timer t1 decrements to 0
91 and
92 counter n0 is equal to 0
93 and
94 the value of local_media_state is not equal to the value of remote_ack.
95 then
96 The endpoint sends an SSE message to the other endpoint exactly as first given above except
97 o counter n0 is not decremented, it is left equal to zero
98 o timer t0 is not set (It too is left equal to 0.)
99 o the must respond flag is set to TRUE
100
101
102
103Upon receipt of an SSE message from the other endpoint
104 if the message is a duplicate or out of sequence (determined using the RTP header sequence number)
105 then
106 the endpoint ignores the received message
107 else
108 set the values of remote_media_state and remote_ack to the values in the message
109 if the message contained a new value for the remote endpoint's mode
110 then
111 or the message's must respond flag is set to TRUE
112 then
113 the endpoint sends an SSE message to the other endpoint exactly as first given above,
114 except counter n0 and timers t0 and t1 are not (re)set.
115
116
117V.150.1 uses the terms "media states" and "SSE events". These SSE events are just changes of the media state.
118So, media states map 1:1 to SSE events.
119*/
120
121static int v150_1_sse_tx_modem_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo);
122static int v150_1_sse_tx_fax_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo);
123
124SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_sse_moip_ric_to_str(int ric)
125{
126 const char *res;
127
128 res = "unknown";
129 switch (ric)
130 {
131 case V150_1_SSE_MOIP_RIC_V8_CM:
132 res = "V.8 CM";
133 break;
134 case V150_1_SSE_MOIP_RIC_V8_JM:
135 res = "V.8 JM";
136 break;
137 case V150_1_SSE_MOIP_RIC_V32BIS_AA:
138 res = "V.32/V.32bis AA";
139 break;
140 case V150_1_SSE_MOIP_RIC_V32BIS_AC:
141 res = "V.32/V.32bis AC";
142 break;
143 case V150_1_SSE_MOIP_RIC_V22BIS_USB1:
144 res = "V.22bis USB1";
145 break;
146 case V150_1_SSE_MOIP_RIC_V22BIS_SB1:
147 res = "V.22bis SB1";
148 break;
149 case V150_1_SSE_MOIP_RIC_V22BIS_S1:
150 res = "V.22bis S1";
151 break;
152 case V150_1_SSE_MOIP_RIC_V21_CH2:
153 res = "V.21 Ch2";
154 break;
155 case V150_1_SSE_MOIP_RIC_V21_CH1:
156 res = "V.21 Ch1";
157 break;
158 case V150_1_SSE_MOIP_RIC_V23_HIGH_CHANNEL:
159 res = "V.23 high channel";
160 break;
161 case V150_1_SSE_MOIP_RIC_V23_LOW_CHANNEL:
162 res = "V.23 low channel";
163 break;
164 case V150_1_SSE_MOIP_RIC_TONE_2225HZ:
165 res = "2225Hz tone";
166 break;
167 case V150_1_SSE_MOIP_RIC_V21_CH2_HDLC_FLAGS:
168 res = "V.21 Ch2 HDLC flags";
169 break;
170 case V150_1_SSE_MOIP_RIC_INDETERMINATE_SIGNAL:
171 res = "Indeterminate signal";
172 break;
173 case V150_1_SSE_MOIP_RIC_SILENCE:
174 res = "Silence";
175 break;
176 case V150_1_SSE_MOIP_RIC_CNG:
177 res = "CNG";
178 break;
179 case V150_1_SSE_MOIP_RIC_VOICE:
180 res = "Voice";
181 break;
182 case V150_1_SSE_MOIP_RIC_TIMEOUT:
183 res = "Time-out";
184 break;
185 case V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION:
186 res = "P' state transition";
187 break;
188 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
189 res = "Cleardown";
190 break;
191 case V150_1_SSE_MOIP_RIC_ANS_CED:
192 res = "CED";
193 break;
194 case V150_1_SSE_MOIP_RIC_ANSAM:
195 res = "ANSam";
196 break;
197 case V150_1_SSE_MOIP_RIC_ANS_PR:
198 res = "/ANS";
199 break;
200 case V150_1_SSE_MOIP_RIC_ANSAM_PR:
201 res = "/ANSam";
202 break;
203 case V150_1_SSE_MOIP_RIC_V92_QC1A:
204 res = "V.92 QC1a";
205 break;
206 case V150_1_SSE_MOIP_RIC_V92_QC1D:
207 res = "V.92 QC1d";
208 break;
209 case V150_1_SSE_MOIP_RIC_V92_QC2A:
210 res = "V.92 QC2a";
211 break;
212 case V150_1_SSE_MOIP_RIC_V92_QC2D:
213 res = "V.92 QC2d";
214 break;
215 case V150_1_SSE_MOIP_RIC_V8BIS_CRE:
216 res = "V.8bis Cre";
217 break;
218 case V150_1_SSE_MOIP_RIC_V8BIS_CRD:
219 res = "V.8bis CRd";
220 break;
221 case V150_1_SSE_MOIP_RIC_TIA825A_45_45BPS:
222 res = "TIA825A 45.45BPS";
223 break;
224 case V150_1_SSE_MOIP_RIC_TIA825A_50BPS:
225 res = "TIA825A 50BPS";
226 break;
227 case V150_1_SSE_MOIP_RIC_EDT:
228 res = "EDT";
229 break;
230 case V150_1_SSE_MOIP_RIC_BELL103:
231 res = "Bell 103";
232 break;
233 case V150_1_SSE_MOIP_RIC_V21_TEXT_TELEPHONE:
234 res = "Text telephone";
235 break;
236 case V150_1_SSE_MOIP_RIC_V23_MINITEL:
237 res = "V.23 Minitel";
238 break;
239 case V150_1_SSE_MOIP_RIC_V18_TEXT_TELEPHONE:
240 res = "Text telephone";
241 break;
242 case V150_1_SSE_MOIP_RIC_V18_DTMF_TEXT_RELAY:
243 res = "Text relay";
244 break;
245 case V150_1_SSE_MOIP_RIC_CTM:
246 res = "CTM";
247 break;
248 }
249 /*endswitch*/
250 return res;
251}
252/*- End of function --------------------------------------------------------*/
253
254SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_sse_timeout_reason_to_str(int reason)
255{
256 const char *res;
257
258 res = "unknown";
259 switch (reason)
260 {
261 case V150_1_SSE_MOIP_RIC_INFO_TIMEOUT_NULL:
262 res = "NULL";
263 break;
264 case V150_1_SSE_MOIP_RIC_INFO_TIMEOUT_CALL_DISCRIMINATION_TIMEOUT:
265 res = "Call discrimination timeout";
266 break;
267 case V150_1_SSE_MOIP_RIC_INFO_TIMEOUT_IP_TLP:
268 res = "IP-TLP";
269 break;
270 case V150_1_SSE_MOIP_RIC_INFO_TIMEOUT_SSE_EXPLICIT_ACK_TIMEOUT:
271 res = "TSSE explicit acknowledgement timeout";
272 break;
273 }
274 /*endswitch*/
275 return res;
276}
277/*- End of function --------------------------------------------------------*/
278
279SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_sse_cleardown_reason_to_str(int reason)
280{
281 const char *res;
282
283 res = "unknown";
284 switch (reason)
285 {
286 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_UNKNOWN:
287 res = "Unknown/unspecified";
288 break;
289 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_PHYSICAL_LAYER_RELEASE:
290 /* Data pump release */
291 res = "Physical Layer Release";
292 break;
293 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_LINK_LAYER_DISCONNECT:
294 /* Received a V.42 DISC frame */
295 res = "Link Layer Disconnect";
296 break;
297 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_COMPRESSION_DISCONNECT:
298 res = "Data compression disconnect";
299 break;
300 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_ABORT:
301 /* Termination due to Abort procedure as specified in SDL */
302 res = "Abort";
303 break;
304 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_ON_HOOK:
305 /* When gateway receives On-hook signal from an end-point device */
306 res = "On-hook";
307 break;
308 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_NETWORK_LAYER_TERMINATION:
309 res = "Network layer termination";
310 break;
311 case V150_1_SSE_MOIP_RIC_INFO_CLEARDOWN_ADMINISTRATIVE:
312 /* Operator action at gateway */
313 res = "Administrative";
314 break;
315 }
316 /*endswitch*/
317 return res;
318}
319/*- End of function --------------------------------------------------------*/
320
321SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_sse_status_to_str(int status)
322{
323 const char *res;
324
325 res = "unknown";
326 switch (status)
327 {
328 case V150_1_SSE_STATUS_V8_CM_RECEIVED:
329 res = "V.8 CM received";
330 break;
331 case V150_1_SSE_STATUS_V8_JM_RECEIVED:
332 res = "V.8 JM received";
333 break;
334 case V150_1_SSE_STATUS_AA_RECEIVED:
335 res = "V.32 AA received";
336 break;
337 case V150_1_SSE_STATUS_V8_CM_RECEIVED_FAX:
338 res = "Fax V.8 CM received";
339 break;
340 case V150_1_SSE_STATUS_V8_JM_RECEIVED_FAX:
341 res = "Fax V.8 JM received";
342 break;
343 case V150_1_SSE_STATUS_AA_RECEIVED_FAX:
344 res = "Fax AA received";
345 break;
346 case V150_1_SSE_STATUS_CLEARDOWN:
347 res = "cleardown";
348 break;
349 }
350 /*endif*/
351 return res;
352}
353/*- End of function --------------------------------------------------------*/
354
355static int update_timer(v150_1_state_t *s)
356{
357 span_timestamp_t shortest;
358 int shortest_is;
359 v150_1_sse_state_t *sse;
360
361 sse = &s->sse;
362 if (sse->immediate_timer)
363 {
364 shortest = 1;
365 shortest_is = 4;
366 }
367 else
368 {
369 /* Find the earliest expiring of the active timers, and set the timeout to that. */
370 shortest = ~0;
371 shortest_is = 0;
372
373 if (sse->ack_timer_t0 && sse->ack_timer_t0 < shortest)
374 {
375 shortest = sse->ack_timer_t0;
376 shortest_is = 0;
377 }
378 /*endif*/
379 if (sse->ack_timer_t1 && sse->ack_timer_t1 < shortest)
380 {
381 shortest = sse->ack_timer_t1;
382 shortest_is = 1;
383 }
384 /*endif*/
385 if (sse->repetition_timer && sse->repetition_timer < shortest)
386 {
387 shortest = sse->repetition_timer;
388 shortest_is = 2;
389 }
390 /*endif*/
391 if (sse->recovery_timer_t1 && sse->recovery_timer_t1 < shortest)
392 {
393 shortest = sse->recovery_timer_t1;
394 shortest_is = 3;
395 }
396 /*endif*/
397 if (sse->recovery_timer_t2 && sse->recovery_timer_t2 < shortest)
398 {
399 shortest = sse->recovery_timer_t2;
400 shortest_is = 4;
401 }
402 /*endif*/
403 /* If we haven't shrunk shortest from maximum, we have no timer to set, so we stop the timer,
404 if its set. */
405 if (shortest == ~0)
406 shortest = 0;
407 /*endif*/
408 }
409 /*endif*/
410 span_log(&s->logging, SPAN_LOG_FLOW, "Update timer to %lu (%d)\n", shortest, shortest_is);
411 sse->latest_timer = shortest;
412 update_sse_timer(s, sse->latest_timer);
413 return 0;
414}
415/*- End of function --------------------------------------------------------*/
416
417static void log_v8_ric_info(v150_1_state_t *s, int ric_info)
418{
419 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_PCM_MODE))
420 span_log(&s->logging, SPAN_LOG_FLOW, " PCM mode\n");
421 /*endif*/
422 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V34_DUPLEX))
423 span_log(&s->logging, SPAN_LOG_FLOW, " V.34 duplex\n");
424 /*endif*/
425 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V34_HALF_DUPLEX))
426 span_log(&s->logging, SPAN_LOG_FLOW, " V.34 half duplex\n");
427 /*endif*/
428 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V32BIS))
429 span_log(&s->logging, SPAN_LOG_FLOW, " V.32/V32.bis\n");
430 /*endif*/
431 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V22BIS))
432 span_log(&s->logging, SPAN_LOG_FLOW, " V.22/V22.bis\n");
433 /*endif*/
434 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V17))
435 span_log(&s->logging, SPAN_LOG_FLOW, " V.17\n");
436 /*endif*/
437 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V29))
438 span_log(&s->logging, SPAN_LOG_FLOW, " V.29 half-duplex\n");
439 /*endif*/
440 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V27TER))
441 span_log(&s->logging, SPAN_LOG_FLOW, " V.27ter\n");
442 /*endif*/
443 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V26TER))
444 span_log(&s->logging, SPAN_LOG_FLOW, " V.26ter\n");
445 /*endif*/
446 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V26BIS))
447 span_log(&s->logging, SPAN_LOG_FLOW, " V.26bis\n");
448 /*endif*/
449 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V23_DUPLEX))
450 span_log(&s->logging, SPAN_LOG_FLOW, " V.23 duplex\n");
451 /*endif*/
452 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V23_HALF_DUPLEX))
453 span_log(&s->logging, SPAN_LOG_FLOW, " V.23 half-duplex\n");
454 /*endif*/
455 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V21))
456 span_log(&s->logging, SPAN_LOG_FLOW, " V.21\n");
457 /*endif*/
458 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V90_V92_ANALOGUE))
459 span_log(&s->logging, SPAN_LOG_FLOW, " V.90/V.92 analogue\n");
460 /*endif*/
461 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V90_V92_DIGITAL))
462 span_log(&s->logging, SPAN_LOG_FLOW, " V.90/V.92 digital\n");
463 /*endif*/
464 if ((ric_info & V150_1_SSE_MOIP_RIC_INFO_V8_CM_V91))
465 span_log(&s->logging, SPAN_LOG_FLOW, " V.91\n");
466 /*endif*/
467}
468/*- End of function --------------------------------------------------------*/
469
470static int rx_initial_audio_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
471{
472 if (s->remote_media_state != V150_1_MEDIA_STATE_INITIAL_AUDIO)
473 {
474 /* Even if we don't support audio, C.5.3.2 says we need to make this our local state */
475 s->local_media_state = V150_1_MEDIA_STATE_INITIAL_AUDIO;
476 s->remote_media_state = V150_1_MEDIA_STATE_INITIAL_AUDIO;
477 }
478 else
479 {
480 }
481 /*endif*/
482 return 0;
483}
484/*- End of function --------------------------------------------------------*/
485
486static int rx_voice_band_data_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
487{
488 if (s->remote_media_state != V150_1_MEDIA_STATE_VOICE_BAND_DATA)
489 {
490 /* Whether we change to VBD or plain audio is our choice. C.5.3.2. */
491 //s->local_media_state = V150_1_MEDIA_STATE_INITIAL_AUDIO;
492 s->local_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
493 s->remote_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
494 }
495 else
496 {
497 }
498 /*endif*/
499 return 0;
500}
501/*- End of function --------------------------------------------------------*/
502
503static int rx_modem_relay_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
504{
505 int res;
506 int ric;
507 int ric_info;
508
509 res = 0;
510 ric = pkt[1];
511 ric_info = get_net_unaligned_uint16(pkt + 2);
512 span_log(&s->logging,
513 SPAN_LOG_FLOW,
514 "%sReason %s - 0x%x\n",
515 ((pkt[0] >> 1) & 0x01) ? "Force response. " : "",
516 v150_1_sse_moip_ric_to_str(ric),
517 ric_info);
518 if (s->remote_media_state != V150_1_MEDIA_STATE_MODEM_RELAY)
519 {
520 /* Whether we change to modem relay, VBD or plain audio is our choice. C.5.3.2. */
521 if (s->cdscselect == V150_1_CDSCSELECT_VBD_PREFERRED
522 ||
523 s->cdscselect == V150_1_CDSCSELECT_MIXED)
524 {
525 s->local_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
526 s->remote_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
527 }
528 else
529 {
530 s->local_media_state = V150_1_MEDIA_STATE_MODEM_RELAY;
531 s->remote_media_state = V150_1_MEDIA_STATE_MODEM_RELAY;
532 }
533 /*endif*/
534 }
535 else
536 {
537 }
538 /*endif*/
539 switch (ric)
540 {
541 case V150_1_SSE_MOIP_RIC_V8_CM:
542 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.8 (CM) detection\n");
543 log_v8_ric_info(s, ric_info);
544 /* We need to respond with a P' */
545 v150_1_sse_tx_modem_relay_packet(s, 0, V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION, 0);
546 res = sse_status_handler(s, V150_1_SSE_STATUS_V8_CM_RECEIVED);
547 break;
548 case V150_1_SSE_MOIP_RIC_V8_JM:
549 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.8 (JM) detection\n");
550 log_v8_ric_info(s, ric_info);
551 res = sse_status_handler(s, V150_1_SSE_STATUS_V8_JM_RECEIVED);
552 break;
553 case V150_1_SSE_MOIP_RIC_V32BIS_AA:
554 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.32bis detection\n");
555 /* We need to respond with a P' */
556 v150_1_sse_tx_modem_relay_packet(s, 0, V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION, 0);
557 res = sse_status_handler(s, V150_1_SSE_STATUS_AA_RECEIVED);
558 break;
559 case V150_1_SSE_MOIP_RIC_V32BIS_AC:
560 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.32bis detection\n");
561 break;
562 case V150_1_SSE_MOIP_RIC_V22BIS_USB1:
563 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
564 break;
565 case V150_1_SSE_MOIP_RIC_V22BIS_SB1:
566 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
567 break;
568 case V150_1_SSE_MOIP_RIC_V22BIS_S1:
569 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
570 break;
571 case V150_1_SSE_MOIP_RIC_V21_CH2:
572 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 detection\n");
573 break;
574 case V150_1_SSE_MOIP_RIC_V21_CH1:
575 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 detection\n");
576 break;
577 case V150_1_SSE_MOIP_RIC_V23_HIGH_CHANNEL:
578 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 detection\n");
579 break;
580 case V150_1_SSE_MOIP_RIC_V23_LOW_CHANNEL:
581 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 detection\n");
582 break;
583 case V150_1_SSE_MOIP_RIC_TONE_2225HZ:
584 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on 2225Hz tone detection\n");
585 break;
586 case V150_1_SSE_MOIP_RIC_V21_CH2_HDLC_FLAGS:
587 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 flags detection\n");
588 break;
589 case V150_1_SSE_MOIP_RIC_INDETERMINATE_SIGNAL:
590 break;
591 case V150_1_SSE_MOIP_RIC_SILENCE:
592 break;
593 case V150_1_SSE_MOIP_RIC_CNG:
594 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on CNG detection\n");
595 break;
596 case V150_1_SSE_MOIP_RIC_VOICE:
597 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on voice detection\n");
598 break;
599 case V150_1_SSE_MOIP_RIC_TIMEOUT:
600 span_log(&s->logging,
601 SPAN_LOG_FLOW,
602 "Timeout %d - %s - 0x%x\n",
603 (ric_info >> 8),
604 v150_1_sse_timeout_reason_to_str(ric_info >> 8),
605 ric_info & 0xFF);
606 break;
607 case V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION:
608 span_log(&s->logging, SPAN_LOG_FLOW, "P' received\n");
609 break;
610 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
611 span_log(&s->logging,
612 SPAN_LOG_FLOW,
613 "Cleardown %d - %s\n",
614 (ric_info >> 8),
615 v150_1_sse_cleardown_reason_to_str(ric_info >> 8));
616 res = sse_status_handler(s, V150_1_SSE_STATUS_CLEARDOWN);
617 break;
618 case V150_1_SSE_MOIP_RIC_ANS_CED:
619 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on ANS/CED detection\n");
620 break;
621 case V150_1_SSE_MOIP_RIC_ANSAM:
622 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on ANSam detection\n");
623 break;
624 case V150_1_SSE_MOIP_RIC_ANS_PR:
625 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on /ANS detection\n");
626 break;
627 case V150_1_SSE_MOIP_RIC_ANSAM_PR:
628 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on /ANSam detection\n");
629 break;
630 case V150_1_SSE_MOIP_RIC_V92_QC1A:
631 break;
632 case V150_1_SSE_MOIP_RIC_V92_QC1D:
633 break;
634 case V150_1_SSE_MOIP_RIC_V92_QC2A:
635 break;
636 case V150_1_SSE_MOIP_RIC_V92_QC2D:
637 break;
638 case V150_1_SSE_MOIP_RIC_V8BIS_CRE:
639 break;
640 case V150_1_SSE_MOIP_RIC_V8BIS_CRD:
641 break;
642 case V150_1_SSE_MOIP_RIC_TIA825A_45_45BPS:
643 break;
644 case V150_1_SSE_MOIP_RIC_TIA825A_50BPS:
645 break;
646 case V150_1_SSE_MOIP_RIC_EDT:
647 break;
648 case V150_1_SSE_MOIP_RIC_BELL103:
649 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on Bell103 detection\n");
650 break;
651 case V150_1_SSE_MOIP_RIC_V21_TEXT_TELEPHONE:
652 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 text telephone detection\n");
653 break;
654 case V150_1_SSE_MOIP_RIC_V23_MINITEL:
655 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 minitel detection\n");
656 break;
657 case V150_1_SSE_MOIP_RIC_V18_TEXT_TELEPHONE:
658 break;
659 case V150_1_SSE_MOIP_RIC_V18_DTMF_TEXT_RELAY:
660 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on DTMF text relay detection\n");
661 break;
662 case V150_1_SSE_MOIP_RIC_CTM:
663 break;
664 }
665 /*endswitch*/
666 return res;
667}
668/*- End of function --------------------------------------------------------*/
669
670static int rx_fax_relay_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
671{
672 int res;
673 int ric;
674 int ric_info;
675
676 res = 0;
677 ric = pkt[1];
678 ric_info = get_net_unaligned_uint16(pkt + 2);
679 span_log(&s->logging,
680 SPAN_LOG_FLOW,
681 "SSE %sReason %s - 0x%x\n",
682 ((pkt[0] >> 1) & 0x01) ? "Force response. " : "",
683 v150_1_sse_moip_ric_to_str(ric),
684 ric_info);
685 if (s->remote_media_state != V150_1_MEDIA_STATE_FAX_RELAY)
686 {
687 /* Whether we change to FAX relay, VBD or plain audio is our choice. C.5.3.2. */
688 //s->local_media_state = V150_1_MEDIA_STATE_INITIAL_AUDIO;
689 //s->local_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
690 s->local_media_state = V150_1_MEDIA_STATE_FAX_RELAY;
691 s->remote_media_state = V150_1_MEDIA_STATE_FAX_RELAY;
692 }
693 else
694 {
695 }
696 /*endif*/
697 switch (ric)
698 {
699 case V150_1_SSE_MOIP_RIC_V8_CM:
700 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.8 detection\n");
701 /* We need to respond with a P' */
702 v150_1_sse_tx_fax_relay_packet(s, 0, V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION, 0);
703 res = sse_status_handler(s, V150_1_SSE_STATUS_V8_CM_RECEIVED_FAX);
704 break;
705 case V150_1_SSE_MOIP_RIC_V8_JM:
706 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.8 detection\n");
707 break;
708 case V150_1_SSE_MOIP_RIC_V32BIS_AA:
709 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.32bis detection\n");
710 /* We need to respond with a P' */
711 v150_1_sse_tx_fax_relay_packet(s, 0, V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION, 0);
712 res = sse_status_handler(s, V150_1_SSE_STATUS_AA_RECEIVED_FAX);
713 break;
714 case V150_1_SSE_MOIP_RIC_V32BIS_AC:
715 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.32bis detection\n");
716 break;
717 case V150_1_SSE_MOIP_RIC_V22BIS_USB1:
718 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
719 break;
720 case V150_1_SSE_MOIP_RIC_V22BIS_SB1:
721 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
722 break;
723 case V150_1_SSE_MOIP_RIC_V22BIS_S1:
724 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.22bis detection\n");
725 break;
726 case V150_1_SSE_MOIP_RIC_V21_CH2:
727 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 detection\n");
728 break;
729 case V150_1_SSE_MOIP_RIC_V21_CH1:
730 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 detection\n");
731 break;
732 case V150_1_SSE_MOIP_RIC_V23_HIGH_CHANNEL:
733 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 detection\n");
734 break;
735 case V150_1_SSE_MOIP_RIC_V23_LOW_CHANNEL:
736 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 detection\n");
737 break;
738 case V150_1_SSE_MOIP_RIC_TONE_2225HZ:
739 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on 2225Hz tone detection\n");
740 break;
741 case V150_1_SSE_MOIP_RIC_V21_CH2_HDLC_FLAGS:
742 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 flags detection\n");
743 break;
744 case V150_1_SSE_MOIP_RIC_INDETERMINATE_SIGNAL:
745 break;
746 case V150_1_SSE_MOIP_RIC_SILENCE:
747 break;
748 case V150_1_SSE_MOIP_RIC_CNG:
749 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on CNG detection\n");
750 break;
751 case V150_1_SSE_MOIP_RIC_VOICE:
752 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on voice detection\n");
753 break;
754 case V150_1_SSE_MOIP_RIC_TIMEOUT:
755 span_log(&s->logging,
756 SPAN_LOG_FLOW,
757 "Timeout %d - %s - 0x%x\n",
758 (ric_info >> 8),
759 v150_1_sse_timeout_reason_to_str(ric_info >> 8),
760 ric_info & 0xFF);
761 break;
762 case V150_1_SSE_MOIP_RIC_P_STATE_TRANSITION:
763 span_log(&s->logging, SPAN_LOG_FLOW, "P' received\n");
764 break;
765 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
766 span_log(&s->logging,
767 SPAN_LOG_FLOW,
768 "Cleardown %d - %s\n",
769 (ric_info >> 8),
770 v150_1_sse_cleardown_reason_to_str(ric_info >> 8));
771 res = sse_status_handler(s, V150_1_SSE_STATUS_CLEARDOWN);
772 break;
773 case V150_1_SSE_MOIP_RIC_ANS_CED:
774 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on ANS/CED detection\n");
775 break;
776 case V150_1_SSE_MOIP_RIC_ANSAM:
777 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on ANSam detection\n");
778 break;
779 case V150_1_SSE_MOIP_RIC_ANS_PR:
780 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on /ANS detection\n");
781 break;
782 case V150_1_SSE_MOIP_RIC_ANSAM_PR:
783 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on /ANSam detection\n");
784 break;
785 case V150_1_SSE_MOIP_RIC_V92_QC1A:
786 break;
787 case V150_1_SSE_MOIP_RIC_V92_QC1D:
788 break;
789 case V150_1_SSE_MOIP_RIC_V92_QC2A:
790 break;
791 case V150_1_SSE_MOIP_RIC_V92_QC2D:
792 break;
793 case V150_1_SSE_MOIP_RIC_V8BIS_CRE:
794 break;
795 case V150_1_SSE_MOIP_RIC_V8BIS_CRD:
796 break;
797 case V150_1_SSE_MOIP_RIC_TIA825A_45_45BPS:
798 break;
799 case V150_1_SSE_MOIP_RIC_TIA825A_50BPS:
800 break;
801 case V150_1_SSE_MOIP_RIC_EDT:
802 break;
803 case V150_1_SSE_MOIP_RIC_BELL103:
804 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on Bell103 detection\n");
805 break;
806 case V150_1_SSE_MOIP_RIC_V21_TEXT_TELEPHONE:
807 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 text telephone detection\n");
808 break;
809 case V150_1_SSE_MOIP_RIC_V23_MINITEL:
810 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 minitel detection\n");
811 break;
812 case V150_1_SSE_MOIP_RIC_V18_TEXT_TELEPHONE:
813 break;
814 case V150_1_SSE_MOIP_RIC_V18_DTMF_TEXT_RELAY:
815 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on DTMF text relay detection\n");
816 break;
817 case V150_1_SSE_MOIP_RIC_CTM:
818 break;
819 }
820 /*endswitch*/
821 return res;
822}
823/*- End of function --------------------------------------------------------*/
824
825static int rx_text_relay_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
826{
827 int ric;
828 int ric_info;
829
830 ric = pkt[1];
831 ric_info = get_net_unaligned_uint16(pkt + 2);
832 span_log(&s->logging,
833 SPAN_LOG_FLOW,
834 "SSE %sReason %s - 0x%x\n",
835 ((pkt[0] >> 1) & 0x01) ? "Force response. " : "",
836 v150_1_sse_moip_ric_to_str(ric),
837 ric_info);
838 if (s->remote_media_state != V150_1_MEDIA_STATE_TEXT_RELAY)
839 {
840 /* Whether we change to text relay, VBD or plain audio is our choice. C.5.3.2. */
841 //s->local_media_state = V150_1_MEDIA_STATE_INITIAL_AUDIO;
842 //s->local_media_state = V150_1_MEDIA_STATE_VOICE_BAND_DATA;
843 s->local_media_state = V150_1_MEDIA_STATE_TEXT_RELAY;
844 s->remote_media_state = V150_1_MEDIA_STATE_TEXT_RELAY;
845 }
846 else
847 {
848 }
849 /*endif*/
850 switch (ric)
851 {
852 case V150_1_SSE_MOIP_RIC_TIMEOUT:
853 span_log(&s->logging,
854 SPAN_LOG_FLOW,
855 "Timeout %d - %s - 0x%x\n",
856 (ric_info >> 8),
857 v150_1_sse_timeout_reason_to_str(ric_info >> 8),
858 ric_info & 0xFF);
859 break;
860 case V150_1_SSE_MOIP_RIC_TIA825A_45_45BPS:
861 break;
862 case V150_1_SSE_MOIP_RIC_TIA825A_50BPS:
863 break;
864 case V150_1_SSE_MOIP_RIC_EDT:
865 break;
866 case V150_1_SSE_MOIP_RIC_BELL103:
867 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on Bell103 detection\n");
868 break;
869 case V150_1_SSE_MOIP_RIC_V21_TEXT_TELEPHONE:
870 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.21 text telephone detection\n");
871 break;
872 case V150_1_SSE_MOIP_RIC_V23_MINITEL:
873 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on V.23 minitel detection\n");
874 break;
875 case V150_1_SSE_MOIP_RIC_V18_TEXT_TELEPHONE:
876 break;
877 case V150_1_SSE_MOIP_RIC_V18_DTMF_TEXT_RELAY:
878 span_log(&s->logging, SPAN_LOG_FLOW, "Switch on DTMF text relay detection\n");
879 break;
880 case V150_1_SSE_MOIP_RIC_CTM:
881 break;
882 }
883 /*endswitch*/
884 return 0;
885}
886/*- End of function --------------------------------------------------------*/
887
888static int rx_text_probe_packet(v150_1_state_t *s, const uint8_t pkt[], int len)
889{
890 int ric;
891 int ric_info;
892
893 ric = pkt[1];
894 ric_info = get_net_unaligned_uint16(pkt + 2);
895 span_log(&s->logging,
896 SPAN_LOG_FLOW,
897 "SSE %sReason %s - 0x%x\n",
898 ((pkt[0] >> 1) & 0x01) ? "Force response. " : "",
899 v150_1_sse_moip_ric_to_str(ric),
900 ric_info);
901 if (s->remote_media_state != V150_1_MEDIA_STATE_TEXT_RELAY)
902 {
903 s->local_media_state = V150_1_MEDIA_STATE_TEXT_RELAY;
904 s->remote_media_state = V150_1_MEDIA_STATE_TEXT_RELAY;
905 }
906 else
907 {
908 }
909 /*endif*/
910 switch (ric)
911 {
912 case V150_1_SSE_MOIP_RIC_TIMEOUT:
913 span_log(&s->logging,
914 SPAN_LOG_FLOW,
915 "Timeout %d - %s - 0x%x\n",
916 (ric_info >> 8),
917 v150_1_sse_timeout_reason_to_str(ric_info >> 8),
918 ric_info & 0xFF);
919 break;
920 }
921 /*endswitch*/
922 return 0;
923}
924/*- End of function --------------------------------------------------------*/
925
926SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_rx_sse_packet(v150_1_state_t *s,
927 uint16_t seq_no,
928 uint32_t timestamp,
929 const uint8_t pkt[],
930 int len)
931{
932 int event;
933 int res;
934 int f;
935 int x;
936 int ext_len;
937 v150_1_sse_state_t *sse;
938
939 sse = &s->sse;
940 span_log(&s->logging, SPAN_LOG_FLOW, "Rx message - %d bytes\n", len);
941
942 if (len < 4)
943 return -1;
944 /*endif*/
945
946 /*
947 Upon receipt of an SSE message from the other endpoint
948
949 if the message is a duplicate or out of sequence (determined using the RTP header sequence number)
950 then
951 the endpoint ignores the received message
952 else
953 set the values of remote_media_state and remote_ack to the values in the message
954 if the message contained a new value for the remote endpoint's mode
955 or
956 the message's must respond flag is set to TRUE
957 then
958 The endpoint sends an SSE message to the other endpoint exactly as first given above except
959 counter n0 and timers t0 and t1 are not (re)set.
960 */
961
962 res = 0;
963 /* V.150.1 C.4.1 says act on the first received copy of an SSE message. Expect
964 the sequence number to increase, but the timestamp should remain the same for
965 redundant repeats. */
966 if (sse->previous_rx_timestamp == timestamp)
967 {
968 span_log(&s->logging, SPAN_LOG_FLOW, "Repeat SSE timestamp %d\n", timestamp);
969 }
970 else
971 {
972 sse->previous_rx_timestamp = timestamp;
973
974 event = (pkt[0] >> 2) & 0x3F;
975 f = (pkt[0] >> 1) & 0x01;
Value stored to 'f' is never read
976 x = pkt[0] & 0x01;
977 span_log(&s->logging, SPAN_LOG_FLOW, "Rx SSE event %s\n", v150_1_media_state_to_str(event));
978 if (x)
979 {
980 if (len >= 6)
981 {
982 /* Deal with the extension */
983 ext_len = get_net_unaligned_uint16(&pkt[4]) & 0x7FF;
984 if (ext_len >= 1)
985 {
986 s->remote_ack = pkt[6] & 0x3F;
987 }
988 /*endif*/
989 }
990 /*endif*/
991 }
992 else
993 {
994 if (len != 4)
995 span_log(&s->logging, SPAN_LOG_FLOW, "Non-extended message of length %d\n", len);
996 /*endif*/
997 }
998 /*endif*/
999 /* TODO event needs to map properly */
1000 v150_1_state_machine(s, event, pkt, len);
1001 switch (event)
1002 {
1003 case V150_1_MEDIA_STATE_INITIAL_AUDIO:
1004 res = rx_initial_audio_packet(s, pkt, len);
1005 break;
1006 case V150_1_MEDIA_STATE_VOICE_BAND_DATA:
1007 res = rx_voice_band_data_packet(s, pkt, len);
1008 break;
1009 case V150_1_MEDIA_STATE_MODEM_RELAY:
1010 res = rx_modem_relay_packet(s, pkt, len);
1011 break;
1012 case V150_1_MEDIA_STATE_FAX_RELAY:
1013 res = rx_fax_relay_packet(s, pkt, len);
1014 break;
1015 case V150_1_MEDIA_STATE_TEXT_RELAY:
1016 res = rx_text_relay_packet(s, pkt, len);
1017 break;
1018 case V150_1_MEDIA_STATE_TEXT_PROBE:
1019 res = rx_text_probe_packet(s, pkt, len);
1020 break;
1021 default:
1022 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected SSE event %d\n", event);
1023 res = -1;
1024 break;
1025 }
1026 /*endswitch*/
1027 s->remote_media_state = event;
1028 }
1029 /*endif*/
1030 return res;
1031}
1032/*- End of function --------------------------------------------------------*/
1033
1034static int send_packet(v150_1_state_t *s, uint8_t *pkt, int len)
1035{
1036 span_timestamp_t now;
1037 v150_1_sse_state_t *sse;
1038
1039 sse = &s->sse;
1040 if (sse->tx_packet_handler)
1041 sse->tx_packet_handler(sse->tx_packet_user_data, false0, pkt, len);
1042 /*endif*/
1043 switch (sse->reliability_method)
1044 {
1045 case V150_1_SSE_RELIABILITY_BY_REPETITION:
1046 memcpy(sse->last_tx_pkt, pkt, len);
1047 sse->last_tx_len = len;
1048 now = update_sse_timer(s, ~0);
1049 sse->repetition_timer = now + sse->repetition_interval;
1050 sse->repetition_counter = sse->repetition_count;
1051 update_timer(s);
1052 break;
1053 case V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK:
1054 /* V.150.1/C.4.3.2 */
1055 /* Save a copy of the message for retransmission */
1056 /* TODO: add local_media_state and remote_media_state to the message */
1057 memcpy(sse->last_tx_pkt, pkt, len);
1058 sse->last_tx_len = len;
1059 now = update_sse_timer(s, ~0);
1060 sse->ack_counter_n0 = sse->ack_n0count;
1061 sse->ack_timer_t0 = now + sse->ack_t0interval;
1062 sse->ack_timer_t1 = now + sse->ack_t1interval;
1063 sse->force_response = false0;
1064 update_timer(s);
1065 break;
1066 }
1067 /*endswitch*/
1068 return 0;
1069}
1070/*- End of function --------------------------------------------------------*/
1071
1072static int v150_1_sse_tx_initial_audio_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1073{
1074 uint8_t pkt[256];
1075 int len;
1076 uint8_t f;
1077 v150_1_sse_state_t *sse;
1078
1079 sse = &s->sse;
1080 f = 0;
1081 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1082 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1083 {
1084 f |= 0x01;
1085 if (sse->force_response)
1086 f |= 0x02;
1087 /*endif*/
1088 }
1089 /*endif*/
1090 span_log(&s->logging, SPAN_LOG_FLOW, "Sending %s\n", v150_1_sse_moip_ric_to_str(ric));
1091 pkt[0] = f | (V150_1_MEDIA_STATE_INITIAL_AUDIO << 2);
1092 pkt[1] = ric;
1093 put_net_unaligned_uint16(&pkt[2], ricinfo);
1094 len = 4;
1095 switch (ric)
1096 {
1097 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
1098 /* We may need to add more information as an extension. Note that V.150.1 originally made
1099 the SSE message lengths variable in a way that can't really work. The only message this
1100 affected was cleardown. Corrigendum 2 changed the extra bytes to an extension field, so
1101 all messages are 4 bytes long until the extension bit it used to stretch them. */
1102 break;
1103 }
1104 /*endswitch*/
1105 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1106 {
1107 /* The length of the extension field */
1108 put_net_unaligned_uint16(&pkt[len], 1);
1109 len += 2;
1110 /* The actual content of the field */
1111 pkt[len++] = s->remote_media_state;
1112 }
1113 /*endif*/
1114 send_packet(s, pkt, len);
1115 return 0;
1116}
1117/*- End of function --------------------------------------------------------*/
1118
1119static int v150_1_sse_tx_voice_band_data_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1120{
1121 uint8_t pkt[256];
1122 int len;
1123 uint8_t f;
1124 v150_1_sse_state_t *sse;
1125
1126 sse = &s->sse;
1127 f = 0;
1128 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1129 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1130 {
1131 f |= 0x01;
1132 if (sse->force_response)
1133 f |= 0x02;
1134 /*endif*/
1135 }
1136 /*endif*/
1137 span_log(&s->logging, SPAN_LOG_FLOW, "Sending %s\n", v150_1_sse_moip_ric_to_str(ric));
1138 pkt[0] = f | (V150_1_MEDIA_STATE_VOICE_BAND_DATA << 2);
1139 pkt[1] = ric;
1140 put_net_unaligned_uint16(&pkt[2], ricinfo);
1141 len = 4;
1142 switch (ric)
1143 {
1144 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
1145 /* We may need to add more information as an extension. Note that V.150.1 originally made
1146 the SSE message lengths variable in a way that can't really work. The only message this
1147 affected was cleardown. Corrigendum 2 changed the extra bytes to an extension field, so
1148 all messages are 4 bytes long until the extension bit it used to stretch them. */
1149 break;
1150 }
1151 /*endswitch*/
1152 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1153 {
1154 /* The length of the extension field */
1155 put_net_unaligned_uint16(&pkt[len], 1);
1156 len += 2;
1157 /* The actual content of the field */
1158 pkt[len++] = s->remote_media_state;
1159 }
1160 /*endif*/
1161 send_packet(s, pkt, len);
1162 return 0;
1163}
1164/*- End of function --------------------------------------------------------*/
1165
1166static int v150_1_sse_tx_modem_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1167{
1168 uint8_t pkt[256];
1169 int len;
1170 uint8_t f;
1171 v150_1_sse_state_t *sse;
1172
1173 sse = &s->sse;
1174 f = 0;
1175 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1176 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1177 {
1178 f |= 0x01;
1179 if (sse->force_response)
1180 f |= 0x02;
1181 /*endif*/
1182 }
1183 /*endif*/
1184 span_log(&s->logging, SPAN_LOG_FLOW, "Sending %s\n", v150_1_sse_moip_ric_to_str(ric));
1185 pkt[0] = f | (V150_1_MEDIA_STATE_MODEM_RELAY << 2);
1186 pkt[1] = ric;
1187 put_net_unaligned_uint16(&pkt[2], ricinfo);
1188 len = 4;
1189 switch (ric)
1190 {
1191 case V150_1_SSE_MOIP_RIC_CLEARDOWN:
1192 /* We may need to add more information as an extension. Note that V.150.1 originally made
1193 the SSE message lengths variable in a way that can't really work. The only message this
1194 affected was cleardown. Corrigendum 2 changed the extra bytes to an extension field, so
1195 all messages are 4 bytes long until the extension bit it used to stretch them. */
1196 break;
1197 }
1198 /*endswitch*/
1199 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1200 {
1201 /* The length of the extension field */
1202 put_net_unaligned_uint16(&pkt[len], 1);
1203 len += 2;
1204 /* The actual content of the field */
1205 pkt[len++] = s->remote_media_state;
1206 }
1207 /*endif*/
1208 send_packet(s, pkt, len);
1209 return 0;
1210}
1211/*- End of function --------------------------------------------------------*/
1212
1213static int v150_1_sse_tx_fax_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1214{
1215 uint8_t pkt[256];
1216 int len;
1217 uint8_t f;
1218 v150_1_sse_state_t *sse;
1219
1220 sse = &s->sse;
1221 f = 0;
1222 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1223 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1224 {
1225 f |= 0x01;
1226 if (sse->force_response)
1227 f |= 0x02;
1228 /*endif*/
1229 }
1230 /*endif*/
1231 pkt[0] = (V150_1_MEDIA_STATE_FAX_RELAY << 2) | f;
1232 pkt[1] = ric;
1233 put_net_unaligned_uint16(&pkt[2], ricinfo);
1234 len = 4;
1235 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1236 {
1237 put_net_unaligned_uint16(&pkt[len], 1);
1238 len += 2;
1239 pkt[len++] = s->remote_media_state;
1240 }
1241 /*endif*/
1242 send_packet(s, pkt, len);
1243 return 0;
1244}
1245/*- End of function --------------------------------------------------------*/
1246
1247static int v150_1_sse_tx_text_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1248{
1249 uint8_t pkt[256];
1250 int len;
1251 uint8_t f;
1252 v150_1_sse_state_t *sse;
1253
1254 sse = &s->sse;
1255 f = 0;
1256 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1257 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1258 {
1259 f |= 0x01;
1260 if (sse->force_response)
1261 f |= 0x02;
1262 /*endif*/
1263 }
1264 /*endif*/
1265 pkt[0] = (V150_1_MEDIA_STATE_TEXT_RELAY << 2) | f;
1266 pkt[1] = ric;
1267 put_net_unaligned_uint16(&pkt[2], ricinfo);
1268 len = 4;
1269 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1270 {
1271 put_net_unaligned_uint16(&pkt[len], 1);
1272 len += 2;
1273 pkt[len++] = s->remote_media_state;
1274 }
1275 /*endif*/
1276 send_packet(s, pkt, len);
1277 return 0;
1278}
1279/*- End of function --------------------------------------------------------*/
1280
1281static int v150_1_sse_tx_text_probe_packet(v150_1_state_t *s, int x, int ric, int ricinfo)
1282{
1283 uint8_t pkt[256];
1284 int len;
1285 uint8_t f;
1286 v150_1_sse_state_t *sse;
1287
1288 sse = &s->sse;
1289 f = 0;
1290 /* If we are using explicit acknowledgements, both the F and X bits need to be set */
1291 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1292 {
1293 f |= 0x01;
1294 if (sse->force_response)
1295 f |= 0x02;
1296 /*endif*/
1297 }
1298 /*endif*/
1299 pkt[0] = (V150_1_MEDIA_STATE_TEXT_PROBE << 2) | f;
1300 pkt[1] = ric;
1301 put_net_unaligned_uint16(&pkt[2], ricinfo);
1302 len = 4;
1303 if (sse->reliability_method == V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK)
1304 {
1305 put_net_unaligned_uint16(&pkt[len], 1);
1306 len += 2;
1307 pkt[len++] = s->remote_media_state;
1308 }
1309 /*endif*/
1310 send_packet(s, pkt, len);
1311 return 0;
1312}
1313/*- End of function --------------------------------------------------------*/
1314
1315SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_sse_packet(v150_1_state_t *s, int event, int ric, int ricinfo)
1316{
1317 int res;
1318 int x;
1319
1320 x = 0;
1321 span_log(&s->logging, SPAN_LOG_FLOW, "Tx event %s\n", v150_1_media_state_to_str(event));
1322 switch (event)
1323 {
1324 case V150_1_MEDIA_STATE_INITIAL_AUDIO:
1325 res = v150_1_sse_tx_initial_audio_packet(s, x, ric, ricinfo);
1326 break;
1327 case V150_1_MEDIA_STATE_VOICE_BAND_DATA:
1328 res = v150_1_sse_tx_voice_band_data_packet(s, x, ric, ricinfo);
1329 break;
1330 case V150_1_MEDIA_STATE_MODEM_RELAY:
1331 res = v150_1_sse_tx_modem_relay_packet(s, x, ric, ricinfo);
1332 break;
1333 case V150_1_MEDIA_STATE_FAX_RELAY:
1334 res = v150_1_sse_tx_fax_relay_packet(s, x, ric, ricinfo);
1335 break;
1336 case V150_1_MEDIA_STATE_TEXT_RELAY:
1337 res = v150_1_sse_tx_text_relay_packet(s, x, ric, ricinfo);
1338 break;
1339 case V150_1_MEDIA_STATE_TEXT_PROBE:
1340 res = v150_1_sse_tx_text_probe_packet(s, x, ric, ricinfo);
1341 break;
1342 default:
1343 span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected SSE event %d\n", event);
1344 res = -1;
1345 break;
1346 }
1347 /*endswitch*/
1348 s->local_media_state = event;
1349 return res;
1350}
1351/*- End of function --------------------------------------------------------*/
1352
1353SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_sse_timer_expired(v150_1_state_t *s, span_timestamp_t now)
1354{
1355 v150_1_sse_state_t *sse;
1356
1357 sse = &s->sse;
1358 span_log(&s->logging, SPAN_LOG_FLOW, "SSE timer expired at %lu\n", now);
1359
1360 if (now < sse->latest_timer)
1361 {
1362 span_log(&s->logging, SPAN_LOG_FLOW, "SSE timer returned %luus early\n", sse->latest_timer - now);
1363 /* Request the same timeout point again. */
1364 update_sse_timer(s, sse->latest_timer);
1365 return 0;
1366 }
1367 /*endif*/
1368
1369 if (sse->immediate_timer)
1370 {
1371 sse->immediate_timer = false0;
1372 /* TODO: */
1373 }
1374 /*endif*/
1375 if (sse->ack_timer_t0 != 0 && sse->ack_timer_t0 <= now)
1376 {
1377 span_log(&s->logging, SPAN_LOG_FLOW, "SSE T0 expired\n");
1378
1379 /* V.150.1/C.4.3.2 */
1380 if (sse->ack_counter_n0 > 0 && s->local_media_state != s->remote_ack)
1381 {
1382 span_log(&s->logging, SPAN_LOG_FLOW, "SSE resend (%d)\n", sse->ack_counter_n0);
1383 /* TODO: The must respond flag is set to TRUE if the value of timer t1 is zero. */
1384 if (sse->tx_packet_handler)
1385 sse->tx_packet_handler(sse->tx_packet_user_data, true1, sse->last_tx_pkt, sse->last_tx_len);
1386 /*endif*/
1387 sse->ack_counter_n0--;
1388 sse->ack_timer_t0 = now + sse->ack_t0interval;
1389 /* T1 is not touched at this time */
1390 update_timer(s);
1391 }
1392 /*endif*/
1393 }
1394 /*endif*/
1395 if (sse->ack_timer_t1 != 0 && sse->ack_timer_t1 <= now)
1396 {
1397 span_log(&s->logging, SPAN_LOG_FLOW, "SSE T1 expired\n");
1398
1399 /* V.150.1/C.4.3.2 */
1400 if (sse->ack_counter_n0 == 0 && s->local_media_state != s->remote_ack)
1401 {
1402 span_log(&s->logging, SPAN_LOG_FLOW, "SSE resend (%d)\n", sse->ack_counter_n0);
1403 /* TODO: The must respond flag is set to TRUE */
1404 if (sse->tx_packet_handler)
1405 sse->tx_packet_handler(sse->tx_packet_user_data, true1, sse->last_tx_pkt, sse->last_tx_len);
1406 /*endif*/
1407 /* counter N0 is not touched at this time */
1408 /* T0 is not touched at this time */
1409 sse->ack_timer_t1 = now + sse->ack_t1interval;
1410 update_timer(s);
1411 }
1412 /*endif*/
1413 }
1414 /*endif*/
1415 if (sse->repetition_timer != 0 && sse->repetition_timer <= now)
1416 {
1417 /* Handle reliability by simple repetition timer */
1418 span_log(&s->logging, SPAN_LOG_FLOW, "SSE repetition timer expired\n");
1419 if (sse->repetition_counter > 1)
1420 {
1421 sse->repetition_timer += sse->repetition_interval;
1422 update_timer(s);
1423 }
1424 else
1425 {
1426 sse->repetition_timer = 0;
1427 }
1428 /*endif*/
1429 --sse->repetition_counter;
1430 if (sse->tx_packet_handler)
1431 sse->tx_packet_handler(sse->tx_packet_user_data, true1, sse->last_tx_pkt, sse->last_tx_len);
1432 /*endif*/
1433 }
1434 /*endif*/
1435 if (sse->recovery_timer_t1 != 0 && sse->recovery_timer_t1 <= now)
1436 {
1437 }
1438 /*endif*/
1439 if (sse->recovery_timer_t2 != 0 && sse->recovery_timer_t2 <= now)
1440 {
1441 }
1442 /*endif*/
1443 return 0;
1444}
1445/*- End of function --------------------------------------------------------*/
1446
1447SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_sse_reliability_method(v150_1_state_t *s,
1448 enum v150_1_sse_reliability_option_e method,
1449 int parm1,
1450 int parm2,
1451 int parm3)
1452{
1453 v150_1_sse_state_t *sse;
1454
1455 sse = &s->sse;
1456 /* Select one of the reliability methods from V.150.1 C.4 */
1457 switch (method)
1458 {
1459 case V150_1_SSE_RELIABILITY_NONE:
1460 break;
1461 case V150_1_SSE_RELIABILITY_BY_REPETITION:
1462 if (parm1 < 2 || parm1 > 10)
1463 return -1;
1464 /*endif*/
1465 if (parm2 < 10000 || parm2 > 1000000)
1466 return -1;
1467 /*endif*/
1468 /* The actual number of repeats is one less than the total number of
1469 transmissions */
1470 sse->repetition_count = parm1 - 1;
1471 sse->repetition_interval = parm2;
1472 break;
1473 case V150_1_SSE_RELIABILITY_BY_RFC2198:
1474 break;
1475 case V150_1_SSE_RELIABILITY_BY_EXPLICIT_ACK:
1476 if (parm1 < 2 || parm1 > 10)
1477 return -1;
1478 /*endif*/
1479 if (parm2 < 10000 || parm2 > 1000000)
1480 return -1;
1481 /*endif*/
1482 if (parm3 < 10000 || parm3 > 1000000)
1483 return -1;
1484 /*endif*/
1485 sse->ack_n0count = parm1;
1486 sse->ack_t0interval = parm2;
1487 sse->ack_t1interval = parm3;
1488 break;
1489 default:
1490 return -1;
1491 }
1492 /*endswitch*/
1493 sse->reliability_method = method;
1494 return 0;
1495}
1496/*- End of function --------------------------------------------------------*/
1497
1498void v150_1_sse_init(v150_1_state_t *s,
1499 v150_1_sse_tx_packet_handler_t tx_packet_handler,
1500 void *tx_packet_user_data)
1501{
1502 v150_1_sse_state_t *sse;
1503
1504 sse = &s->sse;
1505
1506 sse->reliability_method = V150_1_SSE_RELIABILITY_NONE;
1507 /* Set default values for the reliability by redundancy parameters */
1508 /* V.150.1 C.4.1 */
1509 /* The actual number of repeats is one less than the total number of
1510 transmissions */
1511 sse->repetition_count = V150_1_SSE_DEFAULT_REPETITIONS3 - 1;
1512 sse->repetition_interval = V150_1_SSE_DEFAULT_REPETITION_INTERVAL20000;
1513
1514 /* Set default values for the explicit acknowledgement parameters */
1515 /* V.150.1 C.4.3.1 */
1516 sse->ack_n0count = V150_1_SSE_DEFAULT_ACK_N03;
1517 sse->ack_t0interval = V150_1_SSE_DEFAULT_ACK_T010000;
1518 sse->ack_t1interval = V150_1_SSE_DEFAULT_ACK_T1300000;
1519
1520 sse->recovery_n = V150_1_SSE_DEFAULT_RECOVERY_N5;
1521 sse->recovery_t1 = V150_1_SSE_DEFAULT_RECOVERY_T11000000;
1522 sse->recovery_t2 = V150_1_SSE_DEFAULT_RECOVERY_T21000000;
1523
1524 /* V.150.1 C.4.3.1 */
1525 /* Let p be the probability that a packet sent by one MoIP node through the packet
1526 network will be successfully received by the other node.
1527 Let t be the latency that can be tolerated in the delivery of mode updates
1528 Let q be the reliability required in the delivery of mode updates within the given
1529 latency
1530 Let rtd be the round trip delay through the packet network between the two nodes
1531 Let owd be the one way delay through the packet network from one node to the other
1532 (i.e. rtd/2) */
1533 //sse->n0count = floor(log(1 - q)/log(1 - p));
1534 //sse->t0interval = max(0, ((rtd/2) - t)/(n0count - 1));
1535 //sse->t1interval = 1.5*rtd;
1536
1537 sse->explicit_ack_enabled = false0;
1538
1539 sse->previous_rx_timestamp = 0xFFFFFFFF;
1540
1541 sse->tx_packet_handler = tx_packet_handler;
1542 sse->tx_packet_user_data = tx_packet_user_data;
1543}
1544/*- End of function --------------------------------------------------------*/
1545/*- End of file ------------------------------------------------------------*/