1131826Sharti/*
2131826Sharti * Copyright (c) 2003-2004
3131826Sharti *	Hartmut Brandt
4131826Sharti *	All rights reserved.
5131826Sharti *
6131826Sharti * Author: Harti Brandt <harti@freebsd.org>
7131826Sharti *
8131826Sharti * Redistribution of this software and documentation and use in source and
9131826Sharti * binary forms, with or without modification, are permitted provided that
10131826Sharti * the following conditions are met:
11131826Sharti *
12131826Sharti * 1. Redistributions of source code or documentation must retain the above
13131826Sharti *    copyright notice, this list of conditions and the following disclaimer.
14131826Sharti * 2. Redistributions in binary form must reproduce the above copyright
15131826Sharti *    notice, this list of conditions and the following disclaimer in the
16131826Sharti *    documentation and/or other materials provided with the distribution.
17131826Sharti *
18131826Sharti * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
19131826Sharti * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20131826Sharti * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21131826Sharti * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
22131826Sharti * THE AUTHOR OR ITS CONTRIBUTORS  BE LIABLE FOR ANY DIRECT, INDIRECT,
23131826Sharti * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24131826Sharti * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25131826Sharti * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26131826Sharti * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27131826Sharti * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28131826Sharti * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29131826Sharti *
30146539Sharti * $Begemot: libunimsg/netnatm/api/ccpriv.h,v 1.2 2005/05/23 11:49:17 brandt_h Exp $
31131826Sharti *
32131826Sharti * ATM API as defined per af-saa-0108
33131826Sharti *
34131826Sharti * Private declarations.
35131826Sharti */
36131826Sharti#ifdef _KERNEL
37131826Sharti#ifdef __FreeBSD__
38131826Sharti#include <netgraph/atm/ccatm/ng_ccatm_cust.h>
39131826Sharti#endif
40131826Sharti#else	/* !_KERNEL */
41131826Sharti#include "cccust.h"
42131826Sharti#endif
43131826Sharti
44131826Shartistruct ccuser;
45131826Shartistruct ccconn;
46131826Shartistruct ccaddr;
47131826Shartistruct ccport;
48131826Shartistruct ccdata;
49131826Shartistruct ccsig;
50131826Shartistruct ccparty;
51131826Sharti
52131826ShartiLIST_HEAD(ccuser_list, ccuser);
53131826ShartiLIST_HEAD(ccconn_list, ccconn);
54131826ShartiTAILQ_HEAD(ccaddr_list, ccaddr);
55131826ShartiTAILQ_HEAD(ccport_list, ccport);
56131826ShartiTAILQ_HEAD(ccsig_list, ccsig);
57131826ShartiLIST_HEAD(ccparty_list, ccparty);
58131826Sharti
59131826Sharti/*
60131826Sharti * Private node data.
61131826Sharti */
62131826Shartistruct ccdata {
63131826Sharti	struct ccuser_list	user_list;	/* instance list */
64131826Sharti	struct ccport_list	port_list;	/* list of ports */
65131826Sharti	struct ccconn_list	orphaned_conns;	/* list of connections */
66131826Sharti	struct ccsig_list	sigs;		/* current signals */
67131826Sharti	struct ccsig_list	def_sigs;	/* deferred signals */
68131826Sharti	struct ccsig_list	free_sigs;	/* free signals */
69131826Sharti
70131826Sharti	const struct cc_funcs	*funcs;
71131826Sharti	uint32_t		cookie;		/* cookie generator */
72131826Sharti	u_int			log;		/* logging flags */
73131826Sharti};
74131826Sharti
75131826Sharti/* retrieve info on local ports */
76131826Shartistruct atm_port_list *cc_get_local_port_info(struct ccdata *,
77131826Sharti    u_int, size_t *);
78131826Sharti
79131826Sharti/* log */
80131826Sharti#ifdef CCATM_DEBUG
81131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
82131826Sharti#define	cc_log(CC, FMT, ARGS...) do {					\
83131826Sharti	(CC)->funcs->log("%s (data=%p): " FMT, __FUNCTION__,		\
84131826Sharti	    (CC) , ## ARGS);						\
85131826Sharti    } while (0)
86131826Sharti#else
87131826Sharti#define	cc_log(CC, FMT, ...) do {					\
88131826Sharti	(CC)->funcs->log("%s (data=%p): " FMT, __func__,		\
89131826Sharti	    (CC), __VA_ARGS__);						\
90131826Sharti    } while (0)
91131826Sharti#endif
92131826Sharti#else
93131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
94131826Sharti#define	cc_log(CC, FMT, ARGS...) do { } while (0)
95131826Sharti#else
96131826Sharti#define	cc_log(CC, FMT, ...) do { } while (0)
97131826Sharti#endif
98131826Sharti#endif
99131826Sharti
100131826Sharti/*
101131826Sharti * structure to remember cookies for outstanding requests
102131826Sharti * we also remember the request itself but don't use it.
103131826Sharti */
104131826Shartistruct ccreq {
105131826Sharti	TAILQ_ENTRY(ccreq)	link;
106131826Sharti	uint32_t		cookie;
107131826Sharti	uint32_t		req;
108131826Sharti	struct ccconn		*conn;
109131826Sharti};
110131826ShartiTAILQ_HEAD(ccreq_list, ccreq);
111131826Sharti
112131826Sharti/*
113131826Sharti * Port data. Each port has one UNI stack below.
114131826Sharti * The port number is in param.port. The number is assigned when the
115131826Sharti * hook to the uni is connected. This hook has the name 'uni<port>'.
116131826Sharti */
117131826Shartistruct ccport {
118131826Sharti	void		*uarg;		/* hook to UNI protocol */
119131826Sharti	struct ccdata 	*cc;		/* back pointer to node */
120131826Sharti	enum {
121131826Sharti		CCPORT_STOPPED,		/* halted */
122131826Sharti		CCPORT_RUNNING,		/* ok */
123131826Sharti	}		admin;		/* admin status */
124131826Sharti	struct ccconn_list conn_list;	/* list of connections */
125131826Sharti	struct ccaddr_list addr_list;	/* list of network addresses */
126131826Sharti	struct atm_port_info param;	/* parameters */
127131826Sharti
128131826Sharti	/* list of outstanding requests */
129131826Sharti	struct ccreq_list	cookies;
130131826Sharti
131131826Sharti	TAILQ_ENTRY(ccport) node_link;
132131826Sharti};
133131826Sharti
134131826Sharti#ifdef CCATM_DEBUG
135131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
136131826Sharti#define	cc_port_log(P, FMT, ARGS...) do {				\
137131826Sharti	(P)->cc->funcs->log("%s (port=%p/%u): " FMT, __FUNCTION__,	\
138131826Sharti	    (P), (P)->param.port , ## ARGS);				\
139131826Sharti    } while (0)
140131826Sharti#else
141131826Sharti#define	cc_port_log(P, FMT, ...) do {					\
142131826Sharti	(P)->cc->funcs->log("%s (port=%p/%u): " FMT, __func__,		\
143131826Sharti	    (P), (P)->param.port, __VA_ARGS__);				\
144131826Sharti    } while (0)
145131826Sharti#endif
146131826Sharti#else
147131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
148131826Sharti#define	cc_port_log(P, FMT, ARGS...) do { } while (0)
149131826Sharti#else
150131826Sharti#define	cc_port_log(P, FMT, ...) do { } while (0)
151131826Sharti#endif
152131826Sharti#endif
153131826Sharti
154131826Sharti#define CONN_STATES					\
155131826Sharti	DEF(CONN_NULL)			/*  C0 */	\
156131826Sharti	DEF(CONN_OUT_PREPARING)		/*  C1 */	\
157131826Sharti	DEF(CONN_OUT_WAIT_CREATE)	/*  C2 */	\
158131826Sharti	DEF(CONN_OUT_WAIT_OK)		/*  C3 */	\
159131826Sharti	DEF(CONN_OUT_WAIT_CONF)		/*  C4 */	\
160131826Sharti							\
161131826Sharti	DEF(CONN_ACTIVE)		/*  C5 */	\
162131826Sharti							\
163131826Sharti	DEF(CONN_IN_PREPARING)		/* C10 */	\
164131826Sharti	DEF(CONN_IN_WAITING)		/* C21 */	\
165131826Sharti	DEF(CONN_IN_ARRIVED)		/* C11 */	\
166131826Sharti	DEF(CONN_IN_WAIT_ACCEPT_OK)	/* C12 */	\
167131826Sharti	DEF(CONN_IN_WAIT_COMPL)		/* C13 */	\
168131826Sharti							\
169131826Sharti	DEF(CONN_REJ_WAIT_OK)		/* C14 */	\
170131826Sharti	DEF(CONN_REL_IN_WAIT_OK)	/* C15 */	\
171131826Sharti	DEF(CONN_REL_WAIT_OK)		/* C20 */	\
172131826Sharti							\
173131826Sharti	DEF(CONN_AB_WAIT_REQ_OK)	/* C33 */	\
174131826Sharti	DEF(CONN_AB_WAIT_RESP_OK)	/* C34 */	\
175131826Sharti	DEF(CONN_AB_FLUSH_IND)		/* C35 */	\
176131826Sharti	DEF(CONN_OUT_WAIT_DESTROY)	/* C37 */
177131826Sharti
178131826Shartienum conn_state {
179131826Sharti#define DEF(N) N,
180131826Sharti	CONN_STATES
181131826Sharti#undef DEF
182131826Sharti};
183131826Sharti
184131826Sharti#define	CONN_SIGS							\
185131826Sharti	DEF(CONNECT_OUTGOING)	/* U */					\
186131826Sharti	DEF(ARRIVAL)		/* U */					\
187131826Sharti	DEF(RELEASE)		/* U */					\
188131826Sharti	DEF(REJECT)		/* U */					\
189131826Sharti	DEF(ACCEPT)		/* U newuser */				\
190131826Sharti	DEF(ADD_PARTY)		/* U ident */				\
191131826Sharti	DEF(DROP_PARTY)		/* U ident */				\
192131826Sharti	DEF(USER_ABORT)		/* U */					\
193131826Sharti									\
194131826Sharti	DEF(CREATED)		/* P msg */				\
195131826Sharti	DEF(DESTROYED)		/* P */					\
196131826Sharti	DEF(SETUP_CONFIRM)	/* P msg */				\
197131826Sharti	DEF(SETUP_IND)		/* P msg */				\
198131826Sharti	DEF(SETUP_COMPL)	/* P msg */				\
199131826Sharti	DEF(PROC_IND)		/* P msg */				\
200131826Sharti	DEF(ALERTING_IND)	/* P msg */				\
201131826Sharti	DEF(REL_CONF)		/* P msg */				\
202131826Sharti	DEF(REL_IND)		/* P msg */				\
203131826Sharti	DEF(PARTY_CREATED)	/* P msg */				\
204131826Sharti	DEF(PARTY_DESTROYED)	/* P msg */				\
205131826Sharti	DEF(PARTY_ALERTING_IND)	/* P msg */				\
206131826Sharti	DEF(PARTY_ADD_ACK_IND)	/* P msg */				\
207131826Sharti	DEF(PARTY_ADD_REJ_IND)	/* P msg */				\
208131826Sharti	DEF(DROP_PARTY_IND)	/* P msg */				\
209131826Sharti	DEF(DROP_PARTY_ACK_IND)	/* P msg */				\
210131826Sharti									\
211131826Sharti	DEF(OK)			/* P msg */				\
212131826Sharti	DEF(ERROR)		/* P msg */
213131826Sharti
214131826Shartienum conn_sig {
215131826Sharti#define DEF(NAME) CONN_SIG_##NAME,
216131826ShartiCONN_SIGS
217131826Sharti#undef DEF
218131826Sharti};
219131826Shartiextern const char *const cc_conn_sigtab[];
220131826Sharti
221131826Sharti/*
222131826Sharti * This describes a connection and must be in sync with the UNI
223131826Sharti * stack.
224131826Sharti */
225131826Shartistruct ccconn {
226131826Sharti	enum conn_state		state;	/* API state of the connection */
227131826Sharti	struct ccdata		*cc;	/* owner node */
228131826Sharti	struct ccport		*port;	/* the port we belong to */
229131826Sharti	struct ccuser		*user;	/* user instance we belong to */
230131826Sharti    	TAILQ_ENTRY(ccconn)	connq_link;	/* queue of the owner */
231131826Sharti	LIST_ENTRY(ccconn) 	port_link;	/* link in list of port */
232131826Sharti	struct uni_cref		cref;
233131826Sharti	uint8_t			reason;
234131826Sharti	struct ccuser		*acceptor;
235131826Sharti
236131826Sharti	/* attributes */
237131826Sharti	uint32_t		blli_selector;
238131826Sharti	struct uni_ie_blli	blli[UNI_NUM_IE_BLLI];
239131826Sharti
240131826Sharti	struct uni_ie_bearer	bearer;
241131826Sharti	struct uni_ie_traffic	traffic;
242131826Sharti	struct uni_ie_qos	qos;
243131826Sharti	struct uni_ie_exqos	exqos;
244131826Sharti	struct uni_ie_called	called;
245131826Sharti	struct uni_ie_calledsub	calledsub;
246131826Sharti	struct uni_ie_aal	aal;
247131826Sharti	struct uni_ie_epref	epref;
248131826Sharti	struct uni_ie_conned	conned;
249131826Sharti	struct uni_ie_connedsub	connedsub;
250131826Sharti	struct uni_ie_eetd	eetd;
251131826Sharti	struct uni_ie_abrsetup	abrsetup;
252131826Sharti	struct uni_ie_abradd	abradd;
253131826Sharti	struct uni_ie_mdcr	mdcr;
254131826Sharti
255131826Sharti	struct uni_ie_calling	calling;
256131826Sharti	struct uni_ie_callingsub callingsub;
257131826Sharti	struct uni_ie_connid	connid;
258131826Sharti	struct uni_ie_tns	tns[UNI_NUM_IE_TNS];
259131826Sharti	struct uni_ie_atraffic	atraffic;
260131826Sharti	struct uni_ie_mintraffic mintraffic;
261131826Sharti	struct uni_ie_cscope	cscope;
262131826Sharti	struct uni_ie_bhli	bhli;
263131826Sharti
264131826Sharti	/* bit mask of written attributes in A6 */
265131826Sharti	u_int			dirty_attr;
266131826Sharti
267131826Sharti	struct uni_ie_cause	cause[2];
268131826Sharti
269131826Sharti	struct ccparty_list	parties;
270131826Sharti};
271131826Sharti
272131826Sharti/* dirty attribute mask values */
273131826Shartienum {
274131826Sharti	CCDIRTY_AAL		= 0x0001,
275131826Sharti	CCDIRTY_BLLI		= 0x0002,
276131826Sharti	CCDIRTY_CONNID		= 0x0004,
277131826Sharti	CCDIRTY_NOTIFY		= 0x0008,	/* XXX */
278131826Sharti	CCDIRTY_EETD		= 0x0010,
279131826Sharti	CCDIRTY_GIT		= 0x0020,	/* XXX */
280131826Sharti	CCDIRTY_UU		= 0x0040,	/* XXX */
281131826Sharti	CCDIRTY_TRAFFIC		= 0x0080,
282131826Sharti	CCDIRTY_EXQOS		= 0x0100,
283131826Sharti	CCDIRTY_ABRSETUP	= 0x0200,
284131826Sharti	CCDIRTY_ABRADD		= 0x0400,
285131826Sharti};
286131826Sharti
287131826Sharti/* set conn to new state */
288131826Shartivoid cc_conn_set_state(struct ccconn *, enum conn_state);
289131826Sharti
290131826Sharti/* return string for state */
291131826Sharticonst char *cc_conn_state2str(u_int);
292131826Sharti
293131826Sharti/* connect connection to user */
294131826Shartivoid cc_connect_to_user(struct ccconn *, struct ccuser *);
295131826Sharti
296131826Sharti/* disconnect from the user */
297131826Shartivoid cc_disconnect_from_user(struct ccconn *);
298131826Sharti
299131826Sharti/* abort the connection */
300131826Shartivoid cc_conn_abort(struct ccconn *, int);
301131826Sharti
302131826Sharti/* destroy a connection */
303131826Shartivoid cc_conn_destroy(struct ccconn *);
304131826Sharti
305131826Sharti/* create a connection */
306131826Shartistruct ccconn *cc_conn_create(struct ccdata *);
307131826Sharti
308131826Sharti/* assign to port */
309131826Shartivoid cc_conn_ins_port(struct ccconn *, struct ccport *);
310131826Sharti
311131826Sharti/* remove from port */
312131826Shartivoid cc_conn_rem_port(struct ccconn *);
313131826Sharti
314131826Sharti/* dispatch a connection to a user or reject it */
315131826Shartivoid cc_conn_dispatch(struct ccconn *);
316131826Sharti
317131826Sharti/* disconnect from acceptor */
318131826Shartivoid cc_conn_reset_acceptor(struct ccconn *);
319131826Sharti
320131826Sharti/* log on a connection */
321131826Sharti#ifdef CCATM_DEBUG
322131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
323131826Sharti#define	cc_conn_log(C, FMT, ARGS...) do {				\
324131826Sharti	(C)->cc->funcs->log("%s (conn=%p): " FMT, __FUNCTION__,		\
325131826Sharti	    (C) , ## ARGS);						\
326131826Sharti    } while (0)
327131826Sharti#else
328131826Sharti#define	cc_conn_log(C, FMT, ...) do {					\
329131826Sharti	(C)->cc->funcs->log("%s (conn=%p): " FMT, __func__,		\
330131826Sharti	    (C), __VA_ARGS__);						\
331131826Sharti    } while (0)
332131826Sharti#endif
333131826Sharti#else
334131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
335131826Sharti#define	cc_conn_log(C, FMT, ARGS...) do { } while (0)
336131826Sharti#else
337131826Sharti#define	cc_conn_log(C, FMT, ...) do { } while (0)
338131826Sharti#endif
339131826Sharti#endif
340131826Sharti
341131826Sharti/* handle signal to connection */
342131826Shartivoid cc_conn_sig_handle(struct ccconn *, enum conn_sig, void *arg, u_int iarg);
343131826Sharti
344131826Sharti/*
345131826Sharti * Mp connection parties
346131826Sharti */
347131826Sharti#define	PARTY_STATES							\
348131826Sharti	DEF(NULL)		/* 0 created */				\
349131826Sharti	DEF(ACTIVE)		/* 1 active */				\
350131826Sharti	DEF(ADD_WAIT_CREATE)	/* 2 wait for PARTY_CREATE */		\
351131826Sharti	DEF(ADD_WAIT_OK)	/* 3 wait for OK for ADD.request */	\
352131826Sharti	DEF(ADD_WAIT_ACK)	/* 4 wait for ADD.ack/rej */		\
353131826Sharti	DEF(DROP_WAIT_OK)	/* 5 wait for OK for DROP.request */	\
354131826Sharti	DEF(DROP_WAIT_ACK)	/* 6 wait for DROP.ack */		\
355131826Sharti	DEF(WAIT_DESTROY)	/* 7 wait for destroy */		\
356131826Sharti	DEF(WAIT_SETUP_COMPL)	/* 8 wait for setup.complete */		\
357131826Sharti	DEF(WAIT_DROP_ACK_OK)	/* 9 wait for OK for DROP_ACK.request */\
358131826Sharti	DEF(WAIT_SETUP_CONF)	/* 10 wait for setup.confirm */		\
359131826Sharti	DEF(ADD_DROP_WAIT_OK)	/* 11 wait for ok to DROP.request */	\
360131826Sharti	DEF(ADD_DROPACK_WAIT_OK)/* 12 wait for ok to DROP_ACK.req */
361131826Sharti
362131826Shartienum party_state {
363131826Sharti#define	DEF(N)	PARTY_##N,
364131826ShartiPARTY_STATES
365131826Sharti#undef DEF
366131826Sharti};
367131826Sharti
368131826Shartistruct ccparty {
369131826Sharti	struct ccconn		*conn;	/* owner */
370131826Sharti	LIST_ENTRY(ccparty)	link;
371131826Sharti	enum party_state	state;
372131826Sharti	struct uni_ie_called	called;
373131826Sharti	struct uni_ie_epref	epref;
374131826Sharti};
375131826Sharti
376131826Sharti/* set party to new state */
377131826Shartivoid cc_party_set_state(struct ccparty *, enum party_state);
378131826Sharti
379131826Sharti/* return string for state */
380131826Sharticonst char *cc_party_state2str(u_int);
381131826Sharti
382131826Sharti/* create new party */
383131826Shartistruct ccparty *cc_party_create(struct ccconn *, u_int ident, u_int flag);
384131826Sharti
385131826Sharti/* log on a party */
386131826Sharti#ifdef CCATM_DEBUG
387131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
388131826Sharti#define	cc_party_log(P, FMT, ARGS...) do {				\
389131826Sharti	(P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT,	\
390131826Sharti	    __FUNCTION__, (P)->conn, (P) , ## ARGS);			\
391131826Sharti    } while (0)
392131826Sharti#else
393131826Sharti#define	cc_party_log(P, FMT, ...) do {					\
394131826Sharti	(P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT,	\
395131826Sharti	__func__, (P)->conn, (P), __VA_ARGS__);				\
396131826Sharti    } while (0)
397131826Sharti#endif
398131826Sharti#else
399131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
400131826Sharti#define	cc_party_log(P, FMT, ARGS...) do { } while (0)
401131826Sharti#else
402131826Sharti#define	cc_party_log(P, FMT, ...) do { } while (0)
403131826Sharti#endif
404131826Sharti#endif
405131826Sharti
406131826Sharti/*
407131826Sharti * This is kind of a user socket, i.e. the entity managed towards the
408131826Sharti * upper layer.
409131826Sharti */
410131826Sharti#define USER_STATES							\
411131826Sharti	DEF(USER_NULL)		/* U0 none */				\
412131826Sharti	DEF(USER_OUT_PREPARING)	/* U1 process set/query requests */	\
413131826Sharti	DEF(USER_OUT_WAIT_OK)	/* U2 wait for OK to setup */		\
414131826Sharti	DEF(USER_OUT_WAIT_CONF)	/* U3 wait for SETUP.confirm */		\
415131826Sharti	DEF(USER_ACTIVE)	/* U4 A8-9-10/U10 */			\
416131826Sharti	DEF(USER_REL_WAIT)	/* U5 wait for release to compl */	\
417131826Sharti	DEF(USER_IN_PREPARING)	/* U6 set SAP */			\
418131826Sharti	DEF(USER_IN_WAITING)	/* U7 wait and dispatch */		\
419131826Sharti	DEF(USER_IN_ARRIVED)	/* U8 waiting for rej/acc */		\
420131826Sharti	DEF(USER_IN_WAIT_REJ)	/* U9 wait for rejecting */		\
421131826Sharti	DEF(USER_IN_WAIT_ACC)	/* U10 wait for accepting */		\
422131826Sharti	DEF(USER_IN_ACCEPTING)	/* U11 wait for SETUP_complete */	\
423131826Sharti	DEF(USER_REL_WAIT_SCOMP)/* U12 wait for SETUP_complete */	\
424131826Sharti	DEF(USER_REL_WAIT_SCONF)/* U13 wait for SETUP.confirm */	\
425131826Sharti	DEF(USER_REL_WAIT_CONF)	/* U14 wait for confirm */		\
426131826Sharti	DEF(USER_REL_WAIT_CONN)	/* U15 wait for CONN_OK */
427131826Sharti
428131826Shartienum user_state {
429131826Sharti#define	DEF(N) N,
430131826ShartiUSER_STATES
431131826Sharti#undef DEF
432131826Sharti};
433131826Sharti
434131826Sharti#define	USER_SIGS						\
435131826Sharti	DEF(PREPARE_OUTGOING)		/* U */			\
436131826Sharti	DEF(CONNECT_OUTGOING)		/* U msg */		\
437131826Sharti	DEF(PREPARE_INCOMING)		/* U msg */		\
438131826Sharti	DEF(WAIT_ON_INCOMING)		/* U msg */		\
439131826Sharti	DEF(REJECT_INCOMING)		/* U msg */		\
440131826Sharti	DEF(ACCEPT_INCOMING)		/* U msg */		\
441131826Sharti	DEF(CALL_RELEASE)		/* U msg */		\
442131826Sharti	DEF(ADD_PARTY)			/* U msg */		\
443131826Sharti	DEF(DROP_PARTY)			/* U msg */		\
444131826Sharti	DEF(QUERY_ATTR)			/* U msg */		\
445131826Sharti	DEF(QUERY_ATTR_X)		/* U msg */		\
446131826Sharti	DEF(SET_ATTR)			/* U msg */		\
447131826Sharti	DEF(SET_ATTR_X)			/* U msg */		\
448131826Sharti	DEF(QUERY_STATE)		/* U */			\
449131826Sharti	DEF(GET_LOCAL_PORT_INFO)	/* U msg */		\
450131826Sharti	DEF(ABORT_CONNECTION)		/* U msg */		\
451131826Sharti								\
452131826Sharti	DEF(CONNECT_OUTGOING_OK)	/* */			\
453131826Sharti	DEF(CONNECT_OUTGOING_ERR)	/* reason */		\
454131826Sharti	DEF(SETUP_CONFIRM)		/* */			\
455131826Sharti	DEF(SETUP_IND)			/* */			\
456131826Sharti	DEF(REJECT_OK)			/* */			\
457131826Sharti	DEF(REJECT_ERR)			/* reason */		\
458131826Sharti	DEF(ACCEPT_OK)			/* */			\
459131826Sharti	DEF(ACCEPT_ERR)			/* reason */		\
460131826Sharti	DEF(ACCEPTING)			/* */			\
461131826Sharti	DEF(SETUP_COMPL)		/* */			\
462131826Sharti	DEF(RELEASE_CONFIRM)		/* */			\
463131826Sharti	DEF(RELEASE_ERR)		/* reason */		\
464131826Sharti	DEF(ADD_PARTY_ERR)		/* reason */		\
465131826Sharti	DEF(ADD_PARTY_OK)		/* */			\
466131826Sharti	DEF(ADD_PARTY_ACK)		/* leaf-ident */	\
467131826Sharti	DEF(ADD_PARTY_REJ)		/* leaf-ident */	\
468131826Sharti	DEF(DROP_PARTY_ERR)		/* reason */		\
469131826Sharti	DEF(DROP_PARTY_OK)		/* */			\
470131826Sharti	DEF(DROP_PARTY_IND)		/* leaf-ident */	\
471131826Sharti
472131826Sharti
473131826Shartienum user_sig {
474131826Sharti#define	DEF(NAME)	USER_SIG_##NAME,
475131826ShartiUSER_SIGS
476131826Sharti#undef DEF
477131826Sharti};
478131826Shartiextern const char *const cc_user_sigtab[];
479131826Sharti
480131826Shartistruct ccuser {
481131826Sharti	LIST_ENTRY(ccuser) 	node_link;	/* link in list of node */
482131826Sharti	enum user_state		state;		/* type of this instance */
483131826Sharti	struct ccdata		*cc;		/* the node */
484131826Sharti	void			*uarg;		/* the hook (if any) */
485131826Sharti	char			name[ATM_EPNAMSIZ];
486131826Sharti	enum {
487131826Sharti		USER_P2P,
488131826Sharti		USER_ROOT,
489131826Sharti		USER_LEAF
490131826Sharti	}			config;		/* configuration */
491131826Sharti
492131826Sharti	struct uni_sap		*sap;		/* listening SAP */
493131826Sharti	u_int			queue_max;	/* maximum queue size */
494131826Sharti	u_int			queue_act;	/* actual queue size */
495131826Sharti	TAILQ_HEAD(,ccconn)	connq;		/* pending connections */
496131826Sharti	struct ccconn		*accepted;
497131826Sharti	struct uni_ie_cause	cause[2];	/* cause from connection */
498131826Sharti	u_int			aborted;
499131826Sharti};
500131826Sharti
501131826Sharti/* set user to new state */
502131826Shartivoid cc_user_set_state(struct ccuser *, enum user_state);
503131826Sharti
504131826Sharti/* return string for state */
505131826Sharticonst char *cc_user_state2str(u_int);
506131826Sharti
507131826Sharti/* log on a user */
508131826Sharti#ifdef CCATM_DEBUG
509131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
510131826Sharti#define	cc_user_log(U, FMT, ARGS...) do {				\
511131826Sharti	(U)->cc->funcs->log("%s (user=%p): " FMT, __FUNCTION__,		\
512131826Sharti	    (U) , ## ARGS);						\
513131826Sharti    } while (0)
514131826Sharti#else
515131826Sharti#define	cc_user_log(U, FMT, ...) do {					\
516131826Sharti	(U)->cc->funcs->log("%s (user=%p): " FMT, __func__,		\
517131826Sharti	    (U), __VA_ARGS__);						\
518131826Sharti    } while (0)
519131826Sharti#endif
520131826Sharti#else
521131826Sharti#if defined(__GNUC__) && __GNUC__ < 3
522131826Sharti#define	cc_user_log(U, FMT, ARGS...) do { } while (0)
523131826Sharti#else
524131826Sharti#define	cc_user_log(U, FMT, ...) do { } while (0)
525131826Sharti#endif
526131826Sharti#endif
527131826Sharti
528131826Sharti/* Handle a signal to this user */
529131826Shartivoid cc_user_sig_handle(struct ccuser *, enum user_sig, void *, u_int);
530131826Sharti
531131826Sharti/*
532131826Sharti * Addresses
533131826Sharti */
534131826Shartistruct ccaddr {
535131826Sharti	TAILQ_ENTRY(ccaddr) port_link;
536131826Sharti	struct uni_addr	addr;
537131826Sharti};
538131826Sharti
539131826Sharti/* signal to connection */
540131826Shartiint cc_conn_sig(struct ccconn *, enum conn_sig, void *arg);
541131826Sharti
542131826Sharti/* signal with message to connection */
543131826Shartiint cc_conn_sig_msg(struct ccconn *, enum conn_sig, struct uni_msg *);
544131826Shartiint cc_conn_sig_msg_nodef(struct ccconn *, enum conn_sig, struct uni_msg *);
545131826Sharti
546131826Sharti/* response signal to connection */
547131826Shartiint cc_conn_resp(struct ccconn *, enum conn_sig, u_int, u_int, u_int);
548131826Sharti
549131826Sharti/* flush all signals to a given connection */
550131826Shartivoid cc_conn_sig_flush(struct ccconn *);
551131826Sharti
552131826Sharti/* Queue a signal to this user */
553131826Shartiint cc_user_sig(struct ccuser *, enum user_sig, void *, u_int);
554131826Sharti
555131826Sharti/* Queue a signal with message to this user */
556131826Shartiint cc_user_sig_msg(struct ccuser *, enum user_sig, struct uni_msg *);
557131826Sharti
558131826Sharti/* Flush all signals to a given user */
559131826Shartivoid cc_user_sig_flush(struct ccuser *);
560131826Sharti
561131826Sharti/* flush all signals */
562131826Shartivoid cc_sig_flush_all(struct ccdata *);
563