1131826Sharti/*
2131826Sharti* Copyright (c) 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*
30131826Sharti* $Begemot: libunimsg/netnatm/api/cc_data.c,v 1.1 2004/07/08 08:21:50 brandt Exp $
31131826Sharti*
32131826Sharti* ATM API as defined per af-saa-0108
33131826Sharti*/
34131826Sharti#include <netnatm/unimsg.h>
35131826Sharti#include <netnatm/msg/unistruct.h>
36131826Sharti#include <netnatm/msg/unimsglib.h>
37131826Sharti#include <netnatm/api/unisap.h>
38131826Sharti#include <netnatm/sig/unidef.h>
39131826Sharti#include <netnatm/api/atmapi.h>
40131826Sharti#include <netnatm/api/ccatm.h>
41131826Sharti#include <netnatm/api/ccpriv.h>
42131826Sharti
43131826Sharti/*
44131826Sharti * Create a new call control instance
45131826Sharti */
46131826Shartistruct ccdata *
47131826Sharticc_create(const struct cc_funcs *vtab)
48131826Sharti{
49131826Sharti	struct ccdata *cc;
50131826Sharti
51131826Sharti	cc = CCMALLOC(sizeof(*cc));
52131826Sharti	if (cc == NULL)
53131826Sharti		return (NULL);
54131826Sharti
55131826Sharti	LIST_INIT(&cc->user_list);
56131826Sharti	TAILQ_INIT(&cc->port_list);
57131826Sharti	LIST_INIT(&cc->orphaned_conns);
58131826Sharti	TAILQ_INIT(&cc->sigs);
59131826Sharti	TAILQ_INIT(&cc->def_sigs);
60131826Sharti	TAILQ_INIT(&cc->free_sigs);
61131826Sharti	cc->funcs = vtab;
62131826Sharti	cc->cookie = 0;
63131826Sharti
64131826Sharti	return (cc);
65131826Sharti}
66131826Sharti
67131826Sharti/*
68131826Sharti * Reset everything the hard way by just freeing the data
69131826Sharti */
70131826Shartivoid
71131826Sharticc_reset(struct ccdata *cc)
72131826Sharti{
73131826Sharti
74131826Sharti	while (!LIST_EMPTY(&cc->user_list))
75131826Sharti		cc_user_destroy(LIST_FIRST(&cc->user_list));
76131826Sharti
77131826Sharti	while (!TAILQ_EMPTY(&cc->port_list))
78131826Sharti		cc_port_destroy(TAILQ_FIRST(&cc->port_list), 1);
79131826Sharti
80131826Sharti	while (!LIST_EMPTY(&cc->orphaned_conns))
81131826Sharti		cc_conn_destroy(LIST_FIRST(&cc->orphaned_conns));
82131826Sharti
83131826Sharti	CCASSERT(LIST_EMPTY(&cc->user_list),
84131826Sharti	    ("user list not empty"));
85131826Sharti	CCASSERT(LIST_EMPTY(&cc->orphaned_conns),
86131826Sharti	    ("still orphaned conns"));
87131826Sharti
88131826Sharti	cc_sig_flush_all(cc);
89131826Sharti
90131826Sharti	cc->cookie = 0;
91131826Sharti}
92131826Sharti
93131826Sharti/*
94131826Sharti * Destroy a call control instance and free all data
95131826Sharti */
96131826Shartivoid
97131826Sharticc_destroy(struct ccdata *cc)
98131826Sharti{
99131826Sharti
100131826Sharti	cc_reset(cc);
101131826Sharti	CCFREE(cc);
102131826Sharti}
103131826Sharti
104131826Sharti/*
105131826Sharti * set/get logging flags
106131826Sharti */
107131826Shartivoid
108131826Sharticc_set_log(struct ccdata *cc, u_int flags)
109131826Sharti{
110131826Sharti	cc->log = flags;
111131826Sharti}
112131826Shartiu_int
113131826Sharticc_get_log(const struct ccdata *cc)
114131826Sharti{
115131826Sharti	return (cc->log);
116131826Sharti}
117131826Sharti
118131826Sharti/* get extended status */
119131826Shartiint
120131826Sharticc_get_extended_status(const struct ccdata *cc, struct atm_exstatus *status,
121131826Sharti    struct atm_exstatus_ep **pep, struct atm_exstatus_port **pport,
122131826Sharti    struct atm_exstatus_conn **pconn, struct atm_exstatus_party **pparty)
123131826Sharti{
124131826Sharti	const struct ccuser *user;
125131826Sharti	const struct ccport *port;
126131826Sharti	const struct ccconn *conn;
127131826Sharti	const struct ccparty *party;
128131826Sharti	struct atm_exstatus_ep *eep;
129131826Sharti	struct atm_exstatus_port *eport;
130131826Sharti	struct atm_exstatus_conn *econn;
131131826Sharti	struct atm_exstatus_party *eparty;
132131826Sharti
133131826Sharti	/* count and allocate */
134131826Sharti	status->neps = 0;
135131826Sharti	LIST_FOREACH(user, &cc->user_list, node_link)
136131826Sharti		status->neps++;
137131826Sharti
138131826Sharti	status->nports = 0;
139131826Sharti	status->nconns = 0;
140131826Sharti	status->nparties = 0;
141131826Sharti	LIST_FOREACH(conn, &cc->orphaned_conns, port_link) {
142131826Sharti		status->nconns++;
143131826Sharti		LIST_FOREACH(party, &conn->parties, link)
144131826Sharti			status->nparties++;
145131826Sharti	}
146131826Sharti	TAILQ_FOREACH(port, &cc->port_list, node_link) {
147131826Sharti		status->nports++;
148131826Sharti		LIST_FOREACH(conn, &port->conn_list, port_link) {
149131826Sharti			status->nconns++;
150131826Sharti			LIST_FOREACH(party, &conn->parties, link)
151131826Sharti				status->nparties++;
152131826Sharti		}
153131826Sharti	}
154131826Sharti
155131826Sharti	*pep = CCMALLOC(sizeof(**pep) * status->neps);
156131826Sharti	*pport = CCMALLOC(sizeof(**pport) * status->nports);
157131826Sharti	*pconn = CCMALLOC(sizeof(**pconn) * status->nconns);
158131826Sharti	*pparty = CCMALLOC(sizeof(**pparty) * status->nparties);
159131826Sharti
160131826Sharti	if (*pep == NULL || *pport == NULL ||
161131826Sharti	    *pconn == NULL || *pparty == NULL) {
162131826Sharti		CCFREE(*pep);
163131826Sharti		CCFREE(*pport);
164131826Sharti		CCFREE(*pconn);
165131826Sharti		CCFREE(*pparty);
166131826Sharti		return (ENOMEM);
167131826Sharti	}
168131826Sharti
169131826Sharti	eep = *pep;
170131826Sharti	eport = *pport;
171131826Sharti	econn = *pconn;
172131826Sharti	eparty = *pparty;
173131826Sharti
174131826Sharti	/* collect information */
175131826Sharti	LIST_FOREACH(user, &cc->user_list, node_link) {
176131826Sharti		strcpy(eep->name, user->name);
177131826Sharti		eep->state = user->state;
178131826Sharti		eep++;
179131826Sharti	}
180131826Sharti
181131826Sharti	LIST_FOREACH(conn, &cc->orphaned_conns, port_link) {
182131826Sharti		econn->id = econn - *pconn;
183131826Sharti		econn->port = 0;
184131826Sharti		if (conn->user != NULL)
185131826Sharti			strcpy(econn->ep, conn->user->name);
186131826Sharti		else
187131826Sharti			econn->ep[0] = '\0';
188131826Sharti		econn->state = conn->state;
189131826Sharti		econn->cref = conn->cref.cref;
190131826Sharti		if (conn->cref.flag)
191131826Sharti			econn->cref |= (1 << 23);
192131826Sharti		LIST_FOREACH(party, &conn->parties, link) {
193131826Sharti			eparty->connid = econn - *pconn;
194131826Sharti			eparty->epref = party->epref.epref;
195131826Sharti			eparty->state = party->state;
196131826Sharti			eparty++;
197131826Sharti		}
198131826Sharti		econn++;
199131826Sharti	}
200131826Sharti
201131826Sharti	TAILQ_FOREACH(port, &cc->port_list, node_link) {
202131826Sharti		eport->portno = port->param.port;
203131826Sharti		eport->state = port->admin;
204131826Sharti		LIST_FOREACH(conn, &port->conn_list, port_link) {
205131826Sharti			econn->id = econn - *pconn;
206131826Sharti			econn->port = port->param.port;
207131826Sharti			if (conn->user != NULL)
208131826Sharti				strcpy(econn->ep, conn->user->name);
209131826Sharti			else
210131826Sharti				econn->ep[0] = '\0';
211131826Sharti			econn->state = conn->state;
212131826Sharti			econn->cref = conn->cref.cref;
213131826Sharti			if (conn->cref.flag)
214131826Sharti				econn->cref |= (1 << 23);
215131826Sharti			LIST_FOREACH(party, &conn->parties, link) {
216131826Sharti				eparty->connid = econn - *pconn;
217131826Sharti				eparty->epref = party->epref.epref;
218131826Sharti				eparty->state = party->state;
219131826Sharti				eparty++;
220131826Sharti			}
221131826Sharti			econn++;
222131826Sharti		}
223131826Sharti		eport++;
224131826Sharti	}
225131826Sharti	return (0);
226131826Sharti}
227