2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@digium.com>
6 * Copyright (C) 2001, Digium, Inc.
8 * Copyright (C) 2003-2006 Junghanns.NET GmbH
9 * Klaus-Peter Junghanns <kpj@junghanns.net>
13 * See http://www.asterisk.org for more information about
14 * the Asterisk project. Please do not directly contact
15 * any of the maintainers of this project for assistance;
16 * the project provides a web site, mailing lists and IRC
17 * channels for your use.
19 * This program is free software, distributed under the terms of
20 * the GNU General Public License Version 2 as published by the
21 * Free Software Foundation. See the LICENSE file included with
22 * this program for more details.
28 #include <sys/types.h>
29 #if defined(__linux__)
31 #elif defined(__FreeBSD__)
32 #include <sys/endian.h>
33 #define __BYTE_ORDER _BYTE_ORDER
34 #define __BIG_ENDIAN _BIG_ENDIAN
35 #define __LITTLE_ENDIAN _LITTLE_ENDIAN
40 #define T_WAIT_MIN 2000
41 #define T_WAIT_MAX 10000
43 #define Q921_FRAMETYPE_MASK 0x3
45 #define Q921_FRAMETYPE_U 0x3
46 #define Q921_FRAMETYPE_I 0x0
47 #define Q921_FRAMETYPE_S 0x1
49 #define Q921_TEI_GROUP 127
50 #define Q921_TEI_ID_REQUEST 0x1
51 #define Q921_TEI_ID_ASSIGNED 0x2
52 #define Q921_TEI_ID_DENIED 0x3
53 #define Q921_TEI_ID_CHK_REQ 0x4
54 #define Q921_TEI_ID_CHK_RES 0x5
55 #define Q921_TEI_ID_REMOVE 0x6
56 #define Q921_TEI_ID_VERIFY 0x7
57 #define Q921_TEI_GR303_EOC_PATH 0
58 #define Q921_TEI_GR303_EOC_OPS 4
59 #define Q921_TEI_GR303_TMC_SWITCHING 0
60 #define Q921_TEI_GR303_TMC_CALLPROC 0
62 #define Q921_SAPI_CALL_CTRL 0
63 #define Q921_SAPI_GR303_EOC 1
64 #define Q921_SAPI_GR303_TMC_SWITCHING 1
65 #define Q921_SAPI_GR303_TMC_CALLPROC 0
68 #define Q921_SAPI_PACKET_MODE 1
69 #define Q921_SAPI_X25_LAYER3 16
70 #define Q921_SAPI_LAYER2_MANAGEMENT 63
73 typedef struct q921_header
{
74 #if __BYTE_ORDER == __BIG_ENDIAN
75 u_int8_t sapi
:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
76 u_int8_t c_r
:1; /* Command/Response (0 if CPE, 1 if network) */
77 u_int8_t ea1
:1; /* Extended Address (0) */
78 u_int8_t tei
:7; /* Terminal Endpoint Identifier (0) */
79 u_int8_t ea2
:1; /* Extended Address Bit (1) */
81 u_int8_t ea1
:1; /* Extended Address (0) */
82 u_int8_t c_r
:1; /* Command/Response (0 if CPE, 1 if network) */
83 u_int8_t sapi
:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
84 u_int8_t ea2
:1; /* Extended Address Bit (1) */
85 u_int8_t tei
:7; /* Terminal Endpoint Identifier (0) */
87 u_int8_t data
[0]; /* Further data */
88 } __attribute__ ((packed
)) q921_header
;
90 /* A Supervisory Format frame */
91 typedef struct q921_s
{
92 struct q921_header h
; /* Header */
93 #if __BYTE_ORDER == __BIG_ENDIAN
94 u_int8_t x0
:4; /* Unused */
95 u_int8_t ss
:2; /* Supervisory frame bits */
96 u_int8_t ft
:2; /* Frame type bits (01) */
97 u_int8_t n_r
:7; /* Number Received */
98 u_int8_t p_f
:1; /* Poll/Final bit */
100 u_int8_t ft
:2; /* Frame type bits (01) */
101 u_int8_t ss
:2; /* Supervisory frame bits */
102 u_int8_t x0
:4; /* Unused */
103 u_int8_t p_f
:1; /* Poll/Final bit */
104 u_int8_t n_r
:7; /* Number Received */
106 u_int8_t data
[0]; /* Any further data */
107 u_int8_t fcs
[2]; /* At least an FCS */
108 } __attribute__ ((packed
)) q921_s
;
110 /* An Unnumbered Format frame */
111 typedef struct q921_u
{
112 struct q921_header h
; /* Header */
113 #if __BYTE_ORDER == __BIG_ENDIAN
114 u_int8_t m3
:3; /* Top 3 modifier bits */
115 u_int8_t p_f
:1; /* Poll/Final bit */
116 u_int8_t m2
:2; /* Two more modifier bits */
117 u_int8_t ft
:2; /* Frame type bits (11) */
119 u_int8_t ft
:2; /* Frame type bits (11) */
120 u_int8_t m2
:2; /* Two more modifier bits */
121 u_int8_t p_f
:1; /* Poll/Final bit */
122 u_int8_t m3
:3; /* Top 3 modifier bits */
124 u_int8_t data
[0]; /* Any further data */
125 u_int8_t fcs
[2]; /* At least an FCS */
126 } __attribute__ ((packed
)) q921_u
;
128 /* An Information frame */
129 typedef struct q921_i
{
130 struct q921_header h
; /* Header */
131 #if __BYTE_ORDER == __BIG_ENDIAN
132 u_int8_t n_s
:7; /* Number sent */
133 u_int8_t ft
:1; /* Frame type (0) */
134 u_int8_t n_r
:7; /* Number received */
135 u_int8_t p_f
:1; /* Poll/Final bit */
137 u_int8_t ft
:1; /* Frame type (0) */
138 u_int8_t n_s
:7; /* Number sent */
139 u_int8_t p_f
:1; /* Poll/Final bit */
140 u_int8_t n_r
:7; /* Number received */
142 u_int8_t data
[0]; /* Any further data */
143 u_int8_t fcs
[2]; /* At least an FCS */
151 struct q921_header h
;
154 typedef struct q921_frame
{
155 struct q921_frame
*next
; /* Next in list */
156 int len
; /* Length of header + body */
157 int transmitted
; /* Have we been transmitted */
161 #define Q921_INC(j) (j) = (((j) + 1) % 128)
163 typedef enum q921_state
{
164 Q921_LINK_CONNECTION_RELEASED
, /* Also known as TEI_ASSIGNED */
165 Q921_LINK_CONNECTION_ESTABLISHED
,
166 Q921_AWAITING_ESTABLISH
,
167 Q921_AWAITING_RELEASE
170 /* Dumps a *known good* Q.921 packet */
171 extern void q921_dump(struct pri
*pri
, q921_h
*h
, int len
, int showraw
, int txrx
);
173 /* Bring up the D-channel */
174 extern void q921_start(struct pri
*pri
, int now
, int tei
);
176 extern void q921_reset(struct pri
*pri
, int tei
, int discard
);
178 extern pri_event
*q921_receive(struct pri
*pri
, q921_h
*h
, int len
);
180 extern int q921_transmit_uframe(struct pri
*pri
, void *buf
, int len
, int cr
, int tei
);
182 extern int q921_transmit_iframe(struct pri
*pri
, void *buf
, int len
, int cr
, int tei
);