📄 llc_subr.c
字号:
action = 0; } else if (pollfinal == 0 || (cmdrsp == LLC_RSP && pollfinal == 1 && p == 1)) { LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_CLEAR_REMOTE_BUSY(linkp, action); } else action = 0; } break; } case LLCFT_INFO + LLC_CMD: case LLCFT_INFO + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { LLC_INC(linkp->llcl_vr); LLC_SENDACKNOWLEDGE(linkp, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_STOP_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, NORMAL); action = LLC_DATA_INDICATION; } else if ((cmdrsp = LLC_RSP && pollfinal == p) || (cmdrsp == LLC_CMD && pollfinal == 0 && p == 0)) { LLC_INC(linkp->llcl_vr); LLC_SENDACKNOWLEDGE(linkp, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (cmdrsp == LLC_RSP && pollfinal == 1) LLC_CLEAR_REMOTE_BUSY(linkp, action); LLC_STOP_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, NORMAL); action = LLC_DATA_INDICATION; } else if (pollfinal == 0 && p == 1) { LLC_INC(linkp->llcl_vr); LLC_SENDACKNOWLEDGE(linkp, LLC_CMD, 0); LLC_STOP_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, NORMAL); action = LLC_DATA_INDICATION; } break; } case LLCFT_RR + LLC_CMD: case LLCFT_RR + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { LLC_SENDACKNOWLEDGE(linkp, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_CLEAR_REMOTE_BUSY(linkp, action); } else if (pollfinal == 0 || (cmdrsp == LLC_RSP && pollfinal == 1 && p == 1)) { LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_CLEAR_REMOTE_BUSY(linkp, action); } break; } case LLCFT_RNR + LLC_CMD: case LLCFT_RNR + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SET_REMOTE_BUSY(linkp, action); } else if (pollfinal == 0 || (cmdrsp == LLC_RSP && pollfinal == 1 && p == 1)) { LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_UPDATE_NR_RECEIVED(linkp, nr); action = 0; } break; } case LLCFT_REJ + LLC_CMD: case LLCFT_REJ + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { linkp->llcl_vs = nr; LLC_UPDATE_NR_RECEIVED(linkp, nr); llc_resend(linkp, LLC_RSP, 1); LLC_CLEAR_REMOTE_BUSY(linkp, action); } else if ((cmdrsp == LLC_CMD && pollfinal == 0 && p == 0) || (cmdrsp == LLC_RSP && pollfinal == p)) { linkp->llcl_vs = nr; LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); llc_resend(linkp, LLC_CMD, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); } else if (pollfinal == 0 && p == 1) { linkp->llcl_vs = nr; LLC_UPDATE_NR_RECEIVED(linkp, nr); llc_resend(linkp, LLC_CMD, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); } break; } case NL_INITIATE_PF_CYCLE: if (LLC_GETFLAG(linkp, P) == 0) { llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); action = 0; } break; case LLC_REJ_TIMER_EXPIRED: if (LLC_GETFLAG(linkp, P) == 0 && linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_REJ, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_START_REJ_TIMER(linkp); linkp->llcl_retry++; action = 0; } case LLC_P_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_START_REJ_TIMER(linkp); linkp->llcl_retry++; LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; } break; case LLC_ACK_TIMER_EXPIRED: case LLC_BUSY_TIMER_EXPIRED: if (LLC_GETFLAG(linkp, P) == 0 && linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_START_REJ_TIMER(linkp); linkp->llcl_retry++; /* * I cannot locate the description of RESET_V(S) * in ISO 8802-2, table 7-1, state REJECT, last event, * and assume they meant to set V(S) to 0 ... */ linkp->llcl_vs = 0; /* XXX */ LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; } break; } if (action == LLC_PASSITON) action = llc_state_NBRAcore(linkp, frame, frame_kind, cmdrsp, pollfinal); return action;}/* * AWAIT --- A data link connection exists between the local LLC service access * point and the remote LLC service access point. The local LLC is * performing a timer recovery operation and has sent a command PDU * with the P bit set to ``1'', and is awaiting an acknowledgement * from the remote LLC. I PDUs may be received but not sent. * Supervisory PDUs may be both sent and received. */intllc_state_AWAIT(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = LLC_PASSITON; switch(frame_kind + cmdrsp) { case LLC_LOCAL_BUSY_DETECTED: llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_SETFLAG(linkp, DATA, 0); LLC_NEWSTATE(linkp, AWAIT_BUSY); action = 0; break; case LLC_INVALID_NS + LLC_CMD: case LLC_INVALID_NS + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_REJ, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_START_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; } else if (cmdrsp == LLC_RSP && pollfinal == 1) { llc_send(linkp, LLCFT_REJ, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); llc_resend(linkp, LLC_CMD, 0); LLC_START_REJ_TIMER(linkp); LLC_CLEAR_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, REJECT); } else if (pollfinal == 0) { llc_send(linkp, LLCFT_REJ, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_START_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; } break; } case LLCFT_INFO + LLC_RSP: case LLCFT_INFO + LLC_CMD: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); LLC_INC(linkp->llcl_vr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); action = LLC_DATA_INDICATION; } else if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; llc_resend(linkp, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_CLEAR_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, NORMAL); action = LLC_DATA_INDICATION; } else if (pollfinal == 0) { llc_send(linkp, LLCFT_RR, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); action = LLC_DATA_INDICATION; } break; } case LLCFT_RR + LLC_CMD: case LLCFT_RR + LLC_RSP: case LLCFT_REJ + LLC_CMD: case LLCFT_REJ + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_CLEAR_REMOTE_BUSY(linkp, action); } else if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); llc_resend(linkp, LLC_CMD, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, NORMAL); } else if (pollfinal == 0) { LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_CLEAR_REMOTE_BUSY(linkp, action); } break; } case LLCFT_RNR + LLC_CMD: case LLCFT_RNR + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (pollfinal == 1 && cmdrsp == LLC_CMD) { llc_send(linkp, LLCFT_RR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SET_REMOTE_BUSY(linkp, action); } else if (pollfinal == 1 && cmdrsp == LLC_RSP) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); LLC_SET_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, NORMAL); } else if (pollfinal == 0) { LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SET_REMOTE_BUSY(linkp, action); } break; } case LLC_P_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); linkp->llcl_retry++; action = 0; } break; } if (action == LLC_PASSITON) action = llc_state_NBRAcore(linkp, frame, frame_kind, cmdrsp, pollfinal); return action;}/* * AWAIT_BUSY --- A data link connection exists between the local LLC service * access point and the remote LLC service access point. The * local LLC is performing a timer recovery operation and has * sent a command PDU with the P bit set to ``1'', and is * awaiting an acknowledgement from the remote LLC. I PDUs may * not be sent. Local conditions make it likely that the * information feld of receoved I PDUs will be ignored. * Supervisory PDUs may be both sent and received. */intllc_state_AWAIT_BUSY(struct llc_linkcb *linkp, struct llc *frame, int frame_kind, int cmdrsp, int pollfinal){ int action = LLC_PASSITON; switch(frame_kind + cmdrsp) { case LLC_LOCAL_BUSY_CLEARED: switch (LLC_GETFLAG(linkp, DATA)) { case 1: llc_send(linkp, LLCFT_REJ, LLC_CMD, 0); LLC_START_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; break; case 0: llc_send(linkp, LLCFT_RR, LLC_CMD, 0); LLC_NEWSTATE(linkp, AWAIT); action = 0; break; case 2: llc_send(linkp, LLCFT_RR, LLC_CMD, 0); LLC_NEWSTATE(linkp, AWAIT_REJECT); action = 0; break; } break; case LLC_INVALID_NS + LLC_CMD: case LLC_INVALID_NS + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SETFLAG(linkp, DATA, 1); action = 0; } else if (cmdrsp == LLC_RSP && pollfinal == 1) { /* optionally */ llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); LLC_SETFLAG(linkp, DATA, 1); LLC_CLEAR_REMOTE_BUSY(linkp, action); llc_resend(linkp, LLC_CMD, 0); LLC_NEWSTATE(linkp, BUSY); } else if (pollfinal == 0) { /* optionally */ llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SETFLAG(linkp, DATA, 1); action = 0; } } case LLCFT_INFO + LLC_CMD: case LLCFT_INFO + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_INC(linkp->llcl_vr); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SETFLAG(linkp, DATA, 0); action = LLC_DATA_INDICATION; } else if (cmdrsp == LLC_RSP && pollfinal == 1) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_INC(linkp->llcl_vr); LLC_START_P_TIMER(linkp); LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_SETFLAG(linkp, DATA, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); llc_resend(linkp, LLC_CMD, 0); LLC_NEWSTATE(linkp, BUSY); action = LLC_DATA_INDICATION; } else if (pollfinal == 0) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_INC(linkp->llcl_vr); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SETFLAG(linkp, DATA, 0); action = LLC_DATA_INDICATION; } break; } case LLCFT_RR + LLC_CMD: case LLCFT_REJ + LLC_CMD: case LLCFT_RR + LLC_RSP: case LLCFT_REJ + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_CLEAR_REMOTE_BUSY(linkp, action); } else if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); llc_resend(linkp, LLC_CMD, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, BUSY); } else if (pollfinal == 0) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); llc_resend(linkp, LLC_CMD, 0); LLC_CLEAR_REMOTE_BUSY(linkp, action); } break; } case LLCFT_RNR + LLC_CMD: case LLCFT_RNR + LLC_RSP: { register int p = LLC_GETFLAG(linkp, P); register int nr = LLCGBITS(frame->llc_control_ext, s_nr); if (cmdrsp == LLC_CMD && pollfinal == 1) { llc_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SET_REMOTE_BUSY(linkp, action); } else if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_UPDATE_NR_RECEIVED(linkp, nr); linkp->llcl_vs = nr; LLC_STOP_P_TIMER(linkp); LLC_SET_REMOTE_BUSY(linkp, action); LLC_NEWSTATE(linkp, BUSY); } else if (pollfinal == 0) { LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_SET_REMOTE_BUSY(linkp, action); } break; } case LLC_P_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); linkp->llcl_retry++; action = 0; } break; } if (action == LLC_PASSITON) action = llc_state_NBRAcore(linkp, frame, frame_kind, cmdrsp, pollfinal); return action;}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -