diff options
Diffstat (limited to 'sys/netatm/uni/sscf_uni_upper.c')
-rw-r--r-- | sys/netatm/uni/sscf_uni_upper.c | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/sys/netatm/uni/sscf_uni_upper.c b/sys/netatm/uni/sscf_uni_upper.c new file mode 100644 index 0000000..2febb5c --- /dev/null +++ b/sys/netatm/uni/sscf_uni_upper.c @@ -0,0 +1,625 @@ +/* + * + * =================================== + * HARP | Host ATM Research Platform + * =================================== + * + * + * This Host ATM Research Platform ("HARP") file (the "Software") is + * made available by Network Computing Services, Inc. ("NetworkCS") + * "AS IS". NetworkCS does not provide maintenance, improvements or + * support of any kind. + * + * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE + * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. + * In no event shall NetworkCS be responsible for any damages, including + * but not limited to consequential damages, arising from or relating to + * any use of the Software or related support. + * + * Copyright 1994-1998 Network Computing Services, Inc. + * + * Copies of this Software may be made, however, the above copyright + * notice must be reproduced on all copies. + * + * @(#) $Id: sscf_uni_upper.c,v 1.7 1998/06/29 22:15:31 mks Exp $ + * + */ + +/* + * ATM Forum UNI Support + * --------------------- + * + * SSCF UNI - SSCOP SAP interface processing + * + */ + +#ifndef lint +static char *RCSid = "@(#) $Id: sscf_uni_upper.c,v 1.7 1998/06/29 22:15:31 mks Exp $"; +#endif + +#include <netatm/kern_include.h> + +#include <netatm/uni/uni.h> +#include <netatm/uni/sscop.h> +#include <netatm/uni/sscf_uni.h> +#include <netatm/uni/sscf_uni_var.h> + + +/* + * SSCF_UNI Upper Stack Command Handler + * + * This function will receive all of the stack commands issued from the + * layer below SSCF UNI (ie. SSCOP). + * + * Arguments: + * cmd stack command code + * tok session token + * arg1 command specific argument + * arg2 command specific argument + * + * Returns: + * none + * + */ +void +sscf_uni_upper(cmd, tok, arg1, arg2) + int cmd; + void *tok; + int arg1; + int arg2; +{ + struct univcc *uvp = (struct univcc *)tok; + Atm_connvc *cvp = uvp->uv_connvc; + int err; + + ATM_DEBUG5("sscf_uni_upper: cmd=0x%x, uvp=0x%x, lstate=%d, arg1=0x%x, arg2=0x%x\n", + cmd, (int)uvp, uvp->uv_lstate, arg1, arg2); + + switch (cmd) { + + case SSCOP_ESTABLISH_IND: + /* + * We don't support SSCOP User-to-User data, so just + * get rid of any supplied to us + */ + if (arg1 != SSCOP_UU_NULL) + KB_FREEALL((KBuffer *)arg1); + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_READY: + if (uvp->uv_vers != UNI_VERS_3_0) { + goto seqerr; + } + goto doestind; + + case UVL_IDLE: + /* + * Incoming connection establishment request + */ + + /* + * If user doesn't want any more incoming sessions + * accepted, then refuse request + */ + if (uvp->uv_flags & UVF_NOESTIND) { + STACK_CALL(SSCOP_RELEASE_REQ, uvp->uv_lower, + uvp->uv_tokl, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, + "sscf_uni: stack memory\n"); + return; + } + break; + } + +doestind: + /* + * Tell sscop we've accepted the new connection + */ + uvp->uv_lstate = UVL_READY; + STACK_CALL(SSCOP_ESTABLISH_RSP, uvp->uv_lower, + uvp->uv_tokl, cvp, + SSCOP_UU_NULL, SSCOP_BR_YES, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + + /* + * Now notify the user of the new connection + */ + uvp->uv_ustate = UVU_ACTIVE; + STACK_CALL(SSCF_UNI_ESTABLISH_IND, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + default: +seqerr: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_ESTABLISH_CNF: + /* + * We don't support SSCOP User-to-User data, so just + * get rid of any supplied to us + */ + if (arg1 != SSCOP_UU_NULL) + KB_FREEALL((KBuffer *)arg1); + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_OUTCONN: + /* + * Outgoing connection establishment completed + */ + + /* + * Tell the user that the connection is established + */ + uvp->uv_ustate = UVU_ACTIVE; + uvp->uv_lstate = UVL_READY; + STACK_CALL(SSCF_UNI_ESTABLISH_CNF, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + case UVL_READY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RELEASE_IND: + /* + * We don't support SSCOP User-to-User data, so just + * get rid of any supplied to us + */ + if (arg1 != SSCOP_UU_NULL) + KB_FREEALL((KBuffer *)arg1); + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_OUTCONN: + case UVL_OUTRESYN: + case UVL_READY: + /* + * Peer requesting connection termination + */ + + /* + * Notify the user that the connection + * has been terminated + */ + uvp->uv_ustate = UVU_RELEASED; + uvp->uv_lstate = UVL_IDLE; + STACK_CALL(SSCF_UNI_RELEASE_IND, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_INRESYN: + case UVL_RECOVERY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RELEASE_CNF: + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_OUTDISC: + /* + * Peer acknowledging connection termination + */ + + /* + * Notify the user that the connection + * termination is completed + */ + uvp->uv_ustate = UVU_RELEASED; + uvp->uv_lstate = UVL_IDLE; + STACK_CALL(SSCF_UNI_RELEASE_CNF, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + case UVL_READY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_DATA_IND: +#ifdef notdef + sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "DATA_IND"); +#endif + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_READY: + /* + * Incoming assured data from peer + */ + + /* + * Pass the data up to the user + */ + STACK_CALL(SSCF_UNI_DATA_IND, uvp->uv_upper, + uvp->uv_toku, cvp, + arg1, 0, err); + if (err) { + KB_FREEALL((KBuffer *)arg1); + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + KB_FREEALL((KBuffer *)arg1); + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + default: + KB_FREEALL((KBuffer *)arg1); + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RESYNC_IND: + /* + * We don't support SSCOP User-to-User data, so just + * get rid of any supplied to us + */ + if (arg1 != SSCOP_UU_NULL) + KB_FREEALL((KBuffer *)arg1); + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_READY: + /* + * Incoming connection resynchronization request + */ + + /* + * Send resynch acknowledgement to sscop + */ + STACK_CALL(SSCOP_RESYNC_RSP, uvp->uv_lower, + uvp->uv_tokl, cvp, + 0, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + + if (uvp->uv_vers != UNI_VERS_3_0) { + + /* + * Notify the user that the connection + * has been resynced + */ + STACK_CALL(SSCF_UNI_ESTABLISH_IND, + uvp->uv_upper, uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, + "sscf_uni: stack memory\n"); + return; + } + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RESYNC_CNF: + /* + * Not supported in version 3.0 + */ + if (uvp->uv_vers == UNI_VERS_3_0) { + sscf_uni_abort(uvp, + "sscf_uni: SSCOP_RESYNC_CNF in 3.0\n"); + return; + } + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_OUTRESYN: + /* + * Peer acknowledging connection resynchronization + */ + + /* + * Now notify the user that the connection + * has been resynced + */ + uvp->uv_ustate = UVU_ACTIVE; + uvp->uv_lstate = UVL_READY; + STACK_CALL(SSCF_UNI_ESTABLISH_CNF, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_INRESYN: + case UVL_RECOVERY: + case UVL_READY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RECOVER_IND: + /* + * Not supported in version 3.0 + */ + if (uvp->uv_vers == UNI_VERS_3_0) { + sscf_uni_abort(uvp, + "sscf_uni: SSCOP_RECOVER_IND in 3.0\n"); + return; + } + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_READY: + /* + * Recover connection due to internal problems + */ + + /* + * Send recovery acknowledgement to sscop + */ + STACK_CALL(SSCOP_RECOVER_RSP, uvp->uv_lower, + uvp->uv_tokl, cvp, + 0, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + + /* + * Now notify the user that the connection + * has been recovered + */ + STACK_CALL(SSCF_UNI_ESTABLISH_IND, uvp->uv_upper, + uvp->uv_toku, cvp, + SSCOP_UU_NULL, 0, err); + if (err) { + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + break; + + case UVL_INST: + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + default: + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_UNITDATA_IND: +#ifdef notdef + sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "UNITDATA_IND"); +#endif + + /* + * Validation based on sscop state + */ + switch (uvp->uv_lstate) { + + case UVL_IDLE: + case UVL_OUTCONN: + case UVL_INCONN: + case UVL_OUTDISC: + case UVL_OUTRESYN: + case UVL_INRESYN: + case UVL_RECOVERY: + case UVL_READY: + /* + * Incoming unassured data from peer + */ + + /* + * Pass the data up to the user + */ + STACK_CALL(SSCF_UNI_UNITDATA_IND, uvp->uv_upper, + uvp->uv_toku, cvp, + arg1, 0, err); + if (err) { + KB_FREEALL((KBuffer *)arg1); + sscf_uni_abort(uvp, "sscf_uni: stack memory\n"); + return; + } + break; + + case UVL_TERM: + /* + * Ignoring everything + */ + KB_FREEALL((KBuffer *)arg1); + break; + + case UVL_INST: + default: + KB_FREEALL((KBuffer *)arg1); + log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n", + cmd, uvp->uv_lstate); + sscf_uni_abort(uvp, "sscf_uni: sequence err\n"); + } + break; + + case SSCOP_RETRIEVE_IND: + case SSCOP_RETRIEVECMP_IND: + /* + * Not supported + */ + default: + log(LOG_ERR, "sscf_uni_upper: unknown cmd 0x%x, uvp=0x%x\n", + cmd, (int)uvp); + } + + return; +} + |