1 /*
2 * libpri: An implementation of Primary Rate ISDN
3 *
4 * Written by Mark Spencer <markster@digium.com>
5 *
6 * Copyright (C) 2001, Digium, Inc.
7 * All Rights Reserved.
8 */
9
10 /*
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
16 *
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2 as published by the
19 * Free Software Foundation. See the LICENSE file included with
20 * this program for more details.
21 *
22 * In addition, when this program is distributed with Asterisk in
23 * any form that would qualify as a 'combined work' or as a
24 * 'derivative work' (but not mere aggregation), you can redistribute
25 * and/or modify the combination under the terms of the license
26 * provided with that copy of Asterisk, instead of the license
27 * terms granted here.
28 */
29
30 #ifndef _PRI_Q921_H
31 #define _PRI_Q921_H
32
33 #include <sys/types.h>
34 #if defined(__linux__)
35 #include <endian.h>
36 #elif defined(__FreeBSD__)
37 #include <sys/endian.h>
38 #define __BYTE_ORDER _BYTE_ORDER
39 #define __BIG_ENDIAN _BIG_ENDIAN
40 #define __LITTLE_ENDIAN _LITTLE_ENDIAN
41 #endif
42
43 /* Timer values */
44
45 #define T_WAIT_MIN 2000
46 #define T_WAIT_MAX 10000
47
48 #define Q921_FRAMETYPE_MASK 0x3
49
50 #define Q921_FRAMETYPE_U 0x3
51 #define Q921_FRAMETYPE_I 0x0
52 #define Q921_FRAMETYPE_S 0x1
53
54 #define Q921_TEI_GROUP 127
55 #define Q921_TEI_PRI 0
56 #define Q921_TEI_GR303_EOC_PATH 0
57 #define Q921_TEI_GR303_EOC_OPS 4
58 #define Q921_TEI_GR303_TMC_SWITCHING 0
59 #define Q921_TEI_GR303_TMC_CALLPROC 0
60 #define Q921_TEI_AUTO_FIRST 64
61 #define Q921_TEI_AUTO_LAST 126
62
63 #define Q921_SAPI_CALL_CTRL 0
64 #define Q921_SAPI_GR303_EOC 1
65 #define Q921_SAPI_GR303_TMC_SWITCHING 1
66 #define Q921_SAPI_GR303_TMC_CALLPROC 0
67
68
69 #define Q921_SAPI_PACKET_MODE 1
70 #define Q921_SAPI_X25_LAYER3 16
71 #define Q921_SAPI_LAYER2_MANAGEMENT 63
72
73
74 /*! Q.921 TEI management message type */
75 enum q921_tei_identity {
76 Q921_TEI_IDENTITY_REQUEST = 1,
77 Q921_TEI_IDENTITY_ASSIGNED = 2,
78 Q921_TEI_IDENTITY_DENIED = 3,
79 Q921_TEI_IDENTITY_CHECK_REQUEST = 4,
80 Q921_TEI_IDENTITY_CHECK_RESPONSE = 5,
81 Q921_TEI_IDENTITY_REMOVE = 6,
82 Q921_TEI_IDENTITY_VERIFY = 7,
83 };
84
85 typedef struct q921_header {
86 #if __BYTE_ORDER == __BIG_ENDIAN
87 u_int8_t sapi:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
88 u_int8_t c_r:1; /* Command/Response (0 if CPE, 1 if network) */
89 u_int8_t ea1:1; /* Extended Address (0) */
90 u_int8_t tei:7; /* Terminal Endpoint Identifier (0) */
91 u_int8_t ea2:1; /* Extended Address Bit (1) */
92 #else
93 u_int8_t ea1:1; /* Extended Address (0) */
94 u_int8_t c_r:1; /* Command/Response (0 if CPE, 1 if network) */
95 u_int8_t sapi:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
96 u_int8_t ea2:1; /* Extended Address Bit (1) */
97 u_int8_t tei:7; /* Terminal Endpoint Identifier (0) */
98 #endif
99 u_int8_t data[0]; /* Further data */
100 } __attribute__ ((packed)) q921_header;
101
102 /* A Supervisory Format frame */
103 typedef struct q921_s {
104 struct q921_header h; /* Header */
105 #if __BYTE_ORDER == __BIG_ENDIAN
106 u_int8_t x0:4; /* Unused */
107 u_int8_t ss:2; /* Supervisory frame bits */
108 u_int8_t ft:2; /* Frame type bits (01) */
109 u_int8_t n_r:7; /* Number Received */
110 u_int8_t p_f:1; /* Poll/Final bit */
111 #else
112 u_int8_t ft:2; /* Frame type bits (01) */
113 u_int8_t ss:2; /* Supervisory frame bits */
114 u_int8_t x0:4; /* Unused */
115 u_int8_t p_f:1; /* Poll/Final bit */
116 u_int8_t n_r:7; /* Number Received */
117 #endif
118 u_int8_t data[0]; /* Any further data */
119 u_int8_t fcs[2]; /* At least an FCS */
120 } __attribute__ ((packed)) q921_s;
121
122 /* An Unnumbered Format frame */
123 typedef struct q921_u {
124 struct q921_header h; /* Header */
125 #if __BYTE_ORDER == __BIG_ENDIAN
126 u_int8_t m3:3; /* Top 3 modifier bits */
127 u_int8_t p_f:1; /* Poll/Final bit */
128 u_int8_t m2:2; /* Two more modifier bits */
129 u_int8_t ft:2; /* Frame type bits (11) */
130 #else
131 u_int8_t ft:2; /* Frame type bits (11) */
132 u_int8_t m2:2; /* Two more modifier bits */
133 u_int8_t p_f:1; /* Poll/Final bit */
134 u_int8_t m3:3; /* Top 3 modifier bits */
135 #endif
136 u_int8_t data[0]; /* Any further data */
137 u_int8_t fcs[2]; /* At least an FCS */
138 } __attribute__ ((packed)) q921_u;
139
140 /* An Information frame */
141 typedef struct q921_i {
142 struct q921_header h; /* Header */
143 #if __BYTE_ORDER == __BIG_ENDIAN
144 u_int8_t n_s:7; /* Number sent */
145 u_int8_t ft:1; /* Frame type (0) */
146 u_int8_t n_r:7; /* Number received */
147 u_int8_t p_f:1; /* Poll/Final bit */
148 #else
149 u_int8_t ft:1; /* Frame type (0) */
150 u_int8_t n_s:7; /* Number sent */
151 u_int8_t p_f:1; /* Poll/Final bit */
152 u_int8_t n_r:7; /* Number received */
153 #endif
154 u_int8_t data[0]; /* Any further data */
155 u_int8_t fcs[2]; /* At least an FCS */
156 } q921_i;
157
158 typedef union {
159 u_int8_t raw[0];
160 q921_u u;
161 q921_s s;
162 q921_i i;
163 struct q921_header h;
164 } q921_h;
165
166 enum q921_tx_frame_status {
167 Q921_TX_FRAME_NEVER_SENT,
168 Q921_TX_FRAME_PUSHED_BACK,
169 Q921_TX_FRAME_SENT,
170 };
171
172 typedef struct q921_frame {
173 struct q921_frame *next; /*!< Next in list */
174 int len; /*!< Length of header + body */
175 enum q921_tx_frame_status status; /*!< Tx frame status */
176 q921_i h; /*!< Actual frame contents. */
177 } q921_frame;
178
179 #define Q921_INC(j) (j) = (((j) + 1) % 128)
180 #define Q921_DEC(j) (j) = (((j) - 1) % 128)
181
182 typedef enum q921_state {
183 /* All states except Q921_DOWN are defined in Q.921 SDL diagrams */
184 Q921_TEI_UNASSIGNED = 1,
185 Q921_ASSIGN_AWAITING_TEI = 2,
186 Q921_ESTABLISH_AWAITING_TEI = 3,
187 Q921_TEI_ASSIGNED = 4,
188 Q921_AWAITING_ESTABLISHMENT = 5,
189 Q921_AWAITING_RELEASE = 6,
190 Q921_MULTI_FRAME_ESTABLISHED = 7,
191 Q921_TIMER_RECOVERY = 8,
192 } q921_state;
193
194 /*! TEI identity check procedure states. */
195 enum q921_tei_check_state {
196 /*! Not participating in the TEI check procedure. */
197 Q921_TEI_CHECK_NONE,
198 /*! No reply to TEI check received. */
199 Q921_TEI_CHECK_DEAD,
200 /*! Reply to TEI check received in current poll. */
201 Q921_TEI_CHECK_REPLY,
202 /*! No reply to current TEI check poll received. A previous poll got a reply. */
203 Q921_TEI_CHECK_DEAD_REPLY,
204 };
205
206 /*! \brief Q.921 link controller structure */
207 struct q921_link {
208 /*! Next Q.921 link in the chain. */
209 struct q921_link *next;
210 /*! D channel controller associated with this link. */
211 struct pri *ctrl;
212
213 /*!
214 * \brief Q.931 Dummy call reference call associated with this TEI.
215 *
216 * \note If present then this call is allocated with the D
217 * channel control structure or the link control structure
218 * unless this is the TE PTMP broadcast TEI or a GR303 link.
219 */
220 struct q931_call *dummy_call;
221
222 /*! Q.921 Re-transmission queue */
223 struct q921_frame *tx_queue;
224
225 /*! Q.921 State */
226 enum q921_state state;
227
228 /*! TEI identity check procedure state. */
229 enum q921_tei_check_state tei_check;
230
231 /*! Service Access Profile Identifier (SAPI) of this link */
232 int sapi;
233 /*! Terminal Endpoint Identifier (TEI) of this link */
234 int tei;
235 /*! TEI assignment random indicator. */
236 int ri;
237
238 /*! V(A) - Next I-frame sequence number needing ack */
239 int v_a;
240 /*! V(S) - Next I-frame sequence number to send */
241 int v_s;
242 /*! V(R) - Next I-frame sequence number expected to receive */
243 int v_r;
244
245 /* Various timers */
246
247 /*! T-200 retransmission timer */
248 int t200_timer;
249 /*! Retry Count (T200) */
250 int RC;
251 int t202_timer;
252 int n202_counter;
253 /*! Max idle time */
254 int t203_timer;
255 /*! Layer 2 persistence restart delay timer */
256 int restart_timer;
257
258 /* MDL variables */
259 int mdl_timer;
260 int mdl_error;
261 unsigned int mdl_free_me:1;
262
263 unsigned int peer_rx_busy:1;
264 unsigned int own_rx_busy:1;
265 unsigned int acknowledge_pending:1;
266 unsigned int reject_exception:1;
267 unsigned int l3_initiated:1;
268 };
269
Q921_ADD(int a,int b)270 static inline int Q921_ADD(int a, int b)
271 {
272 return (a + b) % 128;
273 }
274
275 /* Dumps a *known good* Q.921 packet */
276 extern void q921_dump(struct pri *pri, q921_h *h, int len, int debugflags, int txrx);
277
278 /* Bring up the D-channel */
279 void q921_start(struct q921_link *link);
280 void q921_bring_layer2_up(struct pri *ctrl);
281
282 //extern void q921_reset(struct pri *pri, int reset_iqueue);
283
284 extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
285
286 int q921_transmit_iframe(struct q921_link *link, void *buf, int len, int cr);
287
288 int q921_transmit_uiframe(struct q921_link *link, void *buf, int len);
289
290 extern pri_event *q921_dchannel_up(struct pri *pri);
291
292 //extern pri_event *q921_dchannel_down(struct pri *pri);
293
294 #endif
295