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 <harti@freebsd.org>
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
44struct call;
45struct party;
46
47enum 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,
198enum coord_sig {
199	DEF_COORD_SIGS
200};
201enum respond_sig {
202	DEF_RESPOND_SIGS
203};
204enum start_sig {
205	DEF_START_SIGS
206};
207enum call_sig {
208	DEF_CALL_SIGS
209};
210enum party_sig {
211	DEF_PARTY_SIGS
212};
213#undef DEF_PRIV_SIG
214
215/*************************************************************
216 *
217 * SIGNALS and SIGNAL QUEUES
218 */
219enum {
220	SIG_COORD,
221	SIG_RESET_START,
222	SIG_RESET_RESP,
223	SIG_CALL,
224	SIG_PARTY,
225};
226
227struct 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};
237TAILQ_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
251void uni_sig_party(struct party *, enum party_sig, uint32_t cookie,
252    struct uni_msg *, struct uni_all *);
253void uni_sig_call(struct call *, enum call_sig, uint32_t cookie,
254    struct uni_msg *, struct uni_all *);
255void uni_sig_coord(struct uni *, enum coord_sig, uint32_t cookie,
256    struct uni_msg *);
257void uni_sig_start(struct uni *, enum start_sig, uint32_t cookie,
258    struct uni_msg *, struct uni_all *);
259void 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 */
266struct 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
280TAILQ_HEAD(partyqueue, party);
281
282void uni_destroy_party(struct party *, int);
283struct party *uni_find_party(struct call *, struct uni_ie_epref *);
284struct party *uni_find_partyx(struct call *, u_int epref, u_int mine);
285struct party *uni_create_party(struct call *, struct uni_ie_epref *);
286struct party *uni_create_partyx(struct call *, u_int epref, u_int mine,
287    uint32_t cookie);
288u_int uni_party_act_count(struct call *, int);
289
290enum 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
298enum 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
306struct 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
335TAILQ_HEAD(callqueue, call);
336
337struct call *uni_find_call(struct uni *, struct uni_cref *);
338struct call *uni_find_callx(struct uni *, u_int cref, u_int mine);
339struct call *uni_create_call(struct uni *, u_int cref, u_int mine,
340	uint32_t cookie);
341struct call *uni_create_new_call(struct uni *, uint32_t cookie);
342void uni_destroy_call(struct call *, int);
343
344void uni_bad_message(struct call *, struct uni_all *, u_int,
345    struct uni_ie_epref *, int);
346
347extern const struct callstates {
348	const char *name;
349	enum uni_callstate ext;
350} callstates[];
351
352/*************************************************************
353 *
354 * UNI INSTANCE
355 */
356struct 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
407void uniapi_uni_error(struct uni *uni, uint32_t reason, uint32_t cookie,
408	uint32_t state);
409void uniapi_call_error(struct call *c, uint32_t reason, uint32_t cookie);
410void 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 */
418void 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 */
422void 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
461int uni_send_output(struct uni_all *u, struct uni *uni);
462void uni_undel(struct uni *, int (*)(struct sig *, void *), void *);
463void uni_delsig(struct uni *, u_int, struct call *, struct party *);
464
465void 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
477enum 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
487void uni_mandate_ie(struct uni *, enum uni_ietype);
488void uni_mandate_epref(struct uni *, struct uni_ie_epref *);
489enum verify uni_verify(struct uni *, enum uni_msgact);
490void uni_respond_status_verify(struct uni *, struct uni_cref *,
491	enum uni_callstate, struct uni_ie_epref *, enum uni_epstate);
492void uni_vfy_remove_unknown(struct uni *);
493void uni_vfy_remove_cause(struct uni *);
494void uni_vfy_collect_ies(struct uni *);
495
496
497void uni_respond_status(struct uni *uni, struct uni_cref *cref,
498    enum uni_callstate cs, enum uni_cause c1);
499void 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