1/* 2* Copyright (c) 2004 3* Hartmut Brandt 4* All rights reserved. 5* 6* Author: Harti Brandt <harti@freebsd.org> 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 */ 46struct ccdata * 47cc_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 */ 70void 71cc_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 */ 96void 97cc_destroy(struct ccdata *cc) 98{ 99 100 cc_reset(cc); 101 CCFREE(cc); 102} 103 104/* 105 * set/get logging flags 106 */ 107void 108cc_set_log(struct ccdata *cc, u_int flags) 109{ 110 cc->log = flags; 111} 112u_int 113cc_get_log(const struct ccdata *cc) 114{ 115 return (cc->log); 116} 117 118/* get extended status */ 119int 120cc_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