📄 llc_subr.c
字号:
break; case NL_DISCONNECT_REQUEST: if (LLC_GETFLAG(linkp, S) == 0) { llc_send(linkp, LLCFT_DISC, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_NEWSTATE(linkp, D_CONN); } else { llc_send(linkp, LLCFT_DM, LLC_RSP, LLC_GETFLAG(linkp, F)); LLC_NEWSTATE(linkp, ADM); } break; case LLCFT_DM + LLC_RSP: LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_SABME + LLC_CMD: LLC_SETFLAG(linkp, S, 1); LLC_SETFLAG(linkp, F, pollfinal); break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_DM, LLC_RSP, pollfinal); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; } return action;}/* * RESET_CHECK --- The local connection component is waiting for the local user * to accept or refuse a remote reset request. */intllc_state_RESET_CHECK(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case NL_RESET_RESPONSE: llc_send(linkp, LLCFT_UA, LLC_RSP, LLC_GETFLAG(linkp, F)); LLC_RESETCOUNTER(linkp); LLC_SETFLAG(linkp, P, 0); LLC_SETFLAG(linkp, REMOTE_BUSY, 0); LLC_NEWSTATE(linkp, NORMAL); break; case NL_DISCONNECT_REQUEST: llc_send(linkp, LLCFT_DM, LLC_RSP, LLC_GETFLAG(linkp, F)); LLC_NEWSTATE(linkp, ADM); break; case LLCFT_DM + LLC_RSP: action = LLC_DISCONNECT_INDICATION; break; case LLCFT_SABME + LLC_CMD: LLC_SETFLAG(linkp, F, pollfinal); break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_DM, LLC_RSP, pollfinal); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; } return action;}/* * SETUP --- The connection component has transmitted an SABME command PDU to a * remote LLC DSAP and is waiting for a reply. */intllc_state_SETUP(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case LLCFT_SABME + LLC_CMD: LLC_RESETCOUNTER(linkp); llc_send(linkp, LLCFT_UA, LLC_RSP, pollfinal); LLC_SETFLAG(linkp, S, 1); break; case LLCFT_UA + LLC_RSP: if (LLC_GETFLAG(linkp, P) == pollfinal) { LLC_STOP_ACK_TIMER(linkp); LLC_RESETCOUNTER(linkp); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_SETFLAG(linkp, REMOTE_BUSY, 0); LLC_NEWSTATE(linkp, NORMAL); action = LLC_CONNECT_CONFIRM; } break; case LLC_ACK_TIMER_EXPIRED: if (LLC_GETFLAG(linkp, S) == 1) { LLC_SETFLAG(linkp, P, 0); LLC_SETFLAG(linkp, REMOTE_BUSY, 0), LLC_NEWSTATE(linkp, NORMAL); action = LLC_CONNECT_CONFIRM; } else if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_SABME, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry++; } else { LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; } break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_DM, LLC_RSP, pollfinal); LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_DM + LLC_RSP: LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; } return action;}/* * RESET --- As a result of a service access point user request or the receipt * of a FRMR response PDU, the local connection component has sent an * SABME command PDU to the remote LLC DSAP to reset the data link * connection and is waiting for a reply. */intllc_state_RESET(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case LLCFT_SABME + LLC_CMD: LLC_RESETCOUNTER(linkp); LLC_SETFLAG(linkp, S, 1); llc_send(linkp, LLCFT_UA, LLC_RSP, pollfinal); break; case LLCFT_UA + LLC_RSP: if (LLC_GETFLAG(linkp, P) == pollfinal) { LLC_STOP_ACK_TIMER(linkp); LLC_RESETCOUNTER(linkp); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_SETFLAG(linkp, REMOTE_BUSY, 0); LLC_NEWSTATE(linkp, NORMAL); action = LLC_RESET_CONFIRM; } break; case LLC_ACK_TIMER_EXPIRED: if (LLC_GETFLAG(linkp, S) == 1) { LLC_SETFLAG(linkp, P, 0); LLC_SETFLAG(linkp, REMOTE_BUSY, 0); LLC_NEWSTATE(linkp, NORMAL); action = LLC_RESET_CONFIRM; } else if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_SABME, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry++; } else { LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; } break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_DM, LLC_RSP, pollfinal); LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_DM + LLC_RSP: LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; } return action;}/* * D_CONN --- At the request of the service access point user, the local LLC * has sent a DISC command PDU to the remote LLC DSAP and is waiting * for a reply. */intllc_state_D_CONN(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case LLCFT_SABME + LLC_CMD: llc_send(linkp, LLCFT_DM, LLC_RSP, pollfinal); LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); break; case LLCFT_UA + LLC_RSP: if (LLC_GETFLAG(linkp, P) == pollfinal) { LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); } break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_UA, LLC_RSP, pollfinal); break; case LLCFT_DM + LLC_RSP: LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); break; case LLC_ACK_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_DISC, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry++; } else LLC_NEWSTATE(linkp, ADM); break; } return action;}/* * ERROR --- The local connection component has detected an error in a received * PDU and has sent a FRMR response PDU. It is waiting for a reply from * the remote connection component. */intllc_state_ERROR(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case LLCFT_SABME + LLC_CMD: LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, RESET_CHECK); action = LLC_RESET_INDICATION_REMOTE; break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_UA, LLC_RSP, pollfinal); LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_DM + LLC_RSP: LLC_STOP_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_FRMR + LLC_RSP: LLC_STOP_ACK_TIMER(linkp); LLC_SETFLAG(linkp, S, 0); LLC_NEWSTATE(linkp, RESET_WAIT); action = LLC_FRMR_RECEIVED; break; case LLC_ACK_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_FRMR, LLC_RSP, 0); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry++; } else { LLC_SETFLAG(linkp, S, 0); LLC_NEWSTATE(linkp, RESET_WAIT); action = LLC_RESET_INDICATION_LOCAL; } break; default: if (cmdrsp == LLC_CMD){ llc_send(linkp, LLCFT_FRMR, LLC_RSP, pollfinal); LLC_START_ACK_TIMER(linkp); } break; } return action;}/* * NORMAL, BUSY, REJECT, AWAIT, AWAIT_BUSY, and AWAIT_REJECT all share * a common core state handler. */intllc_state_NBRAcore(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = 0; switch(frame_kind + cmdrsp) { case NL_DISCONNECT_REQUEST: llc_send(linkp, LLCFT_DISC, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_STOP_ALL_TIMERS(linkp); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_NEWSTATE(linkp, D_CONN); break; case NL_RESET_REQUEST: llc_send(linkp, LLCFT_SABME, LLC_CMD, pollfinal); LLC_SETFLAG(linkp, P, pollfinal); LLC_STOP_ALL_TIMERS(linkp); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_SETFLAG(linkp, S, 0); LLC_NEWSTATE(linkp, RESET); break; case LLCFT_SABME + LLC_CMD: LLC_SETFLAG(linkp, F, pollfinal); LLC_STOP_ALL_TIMERS(linkp); LLC_NEWSTATE(linkp, RESET_CHECK); action = LLC_RESET_INDICATION_REMOTE; break; case LLCFT_DISC + LLC_CMD: llc_send(linkp, LLCFT_UA, LLC_RSP, pollfinal); LLC_STOP_ALL_TIMERS(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLCFT_FRMR + LLC_RSP: LLC_STOP_ALL_TIMERS(linkp); LLC_SETFLAG(linkp, S, 0); LLC_NEWSTATE(linkp, RESET_WAIT); action = LLC_FRMR_RECEIVED; break; case LLCFT_DM + LLC_RSP: LLC_STOP_ALL_TIMERS(linkp); LLC_NEWSTATE(linkp, ADM); action = LLC_DISCONNECT_INDICATION; break; case LLC_INVALID_NR + LLC_CMD: case LLC_INVALID_NS + LLC_CMD: LLC_SETFRMR(linkp, frame, cmdrsp, (frame_kind == LLC_INVALID_NR ? LLC_FRMR_Z : (LLC_FRMR_V | LLC_FRMR_W))); llc_send(linkp, LLCFT_FRMR, LLC_RSP, pollfinal); LLC_STOP_ALL_TIMERS(linkp); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_NEWSTATE(linkp, ERROR); action = LLC_FRMR_SENT; break; case LLC_INVALID_NR + LLC_RSP: case LLC_INVALID_NS + LLC_RSP: case LLCFT_UA + LLC_RSP: case LLC_BAD_PDU: { char frmrcause = 0; switch (frame_kind) { case LLC_INVALID_NR: frmrcause = LLC_FRMR_Z; break; case LLC_INVALID_NS: frmrcause = LLC_FRMR_V | LLC_FRMR_W; break; default: frmrcause = LLC_FRMR_W; } LLC_SETFRMR(linkp, frame, cmdrsp, frmrcause); llc_send(linkp, LLCFT_FRMR, LLC_RSP, 0); LLC_STOP_ALL_TIMERS(linkp); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_NEWSTATE(linkp, ERROR); action = LLC_FRMR_SENT; break; } default: if (cmdrsp == LLC_RSP && pollfinal == 1 && LLC_GETFLAG(linkp, P) == 0) { LLC_SETFRMR(linkp, frame, cmdrsp, LLC_FRMR_W); LLC_STOP_ALL_TIMERS(linkp); LLC_START_ACK_TIMER(linkp); linkp->llcl_retry = 0; LLC_NEWSTATE(linkp, ERROR); action = LLC_FRMR_SENT; } break; case LLC_P_TIMER_EXPIRED: case LLC_ACK_TIMER_EXPIRED: case LLC_REJ_TIMER_EXPIRED: case LLC_BUSY_TIMER_EXPIRED: if (linkp->llcl_retry >= llc_n2) { LLC_STOP_ALL_TIMERS(linkp); LLC_SETFLAG(linkp, S, 0); LLC_NEWSTATE(linkp, RESET_WAIT); action = LLC_RESET_INDICATION_LOCAL; } break; } return action;}/* * NORMAL --- A data link connection exists between the local LLC service access * point and the remote LLC service access point. Sending and * reception of information and supervisory PDUs can be performed. */intllc_state_NORMAL(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = LLC_PASSITON; switch(frame_kind + cmdrsp) { case NL_DATA_REQUEST: if (LLC_GETFLAG(linkp, REMOTE_BUSY) == 0) {#ifdef not_now if (LLC_GETFLAG(linkp, P) == 0) { /* multiple possibilities */ llc_send(linkp, LLCFT_INFO, LLC_CMD, 1); LLC_START_P_TIMER(linkp); if (LLC_TIMERXPIRED(linkp, ACK) != LLC_TIMER_RUNNING) LLC_START_ACK_TIMER(linkp); } else {#endif /* multiple possibilities */ llc_send(linkp, LLCFT_INFO, LLC_CMD, 0); if (LLC_TIMERXPIRED(linkp, ACK) != LLC_TIMER_RUNNING) LLC_START_ACK_TIMER(linkp);#ifdef not_now }#endif action = 0; } break; case LLC_LOCAL_BUSY_DETECTED: if (LLC_GETFLAG(linkp, P) == 0) { /* multiple possibilities --- action-wise */ /* multiple possibilities --- CMD/RSP-wise */ llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_START_P_TIMER(linkp); LLC_SETFLAG(linkp, DATA, 0); LLC_NEWSTATE(linkp, BUSY); action = 0; } else { /* multiple possibilities --- CMD/RSP-wise */ llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_SETFLAG(linkp, DATA, 0); LLC_NEWSTATE(linkp, BUSY); action = 0; } break; case LLC_INVALID_NS + LLC_CMD: case LLC_INVALID_NS + LLC_RSP: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -