1 /*
2 * Copyright (c) 2004
3 *	Hartmut Brandt
4 *	All rights reserved.
5 *
6 * Author: Harti Brandt <[email protected]>
7 *
8 * Redistribution of this software and documentation and use in source and
9 * binary forms, with or without modification, are permitted provided that
10 * the following conditions are met:
11 *
12 * 1. Redistributions of source code or documentation must retain the above
13 *    copyright notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
19 * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
22 * THE AUTHOR OR ITS CONTRIBUTORS  BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $Begemot: libunimsg/netnatm/api/cc_data.c,v 1.1 2004/07/08 08:21:50 brandt Exp $
31 *
32 * ATM API as defined per af-saa-0108
33 */
34 #include <netnatm/unimsg.h>
35 #include <netnatm/msg/unistruct.h>
36 #include <netnatm/msg/unimsglib.h>
37 #include <netnatm/api/unisap.h>
38 #include <netnatm/sig/unidef.h>
39 #include <netnatm/api/atmapi.h>
40 #include <netnatm/api/ccatm.h>
41 #include <netnatm/api/ccpriv.h>
42 
43 /*
44  * Create a new call control instance
45  */
46 struct ccdata *
cc_create(const struct cc_funcs * vtab)47 cc_create(const struct cc_funcs *vtab)
48 {
49 	struct ccdata *cc;
50 
51 	cc = CCMALLOC(sizeof(*cc));
52 	if (cc == NULL)
53 		return (NULL);
54 
55 	LIST_INIT(&cc->user_list);
56 	TAILQ_INIT(&cc->port_list);
57 	LIST_INIT(&cc->orphaned_conns);
58 	TAILQ_INIT(&cc->sigs);
59 	TAILQ_INIT(&cc->def_sigs);
60 	TAILQ_INIT(&cc->free_sigs);
61 	cc->funcs = vtab;
62 	cc->cookie = 0;
63 
64 	return (cc);
65 }
66 
67 /*
68  * Reset everything the hard way by just freeing the data
69  */
70 void
cc_reset(struct ccdata * cc)71 cc_reset(struct ccdata *cc)
72 {
73 
74 	while (!LIST_EMPTY(&cc->user_list))
75 		cc_user_destroy(LIST_FIRST(&cc->user_list));
76 
77 	while (!TAILQ_EMPTY(&cc->port_list))
78 		cc_port_destroy(TAILQ_FIRST(&cc->port_list), 1);
79 
80 	while (!LIST_EMPTY(&cc->orphaned_conns))
81 		cc_conn_destroy(LIST_FIRST(&cc->orphaned_conns));
82 
83 	CCASSERT(LIST_EMPTY(&cc->user_list),
84 	    ("user list not empty"));
85 	CCASSERT(LIST_EMPTY(&cc->orphaned_conns),
86 	    ("still orphaned conns"));
87 
88 	cc_sig_flush_all(cc);
89 
90 	cc->cookie = 0;
91 }
92 
93 /*
94  * Destroy a call control instance and free all data
95  */
96 void
cc_destroy(struct ccdata * cc)97 cc_destroy(struct ccdata *cc)
98 {
99 
100 	cc_reset(cc);
101 	CCFREE(cc);
102 }
103 
104 /*
105  * set/get logging flags
106  */
107 void
cc_set_log(struct ccdata * cc,u_int flags)108 cc_set_log(struct ccdata *cc, u_int flags)
109 {
110 	cc->log = flags;
111 }
112 u_int
cc_get_log(const struct ccdata * cc)113 cc_get_log(const struct ccdata *cc)
114 {
115 	return (cc->log);
116 }
117 
118 /* get extended status */
119 int
cc_get_extended_status(const struct ccdata * cc,struct atm_exstatus * status,struct atm_exstatus_ep ** pep,struct atm_exstatus_port ** pport,struct atm_exstatus_conn ** pconn,struct atm_exstatus_party ** pparty)120 cc_get_extended_status(const struct ccdata *cc, struct atm_exstatus *status,
121     struct atm_exstatus_ep **pep, struct atm_exstatus_port **pport,
122     struct atm_exstatus_conn **pconn, struct atm_exstatus_party **pparty)
123 {
124 	const struct ccuser *user;
125 	const struct ccport *port;
126 	const struct ccconn *conn;
127 	const struct ccparty *party;
128 	struct atm_exstatus_ep *eep;
129 	struct atm_exstatus_port *eport;
130 	struct atm_exstatus_conn *econn;
131 	struct atm_exstatus_party *eparty;
132 
133 	/* count and allocate */
134 	status->neps = 0;
135 	LIST_FOREACH(user, &cc->user_list, node_link)
136 		status->neps++;
137 
138 	status->nports = 0;
139 	status->nconns = 0;
140 	status->nparties = 0;
141 	LIST_FOREACH(conn, &cc->orphaned_conns, port_link) {
142 		status->nconns++;
143 		LIST_FOREACH(party, &conn->parties, link)
144 			status->nparties++;
145 	}
146 	TAILQ_FOREACH(port, &cc->port_list, node_link) {
147 		status->nports++;
148 		LIST_FOREACH(conn, &port->conn_list, port_link) {
149 			status->nconns++;
150 			LIST_FOREACH(party, &conn->parties, link)
151 				status->nparties++;
152 		}
153 	}
154 
155 	*pep = CCMALLOC(sizeof(**pep) * status->neps);
156 	*pport = CCMALLOC(sizeof(**pport) * status->nports);
157 	*pconn = CCMALLOC(sizeof(**pconn) * status->nconns);
158 	*pparty = CCMALLOC(sizeof(**pparty) * status->nparties);
159 
160 	if (*pep == NULL || *pport == NULL ||
161 	    *pconn == NULL || *pparty == NULL) {
162 		CCFREE(*pep);
163 		CCFREE(*pport);
164 		CCFREE(*pconn);
165 		CCFREE(*pparty);
166 		return (ENOMEM);
167 	}
168 
169 	eep = *pep;
170 	eport = *pport;
171 	econn = *pconn;
172 	eparty = *pparty;
173 
174 	/* collect information */
175 	LIST_FOREACH(user, &cc->user_list, node_link) {
176 		strcpy(eep->name, user->name);
177 		eep->state = user->state;
178 		eep++;
179 	}
180 
181 	LIST_FOREACH(conn, &cc->orphaned_conns, port_link) {
182 		econn->id = econn - *pconn;
183 		econn->port = 0;
184 		if (conn->user != NULL)
185 			strcpy(econn->ep, conn->user->name);
186 		else
187 			econn->ep[0] = '\0';
188 		econn->state = conn->state;
189 		econn->cref = conn->cref.cref;
190 		if (conn->cref.flag)
191 			econn->cref |= (1 << 23);
192 		LIST_FOREACH(party, &conn->parties, link) {
193 			eparty->connid = econn - *pconn;
194 			eparty->epref = party->epref.epref;
195 			eparty->state = party->state;
196 			eparty++;
197 		}
198 		econn++;
199 	}
200 
201 	TAILQ_FOREACH(port, &cc->port_list, node_link) {
202 		eport->portno = port->param.port;
203 		eport->state = port->admin;
204 		LIST_FOREACH(conn, &port->conn_list, port_link) {
205 			econn->id = econn - *pconn;
206 			econn->port = port->param.port;
207 			if (conn->user != NULL)
208 				strcpy(econn->ep, conn->user->name);
209 			else
210 				econn->ep[0] = '\0';
211 			econn->state = conn->state;
212 			econn->cref = conn->cref.cref;
213 			if (conn->cref.flag)
214 				econn->cref |= (1 << 23);
215 			LIST_FOREACH(party, &conn->parties, link) {
216 				eparty->connid = econn - *pconn;
217 				eparty->epref = party->epref.epref;
218 				eparty->state = party->state;
219 				eparty++;
220 			}
221 			econn++;
222 		}
223 		eport++;
224 	}
225 	return (0);
226 }
227