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