Bug Summary

File:v150_1.c
Warning:line 2520, column 5
Value stored to 'data_frame_state' 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 default:
1649 res = -1;
1650 break;
1651 }
1652 /*endswitch*/
1653 if (res >= 0)
1654 {
1655 if (s->tx_packet_handler)
1656 res = s->tx_packet_handler(s->tx_packet_user_data, s->near.info_stream_channel, pkt, res);
1657 /*endif*/
1658 }
1659 else
1660 {
1661 span_log(&s->logging, SPAN_LOG_FLOW, "Bad message\n");
1662 }
1663 /*endif*/
1664 return res;
1665}
1666/*- End of function --------------------------------------------------------*/
1667
1668static int select_info_msg_type(v150_1_state_t *s)
1669{
1670 int i;
1671
1672 /* Select the first available information message type we find in the preferences list */
1673 for (i = 0; i < 10 && s->near.info_msg_preferences[i] >= 0; i++)
1674 {
1675 switch (s->near.info_msg_preferences[i])
1676 {
1677 case V150_1_MSGID_I_RAW_OCTET:
1678 /* This is always supported */
1679 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1680 return 0;
1681 case V150_1_MSGID_I_RAW_BIT:
1682 if (s->near.i_raw_bit_available)
1683 {
1684 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1685 return 0;
1686 }
1687 /*endif*/
1688 break;
1689 case V150_1_MSGID_I_OCTET:
1690 /* This is always supported */
1691 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1692 return 0;
1693 case V150_1_MSGID_I_CHAR_STAT:
1694 if (s->near.i_char_stat_available)
1695 {
1696 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1697 return 0;
1698 }
1699 /*endif*/
1700 break;
1701 case V150_1_MSGID_I_CHAR_DYN:
1702 if (s->near.i_char_dyn_available)
1703 {
1704 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1705 return 0;
1706 }
1707 /*endif*/
1708 break;
1709 case V150_1_MSGID_I_FRAME:
1710 if (s->near.i_frame_available)
1711 {
1712 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1713 return 0;
1714 }
1715 /*endif*/
1716 break;
1717 case V150_1_MSGID_I_OCTET_CS:
1718 if (s->near.i_octet_cs_available)
1719 {
1720 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1721 return 0;
1722 }
1723 /*endif*/
1724 break;
1725 case V150_1_MSGID_I_CHAR_STAT_CS:
1726 if (s->near.i_char_stat_cs_available)
1727 {
1728 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1729 return 0;
1730 }
1731 /*endif*/
1732 break;
1733 case V150_1_MSGID_I_CHAR_DYN_CS:
1734 if (s->near.i_char_dyn_cs_available)
1735 {
1736 s->near.info_stream_msg_id = s->near.info_msg_preferences[i];
1737 return 0;
1738 }
1739 /*endif*/
1740 break;
1741 default:
1742 s->near.info_stream_msg_id = -1;
1743 return -1;
1744 }
1745 /*endswitch*/
1746 }
1747 /*endfor*/
1748 s->near.info_stream_msg_id = -1;
1749 return -1;
1750}
1751/*- End of function --------------------------------------------------------*/
1752
1753static int v150_1_process_null(v150_1_state_t *s, const uint8_t buf[], int len)
1754{
1755 if (len != 1)
1756 return -1;
1757 return 0;
1758}
1759/*- End of function --------------------------------------------------------*/
1760
1761static int v150_1_process_init(v150_1_state_t *s, const uint8_t buf[], int len)
1762{
1763 if (len != 3)
1764 {
1765 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid INIT message length %d\n", len);
1766 return -1;
1767 }
1768 /*endif*/
1769 /* Just capture what the far end says about its capabilities */
1770 s->far.necrxch_option = (buf[1] & 0x80) != 0;
1771 s->far.ecrxch_option = (buf[1] & 0x40) != 0;
1772 s->far.xid_profile_exchange_supported = (buf[1] & 0x20) != 0;
1773 s->far.asymmetric_data_types_supported = (buf[1] & 0x10) != 0;
1774 s->far.i_raw_bit_supported = (buf[1] & 0x08) != 0;
1775 s->far.i_frame_supported = (buf[1] & 0x04) != 0;
1776 s->far.i_char_stat_supported = (buf[1] & 0x02) != 0;
1777 s->far.i_char_dyn_supported = (buf[1] & 0x01) != 0;
1778 s->far.i_octet_cs_supported = (buf[2] & 0x80) != 0;
1779 s->far.i_char_stat_cs_supported = (buf[2] & 0x40) != 0;
1780 s->far.i_char_dyn_cs_supported = (buf[2] & 0x20) != 0;
1781
1782 /* Now sift out what will be available, because both ends support the features */
1783 s->near.i_raw_bit_available = s->near.i_raw_bit_supported && s->far.i_raw_bit_supported;
1784 s->near.i_frame_available = s->near.i_frame_supported && s->far.i_frame_supported;
1785 s->near.i_octet_with_dlci_available = s->near.dlci_supported;
1786 s->near.i_octet_without_dlci_available = !s->near.dlci_supported;
1787 s->near.i_char_stat_available = s->near.i_char_stat_supported && s->far.i_char_stat_supported;
1788 s->near.i_char_dyn_available = s->near.i_char_dyn_supported && s->far.i_char_dyn_supported;
1789 s->near.i_octet_cs_available = s->near.i_octet_cs_supported && s->far.i_octet_cs_supported;
1790 s->near.i_char_stat_cs_available = s->near.i_char_stat_cs_supported && s->far.i_char_stat_cs_supported;
1791 s->near.i_char_dyn_cs_available = s->near.i_char_dyn_cs_supported && s->far.i_char_dyn_cs_supported;
1792
1793 span_log(&s->logging, SPAN_LOG_FLOW, " Preferred non-error controlled Rx channel: %s\n", (s->far.necrxch_option) ? "RSC" : "USC");
1794 span_log(&s->logging, SPAN_LOG_FLOW, " Preferred error controlled Rx channel: %s\n", (s->far.necrxch_option) ? "USC" : "RSC");
1795 span_log(&s->logging, SPAN_LOG_FLOW, " XID profile exchange %ssupported\n", (s->far.xid_profile_exchange_supported) ? "" : "not ");
1796 span_log(&s->logging, SPAN_LOG_FLOW, " Asymmetric data types %ssupported\n", (s->far.asymmetric_data_types_supported) ? "" : "not ");
1797 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-CHAR supported\n");
1798 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-BIT %ssupported\n", (s->far.i_raw_bit_supported) ? "" : "not ");
1799 span_log(&s->logging, SPAN_LOG_FLOW, " I_FRAME %ssupported\n", (s->far.i_frame_supported) ? "" : "not ");
1800 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET %s supported\n", (s->near.dlci_supported) ? "(DLCI) " : "(no DLCI)");
1801 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT %ssupported\n", (s->far.i_char_stat_supported) ? "" : "not ");
1802 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN %ssupported\n", (s->far.i_char_dyn_supported) ? "" : "not ");
1803 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET-CS %ssupported\n", (s->far.i_octet_cs_supported) ? "" : "not ");
1804 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT-CS %ssupported\n", (s->far.i_char_stat_cs_supported) ? "" : "not ");
1805 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN-CS %ssupported\n", (s->far.i_char_dyn_cs_supported) ? "" : "not ");
1806 select_info_msg_type(s);
1807
1808 s->far.connection_state = V150_1_STATE_INITED;
1809 if (s->near.connection_state >= V150_1_STATE_INITED)
1810 s->joint_connection_state = V150_1_STATE_INITED;
1811 /*endif*/
1812 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
1813 return 0;
1814}
1815/*- End of function --------------------------------------------------------*/
1816
1817static int v150_1_process_xid_xchg(v150_1_state_t *s, const uint8_t buf[], int len)
1818{
1819 if (s->joint_connection_state < V150_1_STATE_INITED)
1820 {
1821 span_log(&s->logging, SPAN_LOG_WARNING, "XID_XCHG received before INIT. Ignored.\n");
1822 return -1;
1823 }
1824 /*endif*/
1825 if (len != 19)
1826 {
1827 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid XID_XCHG message length %d\n", len);
1828 return -1;
1829 }
1830 /*endif*/
1831 s->far.ecp = buf[1];
1832
1833 s->far.v42bis_supported = (buf[2] & 0x80) != 0;
1834 s->far.v44_supported = (buf[2] & 0x40) != 0;
1835 s->far.mnp5_supported = (buf[2] & 0x20) != 0;
1836
1837 s->far.v42bis_p0 = buf[3];
1838 s->far.v42bis_p1 = get_net_unaligned_uint16(&buf[4]);
1839 s->far.v42bis_p2 = buf[6];
1840 s->far.v44_c0 = buf[7];
1841 s->far.v44_p0 = buf[8];
1842 s->far.v44_p1t = get_net_unaligned_uint16(&buf[9]);
1843 s->far.v44_p1r = get_net_unaligned_uint16(&buf[11]);
1844 s->far.v44_p2t = buf[13];
1845 s->far.v44_p2r = buf[14];
1846 s->far.v44_p3t = get_net_unaligned_uint16(&buf[15]);
1847 s->far.v44_p3r = get_net_unaligned_uint16(&buf[17]);
1848
1849 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis %ssupported\n", (s->far.v42bis_supported) ? "" : "not ");
1850 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 %ssupported\n", (s->far.v44_supported) ? "" : "not ");
1851 span_log(&s->logging, SPAN_LOG_FLOW, " MNP5 %ssupported\n", (s->far.mnp5_supported) ? "" : "not ");
1852 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P0 %d\n", s->far.v42bis_p0);
1853 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P1 %d\n", s->far.v42bis_p1);
1854 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P2 %d\n", s->far.v42bis_p2);
1855 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 C0 %d\n", s->far.v44_c0);
1856 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1 %d\n", s->far.v44_p0);
1857 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1T %d\n", s->far.v44_p1t);
1858 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1R %d\n", s->far.v44_p1r);
1859 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2T %d\n", s->far.v44_p2t);
1860 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2R %d\n", s->far.v44_p2r);
1861 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3T %d\n", s->far.v44_p3t);
1862 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3R %d\n", s->far.v44_p3r);
1863
1864 /* TODO: */
1865 return 0;
1866}
1867/*- End of function --------------------------------------------------------*/
1868
1869static int v150_1_process_jm_info(v150_1_state_t *s, const uint8_t buf[], int len)
1870{
1871 int i;
1872 int id;
1873
1874 if (s->joint_connection_state < V150_1_STATE_INITED)
1875 {
1876 span_log(&s->logging, SPAN_LOG_WARNING, "JM_INFO received before INIT. Ignored.\n");
1877 return -1;
1878 }
1879 /*endif*/
1880 /* The length must be even */
1881 if ((len & 1) != 1)
1882 {
1883 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid JM_INFO message length %d\n", len);
1884 return -1;
1885 }
1886 /*endif*/
1887 for (i = 1; i < len; i += 2)
1888 {
1889 id = (buf[i] >> 4) & 0x0F;
1890 s->far.jm_category_id_seen[id] = true1;
1891 s->far.jm_category_info[id] = get_net_unaligned_uint16(&buf[i]) & 0x0FFF;
1892 }
1893 /*endfor*/
1894 for (i = 1; i < 16; i++)
1895 {
1896 if (s->far.jm_category_id_seen[i])
1897 {
1898 span_log(&s->logging, SPAN_LOG_WARNING, " JM %d 0x%x\n", i, s->far.jm_category_info[i]);
1899 }
1900 /*endif*/
1901 }
1902 /*endfor*/
1903
1904 /* TODO: */
1905 return 0;
1906}
1907/*- End of function --------------------------------------------------------*/
1908
1909static int v150_1_process_start_jm(v150_1_state_t *s, const uint8_t buf[], int len)
1910{
1911 if (s->joint_connection_state < V150_1_STATE_INITED)
1912 {
1913 span_log(&s->logging, SPAN_LOG_WARNING, "START_JM received before INIT. Ignored.\n");
1914 return -1;
1915 }
1916 /*endif*/
1917 if (len > 1)
1918 {
1919 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid START_JM message length %d\n", len);
1920 return -1;
1921 }
1922 /*endif*/
1923
1924 /* TODO: */
1925 return 0;
1926}
1927/*- End of function --------------------------------------------------------*/
1928
1929static int v150_1_process_connect(v150_1_state_t *s, const uint8_t buf[], int len)
1930{
1931 int available_data_types;
1932
1933 if (s->joint_connection_state < V150_1_STATE_INITED)
1934 {
1935 span_log(&s->logging, SPAN_LOG_WARNING, "CONNECT received before INIT. Ignored.\n");
1936 return -1;
1937 }
1938 /*endif*/
1939 if (len < 9 || len > 19)
1940 {
1941 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid CONNECT message length %d\n", len);
1942 return -1;
1943 }
1944 /*endif*/
1945 s->far.selmod = (buf[1] >> 2) & 0x3F;
1946 s->far.selected_compression_direction = buf[1] & 0x03;
1947 s->far.selected_compression = (buf[2] >> 4) & 0x0F;
1948 s->far.selected_error_correction = buf[2] & 0x0F;
1949 s->far.tdsr = get_net_unaligned_uint16(&buf[3]);
1950 s->far.rdsr = get_net_unaligned_uint16(&buf[5]);
1951
1952 available_data_types = get_net_unaligned_uint16(&buf[7]);
1953 s->far.i_octet_with_dlci_available = (available_data_types & 0x8000) != 0;
1954 s->far.i_octet_without_dlci_available = (available_data_types & 0x4000) != 0;
1955 s->far.i_raw_bit_available = (available_data_types & 0x2000) != 0;
1956 s->far.i_frame_available = (available_data_types & 0x1000) != 0;
1957 s->far.i_char_stat_available = (available_data_types & 0x0800) != 0;
1958 s->far.i_char_dyn_available = (available_data_types & 0x0400) != 0;
1959 s->far.i_octet_cs_available = (available_data_types & 0x0200) != 0;
1960 s->far.i_char_stat_cs_available = (available_data_types & 0x0100) != 0;
1961 s->far.i_char_dyn_cs_available = (available_data_types & 0x0080) != 0;
1962
1963 span_log(&s->logging, SPAN_LOG_FLOW, " Modulation %s\n", v150_1_modulation_to_str(s->far.selmod));
1964 span_log(&s->logging, SPAN_LOG_FLOW, " Compression direction %s\n", v150_1_compression_direction_to_str(s->far.selected_compression_direction));
1965 span_log(&s->logging, SPAN_LOG_FLOW, " Compression %s\n", v150_1_compression_to_str(s->far.selected_compression));
1966 span_log(&s->logging, SPAN_LOG_FLOW, " Error correction %s\n", v150_1_error_correction_to_str(s->far.selected_error_correction));
1967 span_log(&s->logging, SPAN_LOG_FLOW, " Tx data rate %d\n", s->far.tdsr);
1968 span_log(&s->logging, SPAN_LOG_FLOW, " Rx data rate %d\n", s->far.rdsr);
1969
1970 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-CHAR available\n");
1971 span_log(&s->logging, SPAN_LOG_FLOW, " I_RAW-BIT %savailable\n", (s->far.i_raw_bit_available) ? "" : "not ");
1972 span_log(&s->logging, SPAN_LOG_FLOW, " I_FRAME %savailable\n", (s->far.i_frame_available) ? "" : "not ");
1973 if (s->far.i_octet_without_dlci_available || s->far.i_octet_without_dlci_available)
1974 {
1975 if (s->far.i_octet_without_dlci_available)
1976 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET (no DLCI) available\n");
1977 /*endif*/
1978 if (s->far.i_octet_with_dlci_available)
1979 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET (DLCI) available\n");
1980 /*endif*/
1981 }
1982 else
1983 {
1984 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET not available\n");
1985 }
1986 /*endif*/
1987 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT %savailable\n", (s->far.i_char_stat_available) ? "" : "not ");
1988 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN %savailable\n", (s->far.i_char_dyn_available) ? "" : "not ");
1989 span_log(&s->logging, SPAN_LOG_FLOW, " I_OCTET-CS %savailable\n", (s->far.i_octet_cs_available) ? "" : "not ");
1990 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-STAT-CS %savailable\n", (s->far.i_char_stat_cs_available) ? "" : "not ");
1991 span_log(&s->logging, SPAN_LOG_FLOW, " I_CHAR-DYN-CS %savailable\n", (s->far.i_char_dyn_cs_available) ? "" : "not ");
1992
1993 if (len >= 15
1994 &&
1995 (s->far.selected_compression == V150_1_COMPRESSION_V42BIS || s->far.selected_compression == V150_1_COMPRESSION_V44))
1996 {
1997 /* Selected_compression should be V150_1_COMPRESSION_V42BIS or V150_1_COMPRESSION_V44 */
1998 s->far.compression_tx_dictionary_size = get_net_unaligned_uint16(&buf[9]);
1999 s->far.compression_rx_dictionary_size = get_net_unaligned_uint16(&buf[11]);
2000 s->far.compression_tx_string_length = buf[13];
2001 s->far.compression_rx_string_length = buf[14];
2002
2003 span_log(&s->logging, SPAN_LOG_FLOW, " Tx dictionary size %d\n", s->far.compression_tx_dictionary_size);
2004 span_log(&s->logging, SPAN_LOG_FLOW, " Rx dictionary size %d\n", s->far.compression_rx_dictionary_size);
2005 span_log(&s->logging, SPAN_LOG_FLOW, " Tx string length %d\n", s->far.compression_tx_string_length);
2006 span_log(&s->logging, SPAN_LOG_FLOW, " Rx string length %d\n", s->far.compression_rx_string_length);
2007 }
2008 else
2009 {
2010 s->far.compression_tx_dictionary_size = 0;
2011 s->far.compression_rx_dictionary_size = 0;
2012 s->far.compression_tx_string_length = 0;
2013 s->far.compression_rx_string_length = 0;
2014 }
2015 /*endif*/
2016
2017 if (len >= 19
2018 &&
2019 s->far.selected_compression == V150_1_COMPRESSION_V44)
2020 {
2021 /* Selected_compression should be V150_1_COMPRESSION_V44 */
2022 s->far.compression_tx_history_size = get_net_unaligned_uint16(&buf[15]);
2023 s->far.compression_rx_history_size = get_net_unaligned_uint16(&buf[17]);
2024
2025 span_log(&s->logging, SPAN_LOG_FLOW, " Tx history size %d\n", s->far.compression_tx_history_size);
2026 span_log(&s->logging, SPAN_LOG_FLOW, " Rx history size %d\n", s->far.compression_rx_history_size);
2027 }
2028 else
2029 {
2030 s->far.compression_tx_history_size = 0;
2031 s->far.compression_rx_history_size = 0;
2032 }
2033 /*endif*/
2034
2035 s->far.connection_state = V150_1_STATE_CONNECTED;
2036 if (s->near.connection_state >= V150_1_STATE_CONNECTED)
2037 s->joint_connection_state = V150_1_STATE_CONNECTED;
2038 /*endif*/
2039 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2040 return 0;
2041}
2042/*- End of function --------------------------------------------------------*/
2043
2044static int v150_1_process_break(v150_1_state_t *s, const uint8_t buf[], int len)
2045{
2046 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2047 {
2048 span_log(&s->logging, SPAN_LOG_WARNING, "BREAK received before CONNECT. Ignored.\n");
2049 return -1;
2050 }
2051 /*endif*/
2052 if (len != 3)
2053 {
2054 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid BREAK message length %d\n", len);
2055 return -1;
2056 }
2057 /*endif*/
2058
2059 s->far.break_source = (buf[1] >> 4) & 0x0F;
2060 s->far.break_type = buf[1] & 0x0F;
2061 s->far.break_duration = buf[2];
2062 span_log(&s->logging, SPAN_LOG_FLOW, "Break source %s\n", v150_1_break_source_to_str(s->far.break_source));
2063 span_log(&s->logging, SPAN_LOG_FLOW, "Break type %s\n", v150_1_break_type_to_str(s->far.break_type));
2064 span_log(&s->logging, SPAN_LOG_FLOW, "Break len %d ms\n", s->far.break_duration*10);
2065 status_report(s, V150_1_STATUS_REASON_BREAK_RECEIVED);
2066 return 0;
2067}
2068/*- End of function --------------------------------------------------------*/
2069
2070static int v150_1_process_break_ack(v150_1_state_t *s, const uint8_t buf[], int len)
2071{
2072 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2073 {
2074 span_log(&s->logging, SPAN_LOG_WARNING, "BREAKACK received before CONNECT. Ignored.\n");
2075 return -1;
2076 }
2077 /*endif*/
2078 if (len != 1)
2079 {
2080 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid BREAKACK message length %d\n", len);
2081 return -1;
2082 }
2083 /*endif*/
2084
2085 return 0;
2086}
2087/*- End of function --------------------------------------------------------*/
2088
2089static int v150_1_process_mr_event(v150_1_state_t *s, const uint8_t buf[], int len)
2090{
2091 int event;
2092 int reason;
2093
2094 if (s->joint_connection_state < V150_1_STATE_INITED)
2095 {
2096 span_log(&s->logging, SPAN_LOG_WARNING, "MR-EVENT received before INIT. Ignored.\n");
2097 return -1;
2098 }
2099 /*endif*/
2100 if (len < 3)
2101 {
2102 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2103 return -1;
2104 }
2105 /*endif*/
2106
2107 event = buf[1];
2108 span_log(&s->logging, SPAN_LOG_FLOW, "MR_EVENT type %s (%d) received\n", v150_1_mr_event_type_to_str(event), event);
2109 switch (event)
2110 {
2111 case V150_1_MR_EVENT_ID_NULL:
2112 if (len != 3)
2113 {
2114 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2115 return -1;
2116 }
2117 /*endif*/
2118 break;
2119 case V150_1_MR_EVENT_ID_RATE_RENEGOTIATION:
2120 case V150_1_MR_EVENT_ID_RETRAIN:
2121 if (len != 3)
2122 {
2123 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2124 return -1;
2125 }
2126 /*endif*/
2127 reason = buf[2];
2128 span_log(&s->logging, SPAN_LOG_FLOW, " Reason %d\n", reason);
2129 if (event == V150_1_MR_EVENT_ID_RETRAIN)
2130 {
2131 s->far.connection_state = V150_1_STATE_RETRAIN;
2132 s->joint_connection_state = V150_1_STATE_RETRAIN;
2133 status_report(s, V150_1_STATUS_REASON_RATE_RETRAIN_RECEIVED);
2134 }
2135 else
2136 {
2137 s->far.connection_state = V150_1_STATE_RATE_RENEGOTIATION;
2138 s->joint_connection_state = V150_1_STATE_RATE_RENEGOTIATION;
2139 status_report(s, V150_1_STATUS_REASON_RATE_RENEGOTIATION_RECEIVED);
2140 }
2141 /*endif*/
2142 break;
2143 case V150_1_MR_EVENT_ID_PHYSUP:
2144 if (len != 10)
2145 {
2146 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid MR_EVENT message length %d\n", len);
2147 return -1;
2148 }
2149 /*endif*/
2150 s->far.selmod = (buf[3] >> 2) & 0x3F;
2151 s->far.txsen = (buf[3] & 0x02) != 0;
2152 s->far.rxsen = (buf[3] & 0x01) != 0;
2153 s->far.tdsr = get_net_unaligned_uint16(&buf[4]);
2154 s->far.rdsr = get_net_unaligned_uint16(&buf[6]);
2155 s->far.txsr = buf[8];
2156 s->far.rxsr = buf[9];
2157
2158 span_log(&s->logging, SPAN_LOG_FLOW, " Selected modulation %s\n", v150_1_modulation_to_str(s->far.selmod));
2159 span_log(&s->logging, SPAN_LOG_FLOW, " Tx data signalling rate %d\n", s->far.tdsr);
2160 span_log(&s->logging, SPAN_LOG_FLOW, " Rx data signalling rate %d\n", s->far.rdsr);
2161 if (s->far.txsen)
2162 span_log(&s->logging, SPAN_LOG_FLOW, " Tx symbol rate %s\n", v150_1_symbol_rate_to_str(s->far.txsr));
2163 /*endif*/
2164 if (s->far.rxsen)
2165 span_log(&s->logging, SPAN_LOG_FLOW, " Rx symbol rate %s\n", v150_1_symbol_rate_to_str(s->far.rxsr));
2166 /*endif*/
2167
2168 /* TODO: report these parameters */
2169
2170 s->far.connection_state = V150_1_STATE_PHYSUP;
2171 if (s->near.connection_state >= V150_1_STATE_PHYSUP)
2172 s->joint_connection_state = V150_1_STATE_PHYSUP;
2173 /*endif*/
2174 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2175 break;
2176 default:
2177 span_log(&s->logging, SPAN_LOG_WARNING, "Unknown MR_EVENT type %d received\n", event);
2178 break;
2179 }
2180 /*endif*/
2181 return 0;
2182}
2183/*- End of function --------------------------------------------------------*/
2184
2185static int v150_1_process_cleardown(v150_1_state_t *s, const uint8_t buf[], int len)
2186{
2187 if (s->joint_connection_state < V150_1_STATE_INITED)
2188 {
2189 span_log(&s->logging, SPAN_LOG_WARNING, "CLEARDOWN received before INIT. Ignored.\n");
2190 return -1;
2191 }
2192 /*endif*/
2193 if (len != 4)
2194 {
2195 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid CLEARDOWN message length %d\n", len);
2196 return -1;
2197 }
2198 /*endif*/
2199
2200 s->far.cleardown_reason = buf[1];
2201 span_log(&s->logging, SPAN_LOG_FLOW, " Reason %s\n", v150_1_cleardown_reason_to_str(s->far.cleardown_reason));
2202 // vendor = buf[2];
2203 // vendor_info = buf[3];
2204 /* A cleardown moves everything back to square one. */
2205 s->far.connection_state = V150_1_STATE_IDLE;
2206 status_report(s, V150_1_STATUS_REASON_STATE_CHANGED);
2207 return 0;
2208}
2209/*- End of function --------------------------------------------------------*/
2210
2211static int v150_1_process_prof_xchg(v150_1_state_t *s, const uint8_t buf[], int len)
2212{
2213 if (s->joint_connection_state < V150_1_STATE_INITED)
2214 {
2215 span_log(&s->logging, SPAN_LOG_WARNING, "PROF_XCHG received before INIT. Ignored.\n");
2216 return -1;
2217 }
2218 /*endif*/
2219 if (len != 19)
2220 {
2221 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid PROF_XCHG message length %d\n", len);
2222 return -1;
2223 }
2224 /*endif*/
2225
2226 /* The following have 3 way options - no, yes and unknown */
2227 s->far.v42_lapm_supported = (buf[1] & 0xC0) == 0x40;
2228 s->far.v42_annex_a_supported = (buf[1] & 0x30) == 0x10;
2229 s->far.v44_supported = (buf[1] & 0x0C) == 0x04;
2230 s->far.v42bis_supported = (buf[1] & 0x03) == 0x01;
2231 s->far.mnp5_supported = (buf[2] & 0xC0) == 0x40;
2232
2233 s->far.v42bis_p0 = buf[3];
2234 s->far.v42bis_p1 = get_net_unaligned_uint16(&buf[4]);
2235 s->far.v42bis_p2 = buf[6];
2236 s->far.v44_c0 = buf[7];
2237 s->far.v44_p0 = buf[8];
2238 s->far.v44_p1t = get_net_unaligned_uint16(&buf[9]);
2239 s->far.v44_p1r = get_net_unaligned_uint16(&buf[11]);
2240 s->far.v44_p2t = buf[13];
2241 s->far.v44_p2r = buf[14];
2242 s->far.v44_p3t = get_net_unaligned_uint16(&buf[15]);
2243 s->far.v44_p3r = get_net_unaligned_uint16(&buf[17]);
2244
2245 span_log(&s->logging, SPAN_LOG_FLOW, " V.42 LAPM %ssupported\n", (s->far.v42_lapm_supported) ? "" : "not ");
2246 span_log(&s->logging, SPAN_LOG_FLOW, " V.42 Annex A %ssupported\n", (s->far.v42_annex_a_supported) ? "" : "not ");
2247 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 %ssupported\n", (s->far.v44_supported) ? "" : "not ");
2248 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis %ssupported\n", (s->far.v42bis_supported) ? "" : "not ");
2249 span_log(&s->logging, SPAN_LOG_FLOW, " MNP5 %ssupported\n", (s->far.mnp5_supported) ? "" : "not ");
2250
2251 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P0 %d\n", s->far.v42bis_p0);
2252 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P1 %d\n", s->far.v42bis_p1);
2253 span_log(&s->logging, SPAN_LOG_FLOW, " V.42bis P2 %d\n", s->far.v42bis_p2);
2254 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 C0 %d\n", s->far.v44_c0);
2255 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1 %d\n", s->far.v44_p0);
2256 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1T %d\n", s->far.v44_p1t);
2257 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P1R %d\n", s->far.v44_p1r);
2258 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2T %d\n", s->far.v44_p2t);
2259 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P2R %d\n", s->far.v44_p2r);
2260 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3T %d\n", s->far.v44_p3t);
2261 span_log(&s->logging, SPAN_LOG_FLOW, " V.44 P3R %d\n", s->far.v44_p3r);
2262
2263 /* TODO: */
2264 return 0;
2265}
2266/*- End of function --------------------------------------------------------*/
2267
2268static int v150_1_process_i_raw_octet(v150_1_state_t *s, const uint8_t buf[], int len)
2269{
2270 int i;
2271 int l;
2272 int n;
2273 int header;
2274
2275 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2276 {
2277 span_log(&s->logging, SPAN_LOG_WARNING, "I_RAW-OCTET received before CONNECT. Ignored.\n");
2278 return -1;
2279 }
2280 /*endif*/
2281 if (len < 2)
2282 {
2283 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-OCTET message length %d\n", len);
2284 return -1;
2285 }
2286 /*endif*/
2287 l = buf[1] & 0x7F;
2288 if ((buf[1] & 0x80) != 0)
2289 {
2290 n = 1;
2291 header = 1;
2292 }
2293 else
2294 {
2295 n = buf[1] + 2;
2296 header = 2;
2297 }
2298 /*endif*/
2299 if (len != l + header)
2300 {
2301 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-OCTET message length %d\n", len);
2302 return -1;
2303 }
2304 /*endif*/
2305 for (i = 0; i < n; i++)
2306 {
2307 if (s->rx_octet_handler)
2308 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2309 /*endif*/
2310 }
2311 /*endif*/
2312 return 0;
2313}
2314/*- End of function --------------------------------------------------------*/
2315
2316static int v150_1_process_i_raw_bit(v150_1_state_t *s, const uint8_t buf[], int len)
2317{
2318 int i;
2319 int l;
2320 int p;
2321 int n;
2322 int header;
2323
2324 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2325 {
2326 span_log(&s->logging, SPAN_LOG_WARNING, "I_RAW-BIT received before CONNECT. Ignored.\n");
2327 return -1;
2328 }
2329 /*endif*/
2330 if (len < 2)
2331 {
2332 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-BIT message length %d\n", len);
2333 return -1;
2334 }
2335 /*endif*/
2336 if ((buf[1] & 0x80) == 0)
2337 {
2338 if ((buf[1] & 0x40) == 0)
2339 {
2340 l = buf[1] & 0x3F;
2341 p = 0;
2342 }
2343 else
2344 {
2345 l = (buf[1] >> 3) & 0x07;
2346 p = buf[1] & 0x07;
2347 }
2348 /*endif*/
2349 n = 1;
2350 header = 1;
2351 }
2352 else
2353 {
2354 l = (buf[1] >> 3) & 0x0F;
2355 p = buf[1] & 0x07;
2356 n = buf[2] + 2;
2357 header = 2;
2358 }
2359 /*endif*/
2360 if (len != l + header)
2361 {
2362 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_RAW-BIT message length %d\n", len);
2363 return -1;
2364 }
2365 /*endif*/
2366 for (i = 0; i < n; i++)
2367 {
2368 if (s->rx_octet_handler)
2369 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2370 /*endif*/
2371 }
2372 /*endfor*/
2373 return 0;
2374}
2375/*- End of function --------------------------------------------------------*/
2376
2377static int v150_1_process_i_octet(v150_1_state_t *s, const uint8_t buf[], int len)
2378{
2379 int header;
2380
2381 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2382 {
2383 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET received before CONNECT. Ignored.\n");
2384 return -1;
2385 }
2386 /*endif*/
2387 if (len < 2)
2388 {
2389 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_OCTET message length %d\n", len);
2390 return -1;
2391 }
2392 /*endif*/
2393 if (s->far.i_octet_with_dlci_available)
2394 {
2395 /* DLCI is one or two bytes (usually just 1). The low bit of each byte is an extension
2396 bit, allowing for a variable number of bytes. */
2397 if (len < 2)
2398 {
2399 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET with DLCI has no DLCI field\n");
2400 }
2401 else
2402 {
2403 if ((buf[1] & 0x01) == 0)
2404 {
2405 if ((buf[2] & 0x01) == 0)
2406 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET with DLCI has bad DLCI field\n");
2407 /*endif*/
2408 header = 3;
2409 s->far.dlci = get_net_unaligned_uint16(&buf[1]);
2410 }
2411 else
2412 {
2413 header = 2;
2414 s->far.dlci = buf[1];
2415 }
2416 /*endif*/
2417 }
2418 /*endif*/
2419 }
2420 else
2421 {
2422 header = 1;
2423 }
2424 /*endif*/
2425 if (len > header)
2426 {
2427 if (s->rx_octet_handler)
2428 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[header], len - header, -1);
2429 /*endif*/
2430 }
2431 /*endif*/
2432 return 0;
2433}
2434/*- End of function --------------------------------------------------------*/
2435
2436static int v150_1_process_i_char_stat(v150_1_state_t *s, const uint8_t buf[], int len)
2437{
2438 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2439 {
2440 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-STAT received before CONNECT. Ignored.\n");
2441 return -1;
2442 }
2443 /*endif*/
2444 if (len < 2)
2445 {
2446 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-STAT message length %d\n", len);
2447 return -1;
2448 }
2449 /*endif*/
2450 if (s->far.data_format_code != buf[1])
2451 {
2452 /* Every packet in a session should have the same data format code */
2453 s->far.data_format_code = buf[1];
2454 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2455 }
2456 /*endif*/
2457 if (len > 2)
2458 {
2459 if (s->rx_octet_handler)
2460 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2461 /*endif*/
2462 }
2463 /*endif*/
2464 return 0;
2465}
2466/*- End of function --------------------------------------------------------*/
2467
2468static int v150_1_process_i_char_dyn(v150_1_state_t *s, const uint8_t buf[], int len)
2469{
2470 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2471 {
2472 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-DYN received before CONNECT. Ignored.\n");
2473 return -1;
2474 }
2475 /*endif*/
2476 if (len < 2)
2477 {
2478 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-DYN message length %d\n", len);
2479 return -1;
2480 }
2481 /*endif*/
2482 if (s->far.data_format_code != buf[1])
2483 {
2484 s->far.data_format_code = buf[1];
2485 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2486 }
2487 /*endif*/
2488 if (len > 2)
2489 {
2490 if (s->rx_octet_handler)
2491 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2492 /*endif*/
2493 }
2494 /*endif*/
2495 return 0;
2496}
2497/*- End of function --------------------------------------------------------*/
2498
2499static int v150_1_process_i_frame(v150_1_state_t *s, const uint8_t buf[], int len)
2500{
2501 int res;
2502 int data_frame_state;
2503
2504 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2505 {
2506 span_log(&s->logging, SPAN_LOG_WARNING, "I_FRAME received before CONNECT. Ignored.\n");
2507 return -1;
2508 }
2509 /*endif*/
2510 if (len < 2)
2511 {
2512 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_FRAME message length %d\n", len);
2513 return -1;
2514 }
2515 /*endif*/
2516 res = (buf[1] >> 2) & 0x3F;
2517 if (res)
2518 span_log(&s->logging, SPAN_LOG_WARNING, "I_FRAME with non-zero 'res' field\n");
2519 /*endif*/
2520 data_frame_state = buf[1] & 0x03;
Value stored to 'data_frame_state' is never read
2521 if (len > 2)
2522 {
2523 if (s->rx_octet_handler)
2524 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[2], len - 2, -1);
2525 /*endif*/
2526 }
2527 /*endif*/
2528 return 0;
2529}
2530/*- End of function --------------------------------------------------------*/
2531
2532static int v150_1_process_i_octet_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2533{
2534 int fill;
2535 int character_seq_no;
2536
2537 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2538 {
2539 span_log(&s->logging, SPAN_LOG_WARNING, "I_OCTET-CS received before CONNECT. Ignored.\n");
2540 return -1;
2541 }
2542 /*endif*/
2543 if (len < 3)
2544 {
2545 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_OCTET-CS message length %d\n", len);
2546 return -1;
2547 }
2548 /*endif*/
2549 character_seq_no = get_net_unaligned_uint16(&buf[1]);
2550 /* Check for a gap in the data */
2551 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2552 if (s->rx_octet_handler)
2553 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[3], len - 3, fill);
2554 /*endif*/
2555 s->far.octet_cs_next_seq_no = (character_seq_no + len - 3) & 0xFFFF;
2556 return 0;
2557}
2558/*- End of function --------------------------------------------------------*/
2559
2560static int v150_1_process_i_char_stat_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2561{
2562 int fill;
2563 int character_seq_no;
2564
2565 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2566 {
2567 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-STAT-CS received before CONNECT. Ignored.\n");
2568 return -1;
2569 }
2570 /*endif*/
2571 if (len < 4)
2572 {
2573 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-STAT-CS message length %d\n", len);
2574 return -1;
2575 }
2576 /*endif*/
2577 if (s->far.data_format_code != buf[1])
2578 {
2579 /* Every packet in a session should have the same data format code */
2580 s->far.data_format_code = buf[1];
2581 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2582 }
2583 /*endif*/
2584 character_seq_no = get_net_unaligned_uint16(&buf[2]);
2585 /* Check for a gap in the data */
2586 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2587 if (s->rx_octet_handler)
2588 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[4], len - 4, fill);
2589 /*endif*/
2590 s->far.octet_cs_next_seq_no = (character_seq_no + len - 4) & 0xFFFF;
2591 return 0;
2592}
2593/*- End of function --------------------------------------------------------*/
2594
2595static int v150_1_process_i_char_dyn_cs(v150_1_state_t *s, const uint8_t buf[], int len)
2596{
2597 int fill;
2598 int character_seq_no;
2599
2600 if (s->joint_connection_state != V150_1_STATE_CONNECTED)
2601 {
2602 span_log(&s->logging, SPAN_LOG_WARNING, "I_CHAR-DYN-CS received before CONNECT. Ignored.\n");
2603 return -1;
2604 }
2605 /*endif*/
2606 if (len < 4)
2607 {
2608 span_log(&s->logging, SPAN_LOG_WARNING, "Invalid I_CHAR-DYN-CS message length %d\n", len);
2609 return -1;
2610 }
2611 /*endif*/
2612 if (s->far.data_format_code != buf[1])
2613 {
2614 s->far.data_format_code = buf[1];
2615 status_report(s, V150_1_STATUS_REASON_DATA_FORMAT_CHANGED);
2616 }
2617 /*endif*/
2618 character_seq_no = get_net_unaligned_uint16(&buf[2]);
2619 /* Check for a gap in the data */
2620 fill = (character_seq_no - s->far.octet_cs_next_seq_no) & 0xFFFF;
2621 if (s->rx_octet_handler)
2622 s->rx_octet_handler(s->rx_octet_handler_user_data, &buf[4], len - 4, fill);
2623 /*endif*/
2624 s->far.octet_cs_next_seq_no = (character_seq_no + len - 4) & 0xFFFF;
2625 return 0;
2626}
2627/*- End of function --------------------------------------------------------*/
2628
2629SPAN_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)
2630{
2631 int res;
2632 int msg_id;
2633
2634 if (chan < SPRT_TCID_MIN || chan > SPRT_TCID_MAX)
2635 {
2636 span_log(&s->logging, SPAN_LOG_ERROR, "Packet arrived on invalid channel %d\n", chan);
2637 return -1;
2638 }
2639 /*endif*/
2640 if ((buf[0] & 0x80))
2641 {
2642 span_log(&s->logging, SPAN_LOG_FLOW, "Don't know how to handle this\n");
2643 return -1;
2644 }
2645 msg_id = buf[0] & 0x7F;
2646 span_log(&s->logging, SPAN_LOG_FLOW, "Message %s received\n", v150_1_msg_id_to_str(msg_id));
2647
2648 if (msg_id < sizeof(channel_check))
2649 {
2650 if ((channel_check[msg_id] & (1 << chan)) == 0)
2651 {
2652 span_log(&s->logging, SPAN_LOG_FLOW, "Bad channel for message ID %d\n", msg_id);
2653 return -1;
2654 }
2655 /*endif*/
2656 }
2657 /*endif*/
2658
2659 switch (msg_id)
2660 {
2661 case V150_1_MSGID_NULL:
2662 res = v150_1_process_null(s, buf, len);
2663 break;
2664 case V150_1_MSGID_INIT:
2665 res = v150_1_process_init(s, buf, len);
2666 break;
2667 case V150_1_MSGID_XID_XCHG:
2668 res = v150_1_process_xid_xchg(s, buf, len);
2669 break;
2670 case V150_1_MSGID_JM_INFO:
2671 res = v150_1_process_jm_info(s, buf, len);
2672 break;
2673 case V150_1_MSGID_START_JM:
2674 res = v150_1_process_start_jm(s, buf, len);
2675 break;
2676 case V150_1_MSGID_CONNECT:
2677 res = v150_1_process_connect(s, buf, len);
2678 break;
2679 case V150_1_MSGID_BREAK:
2680 res = v150_1_process_break(s, buf, len);
2681 break;
2682 case V150_1_MSGID_BREAKACK:
2683 res = v150_1_process_break_ack(s, buf, len);
2684 break;
2685 case V150_1_MSGID_MR_EVENT:
2686 res = v150_1_process_mr_event(s, buf, len);
2687 break;
2688 case V150_1_MSGID_CLEARDOWN:
2689 res = v150_1_process_cleardown(s, buf, len);
2690 break;
2691 case V150_1_MSGID_PROF_XCHG:
2692 res = v150_1_process_prof_xchg(s, buf, len);
2693 break;
2694 case V150_1_MSGID_I_RAW_OCTET:
2695 res = v150_1_process_i_raw_octet(s, buf, len);
2696 break;
2697 case V150_1_MSGID_I_RAW_BIT:
2698 res = v150_1_process_i_raw_bit(s, buf, len);
2699 break;
2700 case V150_1_MSGID_I_OCTET:
2701 res = v150_1_process_i_octet(s, buf, len);
2702 break;
2703 case V150_1_MSGID_I_CHAR_STAT:
2704 res = v150_1_process_i_char_stat(s, buf, len);
2705 break;
2706 case V150_1_MSGID_I_CHAR_DYN:
2707 res = v150_1_process_i_char_dyn(s, buf, len);
2708 break;
2709 case V150_1_MSGID_I_FRAME:
2710 res = v150_1_process_i_frame(s, buf, len);
2711 break;
2712 case V150_1_MSGID_I_OCTET_CS:
2713 res = v150_1_process_i_octet_cs(s, buf, len);
2714 break;
2715 case V150_1_MSGID_I_CHAR_STAT_CS:
2716 res = v150_1_process_i_char_stat_cs(s, buf, len);
2717 break;
2718 case V150_1_MSGID_I_CHAR_DYN_CS:
2719 res = v150_1_process_i_char_dyn_cs(s, buf, len);
2720 break;
2721 default:
2722 span_log(&s->logging, SPAN_LOG_FLOW, "Bad msg ID %d\n", msg_id);
2723 res = -1;
2724 break;
2725 }
2726 /*endswitch*/
2727 if (res < 0)
2728 span_log(&s->logging, SPAN_LOG_FLOW, "Bad message\n");
2729 /*endif*/
2730 return res;
2731}
2732/*- End of function --------------------------------------------------------*/
2733
2734SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_local_busy(v150_1_state_t *s, bool_Bool busy)
2735{
2736 bool_Bool previous_busy;
2737
2738 previous_busy = s->near.busy;
2739 s->near.busy = busy;
2740 return previous_busy;
2741}
2742/*- End of function --------------------------------------------------------*/
2743
2744SPAN_DECLARE(bool)__attribute__((visibility("default"))) _Bool v150_1_get_far_busy_status(v150_1_state_t *s)
2745{
2746 return s->far.busy;
2747}
2748/*- End of function --------------------------------------------------------*/
2749
2750SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_local_tc_payload_bytes(v150_1_state_t *s, int channel, int max_len)
2751{
2752 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2753 return -1;
2754 /*endif*/
2755 if (max_len < channel_parm_limits[channel].min_payload_bytes
2756 ||
2757 max_len > channel_parm_limits[channel].max_payload_bytes)
2758 {
2759 return -1;
2760 }
2761 /*endif*/
2762 s->near.max_payload_bytes[channel] = max_len;
2763 return 0;
2764}
2765/*- End of function --------------------------------------------------------*/
2766
2767SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_get_local_tc_payload_bytes(v150_1_state_t *s, int channel)
2768{
2769 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2770 return -1;
2771 /*endif*/
2772 return s->near.max_payload_bytes[channel];
2773}
2774/*- End of function --------------------------------------------------------*/
2775
2776SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_info_stream_tx_mode(v150_1_state_t *s, int channel, int msg_id)
2777{
2778 if (channel < SPRT_TCID_MIN || channel > SPRT_TCID_MAX)
2779 return -1;
2780 /*endif*/
2781 switch (msg_id)
2782 {
2783 case V150_1_MSGID_I_RAW_OCTET:
2784 case V150_1_MSGID_I_RAW_BIT:
2785 case V150_1_MSGID_I_OCTET:
2786 case V150_1_MSGID_I_CHAR_STAT:
2787 case V150_1_MSGID_I_CHAR_DYN:
2788 case V150_1_MSGID_I_FRAME:
2789 case V150_1_MSGID_I_OCTET_CS:
2790 case V150_1_MSGID_I_CHAR_STAT_CS:
2791 case V150_1_MSGID_I_CHAR_DYN_CS:
2792 s->near.info_stream_channel = channel;
2793 s->near.info_stream_msg_id = msg_id;
2794 break;
2795 default:
2796 return -1;
2797 }
2798 return 0;
2799}
2800/*- End of function --------------------------------------------------------*/
2801
2802SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_info_stream_msg_priorities(v150_1_state_t *s, int msg_ids[])
2803{
2804 int i;
2805
2806 /* Check the list is valid */
2807 for (i = 0; i < 10 && msg_ids[i] >= 0; i++)
2808 {
2809 switch(msg_ids[i])
2810 {
2811 case V150_1_MSGID_I_RAW_OCTET:
2812 case V150_1_MSGID_I_RAW_BIT:
2813 case V150_1_MSGID_I_OCTET:
2814 case V150_1_MSGID_I_CHAR_STAT:
2815 case V150_1_MSGID_I_CHAR_DYN:
2816 case V150_1_MSGID_I_FRAME:
2817 case V150_1_MSGID_I_OCTET_CS:
2818 case V150_1_MSGID_I_CHAR_STAT_CS:
2819 case V150_1_MSGID_I_CHAR_DYN_CS:
2820 /* OK */
2821 break;
2822 default:
2823 return -1;
2824 }
2825 /*endswitch*/
2826 }
2827 /*endfor*/
2828 for (i = 0; i < 10 && msg_ids[i] >= 0; i++)
2829 {
2830 s->near.info_msg_preferences[i] = msg_ids[i];
2831 }
2832 /*endfor*/
2833 if (i < 10)
2834 s->near.info_msg_preferences[i] = -1;
2835 /*endif*/
2836 return 0;
2837}
2838/*- End of function --------------------------------------------------------*/
2839
2840SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_modulation(v150_1_state_t *s, int modulation)
2841{
2842 s->near.selmod = modulation;
2843 return 0;
2844}
2845/*- End of function --------------------------------------------------------*/
2846
2847SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression_direction(v150_1_state_t *s, int compression_direction)
2848{
2849 s->near.selected_compression_direction = compression_direction;
2850 return 0;
2851}
2852/*- End of function --------------------------------------------------------*/
2853
2854SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression(v150_1_state_t *s, int compression)
2855{
2856 s->near.selected_compression = compression;
2857 return 0;
2858}
2859/*- End of function --------------------------------------------------------*/
2860
2861SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_compression_parameters(v150_1_state_t *s,
2862 int tx_dictionary_size,
2863 int rx_dictionary_size,
2864 int tx_string_length,
2865 int rx_string_length,
2866 int tx_history_size,
2867 int rx_history_size)
2868{
2869 s->near.compression_tx_dictionary_size = tx_dictionary_size;
2870 s->near.compression_rx_dictionary_size = rx_dictionary_size;
2871 s->near.compression_tx_string_length = tx_string_length;
2872 s->near.compression_rx_string_length = rx_string_length;
2873 /* These are only relevant for V.44 */
2874 s->near.compression_tx_history_size = tx_history_size;
2875 s->near.compression_rx_history_size = rx_history_size;
2876 return 0;
2877}
2878/*- End of function --------------------------------------------------------*/
2879
2880SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_error_correction(v150_1_state_t *s, int error_correction)
2881{
2882 s->near.selected_error_correction = error_correction;
2883 return 0;
2884}
2885/*- End of function --------------------------------------------------------*/
2886
2887SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_tx_symbol_rate(v150_1_state_t *s, bool_Bool enable, int rate)
2888{
2889 s->near.txsen = enable;
2890 s->near.txsr = (enable) ? rate : 0;
2891 return 0;
2892}
2893/*- End of function --------------------------------------------------------*/
2894
2895SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_rx_symbol_rate(v150_1_state_t *s, bool_Bool enable, int rate)
2896{
2897 s->near.rxsen = enable;
2898 s->near.rxsr = (enable) ? rate : 0;
2899 return 0;
2900}
2901/*- End of function --------------------------------------------------------*/
2902
2903SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_tx_data_signalling_rate(v150_1_state_t *s, int rate)
2904{
2905 s->near.tdsr = rate;
2906 return 0;
2907}
2908/*- End of function --------------------------------------------------------*/
2909
2910SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_set_rx_data_signalling_rate(v150_1_state_t *s, int rate)
2911{
2912 s->near.rdsr = rate;
2913 return 0;
2914}
2915/*- End of function --------------------------------------------------------*/
2916
2917SPAN_DECLARE(logging_state_t *)__attribute__((visibility("default"))) logging_state_t * v150_1_get_logging_state(v150_1_state_t *s)
2918{
2919 return &s->logging;
2920}
2921/*- End of function --------------------------------------------------------*/
2922
2923SPAN_DECLARE(v150_1_state_t *)__attribute__((visibility("default"))) v150_1_state_t * v150_1_init(v150_1_state_t *s,
2924 v150_1_tx_packet_handler_t tx_packet_handler,
2925 void *tx_packet_user_data,
2926 v150_1_rx_packet_handler_t rx_packet_handler,
2927 void *rx_packet_user_data,
2928 v150_1_rx_octet_handler_t rx_octet_handler,
2929 void *rx_octet_handler_user_data,
2930 v150_1_rx_status_report_handler_t rx_status_report_handler,
2931 void *rx_status_report_user_data)
2932{
2933 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))
2934 return NULL((void*)0);
2935 /*endif*/
2936 if (s == NULL((void*)0))
2937 {
2938 if ((s = (v150_1_state_t *) malloc(sizeof(*s))) == NULL((void*)0))
2939 return NULL((void*)0);
2940 /*endif*/
2941 }
2942 /*endif*/
2943 memset(s, 0, sizeof(*s));
2944
2945 span_log_init(&s->logging, SPAN_LOG_NONE, NULL((void*)0));
2946 span_log_set_protocol(&s->logging, "V.150.1");
2947
2948 s->near.max_payload_bytes[SPRT_TCID_UNRELIABLE_UNSEQUENCED] = SPRT_DEFAULT_TC0_PAYLOAD_BYTES140;
2949 s->near.max_payload_bytes[SPRT_TCID_RELIABLE_SEQUENCED] = SPRT_DEFAULT_TC1_PAYLOAD_BYTES132;
2950 s->near.max_payload_bytes[SPRT_TCID_EXPEDITED_RELIABLE_SEQUENCED] = SPRT_DEFAULT_TC2_PAYLOAD_BYTES132;
2951 s->near.max_payload_bytes[SPRT_TCID_UNRELIABLE_SEQUENCED] = SPRT_DEFAULT_TC3_PAYLOAD_BYTES140;
2952
2953 s->near.v42bis_p0 = 3;
2954 s->near.v42bis_p1 = 512;
2955 s->near.v42bis_p2 = 6;
2956 s->near.v44_c0 = 0;
2957 s->near.v44_p0 = 0;
2958 s->near.v44_p1t = 0;
2959 s->near.v44_p1r = 0;
2960 s->near.v44_p2t = 0;
2961 s->near.v44_p2r = 0;
2962 s->near.v44_p3t = 0;
2963 s->near.v44_p3r = 0;
2964
2965 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_CALL_FUNCTION_1] = true1;
2966 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_CALL_FUNCTION_1] = V150_1_JM_CALL_FUNCTION_V_SERIES;
2967 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_MODULATION_MODES] = true1;
2968 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_MODULATION_MODES] =
2969 V150_1_JM_MODULATION_MODE_V34_AVAILABLE
2970 | V150_1_JM_MODULATION_MODE_V32_V32bis_AVAILABLE
2971 | V150_1_JM_MODULATION_MODE_V22_V22bis_AVAILABLE
2972 | V150_1_JM_MODULATION_MODE_V21_AVAILABLE;
2973 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PROTOCOLS] = true1;
2974 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PROTOCOLS] = V150_1_JM_PROTOCOL_V42_LAPM;
2975 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PSTN_ACCESS] = true1;
2976 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PSTN_ACCESS] = 0;
2977 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_PCM_MODEM_AVAILABILITY] = false0;
2978 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_PCM_MODEM_AVAILABILITY] = 0;
2979 s->near.jm_category_id_seen[V150_1_JM_CATEGORY_ID_EXTENSION] = false0;
2980 s->near.jm_category_info[V150_1_JM_CATEGORY_ID_EXTENSION] = 0;
2981
2982 s->near.selmod = V150_1_SELMOD_NULL;
2983 s->near.selected_compression_direction = V150_1_COMPRESS_NEITHER_WAY;
2984 s->near.selected_compression = V150_1_COMPRESSION_NONE;
2985 s->near.selected_error_correction = V150_1_ERROR_CORRECTION_NONE;
2986 s->near.tdsr = 0;
2987 s->near.rdsr = 0;
2988 s->near.txsen = false0;
2989 s->near.txsr = V150_1_SYMBOL_RATE_NULL;
2990 s->near.rxsen = false0;
2991 s->near.rxsr = V150_1_SYMBOL_RATE_NULL;
2992
2993 /* Set default values that suit V.42bis */
2994 s->near.compression_tx_dictionary_size = 512;
2995 s->near.compression_rx_dictionary_size = 512;
2996 s->near.compression_tx_string_length = 6;
2997 s->near.compression_rx_string_length = 6;
2998 s->near.compression_tx_history_size = 0;
2999 s->near.compression_rx_history_size = 0;
3000
3001 s->near.ecp = V150_1_ERROR_CORRECTION_V42_LAPM;
3002 s->near.v42_lapm_supported = true1;
3003 s->near.v42_annex_a_supported = false0; /* This will never be supported, as it was removed from the V.42 spec in 2002. */
3004 s->near.v42bis_supported = true1;
3005 s->near.v44_supported = false0;
3006 s->near.mnp5_supported = false0;
3007
3008 s->near.necrxch_option = false0;
3009 s->near.ecrxch_option = true1;
3010 s->near.xid_profile_exchange_supported = false0;
3011 s->near.asymmetric_data_types_supported = false0;
3012
3013 s->near.i_raw_bit_supported = false0;
3014 s->near.i_frame_supported = false0;
3015 s->near.i_char_stat_supported = false0;
3016 s->near.i_char_dyn_supported = false0;
3017 s->near.i_octet_cs_supported = true1;
3018 s->near.i_char_stat_cs_supported = false0;
3019 s->near.i_char_dyn_cs_supported = false0;
3020
3021 /* Set a default character format. */
3022 s->near.data_format_code = (V150_1_DATA_BITS_7 << 6)
3023 | (V150_1_PARITY_EVEN << 3)
3024 | V150_1_STOP_BITS_1;
3025 s->far.data_format_code = -1;
3026
3027 s->tx_packet_handler = tx_packet_handler;
3028 s->tx_packet_user_data = tx_packet_user_data;
3029 s->rx_packet_handler = rx_packet_handler;
3030 s->rx_packet_user_data = rx_packet_user_data;
3031 s->rx_octet_handler = rx_octet_handler;
3032 s->rx_octet_handler_user_data = rx_octet_handler_user_data;
3033 s->rx_status_report_handler = rx_status_report_handler;
3034 s->rx_status_report_user_data = rx_status_report_user_data;
3035
3036 return s;
3037}
3038/*- End of function --------------------------------------------------------*/
3039
3040SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_release(v150_1_state_t *s)
3041{
3042 return 0;
3043}
3044/*- End of function --------------------------------------------------------*/
3045
3046SPAN_DECLARE(int)__attribute__((visibility("default"))) int v150_1_free(v150_1_state_t *s)
3047{
3048 int ret;
3049
3050 ret = v150_1_release(s);
3051 span_free(s);
3052 return ret;
3053}
3054/*- End of function --------------------------------------------------------*/
3055/*- End of file ------------------------------------------------------------*/