Bug Summary

File:v150_1.c
Warning:line 2283, column 5
Value stored to 'l' is never read

Annotated Source Code

1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * v150_1.c - An implementation of the main part of V.150.1. SPRT is not included in
5 * this code.
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2022 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#if defined(HAVE_CONFIG_H1)
28#include "config.h"
29#endif
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <sys/types.h>
34#include <inttypes.h>
35#include <memory.h>
36#if defined(HAVE_STDBOOL_H1)
37#include <stdbool.h>
38#else
39#include <spandsp/stdbool.h>
40#endif
41
42#include "spandsp/telephony.h"
43#include "spandsp/alloc.h"
44#include "spandsp/unaligned.h"
45#include "spandsp/logging.h"
46#include "spandsp/async.h"
47#include "spandsp/sprt.h"
48#include "spandsp/v150_1.h"
49
50#include "spandsp/private/logging.h"
51#include "spandsp/private/v150_1.h"
52
53/* Terminology
54
55 V.150.1 has several components. The terms used for these are:
56
57 Signalling state events (SSE)
58 An RTP payload type which encodes indications of changes between audio, FoIP, MoIP, and ToIP modes.
59 In SDP this is referred to as v150fw.
60 Simple packet relay transport (SPRT)
61 A hybrid unreliable plus reliable packet over UDP protocol, compatible with sending RTP to and from the
62 same UDP port. You can also find the term IP-TLP associated wtih this protocol. In SDP this is referred
63 to udpsprt.
64 The actual V.150.1 modem relay protocol.
65 These are are messages which typically pass across an SPRT transport. In SDP this is referred to as v150mr.
66*/
67
68/* A Cisco box in V.150.1 mode is quite fussy about what it receives to trigger it into a V.8 exchange with an attached
69 modem.
70
71 Simply sending a bunch of /ANSam RFC3733/RFC4734 packets gets you nowhere, but this does contradict what RFC4734
72 says.
73
74 Waiting 200ms after answer, sending 450ms of ANSam, then switching to sending /ANSam until a v150fw packet
75 arrives, then sending /ANSam-end, sounds compliant, but a Cisco doesn't like that. It would never happen connected
76 to a real modem, as it takes a while to detect ANSam, and be sure the AM part if really there. A real modem
77 connected to a Cisco causes the Cisco to send something like 200ms of ANSam, before the switch to /ANSam. Trying
78 to mimic that gets you farther.
79
80 When I failed to send /ANSam-end at the end of my tone the Cisco behaved quirkily. However, when I call into the
81 Cisco, it just stops sending /ANSam, and never seems to send any /ANSam-end packets.
82
83 Cisco seems to consistently accept the following as a valid ANSamPR, resulting in a v150fw CM packet being received
84 from the Cisco:
85 ANSWER
86 Send 40ms to several seconds of silence
87 Send 11 to 20 ANSam packets at 20ms per packet
88 22 fails, and you get an v150fw AA message, instead of a CM message. This is reasonable, as the phase
89 reversal is almost late, and if you consider the sending end would need some time to detect the
90 initial tone, its really quite late.
91 21 acts really quirky, and you may get nothing back. The Cisco seems to get really messed up. No RTP or
92 SPRT comes from it until the calling hangs up.
93 Values between 1 and 10 seem quirky. 10 fails, and you get an v150fw AA message, instead of a CM message.
94 Some values between 1 and 10 often work OK, while others give an AA.
95 Send sustained /ANSam at 20ms per packet, until...
96 ..... v150fw packet received
97 Send 4 /ANSam end packets at 20ms intervals
98*/
99
100/* A Cisco box has the following parameters:
101
102modem relay latency <milliseconds>
103 Specifies the estimated one-way delay across the IP network.
104 Range is 100 to 1000. Default is 200.
105
106modem relay sse redundancy interval <milliseconds>
107 Specifies the timer value for redundant transmission of SSEs.
108 Range is 5ms to 50ms. Default is 20ms.
109
110modem relay sse redundancy packet <number>
111 Specifies the SSE packet transmission count before disconnecting.
112 Range is 1 to 5 packets. Default is 3.
113
114modem relay sse t1 <milliseconds>
115 Specifies the repeat interval, in milliseconds (ms), for initial audio SSEs used for resetting the SSE protocol state machine (clearing the call) following error recovery.
116 Range is 500ms to 3000ms. Default is 1000ms.
117
118modem relay sse retries <value>
119 Specifies the number of SSE packet retries, repeated every t1 interval, before disconnecting.
120 Range is 0 to 5. Default is 5.
121
122modem relay sprt retries <value>
123 Specifies the number of SPRT packet retries, repeated every t1 interval, before disconnecting.
124 Range is 0 to 10. Default is 10.
125
126modem relay sprt v14 receive playback hold-time <milliseconds>
127 Configures the time, in ms, to hold incoming data in the V.14 receive queue.
128 Range is 20ms to 250ms. Default is 50ms.
129
130modem relay sprt v14 transmit hold-time <milliseconds>
131 Configures the time to wait, in ms, after the first character is ready before sending
132 the SPRT packet.
133 Range is 10ms to 30ms. Default is 20ms.
134
135modem relay sprt v14 transmit maximum hold-count <characters>
136 Configures the number of V.14 characters to be received on the modem interface that will
137 trigger sending an SPRT packet.
138 Range is 8 to 128. Default is 16.
139*/
140
141/*
142
143There are two defined versions of a modem relay gateway:
144
145U-MR: A Universal Modem Relay
146
147 A UMR needs to support V.92 digital, V.90 digital, V.34, V.32bis, V.32, V.22bis, V.22, V.23 and V.21
148
149V-MR: A V.8 Modem Relay
150 A VMR doesn't have to support any specific set of modulations. Instead, V.8 is used to negotiate a
151 common one. Inter-gateway messages exchanged during call setup can be used for each end to inform the
152 other which modulations are supported.
153
154
155The SPRT related SDP needs a entry like:
156
157 a=fmtp:120 mr=1;mg=0;CDSCselect=1;jmdelay=no;versn=1.1
158
159mr=0 for V-MR
160 =1 for U-MR
161
162mg=0 for no transcompression
163 =1 for single transcompression
164 =2 for double transcompression
165
166CDSCselect=1 for audio RFC4733
167 =2 for VBD preferred
168 =3 for Mixed
169
170mrmods=1-4,10-12,14,17
171 where 1 = V.34 duplex
172 2 = V.34 half-duplex
173 3 = V.32bis/V.32
174 4 = V.22bis/V.22
175 5 = V.17
176 6 = V.29
177 7 = V.27ter
178 8 = V.26ter
179 9 = V.26bis
180 10 = V.23 duplex
181 11 = V.23 half-duplex
182 12 = V.21
183 13 = V.90 analogue
184 14 = V.90 digital
185 15 = V/91
186 16 = V.92 analogue
187 17 = V.92 digital
188
189jmdelay=no JM delay not supported
190 =yes JM delay supported
191
192versn=1.1 This is optional. The current version is 1.1
193
194txalgs=1 V.44
195 =2 MNP5
196
197v42bNumCodeWords=1024
198
199v42bMaxStringLength=32
200
201v44NumTxCodewords=1024
202
203v44NumRxCodewords=1024
204
205v44MaxTxStringLength=64
206
207v44MaxRxStringLength=64
208
209V44LenTxHistory=3072
210
211V44LenRxHistory=3072
212
213TCXpreference=1
214 =2
215
216
217
218 a=sprtparm: 140 132 132 140 32 8
219
220 These are the maximum payload sizes for the 4 channels, and the maximum window sizes for
221 the two reliable channels. A '$' may be used for unspecified values.
222
223
224 a=vndpar: <vendorIDformat> <vendorID> <vendorSpecificDataTag> <vendorSpecificData>
225
226<vendorIDformat>=1 for T.35
227 =2 for IANA private enterprise number
228
229<vendorID>
230<vendorSpecificDataTag>
231<vendorSpecificData>
232
233Voice band data (VBD) mode:
234
235<---------------------------------- Data compression ---------------------------------->
236<---------------------------------- Error correction ---------------------------------->
237<------------------------------------- Modulation ------------------------------------->
238 <-- Encapsulated G.711 -->
239
240<----------- PSTN ------------><-----Packet network ----><----------- PSTN ------------>
241
242
243The various modem relay error correction and compression scenarios:
244
245MR1
246
247<---------------------------------- Data compression ---------------------------------->
248<----- Error correction ------> <----- Error correction ------>
249<-------- Modulation ---------> <-------- Modulation --------->
250 <-- Reliable transport -->
251
252<----------- PSTN ------------><-----Packet network ----><----------- PSTN ------------>
253
254
255MR2
256
257<----- Data compression ------> <----- Data compression ------>
258<----- Error correction ------> <----- Error correction ------>
259<-------- Modulation ---------> <-------- Modulation --------->
260 <----- MR2a or MR2b ----->
261
262<----------- PSTN ------------><-----Packet network ----><----------- PSTN ------------>
263
264MR2a: Reliable transport without data compression
265MR2b: Reliable transport with data compression
266
267
268
269MR3
270
271<----- Data compression ------><------------------ Data compression ------------------->
272<------------------ Data compression -------------------><----- Data compression ------>
273<----- Error correction ------> <----- Error correction ------>
274<-------- Modulation ---------> <-------- Modulation --------->
275 <-- Reliable transport -->
276
277<----------- PSTN ------------><-----Packet network ----><----------- PSTN ------------>
278
279
280
281MR4
282
283<------------------ Data compression -------------------><----- Data compression ------>
284<----- Error correction ------> <----- Error correction ------>
285<-------- Modulation ---------> <-------- Modulation --------->
286 <-- Reliable transport -->
287
288<----------- PSTN ------------><-----Packet network ----><----------- PSTN ------------>
289
290*/
291
292#if 0
293
294ASN.1 definition, from V.150.1
295
296V150MOIP-CAPABILITY DEFINITIONS AUTOMATIC TAGS ::= BEGIN
297IMPORTS
298 NonStandardParameter FROM MULTIMEDIA-SYSTEM-CONTROL;
299V150MoIPCapability ::= SEQUENCE
300{
301 nonStandard SEQUENCE OF NonStandardParameter OPTIONAL,
302 modemRelayType CHOICE
303 {
304 v-mr NULL((void*)0),
305 u-mr NULL((void*)0),
306 ...
307 },
308 gatewayType CHOICE
309 {
310 ntcx NULL((void*)0), -- No Transcompression
311 stcx NULL((void*)0), -- Single Transcompression
312 dtcx CHOICE -- Double Transcompression
313 {
314 single NULL((void*)0), -- Preferred mode between two gateways
315 double NULL((void*)0), -- with double transcompression ability
316 ...
317 },
318 ...
319 },
320 callDiscriminationMode CHOICE
321 {
322 audio NULL((void*)0),
323 g2-choice NULL((void*)0),
324 combination NULL((void*)0),
325 ...
326 },
327 sprtParameters SEQUENCE
328 {
329 maxPayloadSizeChannel0 INTEGER(140..256) OPTIONAL, -- Default 140
330 maxPayloadSizeChannel1 INTEGER(132..256) OPTIONAL, -- Default 132
331 maxWindowSizeChannel1 INTEGER(32..96) OPTIONAL, -- Default 32
332 maxPayloadSizeChannel2 INTEGER(132..256) OPTIONAL, -- Default 132
333 maxWindowSizeChannel2 INTEGER(8..32) OPTIONAL, -- Default 8
334 maxPayloadSizeChannel3 INTEGER(140..256) OPTIONAL, -- Default 140
335 ...
336 } OPTIONAL,
337 modulationSupport SEQUENCE
338 {
339 v34FullDuplex NULL((void*)0) OPTIONAL,
340 v34HalfDuplex NULL((void*)0) OPTIONAL,
341 v32bis-v32 NULL((void*)0) OPTIONAL,
342 v22bis-v22 NULL((void*)0) OPTIONAL,
343 v17 NULL((void*)0) OPTIONAL,
344 v29HalfDuplex NULL((void*)0) OPTIONAL,
345 v27ter NULL((void*)0) OPTIONAL,
346 v26ter NULL((void*)0) OPTIONAL,
347 v26bis NULL((void*)0) OPTIONAL,
348 v23FullDuplex NULL((void*)0) OPTIONAL,
349 v23HalfDuplex NULL((void*)0) OPTIONAL,
350 v21 NULL((void*)0) OPTIONAL,
351 v90Analog NULL((void*)0) OPTIONAL,
352 v90Digital NULL((void*)0) OPTIONAL,
353 v92Analog NULL((void*)0) OPTIONAL,
354 v92Digital NULL((void*)0) OPTIONAL,
355 v91 NULL((void*)0) OPTIONAL,
356 ...
357 },
358 compressionMode SEQUENCE
359 {
360 -- Including a SEQUENCE for a particular compression mode, but not
361 -- including any of the optional parameters within the SEQUENCE,
362 -- indicates support for the specific compression mode, but assumes that
363 -- all parameter values are set to their default values
364 mnp5 NULL((void*)0) OPTIONAL,
365 v44 SEQUENCE
366 {
367 numTxCodewords INTEGER(256..65535),
368 numRxCodewords INTEGER(256..65535),
369 maxTxStringLength INTEGER(32..255),
370 maxRxStringLength INTEGER(32..255),
371 lenTxHistory INTEGER(512..65535),
372 lenRxHistory INTEGER(512..65535),
373 ...
374 } OPTIONAL,
375 v42bis SEQUENCE
376 {
377 numCodewords INTEGER(512..65535) OPTIONAL,
378 maxStringLength INTEGER(6..250) OPTIONAL,
379 ...
380 } OPTIONAL,
381 ...
382 } OPTIONAL,
383 delayedJMEnabled BOOLEAN,
384 ...
385}
386#endif
387
388/* Used to verify the message type is compatible with the transmission
389 control channel it arrived on */
390static uint8_t channel_check[25] =
391{
392 0x0F, /* V150_1_MSGID_NULL */
393 0x04, /* V150_1_MSGID_INIT */
394 0x04, /* V150_1_MSGID_XID_XCHG */
395 0x04, /* V150_1_MSGID_JM_INFO */
396 0x04, /* V150_1_MSGID_START_JM */
397 0x04, /* V150_1_MSGID_CONNECT */
398 0x0F, /* V150_1_MSGID_BREAK */
399 0x0F, /* V150_1_MSGID_BREAKACK */
400 0x04, /* V150_1_MSGID_MR_EVENT */
401 0x04, /* V150_1_MSGID_CLEARDOWN */
402 0x04, /* V150_1_MSGID_PROF_XCHG */
403 0x00, /* Reserved (11) */
404 0x00, /* Reserved (12) */
405 0x00, /* Reserved (13) */
406 0x00, /* Reserved (14) */
407 0x00, /* Reserved (15) */
408 0x0A, /* V150_1_MSGID_I_RAW_OCTET */
409 0x0A, /* V150_1_MSGID_I_RAW_BIT (optional) */
410 0x0A, /* V150_1_MSGID_I_OCTET */
411 0x0A, /* V150_1_MSGID_I_CHAR_STAT (optional) */
412 0x0A, /* V150_1_MSGID_I_CHAR_DYN (optional) */
413 0x0A, /* V150_1_MSGID_I_FRAME (optional) */
414 0x0A, /* V150_1_MSGID_I_OCTET_CS (optional) (this only makes sense for the SPRT_TCID_UNRELIABLE_SEQUENCED channel) */
415 0x0A, /* V150_1_MSGID_I_CHAR_STAT_CS (optional) (this only makes sense for the SPRT_TCID_UNRELIABLE_SEQUENCED channel) */
416 0x0A /* V150_1_MSGID_I_CHAR_DYN_CS (optional) (this only makes sense for the SPRT_TCID_UNRELIABLE_SEQUENCED channel) */
417};
418
419static struct
420{
421 uint16_t min_payload_bytes;
422 uint16_t max_payload_bytes;
423} channel_parm_limits[SPRT_CHANNELS4] =
424{
425 {
426 SPRT_MIN_TC0_PAYLOAD_BYTES140,
427 SPRT_MAX_TC0_PAYLOAD_BYTES256
428 },
429 {
430 SPRT_MIN_TC1_PAYLOAD_BYTES132,
431 SPRT_MAX_TC1_PAYLOAD_BYTES256
432 },
433 {
434 SPRT_MIN_TC2_PAYLOAD_BYTES132,
435 SPRT_MAX_TC2_PAYLOAD_BYTES256
436 },
437 {
438 SPRT_MIN_TC3_PAYLOAD_BYTES140,
439 SPRT_MAX_TC3_PAYLOAD_BYTES256
440 }
441};
442
443SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_msg_id_to_str(int msg_id)
444{
445 const char *res;
446
447 res = "unknown";
448 switch (msg_id)
449 {
450 case V150_1_MSGID_NULL:
451 res = "NULL";
452 break;
453 case V150_1_MSGID_INIT:
454 res = "INIT";
455 break;
456 case V150_1_MSGID_XID_XCHG:
457 res = "XID xchg";
458 break;
459 case V150_1_MSGID_JM_INFO:
460 res = "JM info";
461 break;
462 case V150_1_MSGID_START_JM:
463 res = "Start JM";
464 break;
465 case V150_1_MSGID_CONNECT:
466 res = "Connect";
467 break;
468 case V150_1_MSGID_BREAK:
469 res = "Break";
470 break;
471 case V150_1_MSGID_BREAKACK:
472 res = "Break ack";
473 break;
474 case V150_1_MSGID_MR_EVENT:
475 res = "MR event";
476 break;
477 case V150_1_MSGID_CLEARDOWN:
478 res = "Cleardown";
479 break;
480 case V150_1_MSGID_PROF_XCHG:
481 res = "Prof xchg";
482 break;
483 case V150_1_MSGID_I_RAW_OCTET:
484 res = "I raw octet";
485 break;
486 case V150_1_MSGID_I_RAW_BIT:
487 res = "I raw bit";
488 break;
489 case V150_1_MSGID_I_OCTET:
490 res = "I octet";
491 break;
492 case V150_1_MSGID_I_CHAR_STAT:
493 res = "I char stat";
494 break;
495 case V150_1_MSGID_I_CHAR_DYN:
496 res = "I char dyn";
497 break;
498 case V150_1_MSGID_I_FRAME:
499 res = "I frame";
500 break;
501 case V150_1_MSGID_I_OCTET_CS:
502 res = "I octet cs";
503 break;
504 case V150_1_MSGID_I_CHAR_STAT_CS:
505 res = "I char stat cs";
506 break;
507 case V150_1_MSGID_I_CHAR_DYN_CS:
508 res = "I char dyn cs";
509 break;
510 }
511 /*endswitch*/
512 return res;
513}
514/*- End of function --------------------------------------------------------*/
515
516SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_data_bits_to_str(int code)
517{
518 const char *res;
519
520 res = "unknown";
521 switch (code)
522 {
523 case V150_1_DATA_BITS_5:
524 res = "5 bits";
525 break;
526 case V150_1_DATA_BITS_6:
527 res = "6 bits";
528 break;
529 case V150_1_DATA_BITS_7:
530 res = "7 bits";
531 break;
532 case V150_1_DATA_BITS_8:
533 res = "8 bits";
534 break;
535 }
536 /*endswitch*/
537 return res;
538}
539/*- End of function --------------------------------------------------------*/
540
541SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_parity_to_str(int code)
542{
543 const char *res;
544
545 res = "unknown";
546 switch (code)
547 {
548 case V150_1_PARITY_UNKNOWN:
549 res = "unknown";
550 break;
551 case V150_1_PARITY_NONE:
552 res = "none";
553 break;
554 break;
555 case V150_1_PARITY_EVEN:
556 res = "even";
557 break;
558 case V150_1_PARITY_ODD:
559 res = "odd";
560 break;
561 case V150_1_PARITY_SPACE:
562 res = "space";
563 break;
564 case V150_1_PARITY_MARK:
565 res = "mark";
566 break;
567 }
568 /*endswitch*/
569 return res;
570}
571/*- End of function --------------------------------------------------------*/
572
573SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_stop_bits_to_str(int code)
574{
575 const char *res;
576
577 res = "unknown";
578 switch (code)
579 {
580 case V150_1_STOP_BITS_1:
581 res = "1 bit";
582 break;
583 case V150_1_STOP_BITS_2:
584 res = "2 bits";
585 break;
586 }
587 /*endswitch*/
588 return res;
589}
590/*- End of function --------------------------------------------------------*/
591
592SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_mr_event_type_to_str(int type)
593{
594 const char *res;
595
596 res = "unknown";
597 switch (type)
598 {
599 case V150_1_MR_EVENT_ID_NULL:
600 res = "NULL";
601 break;
602 case V150_1_MR_EVENT_ID_RATE_RENEGOTIATION:
603 res = "Renegotiation";
604 break;
605 case V150_1_MR_EVENT_ID_RETRAIN:
606 res = "Retrain";
607 break;
608 case V150_1_MR_EVENT_ID_PHYSUP:
609 res = "Physically up";
610 break;
611 }
612 /*endswitch*/
613 return res;
614}
615/*- End of function --------------------------------------------------------*/
616
617SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_cleardown_reason_to_str(int type)
618{
619 const char *res;
620
621 res = "unknown";
622 switch (type)
623 {
624 case V150_1_CLEARDOWN_REASON_UNKNOWN:
625 res = "Unknown";
626 break;
627 case V150_1_CLEARDOWN_REASON_PHYSICAL_LAYER_RELEASE:
628 res = "Physical layer release";
629 break;
630 case V150_1_CLEARDOWN_REASON_LINK_LAYER_DISCONNECT:
631 res = "Link layer disconnect";
632 break;
633 case V150_1_CLEARDOWN_REASON_DATA_COMPRESSION_DISCONNECT:
634 res = "Data compression disconnect";
635 break;
636 case V150_1_CLEARDOWN_REASON_ABORT:
637 res = "Abort";
638 break;
639 case V150_1_CLEARDOWN_REASON_ON_HOOK:
640 res = "On hook";
641 break;
642 case V150_1_CLEARDOWN_REASON_NETWORK_LAYER_TERMINATION:
643 res = "Network layer termination";
644 break;
645 case V150_1_CLEARDOWN_REASON_ADMINISTRATIVE:
646 res = "Administrative";
647 break;
648 }
649 /*endswitch*/
650 return res;
651}
652/*- End of function --------------------------------------------------------*/
653
654SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_symbol_rate_to_str(int code)
655{
656 const char *res;
657
658 res = "unknown";
659 switch (code)
660 {
661 case V150_1_SYMBOL_RATE_NULL:
662 res = "NULL";
663 break;
664 case V150_1_SYMBOL_RATE_600:
665 res = "600 baud";
666 break;
667 case V150_1_SYMBOL_RATE_1200:
668 res = "1200 baud";
669 break;
670 case V150_1_SYMBOL_RATE_1600:
671 res = "1600 baud";
672 break;
673 case V150_1_SYMBOL_RATE_2400:
674 res = "2400 baud";
675 break;
676 case V150_1_SYMBOL_RATE_2743:
677 res = "2743 baud";
678 break;
679 case V150_1_SYMBOL_RATE_3000:
680 res = "3000 baud";
681 break;
682 case V150_1_SYMBOL_RATE_3200:
683 res = "3200 baud";
684 break;
685 case V150_1_SYMBOL_RATE_3429:
686 res = "3429 baud";
687 break;
688 case V150_1_SYMBOL_RATE_8000:
689 res = "8000 baud";
690 break;
691 }
692 /*endswitch*/
693 return res;
694}
695/*- End of function --------------------------------------------------------*/
696
697SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_modulation_to_str(int modulation)
698{
699 const char *res;
700
701 res = "unknown";
702 switch (modulation)
703 {
704 case V150_1_SELMOD_NULL:
705 res = "NULL";
706 break;
707 case V150_1_SELMOD_V92:
708 res = "V.92";
709 break;
710 case V150_1_SELMOD_V91:
711 res = "V.91";
712 break;
713 case V150_1_SELMOD_V90:
714 res = "V90";
715 break;
716 case V150_1_SELMOD_V34:
717 res = "V.34";
718 break;
719 case V150_1_SELMOD_V32bis:
720 res = "V.32bis";
721 break;
722 case V150_1_SELMOD_V32:
723 res = "V.32";
724 break;
725 case V150_1_SELMOD_V22bis:
726 res = "V.22bis";
727 break;
728 case V150_1_SELMOD_V22:
729 res = "V.22";
730 break;
731 case V150_1_SELMOD_V17:
732 res = "V.17";
733 break;
734 case V150_1_SELMOD_V29:
735 res = "V.29";
736 break;
737 case V150_1_SELMOD_V27ter:
738 res = "V.27ter";
739 break;
740 case V150_1_SELMOD_V26ter:
741 res = "V.26ter";
742 break;
743 case V150_1_SELMOD_V26bis:
744 res = "V.26bis";
745 break;
746 case V150_1_SELMOD_V23:
747 res = "V.23";
748 break;
749 case V150_1_SELMOD_V21:
750 res = "V.21";
751 break;
752 case V150_1_SELMOD_BELL212:
753 res = "Bell 212";
754 break;
755 case V150_1_SELMOD_BELL103:
756 res = "Bell 103";
757 break;
758 }
759 /*endswitch*/
760 return res;
761}
762/*- End of function --------------------------------------------------------*/
763
764SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_compression_to_str(int compression)
765{
766 const char *res;
767
768 res = "unknown";
769 switch (compression)
770 {
771 case V150_1_COMPRESSION_NONE:
772 res = "None";
773 break;
774 case V150_1_COMPRESSION_V42BIS:
775 res = "V.42bis";
776 break;
777 case V150_1_COMPRESSION_V44:
778 res = "V.44";
779 break;
780 case V150_1_COMPRESSION_MNP5:
781 res = "MNP5";
782 break;
783 }
784 /*endswitch*/
785 return res;
786}
787/*- End of function --------------------------------------------------------*/
788
789SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_compression_direction_to_str(int direction)
790{
791 const char *res;
792
793 res = "unknown";
794 switch (direction)
795 {
796 case V150_1_COMPRESS_NEITHER_WAY:
797 res = "Neither way";
798 break;
799 case V150_1_COMPRESS_TX_ONLY:
800 res = "Tx only";
801 break;
802 case V150_1_COMPRESS_RX_ONLY:
803 res = "Rx only";
804 break;
805 case V150_1_COMPRESS_BIDIRECTIONAL:
806 res = "Bidirectional";
807 break;
808 }
809 /*endswitch*/
810 return res;
811}
812/*- End of function --------------------------------------------------------*/
813
814SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_error_correction_to_str(int correction)
815{
816 const char *res;
817
818 res = "unknown";
819 switch (correction)
820 {
821 case V150_1_ERROR_CORRECTION_NONE:
822 res = "None";
823 break;
824 case V150_1_ERROR_CORRECTION_V42_LAPM:
825 res = "V.42 LAPM";
826 break;
827 case V150_1_ERROR_CORRECTION_V42_ANNEX_A:
828 res = "V.42 annex A";
829 break;
830 }
831 /*endswitch*/
832 return res;
833}
834/*- End of function --------------------------------------------------------*/
835
836SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_break_source_to_str(int source)
837{
838 const char *res;
839
840 res = "unknown";
841 switch (source)
842 {
843 case V150_1_BREAK_SOURCE_V42_LAPM:
844 res = "V.42 LAPM";
845 break;
846 case V150_1_BREAK_SOURCE_V42_ANNEX_A:
847 res = "V.42 annex A";
848 break;
849 case V150_1_BREAK_SOURCE_V14:
850 res = "V.14";
851 break;
852 }
853 /*endswitch*/
854 return res;
855}
856/*- End of function --------------------------------------------------------*/
857
858SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_break_type_to_str(int type)
859{
860 const char *res;
861
862 res = "unknown";
863 switch (type)
864 {
865 case V150_1_BREAK_TYPE_NOT_APPLICABLE:
866 res = "Non applicable";
867 break;
868 case V150_1_BREAK_TYPE_DESTRUCTIVE_EXPEDITED:
869 res = "Destructive, expedited";
870 break;
871 case V150_1_BREAK_TYPE_NON_DESTRUCTIVE_EXPEDITED:
872 res = "Non-destructive, expedited";
873 break;
874 case V150_1_BREAK_TYPE_NON_DESTRUCTIVE_NON_EXPEDITED:
875 res = "Non-destructive, non-expedited";
876 break;
877 }
878 /*endswitch*/
879 return res;
880}
881/*- End of function --------------------------------------------------------*/
882
883SPAN_DECLARE(const char *)__attribute__((visibility("default"))) const char * v150_1_state_to_str(int state)
884{
885 const char *res;
886
887 res = "unknown";
888 switch (state)
889 {
890 case V150_1_STATE_IDLE:
891 res = "Idle";
892 break;
893 case V150_1_STATE_INITED:
894 res = "Inited";
895 break;
896 case V150_1_STATE_PHYSUP:
897 res = "Physically up";
898 break;
899 case V150_1_STATE_CONNECTED:
900 res = "Connected";
901 break;
902 }
903 /*endswitch*/
904 return res;
905}
906/*- End of function --------------------------------------------------------*/
907
908SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_bits_per_character(v150_1_state_t *s, int bits)
909{
910 if (bits < 5 || bits > 8)
911 return -1;
912 /*endif*/
913 bits -= 5;
914 s->near.data_format_code &= 0x9F;
915 s->near.data_format_code |= ((bits << 5) & 0x60);
916 return 0;
917}
918/*- End of function --------------------------------------------------------*/
919
920SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_parity(v150_1_state_t *s, int mode)
921{
922 s->near.data_format_code &= 0xE3;
923 s->near.data_format_code |= ((mode << 2) & 0x1C);
924 return 0;
925}
926/*- End of function --------------------------------------------------------*/
927
928SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_stop_bits(v150_1_state_t *s, int bits)
929{
930 if (bits < 1 || bits > 2)
931 return -1;
932 /*endif*/
933 bits -= 1;
934 s->near.data_format_code &= 0xFC;
935 s->near.data_format_code |= (bits & 0x03);
936 return 0;
937}
938/*- End of function --------------------------------------------------------*/
939
940static int status_report(v150_1_state_t *s, int reason)
941{
942 v150_1_status_t report;
943
944 report.reason = reason;
945 switch (reason)
946 {
947 case V150_1_STATUS_REASON_STATE_CHANGED:
948 report.state_change.state = s->far.connection_state;
949 report.state_change.cleardown_reason = s->far.cleardown_reason;
950 break;
951 case V150_1_STATUS_REASON_DATA_FORMAT_CHANGED:
952 report.data_format_change.bits = 5 + ((s->far.data_format_code >> 5) & 0x03);
953 report.data_format_change.parity_code = (s->far.data_format_code >> 2) & 0x07;
954 report.data_format_change.stop_bits = 1 + (s->far.data_format_code & 0x03);
955 break;
956 case V150_1_STATUS_REASON_BREAK_RECEIVED:
957 report.break_received.source = s->far.break_source;
958 report.break_received.type = s->far.break_type;
959 report.break_received.duration = s->far.break_duration*10;
960 break;
961 case V150_1_STATUS_REASON_RATE_RETRAIN_RECEIVED:
962 break;
963 case V150_1_STATUS_REASON_RATE_RENEGOTIATION_RECEIVED:
964 break;
965 case V150_1_STATUS_REASON_BUSY_CHANGED:
966 report.busy_change.local_busy = s->near.busy;
967 report.busy_change.far_busy = s->far.busy;
968 break;
969 case V150_1_STATUS_REASON_PHYSUP:
970 report.physup_parameters.selmod = s->far.selmod;
971 report.physup_parameters.tdsr = s->far.tdsr;
972 report.physup_parameters.rdsr = s->far.rdsr;
973
974 report.physup_parameters.txsen = s->far.txsen;
975 report.physup_parameters.txsr = s->far.txsr;
976 report.physup_parameters.rxsen = s->far.rxsen;
977 report.physup_parameters.rxsr = s->far.rxsr;
978 break;
979 case V150_1_STATUS_REASON_CONNECTED:
980 report.connect_parameters.selmod = s->far.selmod;
981 report.connect_parameters.tdsr = s->far.tdsr;
982 report.connect_parameters.rdsr = s->far.rdsr;
983
984 report.connect_parameters.selected_compression_direction = s->far.selected_compression_direction;
985 report.connect_parameters.selected_compression = s->far.selected_compression;
986 report.connect_parameters.selected_error_correction = s->far.selected_error_correction;
987
988 report.connect_parameters.compression_tx_dictionary_size = s->far.compression_tx_dictionary_size;
989 report.connect_parameters.compression_rx_dictionary_size = s->far.compression_rx_dictionary_size;
990 report.connect_parameters.compression_tx_string_length = s->far.compression_tx_string_length;
991 report.connect_parameters.compression_rx_string_length = s->far.compression_rx_string_length;
992 report.connect_parameters.compression_tx_history_size = s->far.compression_tx_history_size;
993 report.connect_parameters.compression_rx_history_size = s->far.compression_rx_history_size;
994
995 /* I_RAW-OCTET is always available. There is no selection flag for it. */
996 report.connect_parameters.i_raw_octet_available = true1;
997 report.connect_parameters.i_raw_bit_available = s->far.i_raw_bit_available;
998 report.connect_parameters.i_frame_available = s->far.i_frame_available;
999 /* I_OCTET is an oddity, as you need to know in advance whether there will be a DLCI field
1000 present. So, functionally its really like 2 different types of message. */
1001 report.connect_parameters.i_octet_with_dlci_available = s->far.i_octet_with_dlci_available;
1002 report.connect_parameters.i_octet_without_dlci_available = s->far.i_octet_without_dlci_available;
1003 report.connect_parameters.i_char_stat_available = s->far.i_char_stat_available;
1004 report.connect_parameters.i_char_dyn_available = s->far.i_char_dyn_available;
1005 /* Unlike I_OCTET, I_OCTET-CS is only defined without a DLCI field. */
1006 report.connect_parameters.i_octet_cs_available = s->far.i_octet_cs_available;
1007 report.connect_parameters.i_char_stat_cs_available = s->far.i_char_stat_cs_available;
1008 report.connect_parameters.i_char_dyn_cs_available = s->far.i_char_dyn_cs_available;
1009 break;
1010 }
1011 /*endswitch*/
1012 if (s->rx_status_report_handler)
1013 s->rx_status_report_handler(s->rx_status_report_user_data, &report);
1014 /*endif*/
1015 return 0;
1016}
1017/*- End of function --------------------------------------------------------*/
1018
1019SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_null(v150_1_state_t *s)
1020{
1021 int res;
1022 uint8_t pkt[256];
1023
1024 res = -1;
1025 /* This isn't a real message. Its marked as reserved by the ITU-T in V.150.1 */
1026 pkt[0] = V150_1_MSGID_NULL;
1027 if (s->tx_packet_handler)
1028 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 1);
1029 /*endif*/
1030 return res;
1031}
1032/*- End of function --------------------------------------------------------*/
1033
1034SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_init(v150_1_state_t *s)
1035{
1036 int res;
1037 uint8_t i;
1038 uint8_t pkt[256];
1039
1040 res = -1;
1041 pkt[0] = V150_1_MSGID_INIT;
1042 /* At this stage we just tell the far end the things we support. */
1043 i = 0;
1044 if (s->near.necrxch_option)
1045 i |= 0x80;
1046 /*endif*/
1047 if (s->near.ecrxch_option)
1048 i |= 0x40;
1049 /*endif*/
1050 if (s->near.xid_profile_exchange_supported)
1051 i |= 0x20;
1052 /*endif*/
1053 if (s->near.asymmetric_data_types_supported)
1054 i |= 0x10;
1055 /*endif*/
1056 if (s->near.i_raw_bit_supported)
1057 i |= 0x08;
1058 /*endif*/
1059 if (s->near.i_frame_supported)
1060 i |= 0x04;
1061 /*endif*/
1062 if (s->near.i_char_stat_supported)
1063 i |= 0x02;
1064 /*endif*/
1065 if (s->near.i_char_dyn_supported)
1066 i |= 0x01;
1067 /*endif*/
1068 pkt[1] = i;
1069 i = 0;
1070 if (s->near.i_octet_cs_supported)
1071 i |= 0x80;
1072 /*endif*/
1073 if (s->near.i_char_stat_cs_supported)
1074 i |= 0x40;
1075 /*endif*/
1076 if (s->near.i_char_dyn_cs_supported)
1077 i |= 0x20;
1078 /*endif*/
1079 pkt[2] = i;
1080 if (s->tx_packet_handler)
1081 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 3);
1082 /*endif*/
1083 if (res >= 0)
1084 {
1085 s->near.connection_state = V150_1_STATE_INITED;
1086 if (s->far.connection_state >= V150_1_STATE_INITED)
1087 s->joint_connection_state = V150_1_STATE_INITED;
1088 /*endif*/
1089 }
1090 /*endif*/
1091 return res;
1092}
1093/*- End of function --------------------------------------------------------*/
1094
1095SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_xid_xchg(v150_1_state_t *s)
1096{
1097 int res;
1098 uint8_t i;
1099 uint8_t pkt[256];
1100
1101 res = -1;
1102 if (!s->far.xid_profile_exchange_supported)
1103 return -1;
1104 /*endif*/
1105 pkt[0] = V150_1_MSGID_XID_XCHG;
1106 pkt[1] = s->near.ecp;
1107 i = 0;
1108 if (s->near.v42bis_supported)
1109 i |= 0x80;
1110 /*endif*/
1111 if (s->near.v44_supported)
1112 i |= 0x40;
1113 /*endif*/
1114 if (s->near.mnp5_supported)
1115 i |= 0x20;
1116 /*endif*/
1117 pkt[2] = i;
1118 if (s->near.v42bis_supported)
1119 {
1120 pkt[3] = s->near.v42bis_p0;
1121 put_net_unaligned_uint16(&pkt[4], s->near.v42bis_p1);
1122 pkt[6] = s->near.v42bis_p2;
1123 }
1124 else
1125 {
1126 memset(&pkt[3], 0, 4);
1127 }
1128 /*endif*/
1129 if (s->near.v44_supported)
1130 {
1131 pkt[7] = s->near.v44_c0;
1132 pkt[8] = s->near.v44_p0;
1133 put_net_unaligned_uint16(&pkt[9], s->near.v44_p1t);
1134 put_net_unaligned_uint16(&pkt[11], s->near.v44_p1r);
1135 pkt[13] = s->near.v44_p2t;
1136 pkt[14] = s->near.v44_p2r;
1137 put_net_unaligned_uint16(&pkt[15], s->near.v44_p3t);
1138 put_net_unaligned_uint16(&pkt[17], s->near.v44_p3r);
1139 }
1140 else
1141 {
1142 memset(&pkt[7], 0, 12);
1143 }
1144 /*endif*/
1145 if (s->tx_packet_handler)
1146 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 19);
1147 /*endif*/
1148 return res;
1149}
1150/*- End of function --------------------------------------------------------*/
1151
1152SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_jm_info(v150_1_state_t *s)
1153{
1154 int res;
1155 int i;
1156 int len;
1157 uint8_t pkt[256];
1158
1159 res = -1;
1160 pkt[0] = V150_1_MSGID_JM_INFO;
1161 len = 1;
1162 for (i = 0; i < 16; i++)
1163 {
1164 if (s->near.jm_category_id_seen[i])
1165 {
1166 put_net_unaligned_uint16(&pkt[len], (i << 12) | (s->near.jm_category_info[i] & 0x0FFF));
1167 len += 2;
1168 }
1169 /*endif*/
1170 }
1171 if (s->tx_packet_handler)
1172 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, len);
1173 /*endif*/
1174 return res;
1175}
1176/*- End of function --------------------------------------------------------*/
1177
1178SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_start_jm(v150_1_state_t *s)
1179{
1180 int res;
1181 uint8_t pkt[256];
1182
1183 res = -1;
1184 pkt[0] = V150_1_MSGID_START_JM;
1185 if (s->tx_packet_handler)
1186 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 1);
1187 /*endif*/
1188 return res;
1189}
1190/*- End of function --------------------------------------------------------*/
1191
1192SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_connect(v150_1_state_t *s)
1193{
1194 int res;
1195 int available_data_types;
1196 int len;
1197 uint8_t pkt[256];
1198
1199 res = -1;
1200 pkt[0] = V150_1_MSGID_CONNECT;
1201 pkt[1] = (s->near.selmod << 2) | s->near.selected_compression_direction;
1202 pkt[2] = (s->near.selected_compression << 4) | s->near.selected_error_correction;
1203 put_net_unaligned_uint16(&pkt[3], s->near.tdsr);
1204 put_net_unaligned_uint16(&pkt[5], s->near.rdsr);
1205
1206 available_data_types = 0;
1207 if (s->near.i_octet_with_dlci_available)
1208 available_data_types |= 0x8000;
1209 /*endif*/
1210 if (s->near.i_octet_without_dlci_available)
1211 available_data_types |= 0x4000;
1212 /*endif*/
1213 if (s->near.i_raw_bit_available)
1214 available_data_types |= 0x2000;
1215 /*endif*/
1216 if (s->near.i_frame_available)
1217 available_data_types |= 0x1000;
1218 /*endif*/
1219 if (s->near.i_char_stat_available)
1220 available_data_types |= 0x0800;
1221 /*endif*/
1222 if (s->near.i_char_dyn_available)
1223 available_data_types |= 0x0400;
1224 /*endif*/
1225 if (s->near.i_octet_cs_available)
1226 available_data_types |= 0x0200;
1227 /*endif*/
1228 if (s->near.i_char_stat_cs_available)
1229 available_data_types |= 0x0100;
1230 /*endif*/
1231 if (s->near.i_char_dyn_cs_available)
1232 available_data_types |= 0x0080;
1233 /*endif*/
1234 put_net_unaligned_uint16(&pkt[7], available_data_types);
1235 len = 9;
1236 if (s->near.selected_compression == V150_1_COMPRESSION_V42BIS || s->near.selected_compression == V150_1_COMPRESSION_V44)
1237 {
1238 /* This is only included if V.42bis or V.44 is selected. For no compression, or MNP5 this is omitted */
1239 put_net_unaligned_uint16(&pkt[9], s->near.compression_tx_dictionary_size);
1240 put_net_unaligned_uint16(&pkt[11], s->near.compression_rx_dictionary_size);
1241 pkt[13] = s->near.compression_tx_string_length;
1242 pkt[14] = s->near.compression_rx_string_length;
1243 len += 6;
1244 }
1245 /*endif*/
1246 if (s->near.selected_compression == V150_1_COMPRESSION_V44)
1247 {
1248 /* This is only included if V.44 is selected. For no compression, MNP5, or V.42bis this is omitted */
1249 put_net_unaligned_uint16(&pkt[15], s->near.compression_tx_history_size);
1250 put_net_unaligned_uint16(&pkt[15], s->near.compression_rx_history_size);
1251 len += 4;
1252 }
1253 /*endif*/
1254 if (s->tx_packet_handler)
1255 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, len);
1256 /*endif*/
1257 if (res >= 0)
1258 {
1259 s->near.connection_state = V150_1_STATE_CONNECTED;
1260 if (s->near.connection_state >= V150_1_STATE_CONNECTED)
1261 s->joint_connection_state = V150_1_STATE_CONNECTED;
1262 /*endif*/
1263 }
1264 /*endif*/
1265 return res;
1266}
1267/*- End of function --------------------------------------------------------*/
1268
1269SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_break(v150_1_state_t *s, int source, int type, int duration)
1270{
1271 int res;
1272 uint8_t pkt[256];
1273
1274 res = -1;
1275 pkt[0] = V150_1_MSGID_BREAK;
1276 pkt[1] = (source << 4) | type;
1277 pkt[2] = duration/10;
1278 if (s->tx_packet_handler)
1279 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 3);
1280 /*endif*/
1281 return res;
1282}
1283/*- End of function --------------------------------------------------------*/
1284
1285SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_break_ack(v150_1_state_t *s)
1286{
1287 int res;
1288 uint8_t pkt[256];
1289
1290 res = -1;
1291 pkt[0] = V150_1_MSGID_BREAKACK;
1292 if (s->tx_packet_handler)
1293 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 1);
1294 /*endif*/
1295 return res;
1296}
1297/*- End of function --------------------------------------------------------*/
1298
1299SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_mr_event(v150_1_state_t *s, int event_id)
1300{
1301 int res;
1302 int len;
1303 uint8_t i;
1304 uint8_t pkt[256];
1305
1306 res = -1;
1307 pkt[0] = V150_1_MSGID_MR_EVENT;
1308 pkt[1] = event_id;
1309 switch (event_id)
1310 {
1311 case V150_1_MR_EVENT_ID_RETRAIN:
1312 pkt[2] = V150_1_MR_EVENT_REASON_NULL;
1313 len = 3;
1314 s->near.connection_state = V150_1_STATE_RETRAIN;
1315 s->joint_connection_state = V150_1_STATE_RETRAIN;
1316 break;
1317 case V150_1_MR_EVENT_ID_RATE_RENEGOTIATION:
1318 pkt[2] = V150_1_MR_EVENT_REASON_NULL;
1319 len = 3;
1320 s->near.connection_state = V150_1_STATE_RATE_RENEGOTIATION;
1321 s->joint_connection_state = V150_1_STATE_RATE_RENEGOTIATION;
1322 break;
1323 case V150_1_MR_EVENT_ID_PHYSUP:
1324 pkt[2] = 0;
1325 i = (s->near.selmod << 2);
1326 if (s->near.txsen)
1327 i |= 0x02;
1328 /*endif*/
1329 if (s->near.rxsen)
1330 i |= 0x01;
1331 /*endif*/
1332 pkt[3] = i;
1333 put_net_unaligned_uint16(&pkt[4], s->near.tdsr);
1334 put_net_unaligned_uint16(&pkt[4], s->near.rdsr);
1335 pkt[8] = (s->near.txsen) ? s->near.txsr : V150_1_SYMBOL_RATE_NULL;
1336 pkt[9] = (s->near.rxsen) ? s->near.rxsr : V150_1_SYMBOL_RATE_NULL;
1337 len = 10;
1338 s->near.connection_state = V150_1_STATE_PHYSUP;
1339 if (s->far.connection_state >= V150_1_STATE_PHYSUP)
1340 s->joint_connection_state = V150_1_STATE_PHYSUP;
1341 /*endif*/
1342 break;
1343 case V150_1_MR_EVENT_ID_NULL:
1344 default:
1345 pkt[2] = 0;
1346 len = 3;
1347 break;
1348 }
1349 /*endswitch*/
1350 if (s->tx_packet_handler)
1351 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, len);
1352 /*endif*/
1353 return res;
1354}
1355/*- End of function --------------------------------------------------------*/
1356
1357SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_cleardown(v150_1_state_t *s, int reason)
1358{
1359 int res;
1360 uint8_t pkt[256];
1361
1362 res = -1;
1363
1364 pkt[0] = V150_1_MSGID_CLEARDOWN;
1365 pkt[1] = reason;
1366 pkt[2] = 0; /* Vendor tag */
1367 pkt[3] = 0; /* Vendor info */
1368 if (s->tx_packet_handler)
1369 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 4);
1370 /*endif*/
1371 if (res >= 0)
1372 s->near.connection_state = V150_1_STATE_IDLE;
1373 /*endif*/
1374 return res;
1375}
1376/*- End of function --------------------------------------------------------*/
1377
1378SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_prof_xchg(v150_1_state_t *s)
1379{
1380 int res;
1381 uint8_t i;
1382 uint8_t pkt[256];
1383
1384 res = -1;
1385 pkt[0] = V150_1_MSGID_PROF_XCHG;
1386 i = 0;
1387 if (s->near.v42_lapm_supported)
1388 i |= 0x40;
1389 /*endif*/
1390 if (s->near.v42_annex_a_supported)
1391 i |= 0x10;
1392 /*endif*/
1393 if (s->near.v44_supported)
1394 i |= 0x04;
1395 /*endif*/
1396 if (s->near.v42bis_supported)
1397 i |= 0x01;
1398 /*endif*/
1399 pkt[1] = i;
1400 i = 0;
1401 if (s->near.mnp5_supported)
1402 i |= 0x40;
1403 /*endif*/
1404 pkt[2] = i;
1405 if (s->near.v42bis_supported)
1406 {
1407 pkt[3] = s->near.v42bis_p0;
1408 put_net_unaligned_uint16(&pkt[4], s->near.v42bis_p1);
1409 pkt[6] = s->near.v42bis_p2;
1410 }
1411 else
1412 {
1413 memset(&pkt[3], 0, 4);
1414 }
1415 /*endif*/
1416 if (s->near.v44_supported)
1417 {
1418 pkt[7] = s->near.v44_c0;
1419 pkt[8] = s->near.v44_p0;
1420 put_net_unaligned_uint16(&pkt[9], s->near.v44_p1t);
1421 put_net_unaligned_uint16(&pkt[11], s->near.v44_p1r);
1422 pkt[13] = s->near.v44_p2t;
1423 pkt[14] = s->near.v44_p2r;
1424 put_net_unaligned_uint16(&pkt[15], s->near.v44_p3t);
1425 put_net_unaligned_uint16(&pkt[17], s->near.v44_p3r);
1426 }
1427 else
1428 {
1429 memset(&pkt[7], 0, 12);
1430 }
1431 /*endif*/
1432 if (s->tx_packet_handler)
1433 res = s->tx_packet_handler(s->tx_packet_user_data, SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED, pkt, 19);
1434 /*endif*/
1435 return res;
1436}
1437/*- End of function --------------------------------------------------------*/
1438
1439static int v150_1_build_i_raw_octet(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1440{
1441 if (len > max_len - 3)
1442 return -1;
1443 /*endif*/
1444 pkt[0] = V150_1_MSGID_I_RAW_OCTET;
1445 pkt[1] = 0x80 | 0x02; /* L */
1446 pkt[2] = 0x02; /* N */
1447 memcpy(&pkt[3], buf, len);
1448 len += 3;
1449 return len;
1450}
1451/*- End of function --------------------------------------------------------*/
1452
1453static int v150_1_build_i_raw_bit(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1454{
1455 if (!s->far.i_raw_bit_available)
1456 return -1;
1457 /*endif*/
1458 if (len > max_len - 3)
1459 return -1;
1460 /*endif*/
1461 pkt[0] = V150_1_MSGID_I_RAW_BIT;
1462 pkt[1] = 0x80 | 0x02; /* L */
1463 pkt[2] = 0x02; /* N */
1464 memcpy(&pkt[3], buf, len);
1465 len += 3;
1466 return len;
1467}
1468/*- End of function --------------------------------------------------------*/
1469
1470static int v150_1_build_i_octet(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1471{
1472 int header;
1473
1474 if (!s->far.i_octet_without_dlci_available && !s->far.i_octet_with_dlci_available)
1475 return -1;
1476 /*endif*/
1477 if (len > max_len - 3)
1478 return -1;
1479 /*endif*/
1480 pkt[0] = V150_1_MSGID_I_OCTET;
1481 if (s->far.i_octet_with_dlci_available)
1482 {
1483 /* The DLCI may be one or two octets long. */
1484 if ((s->near.dlci & 0x01) == 0)
1485 {
1486 pkt[1] = s->near.dlci & 0xFF;
1487 header = 2;
1488 }
1489 else
1490 {
1491 put_net_unaligned_uint16(&pkt[1], s->near.dlci);
1492 header = 3;
1493 }
1494 /*endif*/
1495 }
1496 else
1497 {
1498 header = 1;
1499 }
1500 /*endif*/
1501 memcpy(&pkt[header], buf, len);
1502 len += header;
1503 return len;
1504}
1505/*- End of function --------------------------------------------------------*/
1506
1507static int v150_1_build_i_char_stat(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1508{
1509 if (!s->far.i_char_stat_available)
1510 return -1;
1511 /*endif*/
1512 if (len > max_len - 2)
1513 return -1;
1514 /*endif*/
1515 pkt[0] = V150_1_MSGID_I_CHAR_STAT;
1516 pkt[1] = s->near.data_format_code;
1517 memcpy(&pkt[2], buf, len);
1518 len += 2;
1519 return len;
1520}
1521/*- End of function --------------------------------------------------------*/
1522
1523static int v150_1_build_i_char_dyn(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1524{
1525 if (!s->far.i_char_dyn_available)
1526 return -1;
1527 /*endif*/
1528 if (len > max_len - 2)
1529 return -1;
1530 /*endif*/
1531 pkt[0] = V150_1_MSGID_I_CHAR_DYN;
1532 pkt[1] = s->near.data_format_code;
1533 memcpy(&pkt[2], buf, len);
1534 len += 2;
1535 return len;
1536}
1537/*- End of function --------------------------------------------------------*/
1538
1539static int v150_1_build_i_frame(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1540{
1541 int data_frame_state;
1542
1543 data_frame_state = 0;
1544
1545 if (!s->far.i_frame_available)
1546 return -1;
1547 /*endif*/
1548 if (len > max_len - 2)
1549 return -1;
1550 /*endif*/
1551 pkt[0] = V150_1_MSGID_I_FRAME;
1552 pkt[1] = data_frame_state & 0x03;
1553 memcpy(&pkt[2], buf, len);
1554 len += 2;
1555 return len;
1556}
1557/*- End of function --------------------------------------------------------*/
1558
1559static int v150_1_build_i_octet_cs(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1560{
1561 if (!s->far.i_octet_cs_available)
1562 return -1;
1563 /*endif*/
1564 if (len > max_len - 3)
1565 return -1;
1566 /*endif*/
1567 pkt[0] = V150_1_MSGID_I_OCTET_CS;
1568 put_net_unaligned_uint16(&pkt[1], s->near.octet_cs_next_seq_no & 0xFFFF);
1569 memcpy(&pkt[3], buf, len);
1570 s->near.octet_cs_next_seq_no += len;
1571 len += 3;
1572 return len;
1573}
1574/*- End of function --------------------------------------------------------*/
1575
1576static int v150_1_build_i_char_stat_cs(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1577{
1578 if (!s->far.i_char_stat_cs_available)
1579 return -1;
1580 /*endif*/
1581 if (len > max_len - 4)
1582 return -1;
1583 /*endif*/
1584 pkt[0] = V150_1_MSGID_I_CHAR_STAT_CS;
1585 pkt[1] = s->near.data_format_code;
1586 put_net_unaligned_uint16(&pkt[2], s->near.octet_cs_next_seq_no & 0xFFFF);
1587 memcpy(&pkt[4], buf, len);
1588 len += 4;
1589 s->near.octet_cs_next_seq_no += len;
1590 return len;
1591}
1592/*- End of function --------------------------------------------------------*/
1593
1594static int v150_1_build_i_char_dyn_cs(v150_1_state_t *s, uint8_t pkt[], int max_len, const uint8_t buf[], int len)
1595{
1596 if (!s->far.i_char_dyn_cs_available)
1597 return -1;
1598 /*endif*/
1599 if (len > max_len - 4)
1600 return -1;
1601 /*endif*/
1602 pkt[0] = V150_1_MSGID_I_CHAR_DYN_CS;
1603 pkt[1] = s->near.data_format_code;
1604 put_net_unaligned_uint16(&pkt[2], s->near.octet_cs_next_seq_no & 0xFFFF);
1605 memcpy(&pkt[4], buf, len);
1606 s->near.octet_cs_next_seq_no += len;
1607 len += 4;
1608 return len;
1609}
1610/*- End of function --------------------------------------------------------*/
1611
1612SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_tx_info_stream(v150_1_state_t *s, const uint8_t buf[], int len)
1613{
1614 uint8_t pkt[256];
1615 int max_len;
1616 int res;
1617
1618 max_len = s->near.max_payload_bytes[s->near.info_stream_channel];
1619 switch (s->near.info_stream_msg_id)
1620 {
1621 case V150_1_MSGID_I_RAW_OCTET:
1622 res = v150_1_build_i_raw_octet(s, pkt, max_len, buf, len);
1623 break;
1624 case V150_1_MSGID_I_RAW_BIT:
1625 res = v150_1_build_i_raw_bit(s, pkt, max_len, buf, len);
1626 break;
1627 case V150_1_MSGID_I_OCTET:
1628 res = v150_1_build_i_octet(s, pkt, max_len, buf, len);
1629 break;
1630 case V150_1_MSGID_I_CHAR_STAT:
1631 res = v150_1_build_i_char_stat(s, pkt, max_len, buf, len);
1632 break;
1633 case V150_1_MSGID_I_CHAR_DYN:
1634 res = v150_1_build_i_char_dyn(s, pkt, max_len, buf, len);
1635 break;
1636 case V150_1_MSGID_I_FRAME:
1637 res = v150_1_build_i_frame(s, pkt, max_len, buf, len);
1638 break;
1639 case V150_1_MSGID_I_OCTET_CS:
1640 res = v150_1_build_i_octet_cs(s, pkt, max_len, buf, len);
1641 break;
1642 case V150_1_MSGID_I_CHAR_STAT_CS:
1643 res = v150_1_build_i_char_stat_cs(s, pkt, max_len, buf, len);
1644 break;
1645 case V150_1_MSGID_I_CHAR_DYN_CS:
1646 res = v150_1_build_i_char_dyn_cs(s, pkt, max_len, buf, len);
1647 break;
1648 }
1649 /*endswitch*/
1650 if (res >= 0)
1651 {
1652 if (s->tx_packet_handler)
1653 res = s->tx_packet_handler(s->tx_packet_user_data, s->near.info_stream_channel, pkt, res);
1654 /*endif*/
1655 }
1656 else
1657 {
1658 span_log(&s->logging, SPAN_LOG_FLOW, "Bad message\n");
1659 }
1660 /*endif*/
1661 return res;
1662}
1663/*- End of function --------------------------------------------------------*/
1664
1665static int select_info_msg_type(v150_1_state_t *s)
1666{
1667 int i;
1668
1669 /* Select the first available information message type we find in the preferences list */
1670 for (i = 0; i < 10 && s->near.info_msg_preferences[i] >= 0; i++)
1671 {
1672 switch (s->near.info_msg_preferences[i])
1673 {
1674 case V150_1_MSGID_I_RAW_OCTET:
1675 /* This is always supported */
1676 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1677 return 0;
1678 case V150_1_MSGID_I_RAW_BIT:
1679 if (s->near.i_raw_bit_available)
1680 {
1681 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1682 return 0;
1683 }
1684 /*endif*/
1685 break;
1686 case V150_1_MSGID_I_OCTET:
1687 /* This is always supported */
1688 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1689 return 0;
1690 case V150_1_MSGID_I_CHAR_STAT:
1691 if (s->near.i_char_stat_available)
1692 {
1693 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1694 return 0;
1695 }
1696 /*endif*/
1697 break;
1698 case V150_1_MSGID_I_CHAR_DYN:
1699 if (s->near.i_char_dyn_available)
1700 {
1701 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1702 return 0;
1703 }
1704 /*endif*/
1705 break;
1706 case V150_1_MSGID_I_FRAME:
1707 if (s->near.i_frame_available)
1708 {
1709 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1710 return 0;
1711 }
1712 /*endif*/
1713 break;
1714 case V150_1_MSGID_I_OCTET_CS:
1715 if (s->near.i_octet_cs_available)
1716 {
1717 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1718 return 0;
1719 }
1720 /*endif*/
1721 break;
1722 case V150_1_MSGID_I_CHAR_STAT_CS:
1723 if (s->near.i_char_stat_cs_available)
1724 {
1725 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1726 return 0;
1727 }
1728 /*endif*/
1729 break;
1730 case V150_1_MSGID_I_CHAR_DYN_CS:
1731 if (s->near.i_char_dyn_cs_available)
1732 {
1733 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1734 return 0;
1735 }
1736 /*endif*/
1737 break;
1738 default:
1739 s->near.info_stream_msg_id = -1;
1740 return -1;
1741 }
1742 /*endswitch*/
1743 }
1744 /*endfor*/
1745 s->near.info_stream_msg_id = -1;
1746 return -1;
1747}
1748/*- End of function --------------------------------------------------------*/
1749
1750static int v150_1_process_null(v150_1_state_t *s, const uint8_t buf[], int len)
1751{
1752 if (len != 1)
1753 return -1;
1754 return 0;
1755}
1756/*- End of function --------------------------------------------------------*/
1757
1758static int v150_1_process_init(v150_1_state_t *s, const uint8_t buf[], int len)
1759{
1760 if (len != 3)
1761 {
1762 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid INIT message length %d\n", len);
1763 return -1;
1764 }
1765 /*endif*/
1766 /* Just capture what the far end says about its capabilities */
1767 s->far.necrxch_option = (buf[1] & 0x80) != 0;
1768 s->far.ecrxch_option = (buf[1] & 0x40) != 0;
1769 s->far.xid_profile_exchange_supported = (buf[1] & 0x20) != 0;
1770 s->far.asymmetric_data_types_supported = (buf[1] & 0x10) != 0;
1771 s->far.i_raw_bit_supported = (buf[1] & 0x08) != 0;
1772 s->far.i_frame_supported = (buf[1] & 0x04) != 0;
1773 s->far.i_char_stat_supported = (buf[1] & 0x02) != 0;
1774 s->far.i_char_dyn_supported = (buf[1] & 0x01) != 0;
1775 s->far.i_octet_cs_supported = (buf[2] & 0x80) != 0;
1776 s->far.i_char_stat_cs_supported = (buf[2] & 0x40) != 0;
1777 s->far.i_char_dyn_cs_supported = (buf[2] & 0x20) != 0;
1778
1779 /* Now sift out what will be available, because both ends support the features */
1780 s->near.i_raw_bit_available = s->near.i_raw_bit_supported && s->far.i_raw_bit_supported;
1781 s->near.i_frame_available = s->near.i_frame_supported && s->far.i_frame_supported;
1782 s->near.i_octet_with_dlci_available = s->near.dlci_supported;
1783 s->near.i_octet_without_dlci_available = !s->near.dlci_supported;
1784 s->near.i_char_stat_available = s->near.i_char_stat_supported && s->far.i_char_stat_supported;
1785 s->near.i_char_dyn_available = s->near.i_char_dyn_supported && s->far.i_char_dyn_supported;
1786 s->near.i_octet_cs_available = s->near.i_octet_cs_supported && s->far.i_octet_cs_supported;
1787 s->near.i_char_stat_cs_available = s->near.i_char_stat_cs_supported && s->far.i_char_stat_cs_supported;
1788 s->near.i_char_dyn_cs_available = s->near.i_char_dyn_cs_supported && s->far.i_char_dyn_cs_supported;
1789
1790 span_log(&s->logging, SPAN_LOG_FLOW, " Preferred non-error controlled Rx channel: %s\n", (s->far.necrxch_option) ? "RSC" : "USC");
1791 span_log(&s->logging, SPAN_LOG_FLOW, " Preferred error controlled Rx channel: %s\n", (s->far.necrxch_option) ? "USC" : "RSC");
1792 span_log(&s->logging, SPAN_LOG_FLOW, " XID profile exchange %ssupported\n", (s->far.xid_profile_exchange_supported) ? "" : "not ");
1793 span_log(&s->logging, SPAN_LOG_FLOW, " Asymmetric data types %ssupported\n", (s->far.asymmetric_data_types_supported) ? "" : "not ");
1794 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-CHAR supported\n");
1795 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-BIT %ssupported\n", (s->far.i_raw_bit_supported) ? "" : "not ");
1796 span_log(&s->logging, SPAN_LOG_FLOW, " I_FRAME %ssupported\n", (s->far.i_frame_supported) ? "" : "not ");
1797 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET %s supported\n", (s->near.dlci_supported) ? "(DLCI) " : "(no DLCI)");
1798 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT %ssupported\n", (s->far.i_char_stat_supported) ? "" : "not ");
1799 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN %ssupported\n", (s->far.i_char_dyn_supported) ? "" : "not ");
1800 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET-CS %ssupported\n", (s->far.i_octet_cs_supported) ? "" : "not ");
1801 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT-CS %ssupported\n", (s->far.i_char_stat_cs_supported) ? "" : "not ");
1802 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN-CS %ssupported\n", (s->far.i_char_dyn_cs_supported) ? "" : "not ");
1803 select_info_msg_type(s);
1804
1805 s->far.connection_state = V150_1_STATE_INITED;
1806 if (s->near.connection_state >= V150_1_STATE_INITED)
1807 s->joint_connection_state = V150_1_STATE_INITED;
1808 /*endif*/
1809 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
1810 return 0;
1811}
1812/*- End of function --------------------------------------------------------*/
1813
1814static int v150_1_process_xid_xchg(v150_1_state_t *s, const uint8_t buf[], int len)
1815{
1816 if (s->joint_connection_state < V150_1_STATE_INITED)
1817 {
1818 span_log(&s->logging, SPAN_LOG_WARNING, "XID_XCHG received before INIT. Ignored.\n");
1819 return -1;
1820 }
1821 /*endif*/
1822 if (len != 19)
1823 {
1824 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid XID_XCHG message length %d\n", len);
1825 return -1;
1826 }
1827 /*endif*/
1828 s->far.ecp = buf[1];
1829
1830 s->far.v42bis_supported = (buf[2] & 0x80) != 0;
1831 s->far.v44_supported = (buf[2] & 0x40) != 0;
1832 s->far.mnp5_supported = (buf[2] & 0x20) != 0;
1833
1834 s->far.v42bis_p0 = buf[3];
1835 s->far.v42bis_p1 = get_net_unaligned_uint16(&buf[4]);
1836 s->far.v42bis_p2 = buf[6];
1837 s->far.v44_c0 = buf[7];
1838 s->far.v44_p0 = buf[8];
1839 s->far.v44_p1t = get_net_unaligned_uint16(&buf[9]);
1840 s->far.v44_p1r = get_net_unaligned_uint16(&buf[11]);
1841 s->far.v44_p2t = buf[13];
1842 s->far.v44_p2r = buf[14];
1843 s->far.v44_p3t = get_net_unaligned_uint16(&buf[15]);
1844 s->far.v44_p3r = get_net_unaligned_uint16(&buf[17]);
1845
1846 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis %ssupported\n", (s->far.v42bis_supported) ? "" : "not ");
1847 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 %ssupported\n", (s->far.v44_supported) ? "" : "not ");
1848 span_log(&s->logging, SPAN_LOG_FLOW, " MNP5 %ssupported\n", (s->far.mnp5_supported) ? "" : "not ");
1849 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P0 %d\n", s->far.v42bis_p0);
1850 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P1 %d\n", s->far.v42bis_p1);
1851 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P2 %d\n", s->far.v42bis_p2);
1852 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 C0 %d\n", s->far.v44_c0);
1853 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1 %d\n", s->far.v44_p0);
1854 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1T %d\n", s->far.v44_p1t);
1855 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1R %d\n", s->far.v44_p1r);
1856 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2T %d\n", s->far.v44_p2t);
1857 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2R %d\n", s->far.v44_p2r);
1858 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3T %d\n", s->far.v44_p3t);
1859 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3R %d\n", s->far.v44_p3r);
1860
1861 /* TODO: */
1862 return 0;
1863}
1864/*- End of function --------------------------------------------------------*/
1865
1866static int v150_1_process_jm_info(v150_1_state_t *s, const uint8_t buf[], int len)
1867{
1868 int i;
1869 int id;
1870
1871 if (s->joint_connection_state < V150_1_STATE_INITED)
1872 {
1873 span_log(&s->logging, SPAN_LOG_WARNING, "JM_INFO received before INIT. Ignored.\n");
1874 return -1;
1875 }
1876 /*endif*/
1877 /* The length must be even */
1878 if ((len & 1) != 1)
1879 {
1880 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid JM_INFO message length %d\n", len);
1881 return -1;
1882 }
1883 /*endif*/
1884 for (i = 1; i < len; i += 2)
1885 {
1886 id = (buf[i] >> 4) & 0x0F;
1887 s->far.jm_category_id_seen[id] = true1;
1888 s->far.jm_category_info[id] = get_net_unaligned_uint16(&buf[i]) & 0x0FFF;
1889 }
1890 /*endfor*/
1891 for (i = 1; i < 16; i++)
1892 {
1893 if (s->far.jm_category_id_seen[i])
1894 {
1895 span_log(&s->logging, SPAN_LOG_WARNING, " JM %d 0x%x\n", i, s->far.jm_category_info[id]);
1896 }
1897 /*endif*/
1898 }
1899 /*endfor*/
1900
1901 /* TODO: */
1902 return 0;
1903}
1904/*- End of function --------------------------------------------------------*/
1905
1906static int v150_1_process_start_jm(v150_1_state_t *s, const uint8_t buf[], int len)
1907{
1908 if (s->joint_connection_state < V150_1_STATE_INITED)
1909 {
1910 span_log(&s->logging, SPAN_LOG_WARNING, "START_JM received before INIT. Ignored.\n");
1911 return -1;
1912 }
1913 /*endif*/
1914 if (len > 1)
1915 {
1916 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid START_JM message length %d\n", len);
1917 return -1;
1918 }
1919 /*endif*/
1920
1921 /* TODO: */
1922 return 0;
1923}
1924/*- End of function --------------------------------------------------------*/
1925
1926static int v150_1_process_connect(v150_1_state_t *s, const uint8_t buf[], int len)
1927{
1928 int available_data_types;
1929
1930 if (s->joint_connection_state < V150_1_STATE_INITED)
1931 {
1932 span_log(&s->logging, SPAN_LOG_WARNING, "CONNECT received before INIT. Ignored.\n");
1933 return -1;
1934 }
1935 /*endif*/
1936 if (len < 9 || len > 19)
1937 {
1938 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid CONNECT message length %d\n", len);
1939 return -1;
1940 }
1941 /*endif*/
1942 s->far.selmod = (buf[1] >> 2) & 0x3F;
1943 s->far.selected_compression_direction = buf[1] & 0x03;
1944 s->far.selected_compression = (buf[2] >> 4) & 0x0F;
1945 s->far.selected_error_correction = buf[2] & 0x0F;
1946 s->far.tdsr = get_net_unaligned_uint16(&buf[3]);
1947 s->far.rdsr = get_net_unaligned_uint16(&buf[5]);
1948
1949 available_data_types = get_net_unaligned_uint16(&buf[7]);
1950 s->far.i_octet_with_dlci_available = (available_data_types & 0x8000) != 0;
1951 s->far.i_octet_without_dlci_available = (available_data_types & 0x4000) != 0;
1952 s->far.i_raw_bit_available = (available_data_types & 0x2000) != 0;
1953 s->far.i_frame_available = (available_data_types & 0x1000) != 0;
1954 s->far.i_char_stat_available = (available_data_types & 0x0800) != 0;
1955 s->far.i_char_dyn_available = (available_data_types & 0x0400) != 0;
1956 s->far.i_octet_cs_available = (available_data_types & 0x0200) != 0;
1957 s->far.i_char_stat_cs_available = (available_data_types & 0x0100) != 0;
1958 s->far.i_char_dyn_cs_available = (available_data_types & 0x0080) != 0;
1959
1960 span_log(&s->logging, SPAN_LOG_FLOW, " Modulation %s\n", v150_1_modulation_to_str(s->far.selmod));
1961 span_log(&s->logging, SPAN_LOG_FLOW, " Compression direction %s\n", v150_1_compression_direction_to_str(s->far.selected_compression_direction));
1962 span_log(&s->logging, SPAN_LOG_FLOW, " Compression %s\n", v150_1_compression_to_str(s->far.selected_compression));
1963 span_log(&s->logging, SPAN_LOG_FLOW, " Error correction %s\n", v150_1_error_correction_to_str(s->far.selected_error_correction));
1964 span_log(&s->logging, SPAN_LOG_FLOW, " Tx data rate %d\n", s->far.tdsr);
1965 span_log(&s->logging, SPAN_LOG_FLOW, " Rx data rate %d\n", s->far.rdsr);
1966
1967 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-CHAR available\n");
1968 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-BIT %savailable\n", (s->far.i_raw_bit_available) ? "" : "not ");
1969 span_log(&s->logging, SPAN_LOG_FLOW, " I_FRAME %savailable\n", (s->far.i_frame_available) ? "" : "not ");
1970 if (s->far.i_octet_without_dlci_available || s->far.i_octet_without_dlci_available)
1971 {
1972 if (s->far.i_octet_without_dlci_available)
1973 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET (no DLCI) available\n");
1974 /*endif*/
1975 if (s->far.i_octet_with_dlci_available)
1976 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET (DLCI) available\n");
1977 /*endif*/
1978 }
1979 else
1980 {
1981 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET not available\n");
1982 }
1983 /*endif*/
1984 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT %savailable\n", (s->far.i_char_stat_available) ? "" : "not ");
1985 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN %savailable\n", (s->far.i_char_dyn_available) ? "" : "not ");
1986 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET-CS %savailable\n", (s->far.i_octet_cs_available) ? "" : "not ");
1987 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT-CS %savailable\n", (s->far.i_char_stat_cs_available) ? "" : "not ");
1988 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN-CS %savailable\n", (s->far.i_char_dyn_cs_available) ? "" : "not ");
1989
1990 if (len >= 15
1991 &&
1992 (s->far.selected_compression == V150_1_COMPRESSION_V42BIS || s->far.selected_compression == V150_1_COMPRESSION_V44))
1993 {
1994 /* Selected_compression should be V150_1_COMPRESSION_V42BIS or V150_1_COMPRESSION_V44 */
1995 s->far.compression_tx_dictionary_size = get_net_unaligned_uint16(&buf[9]);
1996 s->far.compression_rx_dictionary_size = get_net_unaligned_uint16(&buf[11]);
1997 s->far.compression_tx_string_length = buf[13];
1998 s->far.compression_rx_string_length = buf[14];
1999
2000 span_log(&s->logging, SPAN_LOG_FLOW, " Tx dictionary size %d\n", s->far.compression_tx_dictionary_size);
2001 span_log(&s->logging, SPAN_LOG_FLOW, " Rx dictionary size %d\n", s->far.compression_rx_dictionary_size);
2002 span_log(&s->logging, SPAN_LOG_FLOW, " Tx string length %d\n", s->far.compression_tx_string_length);
2003 span_log(&s->logging, SPAN_LOG_FLOW, " Rx string length %d\n", s->far.compression_rx_string_length);
2004 }
2005 else
2006 {
2007 s->far.compression_tx_dictionary_size = 0;
2008 s->far.compression_rx_dictionary_size = 0;
2009 s->far.compression_tx_string_length = 0;
2010 s->far.compression_rx_string_length = 0;
2011 }
2012 /*endif*/
2013
2014 if (len >= 19
2015 &&
2016 s->far.selected_compression == V150_1_COMPRESSION_V44)
2017 {
2018 /* Selected_compression should be V150_1_COMPRESSION_V44 */
2019 s->far.compression_tx_history_size = get_net_unaligned_uint16(&buf[15]);
2020 s->far.compression_rx_history_size = get_net_unaligned_uint16(&buf[17]);
2021
2022 span_log(&s->logging, SPAN_LOG_FLOW, " Tx history size %d\n", s->far.compression_tx_history_size);
2023 span_log(&s->logging, SPAN_LOG_FLOW, " Rx history size %d\n", s->far.compression_rx_history_size);
2024 }
2025 else
2026 {
2027 s->far.compression_tx_history_size = 0;
2028 s->far.compression_rx_history_size = 0;
2029 }
2030 /*endif*/
2031
2032 s->far.connection_state = V150_1_STATE_CONNECTED;
2033 if (s->near.connection_state >= V150_1_STATE_CONNECTED)
2034 s->joint_connection_state = V150_1_STATE_CONNECTED;
2035 /*endif*/
2036 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2037 return 0;
2038}
2039/*- End of function --------------------------------------------------------*/
2040
2041static int v150_1_process_break(v150_1_state_t *s, const uint8_t buf[], int len)
2042{
2043 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2044 {
2045 span_log(&s->logging, SPAN_LOG_WARNING, "BREAK received before CONNECT. Ignored.\n");
2046 return -1;
2047 }
2048 /*endif*/
2049 if (len != 3)
2050 {
2051 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid BREAK message length %d\n", len);
2052 return -1;
2053 }
2054 /*endif*/
2055
2056 s->far.break_source = (buf[1] >> 4) & 0x0F;
2057 s->far.break_type = buf[1] & 0x0F;
2058 s->far.break_duration = buf[2];
2059 span_log(&s->logging, SPAN_LOG_FLOW, "Break source %s\n", v150_1_break_source_to_str(s->far.break_source));
2060 span_log(&s->logging, SPAN_LOG_FLOW, "Break type %s\n", v150_1_break_type_to_str(s->far.break_type));
2061 span_log(&s->logging, SPAN_LOG_FLOW, "Break len %d ms\n", s->far.break_duration*10);
2062 status_report(s, V150_1_STATUS_REASON_BREAK_RECEIVED);
2063 return 0;
2064}
2065/*- End of function --------------------------------------------------------*/
2066
2067static int v150_1_process_break_ack(v150_1_state_t *s, const uint8_t buf[], int len)
2068{
2069 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2070 {
2071 span_log(&s->logging, SPAN_LOG_WARNING, "BREAKACK received before CONNECT. Ignored.\n");
2072 return -1;
2073 }
2074 /*endif*/
2075 if (len != 1)
2076 {
2077 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid BREAKACK message length %d\n", len);
2078 return -1;
2079 }
2080 /*endif*/
2081
2082 return 0;
2083}
2084/*- End of function --------------------------------------------------------*/
2085
2086static int v150_1_process_mr_event(v150_1_state_t *s, const uint8_t buf[], int len)
2087{
2088 int event;
2089 int reason;
2090
2091 if (s->joint_connection_state < V150_1_STATE_INITED)
2092 {
2093 span_log(&s->logging, SPAN_LOG_WARNING, "MR-EVENT received before INIT. Ignored.\n");
2094 return -1;
2095 }
2096 /*endif*/
2097 if (len < 3)
2098 {
2099 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2100 return -1;
2101 }
2102 /*endif*/
2103
2104 event = buf[1];
2105 span_log(&s->logging, SPAN_LOG_FLOW, "MR_EVENT type %s (%d) received\n", v150_1_mr_event_type_to_str(event), event);
2106 switch (event)
2107 {
2108 case V150_1_MR_EVENT_ID_NULL:
2109 if (len != 3)
2110 {
2111 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2112 return -1;
2113 }
2114 /*endif*/
2115 break;
2116 case V150_1_MR_EVENT_ID_RATE_RENEGOTIATION:
2117 case V150_1_MR_EVENT_ID_RETRAIN:
2118 if (len != 3)
2119 {
2120 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2121 return -1;
2122 }
2123 /*endif*/
2124 reason = buf[2];
2125 span_log(&s->logging, SPAN_LOG_FLOW, " Reason %d\n", reason);
2126 if (event == V150_1_MR_EVENT_ID_RETRAIN)
2127 {
2128 s->far.connection_state = V150_1_STATE_RETRAIN;
2129 s->joint_connection_state = V150_1_STATE_RETRAIN;
2130 status_report(s, V150_1_STATUS_REASON_RATE_RETRAIN_RECEIVED);
2131 }
2132 else
2133 {
2134 s->far.connection_state = V150_1_STATE_RATE_RENEGOTIATION;
2135 s->joint_connection_state = V150_1_STATE_RATE_RENEGOTIATION;
2136 status_report(s, V150_1_STATUS_REASON_RATE_RENEGOTIATION_RECEIVED);
2137 }
2138 /*endif*/
2139 break;
2140 case V150_1_MR_EVENT_ID_PHYSUP:
2141 if (len != 10)
2142 {
2143 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2144 return -1;
2145 }
2146 /*endif*/
2147 s->far.selmod = (buf[3] >> 2) & 0x3F;
2148 s->far.txsen = (buf[3] & 0x02) != 0;
2149 s->far.rxsen = (buf[3] & 0x01) != 0;
2150 s->far.tdsr = get_net_unaligned_uint16(&buf[4]);
2151 s->far.rdsr = get_net_unaligned_uint16(&buf[6]);
2152 s->far.txsr = buf[8];
2153 s->far.rxsr = buf[9];
2154
2155 span_log(&s->logging, SPAN_LOG_FLOW, " Selected modulation %s\n", v150_1_modulation_to_str(s->far.selmod));
2156 span_log(&s->logging, SPAN_LOG_FLOW, " Tx data signalling rate %d\n", s->far.tdsr);
2157 span_log(&s->logging, SPAN_LOG_FLOW, " Rx data signalling rate %d\n", s->far.rdsr);
2158 if (s->far.txsen)
2159 span_log(&s->logging, SPAN_LOG_FLOW, " Tx symbol rate %s\n", v150_1_symbol_rate_to_str(s->far.txsr));
2160 /*endif*/
2161 if (s->far.rxsen)
2162 span_log(&s->logging, SPAN_LOG_FLOW, " Rx symbol rate %s\n", v150_1_symbol_rate_to_str(s->far.rxsr));
2163 /*endif*/
2164
2165 /* TODO: report these parameters */
2166
2167 s->far.connection_state = V150_1_STATE_PHYSUP;
2168 if (s->near.connection_state >= V150_1_STATE_PHYSUP)
2169 s->joint_connection_state = V150_1_STATE_PHYSUP;
2170 /*endif*/
2171 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2172 break;
2173 default:
2174 span_log(&s->logging, SPAN_LOG_WARNING, "Unknown MR_EVENT type %d received\n", event);
2175 break;
2176 }
2177 /*endif*/
2178 return 0;
2179}
2180/*- End of function --------------------------------------------------------*/
2181
2182static int v150_1_process_cleardown(v150_1_state_t *s, const uint8_t buf[], int len)
2183{
2184 if (s->joint_connection_state < V150_1_STATE_INITED)
2185 {
2186 span_log(&s->logging, SPAN_LOG_WARNING, "CLEARDOWN received before INIT. Ignored.\n");
2187 return -1;
2188 }
2189 /*endif*/
2190 if (len != 4)
2191 {
2192 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid CLEARDOWN message length %d\n", len);
2193 return -1;
2194 }
2195 /*endif*/
2196
2197 s->far.cleardown_reason = buf[1];
2198 span_log(&s->logging, SPAN_LOG_FLOW, " Reason %s\n", v150_1_cleardown_reason_to_str(s->far.cleardown_reason));
2199 // vendor = buf[2];
2200 // vendor_info = buf[3];
2201 /* A cleardown moves everything back to square one. */
2202 s->far.connection_state = V150_1_STATE_IDLE;
2203 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2204 return 0;
2205}
2206/*- End of function --------------------------------------------------------*/
2207
2208static int v150_1_process_prof_xchg(v150_1_state_t *s, const uint8_t buf[], int len)
2209{
2210 if (s->joint_connection_state < V150_1_STATE_INITED)
2211 {
2212 span_log(&s->logging, SPAN_LOG_WARNING, "PROF_XCHG received before INIT. Ignored.\n");
2213 return -1;
2214 }
2215 /*endif*/
2216 if (len != 19)
2217 {
2218 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid PROF_XCHG message length %d\n", len);
2219 return -1;
2220 }
2221 /*endif*/
2222
2223 /* The following have 3 way options - no, yes and unknown */
2224 s->far.v42_lapm_supported = (buf[1] & 0xC0) == 0x40;
2225 s->far.v42_annex_a_supported = (buf[1] & 0x30) == 0x10;
2226 s->far.v44_supported = (buf[1] & 0x0C) == 0x04;
2227 s->far.v42bis_supported = (buf[1] & 0x03) == 0x01;
2228 s->far.mnp5_supported = (buf[2] & 0xC0) == 0x40;
2229
2230 s->far.v42bis_p0 = buf[3];
2231 s->far.v42bis_p1 = get_net_unaligned_uint16(&buf[4]);
2232 s->far.v42bis_p2 = buf[6];
2233 s->far.v44_c0 = buf[7];
2234 s->far.v44_p0 = buf[8];
2235 s->far.v44_p1t = get_net_unaligned_uint16(&buf[9]);
2236 s->far.v44_p1r = get_net_unaligned_uint16(&buf[11]);
2237 s->far.v44_p2t = buf[13];
2238 s->far.v44_p2r = buf[14];
2239 s->far.v44_p3t = get_net_unaligned_uint16(&buf[15]);
2240 s->far.v44_p3r = get_net_unaligned_uint16(&buf[17]);
2241
2242 span_log(&s->logging, SPAN_LOG_FLOW, " V.42 LAPM %ssupported\n", (s->far.v42_lapm_supported) ? "" : "not ");
2243 span_log(&s->logging, SPAN_LOG_FLOW, " V.42 Annex A %ssupported\n", (s->far.v42_annex_a_supported) ? "" : "not ");
2244 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 %ssupported\n", (s->far.v44_supported) ? "" : "not ");
2245 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis %ssupported\n", (s->far.v42bis_supported) ? "" : "not ");
2246 span_log(&s->logging, SPAN_LOG_FLOW, " MNP5 %ssupported\n", (s->far.mnp5_supported) ? "" : "not ");
2247
2248 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P0 %d\n", s->far.v42bis_p0);
2249 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P1 %d\n", s->far.v42bis_p1);
2250 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P2 %d\n", s->far.v42bis_p2);
2251 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 C0 %d\n", s->far.v44_c0);
2252 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1 %d\n", s->far.v44_p0);
2253 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1T %d\n", s->far.v44_p1t);
2254 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1R %d\n", s->far.v44_p1r);
2255 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2T %d\n", s->far.v44_p2t);
2256 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2R %d\n", s->far.v44_p2r);
2257 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3T %d\n", s->far.v44_p3t);
2258 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3R %d\n", s->far.v44_p3r);
2259
2260 /* TODO: */
2261 return 0;
2262}
2263/*- End of function --------------------------------------------------------*/
2264
2265static int v150_1_process_i_raw_octet(v150_1_state_t *s, const uint8_t buf[], int len)
2266{
2267 int l;
2268 int n;
2269 int header;
2270
2271 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2272 {
2273 span_log(&s->logging, SPAN_LOG_WARNING, "I_RAW-OCTET received before CONNECT. Ignored.\n");
2274 return -1;
2275 }
2276 /*endif*/
2277 if (len < 2)
2278 {
2279 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-OCTET message length %d\n", len);
2280 return -1;
2281 }
2282 /*endif*/
2283 l = buf[1] & 0x7F;
Value stored to 'l' is never read
2284 if ((buf[1] & 0x80) != 0)
2285 {
2286 n = 0;
2287 header = 1;
2288 }
2289 else
2290 {
2291 n = buf[1];
2292 header = 2;
2293 }
2294 /*endif*/
2295 if (s->rx_octet_handler)
2296 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2297 /*endif*/
2298 return 0;
2299}
2300/*- End of function --------------------------------------------------------*/
2301
2302static int v150_1_process_i_raw_bit(v150_1_state_t *s, const uint8_t buf[], int len)
2303{
2304 int l;
2305 int p;
2306 int n;
2307 int header;
2308
2309 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2310 {
2311 span_log(&s->logging, SPAN_LOG_WARNING, "I_RAW-BIT received before CONNECT. Ignored.\n");
2312 return -1;
2313 }
2314 /*endif*/
2315 if (len < 2)
2316 {
2317 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-BIT message length %d\n", len);
2318 return -1;
2319 }
2320 /*endif*/
2321 if ((buf[1] & 0x80) == 0)
2322 {
2323 if ((buf[1] & 0x40) == 0)
2324 {
2325 l = buf[1] & 0x3F;
2326 p = 0;
2327 }
2328 else
2329 {
2330 l = (buf[1] >> 3) & 0x07;
2331 p = buf[1] & 0x07;
2332 }
2333 /*endif*/
2334 n = 0;
2335 header = 1;
2336 }
2337 else
2338 {
2339 l = (buf[1] >> 3) & 0x0F;
2340 p = buf[1] & 0x07;
2341 n = buf[2];
2342 header = 2;
2343 }
2344 /*endif*/
2345 if (s->rx_octet_handler)
2346 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2347 /*endif*/
2348 return 0;
2349}
2350/*- End of function --------------------------------------------------------*/
2351
2352static int v150_1_process_i_octet(v150_1_state_t *s, const uint8_t buf[], int len)
2353{
2354 int header;
2355
2356 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2357 {
2358 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET received before CONNECT. Ignored.\n");
2359 return -1;
2360 }
2361 /*endif*/
2362 if (len < 2)
2363 {
2364 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_OCTET message length %d\n", len);
2365 return -1;
2366 }
2367 /*endif*/
2368 if (s->far.i_octet_with_dlci_available)
2369 {
2370 /* DLCI is one or two bytes (usually just 1). The low bit of each byte is an extension
2371 bit, allowing for a variable number of bytes. */
2372 if (len < 2)
2373 {
2374 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET with DLCI has no DLCI field\n");
2375 }
2376 else
2377 {
2378 if ((buf[1] & 0x01) == 0)
2379 {
2380 if ((buf[2] & 0x01) == 0)
2381 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET with DLCI has bad DLCI field\n");
2382 /*endif*/
2383 header = 3;
2384 s->far.dlci = get_net_unaligned_uint16(&buf[1]);
2385 }
2386 else
2387 {
2388 header = 2;
2389 s->far.dlci = buf[1];
2390 }
2391 /*endif*/
2392 }
2393 /*endif*/
2394 }
2395 else
2396 {
2397 header = 1;
2398 }
2399 /*endif*/
2400 if (len > header)
2401 {
2402 if (s->rx_octet_handler)
2403 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2404 /*endif*/
2405 }
2406 /*endif*/
2407 return 0;
2408}
2409/*- End of function --------------------------------------------------------*/
2410
2411static int v150_1_process_i_char_stat(v150_1_state_t *s, const uint8_t buf[], int len)
2412{
2413 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2414 {
2415 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-STAT received before CONNECT. Ignored.\n");
2416 return -1;
2417 }
2418 /*endif*/
2419 if (len < 2)
2420 {
2421 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-STAT message length %d\n", len);
2422 return -1;
2423 }
2424 /*endif*/
2425 if (s->far.data_format_code != buf[1])
2426 {
2427 /* Every packet in a session should have the same data format code */
2428 s->far.data_format_code = buf[1];
2429 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2430 }
2431 /*endif*/
2432 if (len > 2)
2433 {
2434 if (s->rx_octet_handler)
2435 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2436 /*endif*/
2437 }
2438 /*endif*/
2439 return 0;
2440}
2441/*- End of function --------------------------------------------------------*/
2442
2443static int v150_1_process_i_char_dyn(v150_1_state_t *s, const uint8_t buf[], int len)
2444{
2445 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2446 {
2447 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-DYN received before CONNECT. Ignored.\n");
2448 return -1;
2449 }
2450 /*endif*/
2451 if (len < 2)
2452 {
2453 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-DYN message length %d\n", len);
2454 return -1;
2455 }
2456 /*endif*/
2457 if (s->far.data_format_code != buf[1])
2458 {
2459 s->far.data_format_code = buf[1];
2460 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2461 }
2462 /*endif*/
2463 if (len > 2)
2464 {
2465 if (s->rx_octet_handler)
2466 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2467 /*endif*/
2468 }
2469 /*endif*/
2470 return 0;
2471}
2472/*- End of function --------------------------------------------------------*/
2473
2474static int v150_1_process_i_frame(v150_1_state_t *s, const uint8_t buf[], int len)
2475{
2476 int res;
2477 int data_frame_state;
2478
2479 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2480 {
2481 span_log(&s->logging, SPAN_LOG_WARNING, "I_FRAME received before CONNECT. Ignored.\n");
2482 return -1;
2483 }
2484 /*endif*/
2485 if (len < 2)
2486 {
2487 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_FRAME message length %d\n", len);
2488 return -1;
2489 }
2490 /*endif*/
2491 res = (buf[1] >> 2) & 0x3F;
2492 if (res)
2493 span_log(&s->logging, SPAN_LOG_WARNING, "I_FRAME with non-zero 'res' field\n");
2494 /*endif*/
2495 data_frame_state = buf[1] & 0x03;
2496 if (len > 2)
2497 {
2498 if (s->rx_octet_handler)
2499 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2500 /*endif*/
2501 }
2502 /*endif*/
2503 return 0;
2504}
2505/*- End of function --------------------------------------------------------*/
2506
2507static int v150_1_process_i_octet_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2508{
2509 int fill;
2510 int character_seq_no;
2511
2512 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2513 {
2514 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET-CS received before CONNECT. Ignored.\n");
2515 return -1;
2516 }
2517 /*endif*/
2518 if (len < 3)
2519 {
2520 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_OCTET-CS message length %d\n", len);
2521 return -1;
2522 }
2523 /*endif*/
2524 character_seq_no = get_net_unaligned_uint16(&buf[1]);
2525 /* Check for a gap in the data */
2526 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2527 if (s->rx_octet_handler)
2528 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[3], len - 3, fill);
2529 /*endif*/
2530 s->far.octet_cs_next_seq_no = (character_seq_no + len - 3) & 0xFFFF;
2531 return 0;
2532}
2533/*- End of function --------------------------------------------------------*/
2534
2535static int v150_1_process_i_char_stat_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2536{
2537 int fill;
2538 int character_seq_no;
2539
2540 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2541 {
2542 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-STAT-CS received before CONNECT. Ignored.\n");
2543 return -1;
2544 }
2545 /*endif*/
2546 if (len < 4)
2547 {
2548 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-STAT-CS message length %d\n", len);
2549 return -1;
2550 }
2551 /*endif*/
2552 if (s->far.data_format_code != buf[1])
2553 {
2554 /* Every packet in a session should have the same data format code */
2555 s->far.data_format_code = buf[1];
2556 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2557 }
2558 /*endif*/
2559 character_seq_no = get_net_unaligned_uint16(&buf[2]);
2560 /* Check for a gap in the data */
2561 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2562 if (s->rx_octet_handler)
2563 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[4], len - 4, fill);
2564 /*endif*/
2565 s->far.octet_cs_next_seq_no = (character_seq_no + len - 4) & 0xFFFF;
2566 return 0;
2567}
2568/*- End of function --------------------------------------------------------*/
2569
2570static int v150_1_process_i_char_dyn_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2571{
2572 int fill;
2573 int character_seq_no;
2574
2575 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2576 {
2577 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-DYN-CS received before CONNECT. Ignored.\n");
2578 return -1;
2579 }
2580 /*endif*/
2581 if (len < 4)
2582 {
2583 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-DYN-CS message length %d\n", len);
2584 return -1;
2585 }
2586 /*endif*/
2587 if (s->far.data_format_code != buf[1])
2588 {
2589 s->far.data_format_code = buf[1];
2590 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2591 }
2592 /*endif*/
2593 character_seq_no = get_net_unaligned_uint16(&buf[2]);
2594 /* Check for a gap in the data */
2595 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2596 if (s->rx_octet_handler)
2597 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[4], len - 4, fill);
2598 /*endif*/
2599 s->far.octet_cs_next_seq_no = (character_seq_no + len - 4) & 0xFFFF;
2600 return 0;
2601}
2602/*- End of function --------------------------------------------------------*/
2603
2604SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_process_rx_msg(v150_1_state_t *s, int chan, int seq_no, const uint8_t buf[], int len)
2605{
2606 int res;
2607 int msg_id;
2608
2609 if (chan < SPRT_TCID_MIN || chan > SPRT_TCID_MAX)
2610 {
2611 span_log(&s->logging, SPAN_LOG_ERROR, "Packet arrived on invalid channel %d\n", chan);
2612 return -1;
2613 }
2614 /*endif*/
2615 if ((buf[0] & 0x80))
2616 {
2617 span_log(&s->logging, SPAN_LOG_FLOW, "Don't know how to handle this\n");
2618 return -1;
2619 }
2620 msg_id = buf[0] & 0x7F;
2621 span_log(&s->logging, SPAN_LOG_FLOW, "Message %s received\n", v150_1_msg_id_to_str(msg_id));
2622
2623 if (msg_id < sizeof(channel_check))
2624 {
2625 if ((channel_check[msg_id] & (1 << chan)) == 0)
2626 {
2627 span_log(&s->logging, SPAN_LOG_FLOW, "Bad channel for message ID %d\n", msg_id);
2628 return -1;
2629 }
2630 /*endif*/
2631 }
2632 /*endif*/
2633
2634 switch (msg_id)
2635 {
2636 case V150_1_MSGID_NULL:
2637 res = v150_1_process_null(s, buf, len);
2638 break;
2639 case V150_1_MSGID_INIT:
2640 res = v150_1_process_init(s, buf, len);
2641 break;
2642 case V150_1_MSGID_XID_XCHG:
2643 res = v150_1_process_xid_xchg(s, buf, len);
2644 break;
2645 case V150_1_MSGID_JM_INFO:
2646 res = v150_1_process_jm_info(s, buf, len);
2647 break;
2648 case V150_1_MSGID_START_JM:
2649 res = v150_1_process_start_jm(s, buf, len);
2650 break;
2651 case V150_1_MSGID_CONNECT:
2652 res = v150_1_process_connect(s, buf, len);
2653 break;
2654 case V150_1_MSGID_BREAK:
2655 res = v150_1_process_break(s, buf, len);
2656 break;
2657 case V150_1_MSGID_BREAKACK:
2658 res = v150_1_process_break_ack(s, buf, len);
2659 break;
2660 case V150_1_MSGID_MR_EVENT:
2661 res = v150_1_process_mr_event(s, buf, len);
2662 break;
2663 case V150_1_MSGID_CLEARDOWN:
2664 res = v150_1_process_cleardown(s, buf, len);
2665 break;
2666 case V150_1_MSGID_PROF_XCHG:
2667 res = v150_1_process_prof_xchg(s, buf, len);
2668 break;
2669 case V150_1_MSGID_I_RAW_OCTET:
2670 res = v150_1_process_i_raw_octet(s, buf, len);
2671 break;
2672 case V150_1_MSGID_I_RAW_BIT:
2673 res = v150_1_process_i_raw_bit(s, buf, len);
2674 break;
2675 case V150_1_MSGID_I_OCTET:
2676 res = v150_1_process_i_octet(s, buf, len);
2677 break;
2678 case V150_1_MSGID_I_CHAR_STAT:
2679 res = v150_1_process_i_char_stat(s, buf, len);
2680 break;
2681 case V150_1_MSGID_I_CHAR_DYN:
2682 res = v150_1_process_i_char_dyn(s, buf, len);
2683 break;
2684 case V150_1_MSGID_I_FRAME:
2685 res = v150_1_process_i_frame(s, buf, len);
2686 break;
2687 case V150_1_MSGID_I_OCTET_CS:
2688 res = v150_1_process_i_octet_cs(s, buf, len);
2689 break;
2690 case V150_1_MSGID_I_CHAR_STAT_CS:
2691 res = v150_1_process_i_char_stat_cs(s, buf, len);
2692 break;
2693 case V150_1_MSGID_I_CHAR_DYN_CS:
2694 res = v150_1_process_i_char_dyn_cs(s, buf, len);
2695 break;
2696 default:
2697 span_log(&s->logging, SPAN_LOG_FLOW, "Bad msg ID %d\n", msg_id);
2698 res = -1;
2699 break;
2700 }
2701 /*endswitch*/
2702 if (res < 0)
2703 span_log(&s->logging, SPAN_LOG_FLOW, "Bad message\n");
2704 /*endif*/
2705 return res;
2706}
2707/*- End of function --------------------------------------------------------*/
2708
2709SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_local_busy(v150_1_state_t *s, bool_Bool busy)
2710{
2711 bool_Bool previous_busy;
2712
2713 previous_busy = s->near.busy;
2714 s->near.busy = busy;
2715 return previous_busy;
2716}
2717/*- End of function --------------------------------------------------------*/
2718
2719SPAN_DECLARE(bool)__attribute__((visibility("default"))) _Bool v150_1_get_far_busy_status(v150_1_state_t *s)
2720{
2721 return s->far.busy;
2722}
2723/*- End of function --------------------------------------------------------*/
2724
2725SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_local_tc_payload_bytes(v150_1_state_t *s, int channel, int max_len)
2726{
2727 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2728 return -1;
2729 /*endif*/
2730 if (max_len < channel_parm_limits[channel].min_payload_bytes
2731 ||
2732 max_len > channel_parm_limits[channel].max_payload_bytes)
2733 {
2734 return -1;
2735 }
2736 /*endif*/
2737 s->near.max_payload_bytes[channel] = max_len;
2738 return 0;
2739}
2740/*- End of function --------------------------------------------------------*/
2741
2742SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_get_local_tc_payload_bytes(v150_1_state_t *s, int channel)
2743{
2744 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2745 return -1;
2746 /*endif*/
2747 return s->near.max_payload_bytes[channel];
2748}
2749/*- End of function --------------------------------------------------------*/
2750
2751SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_info_stream_tx_mode(v150_1_state_t *s, int channel, int msg_id)
2752{
2753 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2754 return -1;
2755 /*endif*/
2756 switch (msg_id)
2757 {
2758 case V150_1_MSGID_I_RAW_OCTET:
2759 case V150_1_MSGID_I_RAW_BIT:
2760 case V150_1_MSGID_I_OCTET:
2761 case V150_1_MSGID_I_CHAR_STAT:
2762 case V150_1_MSGID_I_CHAR_DYN:
2763 case V150_1_MSGID_I_FRAME:
2764 case V150_1_MSGID_I_OCTET_CS:
2765 case V150_1_MSGID_I_CHAR_STAT_CS:
2766 case V150_1_MSGID_I_CHAR_DYN_CS:
2767 s->near.info_stream_channel = channel;
2768 s->near.info_stream_msg_id = msg_id;
2769 break;
2770 default:
2771 return -1;
2772 }
2773 return 0;
2774}
2775/*- End of function --------------------------------------------------------*/
2776
2777SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_info_stream_msg_priorities(v150_1_state_t *s, int msg_ids[])
2778{
2779 int i;
2780
2781 /* Check the list is valid */
2782 for (i = 0; i < 10 && msg_ids[i] >= 0; i++)
2783 {
2784 switch(msg_ids[i])
2785 {
2786 case V150_1_MSGID_I_RAW_OCTET:
2787 case V150_1_MSGID_I_RAW_BIT:
2788 case V150_1_MSGID_I_OCTET:
2789 case V150_1_MSGID_I_CHAR_STAT:
2790 case V150_1_MSGID_I_CHAR_DYN:
2791 case V150_1_MSGID_I_FRAME:
2792 case V150_1_MSGID_I_OCTET_CS:
2793 case V150_1_MSGID_I_CHAR_STAT_CS:
2794 case V150_1_MSGID_I_CHAR_DYN_CS:
2795 /* OK */
2796 break;
2797 default:
2798 return -1;
2799 }
2800 /*endswitch*/
2801 }
2802 /*endfor*/
2803 for (i = 0; i < 10 && msg_ids[i] >= 0; i++)
2804 {
2805 s->near.info_msg_preferences[i] = msg_ids[i];
2806 }
2807 /*endfor*/
2808 if (i < 10)
2809 s->near.info_msg_preferences[i] = -1;
2810 /*endif*/
2811 return 0;
2812}
2813/*- End of function --------------------------------------------------------*/
2814
2815SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_modulation(v150_1_state_t *s, int modulation)
2816{
2817 s->near.selmod = modulation;
2818 return 0;
2819}
2820/*- End of function --------------------------------------------------------*/
2821
2822SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression_direction(v150_1_state_t *s, int compression_direction)
2823{
2824 s->near.selected_compression_direction = compression_direction;
2825 return 0;
2826}
2827/*- End of function --------------------------------------------------------*/
2828
2829SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression(v150_1_state_t *s, int compression)
2830{
2831 s->near.selected_compression = compression;
2832 return 0;
2833}
2834/*- End of function --------------------------------------------------------*/
2835
2836SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression_parameters(v150_1_state_t *s,
2837 int tx_dictionary_size,
2838 int rx_dictionary_size,
2839 int tx_string_length,
2840 int rx_string_length,
2841 int tx_history_size,
2842 int rx_history_size)
2843{
2844 s->near.compression_tx_dictionary_size = tx_dictionary_size;
2845 s->near.compression_rx_dictionary_size = rx_dictionary_size;
2846 s->near.compression_tx_string_length = tx_string_length;
2847 s->near.compression_rx_string_length = rx_string_length;
2848 /* These are only relevant for V.44 */
2849 s->near.compression_tx_history_size = tx_history_size;
2850 s->near.compression_rx_history_size = rx_history_size;
2851 return 0;
2852}
2853/*- End of function --------------------------------------------------------*/
2854
2855SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_error_correction(v150_1_state_t *s, int error_correction)
2856{
2857 s->near.selected_error_correction = error_correction;
2858 return 0;
2859}
2860/*- End of function --------------------------------------------------------*/
2861
2862SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_tx_symbol_rate(v150_1_state_t *s, bool_Bool enable, int rate)
2863{
2864 s->near.txsen = enable;
2865 s->near.txsr = (enable) ? rate : 0;
2866 return 0;
2867}
2868/*- End of function --------------------------------------------------------*/
2869
2870SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_rx_symbol_rate(v150_1_state_t *s, bool_Bool enable, int rate)
2871{
2872 s->near.rxsen = enable;
2873 s->near.rxsr = (enable) ? rate : 0;
2874 return 0;
2875}
2876/*- End of function --------------------------------------------------------*/
2877
2878SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_tx_data_signalling_rate(v150_1_state_t *s, int rate)
2879{
2880 s->near.tdsr = rate;
2881 return 0;
2882}
2883/*- End of function --------------------------------------------------------*/
2884
2885SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_rx_data_signalling_rate(v150_1_state_t *s, int rate)
2886{
2887 s->near.rdsr = rate;
2888 return 0;
2889}
2890/*- End of function --------------------------------------------------------*/
2891
2892SPAN_DECLARE(logging_state_t *)__attribute__((visibility("default"))) logging_state_t * v150_1_get_logging_state(v150_1_state_t *s)
2893{
2894 return &s->logging;
2895}
2896/*- End of function --------------------------------------------------------*/
2897
2898SPAN_DECLARE(v150_1_state_t *)__attribute__((visibility("default"))) v150_1_state_t * v150_1_init(v150_1_state_t *s,
2899 v150_1_tx_packet_handler_t tx_packet_handler,
2900 void *tx_packet_user_data,
2901 v150_1_rx_packet_handler_t rx_packet_handler,
2902 void *rx_packet_user_data,
2903 v150_1_rx_octet_handler_t rx_octet_handler,
2904 void *rx_octet_handler_user_data,
2905 v150_1_rx_status_report_handler_t rx_status_report_handler,
2906 void *rx_status_report_user_data)
2907{
2908 if (tx_packet_handler == NULL((void*)0) || rx_packet_handler == NULL((void*)0) || rx_octet_handler == NULL((void*)0) || rx_status_report_handler == NULL((void*)0))
2909 return NULL((void*)0);
2910 /*endif*/
2911 if (s == NULL((void*)0))
2912 {
2913 if ((s = (v150_1_state_t *) malloc(sizeof(*s))) == NULL((void*)0))
2914 return NULL((void*)0);
2915 /*endif*/
2916 }
2917 /*endif*/
2918 memset(s, 0, sizeof(*s));
2919
2920 span_log_init(&s->logging, SPAN_LOG_NONE, NULL((void*)0));
2921 span_log_set_protocol(&s->logging, "V.150.1");
2922
2923 s->near.max_payload_bytes[SPRT_TCID_UNRELIABLE_UNSEQUENCED] = SPRT_DEFAULT_TC0_PAYLOAD_BYTES140;
2924 s->near.max_payload_bytes[SPRT_TCID_RELIABLE_SEQUENCED] = SPRT_DEFAULT_TC1_PAYLOAD_BYTES132;
2925 s->near.max_payload_bytes[SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED] = SPRT_DEFAULT_TC2_PAYLOAD_BYTES132;
2926 s->near.max_payload_bytes[SPRT_TCID_UNRELIABLE_SEQUENCED] = SPRT_DEFAULT_TC3_PAYLOAD_BYTES140;
2927
2928 s->near.v42bis_p0 = 3;
2929 s->near.v42bis_p1 = 512;
2930 s->near.v42bis_p2 = 6;
2931 s->near.v44_c0 = 0;
2932 s->near.v44_p0 = 0;
2933 s->near.v44_p1t = 0;
2934 s->near.v44_p1r = 0;
2935 s->near.v44_p2t = 0;
2936 s->near.v44_p2r = 0;
2937 s->near.v44_p3t = 0;
2938 s->near.v44_p3r = 0;
2939
2940 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_CALL_FUNCTION_1] = true1;
2941 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_CALL_FUNCTION_1] = V150_1_JM_CALL_FUNCTION_V_SERIES;
2942 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_MODULATION_MODES] = true1;
2943 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_MODULATION_MODES] =
2944 V150_1_JM_MODULATION_MODE_V34_AVAILABLE
2945 | V150_1_JM_MODULATION_MODE_V32_V32bis_AVAILABLE
2946 | V150_1_JM_MODULATION_MODE_V22_V22bis_AVAILABLE
2947 | V150_1_JM_MODULATION_MODE_V21_AVAILABLE;
2948 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PROTOCOLS] = true1;
2949 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PROTOCOLS] = V150_1_JM_PROTOCOL_V42_LAPM;
2950 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PSTN_ACCESS] = true1;
2951 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PSTN_ACCESS] = 0;
2952 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PCM_MODEM_AVAILABILITY] = false0;
2953 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PCM_MODEM_AVAILABILITY] = 0;
2954 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_EXTENSION] = false0;
2955 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_EXTENSION] = 0;
2956
2957 s->near.selmod = V150_1_SELMOD_NULL;
2958 s->near.selected_compression_direction = V150_1_COMPRESS_NEITHER_WAY;
2959 s->near.selected_compression = V150_1_COMPRESSION_NONE;
2960 s->near.selected_error_correction = V150_1_ERROR_CORRECTION_NONE;
2961 s->near.tdsr = 0;
2962 s->near.rdsr = 0;
2963 s->near.txsen = false0;
2964 s->near.txsr = V150_1_SYMBOL_RATE_NULL;
2965 s->near.rxsen = false0;
2966 s->near.rxsr = V150_1_SYMBOL_RATE_NULL;
2967
2968 /* Set default values that suit V.42bis */
2969 s->near.compression_tx_dictionary_size = 512;
2970 s->near.compression_rx_dictionary_size = 512;
2971 s->near.compression_tx_string_length = 6;
2972 s->near.compression_rx_string_length = 6;
2973 s->near.compression_tx_history_size = 0;
2974 s->near.compression_rx_history_size = 0;
2975
2976 s->near.ecp = V150_1_ERROR_CORRECTION_V42_LAPM;
2977 s->near.v42_lapm_supported = true1;
2978 s->near.v42_annex_a_supported = false0; /* This will never be supported, as it was removed from the V.42 spec in 2002. */
2979 s->near.v42bis_supported = true1;
2980 s->near.v44_supported = false0;
2981 s->near.mnp5_supported = false0;
2982
2983 s->near.necrxch_option = false0;
2984 s->near.ecrxch_option = true1;
2985 s->near.xid_profile_exchange_supported = false0;
2986 s->near.asymmetric_data_types_supported = false0;
2987
2988 s->near.i_raw_bit_supported = false0;
2989 s->near.i_frame_supported = false0;
2990 s->near.i_char_stat_supported = false0;
2991 s->near.i_char_dyn_supported = false0;
2992 s->near.i_octet_cs_supported = true1;
2993 s->near.i_char_stat_cs_supported = false0;
2994 s->near.i_char_dyn_cs_supported = false0;
2995
2996 /* Set a default character format. */
2997 s->near.data_format_code = (V150_1_DATA_BITS_7 << 6)
2998 | (V150_1_PARITY_EVEN << 3)
2999 | V150_1_STOP_BITS_1;
3000 s->far.data_format_code = -1;
3001
3002 s->tx_packet_handler = tx_packet_handler;
3003 s->tx_packet_user_data = tx_packet_user_data;
3004 s->rx_packet_handler = rx_packet_handler;
3005 s->rx_packet_user_data = rx_packet_user_data;
3006 s->rx_octet_handler = rx_octet_handler;
3007 s->rx_octet_handler_user_data = rx_octet_handler_user_data;
3008 s->rx_status_report_handler = rx_status_report_handler;
3009 s->rx_status_report_user_data = rx_status_report_user_data;
3010
3011 return s;
3012}
3013/*- End of function --------------------------------------------------------*/
3014
3015SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_release(v150_1_state_t *s)
3016{
3017 return 0;
3018}
3019/*- End of function --------------------------------------------------------*/
3020
3021SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_free(v150_1_state_t *s)
3022{
3023 int ret;
3024
3025 ret = v150_1_release(s);
3026 span_free(s);
3027 return ret;
3028}
3029/*- End of function --------------------------------------------------------*/
3030/*- End of file ------------------------------------------------------------*/