3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/sscop.c,v 1.6.2.1 2001/09/30 22:54:35 kris Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * Service Specific Connection Oriented Protocol (SSCOP)
38 #include <netatm/kern_include.h>
40 #include <netatm/uni/sscop.h>
41 #include <netatm/uni/sscop_misc.h>
42 #include <netatm/uni/sscop_pdu.h>
43 #include <netatm/uni/sscop_var.h>
46 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscop.c,v 1.6.2.1 2001/09/30 22:54:35 kris Exp $");
55 struct sscop *sscop_head = NULL;
57 struct sscop_stat sscop_stat = {0};
59 struct atm_time sscop_timer = {0, 0};
61 struct sp_info sscop_pool = {
62 "sscop pool", /* si_name */
63 sizeof(struct sscop), /* si_blksiz */
72 static int sscop_inst __P((struct stack_defn **, Atm_connvc *));
78 static struct stack_defn sscop_service = {
88 static struct t_atm_cause sscop_cause = {
91 T_ATM_CAUSE_TEMPORARY_FAILURE,
95 static u_char sscop_maa_log[MAA_ERROR_COUNT] = {
125 * Initialize SSCOP processing
127 * This will be called during module loading. We will register our stack
128 * service and wait for someone to talk to us.
134 * 0 initialization was successful
135 * errno initialization failed - reason indicated
144 * Register stack service
146 if ((err = atm_stack_register(&sscop_service)) != 0)
152 atm_timeout(&sscop_timer, ATM_HZ/SSCOP_HZ, sscop_timeout);
160 * Terminate SSCOP processing
162 * This will be called just prior to unloading the module from memory. All
163 * signalling instances should have been terminated by now, so we just free
164 * up all of our resources.
172 * 0 termination was successful
173 * errno termination failed - reason indicated
182 * Any connections still exist??
187 * Yes, can't stop yet
195 (void) atm_untimeout(&sscop_timer);
198 * Deregister the stack service
200 (void) atm_stack_deregister(&sscop_service);
203 * Free our storage pools
205 atm_release_pool(&sscop_pool);
212 * SSCOP Stack Instantiation
217 * ssp pointer to array of stack definition pointers for connection
218 * ssp[0] points to upper layer's stack service definition
219 * ssp[1] points to this layer's stack service definition
220 * ssp[2] points to lower layer's stack service definition
221 * cvp pointer to connection vcc for this stack
224 * 0 instantiation successful
225 * errno instantiation failed - reason indicated
230 struct stack_defn **ssp;
233 struct stack_defn *sdp_up = ssp[0],
239 ATM_DEBUG2("sscop_inst: ssp=%p, cvp=%p\n", ssp, cvp);
244 if ((sdp_low->sd_sap & SAP_CLASS_MASK) != SAP_CPCS)
248 * Allocate our control block
250 sop = (struct sscop *)atm_allocate(&sscop_pool);
254 sop->so_state = SOS_INST;
255 sop->so_connvc = cvp;
256 sop->so_toku = sdp_up->sd_toku;
257 sop->so_upper = sdp_up->sd_upper;
260 * Store my token into service definition
262 sdp_me->sd_toku = sop;
265 * Update and save input buffer headroom
267 HEADIN(cvp, sizeof(struct pdu_hdr), 0);
268 /* sop->so_headin = cvp->cvc_attr.headin; */
271 * Pass instantiation down the stack
273 err = sdp_low->sd_inst(ssp + 1, cvp);
276 * Lower layer instantiation failed, free our resources
278 atm_free((caddr_t)sop);
283 * Link in connection block
285 LINK2TAIL(sop, struct sscop, sscop_head, so_next);
287 sscop_stat.sos_connects++;
290 * Save and update output buffer headroom
292 sop->so_headout = cvp->cvc_attr.headout;
293 HEADOUT(cvp, sizeof(struct pdu_hdr), 0);
296 * Save lower layer's interface info
298 sop->so_lower = sdp_low->sd_lower;
299 sop->so_tokl = sdp_low->sd_toku;
302 * Initialize version (until INIT received)
304 sop->so_vers = SSCOP_VERS_Q2110;
311 * Report Management Error
313 * Called to report an error to the layer management entity.
316 * sop pointer to sscop control block
324 sscop_maa_error(sop, code)
331 * Validate error code
333 if ((code < MAA_ERROR_MIN) ||
334 (code > MAA_ERROR_MAX))
335 code = MAA_ERROR_INVAL;
336 i = code - MAA_ERROR_MIN;
339 * Bump statistics counters
341 sscop_stat.sos_maa_error[i]++;
346 if (sscop_maa_log[i] != 0) {
347 struct vccb *vcp = sop->so_connvc->cvc_vcc;
348 struct atm_pif *pip = vcp->vc_pif;
351 "sscop_maa_error: intf=%s%d vpi=%d vci=%d code=%c state=%d\n",
352 pip->pif_name, pip->pif_unit,
353 vcp->vc_vpi, vcp->vc_vci, code, sop->so_state);
359 * Abort an SSCOP connection
361 * Called when an unrecoverable or "should never happen" error occurs.
362 * We log a message, send an END PDU to our peer and request the signalling
363 * manager to abort the connection.
366 * sop pointer to sscop control block
367 * msg pointer to error message
374 sscop_abort(sop, msg)
378 Atm_connvc *cvp = sop->so_connvc;
381 * Log and count error
383 log(LOG_ERR, "%s", msg);
384 sscop_stat.sos_aborts++;
387 * Send an END PDU as a courtesy to peer
389 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
392 * Set termination state
394 sop->so_state = SOS_TERM;
397 * Flush all of our queues
399 sscop_xmit_drain(sop);
400 sscop_rcvr_drain(sop);
403 * Tell Connection Manager to abort this connection
405 (void) atm_cm_abort(cvp, &sscop_cause);