1 /*
2  * Copyright (c) 1996-2003
3  *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4  * 	All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * Author: Hartmut Brandt <[email protected]>
28  *
29  * $Begemot: libunimsg/netnatm/sig/unipriv.h,v 1.17 2004/07/08 08:22:25 brandt Exp $
30  *
31  * Private UNI stuff.
32  */
33 #ifndef unipriv_h
34 #define unipriv_h
35 
36 #ifdef _KERNEL
37 #ifdef __FreeBSD__
38 #include <netgraph/atm/uni/ng_uni_cust.h>
39 #endif
40 #else
41 #include "unicust.h"
42 #endif
43 
44 struct call;
45 struct party;
46 
47 enum cu_stat {
48 	CU_STAT0,	/* AAL connection released */
49 	CU_STAT1,	/* awaiting establish */
50 	CU_STAT2,	/* awaiting release */
51 	CU_STAT3,	/* AAL connection established */
52 };
53 
54 /*
55  * Internal Signals
56  */
57 #define DEF_COORD_SIGS						\
58   DEF_PRIV_SIG(O_SAAL_ESTABLISH_indication,	SAAL)		\
59   DEF_PRIV_SIG(O_SAAL_ESTABLISH_confirm,	SAAL)		\
60   DEF_PRIV_SIG(O_SAAL_RELEASE_indication,	SAAL)		\
61   DEF_PRIV_SIG(O_SAAL_RELEASE_confirm,		SAAL)		\
62   DEF_PRIV_SIG(O_SAAL_DATA_indication,		SAAL)		\
63   DEF_PRIV_SIG(O_SAAL_UDATA_indication,		SAAL)		\
64   DEF_PRIV_SIG(O_T309,				Coord)		\
65   DEF_PRIV_SIG(O_DATA,				Coord)		\
66   DEF_PRIV_SIG(O_LINK_ESTABLISH_request,	API)		\
67   DEF_PRIV_SIG(O_LINK_RELEASE_request,		API)		\
68   DEF_PRIV_SIG(O_RESET_request,			API)		\
69   DEF_PRIV_SIG(O_RESET_response,		API)		\
70   DEF_PRIV_SIG(O_RESET_ERROR_response,		API)		\
71   DEF_PRIV_SIG(O_SETUP_request,			API)		\
72   DEF_PRIV_SIG(O_SETUP_response,		API)		\
73   DEF_PRIV_SIG(O_SETUP_COMPLETE_request,	API)		\
74   DEF_PRIV_SIG(O_PROCEEDING_request,		API)		\
75   DEF_PRIV_SIG(O_ALERTING_request,		API)		\
76   DEF_PRIV_SIG(O_RELEASE_request,		API)		\
77   DEF_PRIV_SIG(O_RELEASE_response,		API)		\
78   DEF_PRIV_SIG(O_NOTIFY_request,		API)		\
79   DEF_PRIV_SIG(O_STATUS_ENQUIRY_request,	API)		\
80   DEF_PRIV_SIG(O_ADD_PARTY_request,		API)		\
81   DEF_PRIV_SIG(O_PARTY_ALERTING_request,	API)		\
82   DEF_PRIV_SIG(O_ADD_PARTY_ACK_request,		API)		\
83   DEF_PRIV_SIG(O_ADD_PARTY_REJ_request,		API)		\
84   DEF_PRIV_SIG(O_DROP_PARTY_request,		API)		\
85   DEF_PRIV_SIG(O_DROP_PARTY_ACK_request,	API)		\
86   DEF_PRIV_SIG(O_ABORT_CALL_request,		API)		\
87   DEF_PRIV_SIG(O_CALL_DESTROYED,		CallControl)	\
88   DEF_PRIV_SIG(O_RESET_indication,		ResetRespond)	\
89   DEF_PRIV_SIG(O_END,				Coord)
90 
91 #define DEF_RESPOND_SIGS					\
92   DEF_PRIV_SIG(R_RESTART,			Coord)		\
93   DEF_PRIV_SIG(R_STATUS,			Coord)		\
94   DEF_PRIV_SIG(R_RESET_response,		Coord)		\
95   DEF_PRIV_SIG(R_RESET_ERROR_response,		Coord)		\
96   DEF_PRIV_SIG(R_T317,				ResetRespond)	\
97   DEF_PRIV_SIG(R_END,				ResetRespond)
98 
99 #define DEF_START_SIGS						\
100   DEF_PRIV_SIG(S_RESTART_ACK,			Coord)		\
101   DEF_PRIV_SIG(S_STATUS,			Coord)		\
102   DEF_PRIV_SIG(S_RESET_request,			Coord)		\
103   DEF_PRIV_SIG(S_T316,				ResetStart)	\
104   DEF_PRIV_SIG(S_END,				ResetStart)
105 
106 #define DEF_CALL_SIGS						\
107   DEF_PRIV_SIG(C_LINK_ESTABLISH_confirm,	Coord)		\
108   DEF_PRIV_SIG(C_LINK_ESTABLISH_indication,	Coord)		\
109   DEF_PRIV_SIG(C_LINK_ESTABLISH_ERROR_indication,Coord)		\
110   DEF_PRIV_SIG(C_LINK_RELEASE_indication,	Coord)		\
111   DEF_PRIV_SIG(C_SETUP_request,			Coord)		\
112   DEF_PRIV_SIG(C_SETUP_response,		Coord)		\
113   DEF_PRIV_SIG(C_SETUP_COMPLETE_request,	Coord)		\
114   DEF_PRIV_SIG(C_PROCEEDING_request,		Coord)		\
115   DEF_PRIV_SIG(C_ALERTING_request,		Coord)		\
116   DEF_PRIV_SIG(C_RELEASE_request,		Coord)		\
117   DEF_PRIV_SIG(C_RELEASE_response,		Coord)		\
118   DEF_PRIV_SIG(C_NOTIFY_request,		Coord)		\
119   DEF_PRIV_SIG(C_STATUS_ENQUIRY_request,	Coord)		\
120   DEF_PRIV_SIG(C_ADD_PARTY_request,		Coord)		\
121   DEF_PRIV_SIG(C_PARTY_ALERTING_request,	Coord)		\
122   DEF_PRIV_SIG(C_ADD_PARTY_ACK_request,		Coord)		\
123   DEF_PRIV_SIG(C_ADD_PARTY_REJ_request,		Coord)		\
124   DEF_PRIV_SIG(C_DROP_PARTY_request,		Coord)		\
125   DEF_PRIV_SIG(C_DROP_PARTY_ACK_request,	Coord)		\
126   DEF_PRIV_SIG(C_ABORT_CALL_request,		Coord)		\
127   DEF_PRIV_SIG(C_UNKNOWN,			Coord)		\
128   DEF_PRIV_SIG(C_SETUP,				Coord)		\
129   DEF_PRIV_SIG(C_CALL_PROC,			Coord)		\
130   DEF_PRIV_SIG(C_ALERTING,			Coord)		\
131   DEF_PRIV_SIG(C_CONNECT,			Coord)		\
132   DEF_PRIV_SIG(C_CONNECT_ACK,			Coord)		\
133   DEF_PRIV_SIG(C_RELEASE,			Coord)		\
134   DEF_PRIV_SIG(C_RELEASE_COMPL,			Coord)		\
135   DEF_PRIV_SIG(C_COBISETUP,			Coord)		\
136   DEF_PRIV_SIG(C_NOTIFY,			Coord)		\
137   DEF_PRIV_SIG(C_STATUS,			Coord)		\
138   DEF_PRIV_SIG(C_STATUS_ENQ,			Coord)		\
139   DEF_PRIV_SIG(C_ADD_PARTY,			Coord)		\
140   DEF_PRIV_SIG(C_PARTY_ALERTING,		Coord)		\
141   DEF_PRIV_SIG(C_ADD_PARTY_ACK,			Coord)		\
142   DEF_PRIV_SIG(C_ADD_PARTY_REJ,			Coord)		\
143   DEF_PRIV_SIG(C_DROP_PARTY,			Coord)		\
144   DEF_PRIV_SIG(C_DROP_PARTY_ACK,		Coord)		\
145   DEF_PRIV_SIG(C_CALL_DELETE,			CallControl)	\
146   DEF_PRIV_SIG(C_T301,				CallControl)	\
147   DEF_PRIV_SIG(C_T303,				CallControl)	\
148   DEF_PRIV_SIG(C_T308,				CallControl)	\
149   DEF_PRIV_SIG(C_T310,				CallControl)	\
150   DEF_PRIV_SIG(C_T313,				CallControl)	\
151   DEF_PRIV_SIG(C_T322,				CallControl)	\
152   DEF_PRIV_SIG(C_DROP_PARTY_indication,		PartyControl)	\
153   DEF_PRIV_SIG(C_SEND_DROP_PARTY,		PartyControl)	\
154   DEF_PRIV_SIG(C_DROP_PARTY_ACK_indication,	PartyControl)	\
155   DEF_PRIV_SIG(C_SEND_DROP_PARTY_ACK,		PartyControl)	\
156   DEF_PRIV_SIG(C_ADD_PARTY_REJ_indication,	PartyControl)	\
157   DEF_PRIV_SIG(C_SEND_ADD_PARTY_REJ,		PartyControl)	\
158   DEF_PRIV_SIG(C_SEND_STATUS_ENQ,		PartyControl)	\
159   DEF_PRIV_SIG(C_PARTY_DESTROYED,		PartyControl)	\
160   DEF_PRIV_SIG(C_END,				CallControl)
161 
162 #define DEF_PARTY_SIGS							\
163   DEF_PRIV_SIG(P_SETUP,				CallControl)		\
164   DEF_PRIV_SIG(P_ALERTING,			CallControl)		\
165   DEF_PRIV_SIG(P_CONNECT,			CallControl)		\
166   DEF_PRIV_SIG(P_CONNECT_ACK,			CallControl)		\
167   DEF_PRIV_SIG(P_RELEASE,			CallControl)		\
168   DEF_PRIV_SIG(P_RELEASE_COMPL,			CallControl)		\
169   DEF_PRIV_SIG(P_STATUS,			CallControl)		\
170   DEF_PRIV_SIG(P_ADD_PARTY,			CallControl)		\
171   DEF_PRIV_SIG(P_PARTY_ALERTING,		CallControl)		\
172   DEF_PRIV_SIG(P_ADD_PARTY_ACK,			CallControl)		\
173   DEF_PRIV_SIG(P_ADD_PARTY_REJ,			CallControl)		\
174   DEF_PRIV_SIG(P_DROP_PARTY,			CallControl)		\
175   DEF_PRIV_SIG(P_DROP_PARTY_ACK,		CallControl)		\
176   DEF_PRIV_SIG(P_SETUP_request,			CallControl)		\
177   DEF_PRIV_SIG(P_SETUP_response,		CallControl)		\
178   DEF_PRIV_SIG(P_SETUP_COMPL_request,		CallControl)		\
179   DEF_PRIV_SIG(P_ALERTING_request,		CallControl)		\
180   DEF_PRIV_SIG(P_RELEASE_request,		CallControl)		\
181   DEF_PRIV_SIG(P_RELEASE_response,		CallControl)		\
182   DEF_PRIV_SIG(P_RELEASE_confirm,		CallControl)		\
183   DEF_PRIV_SIG(P_STATUS_ENQUIRY_request,	CallControl)		\
184   DEF_PRIV_SIG(P_ADD_PARTY_request,		CallControl)		\
185   DEF_PRIV_SIG(P_PARTY_ALERTING_request,	CallControl)		\
186   DEF_PRIV_SIG(P_ADD_PARTY_ACK_request,		CallControl)		\
187   DEF_PRIV_SIG(P_ADD_PARTY_REJ_request,		CallControl)		\
188   DEF_PRIV_SIG(P_DROP_PARTY_request,		CallControl)		\
189   DEF_PRIV_SIG(P_DROP_PARTY_ACK_request,	CallControl)		\
190   DEF_PRIV_SIG(P_PARTY_DELETE,			PartyControl)		\
191   DEF_PRIV_SIG(P_T397,				PartyControl)		\
192   DEF_PRIV_SIG(P_T398,				PartyControl)		\
193   DEF_PRIV_SIG(P_T399,				PartyControl)		\
194   DEF_PRIV_SIG(P_END,				PartyControl)
195 
196 
197 #define DEF_PRIV_SIG(NAME, FROM)	SIG##NAME,
198 enum coord_sig {
199 	DEF_COORD_SIGS
200 };
201 enum respond_sig {
202 	DEF_RESPOND_SIGS
203 };
204 enum start_sig {
205 	DEF_START_SIGS
206 };
207 enum call_sig {
208 	DEF_CALL_SIGS
209 };
210 enum party_sig {
211 	DEF_PARTY_SIGS
212 };
213 #undef DEF_PRIV_SIG
214 
215 /*************************************************************
216  *
217  * SIGNALS and SIGNAL QUEUES
218  */
219 enum {
220 	SIG_COORD,
221 	SIG_RESET_START,
222 	SIG_RESET_RESP,
223 	SIG_CALL,
224 	SIG_PARTY,
225 };
226 
227 struct sig {
228 	TAILQ_ENTRY(sig) link;
229 	u_int		type;	/* one of the above */
230 	struct call	*call;	/* call to send to */
231 	struct party	*party;	/* party to send to */
232 	uint32_t	sig;	/* the signal */
233 	uint32_t	cookie;	/* user cookie */
234 	struct uni_msg	*msg;	/* attached message */
235 	struct uni_all	*u;	/* dito */
236 };
237 TAILQ_HEAD(sigqueue, sig);
238 
239 #define SIGQ_CLEAR(Q)							\
240     do {								\
241 	struct sig *s;							\
242 	while(!TAILQ_EMPTY(Q)) {					\
243 		s = TAILQ_FIRST(Q);					\
244 		TAILQ_REMOVE(Q, s, link);				\
245 		if(s->msg) uni_msg_destroy(s->msg);			\
246 		if(s->u) UNI_FREE(s->u);				\
247 		SIG_FREE(s);						\
248 	}								\
249     } while(0)
250 
251 void uni_sig_party(struct party *, enum party_sig, uint32_t cookie,
252     struct uni_msg *, struct uni_all *);
253 void uni_sig_call(struct call *, enum call_sig, uint32_t cookie,
254     struct uni_msg *, struct uni_all *);
255 void uni_sig_coord(struct uni *, enum coord_sig, uint32_t cookie,
256     struct uni_msg *);
257 void uni_sig_start(struct uni *, enum start_sig, uint32_t cookie,
258     struct uni_msg *, struct uni_all *);
259 void uni_sig_respond(struct uni *, enum respond_sig, uint32_t cookie,
260     struct uni_msg *, struct uni_all *);
261 
262 /*************************************************************
263  *
264  * CALL INSTANCES
265  */
266 struct party {
267 	struct call		*call;
268 	TAILQ_ENTRY(party)	link;
269 	u_int			epref;	/* endpoint reference */
270 	u_int			flags;	/* flags */
271 	enum uni_epstate	state;	/* party state */
272 
273 	struct uni_timer	t397;	/* T397 */
274 	struct uni_timer	t398;	/* T398 */
275 	struct uni_timer	t399;	/* T399 */
276 };
277 #define	PARTY_MINE	0x0001		/* must be 1 */
278 #define	PARTY_CONNECT	0x0002		/* connect request from this party */
279 
280 TAILQ_HEAD(partyqueue, party);
281 
282 void uni_destroy_party(struct party *, int);
283 struct party *uni_find_party(struct call *, struct uni_ie_epref *);
284 struct party *uni_find_partyx(struct call *, u_int epref, u_int mine);
285 struct party *uni_create_party(struct call *, struct uni_ie_epref *);
286 struct party *uni_create_partyx(struct call *, u_int epref, u_int mine,
287     uint32_t cookie);
288 u_int uni_party_act_count(struct call *, int);
289 
290 enum call_type {
291 	CALL_NULL,	/* not known yet */
292 	CALL_P2P,	/* normal point-to-point call */
293 	CALL_COBI,	/* Q.2932.1 COBI call */
294 	CALL_ROOT,	/* point-to-multipoint root */
295 	CALL_LEAF,	/* point-to-multipoint leaf */
296 };
297 
298 enum call_state {
299 	CALLST_NULL,
300 	CALLST_U1, CALLST_U3, CALLST_U4, CALLST_U6, CALLST_U7, CALLST_U8,
301 	CALLST_U9, CALLST_U10, CALLST_U11, CALLST_U12,
302 	CALLST_N1, CALLST_N3, CALLST_N4, CALLST_N6, CALLST_N7, CALLST_N8,
303 	CALLST_N9, CALLST_N10, CALLST_N11, CALLST_N12
304 };
305 
306 struct call {
307 	TAILQ_ENTRY(call)	link;	/* link between calls */
308 	struct uni		*uni;	/* backpointer to owning UNI */
309 	u_int			cref;	/* call reference value or lij seqno */
310 	u_int			mine;	/* if TRUE this is my call */
311 	enum call_type		type;	/* what call is it */
312 	enum call_state		cstate;	/* the state of the call */
313 	struct uni_ie_connid	connid;	/* the connection ID */
314 	struct uni_setup	msg_setup;	/* retransmission */
315 	struct uni_release	msg_release;	/* retransmission */
316 	struct uni_ie_epref	stat_epref;	/* retransmission */
317 	struct partyqueue	parties;
318 	u_int			se_active;	/* status enquiry active */
319 	u_int			epref_alloc;
320 
321 	struct uni_timer	t308;	/* T303 */
322 	u_int			cnt308;
323 
324 	struct uni_timer	t303;	/* T303 */
325 	u_int			cnt303;
326 
327 	struct uni_timer	t301;	/* T301 */
328 	struct uni_timer	t310;	/* T310 */
329 	struct uni_timer	t313;	/* T313 */
330 
331 	struct uni_timer	t322;	/* T322 */
332 	u_int			cnt322;
333 };
334 
335 TAILQ_HEAD(callqueue, call);
336 
337 struct call *uni_find_call(struct uni *, struct uni_cref *);
338 struct call *uni_find_callx(struct uni *, u_int cref, u_int mine);
339 struct call *uni_create_call(struct uni *, u_int cref, u_int mine,
340 	uint32_t cookie);
341 struct call *uni_create_new_call(struct uni *, uint32_t cookie);
342 void uni_destroy_call(struct call *, int);
343 
344 void uni_bad_message(struct call *, struct uni_all *, u_int,
345     struct uni_ie_epref *, int);
346 
347 extern const struct callstates {
348 	const char *name;
349 	enum uni_callstate ext;
350 } callstates[];
351 
352 /*************************************************************
353  *
354  * UNI INSTANCE
355  */
356 struct uni {
357 	void			*arg;	/* user arg */
358 	const struct uni_funcs	*funcs;
359 
360 	enum uni_proto		proto;	/* protocol */
361 	struct unicx		cx;	/* decoding/coding context */
362 	int			sb_tb : 1;	/* Sb-Tb/Tb point */
363 
364 	struct sigqueue		workq;	/* work queue */
365 	struct sigqueue		delq;	/* delayed signal queue */
366 	int			working;
367 
368 	uint32_t		cref_alloc;
369 
370 	enum cu_stat		custat;	/* coordinator state */
371 	struct uni_timer	t309;
372 	u_int			timer309;
373 
374 	enum uni_callstate	glob_start;
375 	enum uni_callstate	glob_respond;
376 	struct uni_timer	t316;
377 	struct uni_timer	t317;
378 	struct uni_ie_connid	connid_start;
379 	struct uni_ie_connid	connid_respond;
380 	u_int			cnt316;
381 	struct uni_ie_restart	restart_start;
382 
383 	struct callqueue	calls;
384 
385 	struct uni_ie_cause	cause;	/* working area for verify */
386 
387 	/* tuneable parameters */
388 	u_int			timer301;
389 	u_int			init303;
390 	u_int			timer303;
391 	u_int			init308;
392 	u_int			timer308;
393 	u_int			timer310;
394 	u_int			timer313;
395 	u_int			init316;
396 	u_int			timer316;
397 	u_int			timer317;
398 	u_int			timer322;
399 	u_int			init322;
400 	u_int			timer397;
401 	u_int			timer398;
402 	u_int			timer399;
403 
404 	u_int			debug[UNI_MAXFACILITY];
405 };
406 
407 void uniapi_uni_error(struct uni *uni, uint32_t reason, uint32_t cookie,
408 	uint32_t state);
409 void uniapi_call_error(struct call *c, uint32_t reason, uint32_t cookie);
410 void uniapi_party_error(struct party *p, uint32_t reason, uint32_t cookie);
411 
412 /*************************************************************
413  *
414  * INLINE FUNCTIONS
415  */
416 
417 /* Enqueue a signal in the working queue */
418 void uni_enq_sig(struct uni *, u_int, struct call *, struct party *,
419     uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
420 
421 /* Enqueue a signal in the delayed queue */
422 void uni_delenq_sig(struct uni *, u_int, struct call *, struct party *,
423     uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
424 
425 /* Enqueue a signal to the coordinator */
426 #define	uni_enq_coord(UNI, SIG, COOKIE, MSG) do {			\
427 	uni_enq_sig((UNI), SIG_COORD, NULL, NULL,			\
428 	    (SIG), (COOKIE), (MSG), NULL);				\
429     } while (0)
430 
431 /* Enqueue a delayed signal to the coordinator */
432 #define	uni_delenq_coord(UNI, SIG, COOKIE, MSG) do {			\
433 	uni_delenq_sig((UNI), SIG_COORD, NULL, NULL,			\
434 	    (SIG), (COOKIE), (MSG), NULL);				\
435     } while (0)
436 
437 /* Enqueue a signal to a call */
438 #define uni_enq_call(CALL, SIG, COOKIE, MSG, U) do {			\
439 	uni_enq_sig((CALL)->uni, SIG_CALL, (CALL), NULL,		\
440 	    (SIG), (COOKIE), (MSG), (U));				\
441     } while (0)
442 
443 /* Enqueue a signal to a party */
444 #define uni_enq_party(PARTY, SIG, COOKIE, MSG, U) do {			\
445 	uni_enq_sig((PARTY)->call->uni, SIG_PARTY, (PARTY)->call,	\
446 	    (PARTY), (SIG), (COOKIE), (MSG), (U));			\
447     } while (0)
448 
449 /* Enqueue a signal to RESET-START */
450 #define	uni_enq_start(UNI, SIG, COOKIE, MSG, U) do {			\
451 	uni_enq_sig((UNI), SIG_RESET_START, NULL, NULL,			\
452 	    (SIG), (COOKIE), (MSG), (U));				\
453     } while (0)
454 
455 /* Enqueue a signal to RESET-RESPOND */
456 #define	uni_enq_resp(UNI, SIG, COOKIE, MSG, U) do {			\
457 	uni_enq_sig((UNI), SIG_RESET_RESP, NULL, NULL,			\
458 	    (SIG), (COOKIE), (MSG), (U));				\
459     } while (0)
460 
461 int uni_send_output(struct uni_all *u, struct uni *uni);
462 void uni_undel(struct uni *, int (*)(struct sig *, void *), void *);
463 void uni_delsig(struct uni *, u_int, struct call *, struct party *);
464 
465 void uni_release_compl(struct call *, struct uni_all *);
466 
467 /*************************************************************/
468 /*
469  * Message verification.
470  */
471 #define MANDATE_IE(UNI,MSG,IE)						\
472     do {								\
473 	if (!IE_ISGOOD(MSG))						\
474 		uni_mandate_ie(UNI, IE);				\
475     } while(0)
476 
477 enum verify {
478 	VFY_OK,		/* ok */
479 	VFY_RAP,	/* report and proceed */
480 	VFY_RAPU,	/* report and proceed becuase of unknown IEs */
481 	VFY_I,		/* ignore */
482 	VFY_CLR,	/* clear call */
483 	VFY_RAI,	/* report and ignore */
484 	VFY_RAIM,	/* report and ignore because if mandat. IE miss */
485 };
486 
487 void uni_mandate_ie(struct uni *, enum uni_ietype);
488 void uni_mandate_epref(struct uni *, struct uni_ie_epref *);
489 enum verify uni_verify(struct uni *, enum uni_msgact);
490 void uni_respond_status_verify(struct uni *, struct uni_cref *,
491 	enum uni_callstate, struct uni_ie_epref *, enum uni_epstate);
492 void uni_vfy_remove_unknown(struct uni *);
493 void uni_vfy_remove_cause(struct uni *);
494 void uni_vfy_collect_ies(struct uni *);
495 
496 
497 void uni_respond_status(struct uni *uni, struct uni_cref *cref,
498     enum uni_callstate cs, enum uni_cause c1);
499 void uni_respond_status_mtype(struct uni *uni, struct uni_cref *cref,
500     enum uni_callstate cs, enum uni_cause c1, u_int mtype);
501 
502 #define	FOREACH_ERR(E, UNI) \
503 	for ((E) = (UNI)->cx.err; (E) < (UNI)->cx.err + (UNI)->cx.errcnt; (E)++)
504 
505 #define ALLOC_API(TYPE,API)					\
506     ({								\
507 	TYPE *_tmp = NULL;					\
508 								\
509 	if(((API) = uni_msg_alloc(sizeof(TYPE))) != NULL) {	\
510 		_tmp = uni_msg_wptr((API), TYPE *);		\
511 		(API)->b_wptr += sizeof(TYPE);			\
512 		memset(_tmp, 0, sizeof(TYPE));			\
513 	}							\
514 	_tmp;							\
515     })
516 
517 #if defined(__GNUC__) && __GNUC__ < 3
518 
519 #define	VERBOSE(UNI, FAC, LEVEL, ARGS...) do {			\
520 	if ((UNI)->debug[(FAC)] >= (LEVEL)) {			\
521 		(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC) ,\
522 		   ## ARGS);					\
523 	}							\
524     } while(0)
525 
526 #define VERBOSE0(UNI, FAC, ARGS...) do {			\
527 	(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC) ,	\
528 	    ## ARGS);						\
529     } while(0)
530 
531 #else
532 
533 #define VERBOSE(UNI, FAC, LEVEL, ...) do {			\
534 	if ((UNI)->debug[(FAC)] >= (LEVEL)) {			\
535 		(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC),	\
536 		    __VA_ARGS__);				\
537 	}							\
538     } while(0)
539 
540 #define VERBOSE0(UNI, FAC, ...) do {				\
541 	(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC),		\
542 	    __VA_ARGS__);					\
543     } while(0)
544 
545 #endif
546 
547 #define TIMER_INIT_UNI(U,T)	_TIMER_INIT(U,T)
548 #define TIMER_INIT_CALL(C,T)	_TIMER_INIT(C,T)
549 #define TIMER_INIT_PARTY(P,T)	_TIMER_INIT(P,T)
550 
551 #define TIMER_DESTROY_UNI(U,T)		_TIMER_DESTROY(U, (U)->T)
552 #define TIMER_DESTROY_CALL(C,T)		_TIMER_DESTROY((C)->uni, (C)->T)
553 #define TIMER_DESTROY_PARTY(P,T)	_TIMER_DESTROY((P)->call->uni, (P)->T)
554 
555 #define TIMER_STOP_UNI(U,T)	_TIMER_STOP(U, (U)->T)
556 #define TIMER_STOP_CALL(C,T)	_TIMER_STOP((C)->uni, (C)->T)
557 #define TIMER_STOP_PARTY(P,T)	_TIMER_STOP((P)->call->uni, (P)->T)
558 
559 #define TIMER_START_UNI(U,T,N) _TIMER_START(U, U, (U)->T, N, _##T##_func)
560 #define TIMER_START_CALL(C,T,N) _TIMER_START(C->uni, C, (C)->T, N, _##T##_func)
561 #define TIMER_START_PARTY(P,T,N) _TIMER_START(P->call->uni, P, (P)->T, N, _##T##_func)
562 
563 #endif
564