File: | src/v150_1_sse.c |
Warning: | line 975, column 9 Value stored to 'f' is never read |
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 | /* |
62 | If the explicit acknowledgement procedure is being used for a call, the endpoints shall execute the |
63 | following procedures. |
64 | |
65 | When 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 | |
85 | NOTE - 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 | |
103 | Upon 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 | |
117 | V.150.1 uses the terms "media states" and "SSE events". These SSE events are just changes of the media state. |
118 | So, media states map 1:1 to SSE events. |
119 | */ |
120 | |
121 | static int v150_1_sse_tx_modem_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo); |
122 | static int v150_1_sse_tx_fax_relay_packet(v150_1_state_t *s, int x, int ric, int ricinfo); |
123 | |
124 | SPAN_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 | |
254 | SPAN_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 | |
279 | SPAN_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 | |
321 | SPAN_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 | |
355 | static 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 | |
417 | static 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 | |
470 | static 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 | |
486 | static 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 | |
503 | static 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 | |
670 | static 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 | |
825 | static 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 | |
888 | static 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 | |
926 | SPAN_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 | |
1034 | static 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 | |
1072 | static 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 | |
1119 | static 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 | |
1166 | static 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 | |
1213 | static 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 | |
1247 | static 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 | |
1281 | static 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 | |
1315 | SPAN_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 | |
1353 | SPAN_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 | |
1447 | SPAN_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 | |
1498 | void 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 ------------------------------------------------------------*/ |