📄 llc_subr.c
字号:
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, REJECT); action = 0; } else if (pollfinal == 0 && p == 1) { llc_send(linkp, LLCFT_REJ, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_START_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, REJECT); action = 0; } else if ((pollfinal == 0 && p == 0) || (pollfinal == 1 && p == 1 && cmdrsp == LLC_RSP)) { llc_send(linkp, LLCFT_REJ, LLC_CMD, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_START_P_TIMER(linkp); LLC_START_REJ_TIMER(linkp); if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_CLEAR_REMOTE_BUSY(linkp, action); } else action = 0; LLC_NEWSTATE(linkp, REJECT); } 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); action = LLC_DATA_INDICATION; } else if (pollfinal == 0 && p == 1) { LLC_INC(linkp->llcl_vr); LLC_SENDACKNOWLEDGE(linkp, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); action = LLC_DATA_INDICATION; } else if ((pollfinal == 0 && p == 0 && cmdrsp == LLC_CMD) || (pollfinal == p && cmdrsp == LLC_RSP)) { LLC_INC(linkp->llcl_vr); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_SENDACKNOWLEDGE(linkp, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (cmdrsp == LLC_RSP && pollfinal == 1) LLC_CLEAR_REMOTE_BUSY(linkp, action); 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); LLC_SET_REMOTE_BUSY(linkp, action); } 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 (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); } else if ((pollfinal == 0 && p == 0 && cmdrsp == LLC_CMD) || (pollfinal == p && cmdrsp == LLC_RSP)) { linkp->llcl_vs = nr; LLC_UPDATE_NR_RECEIVED(linkp, nr); LLC_START_P_TIMER(linkp); llc_resend(linkp, LLC_CMD, 1); 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_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++; LLC_NEWSTATE(linkp, AWAIT); 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); linkp->llcl_retry++; LLC_NEWSTATE(linkp, AWAIT); action = 0; } break; } if (action == LLC_PASSITON) action = llc_state_NBRAcore(linkp, frame, frame_kind, cmdrsp, pollfinal); return action;}/* * BUSY --- A data link connection exists between the local LLC service access * point and the remote LLC service access point. I PDUs may be sent. * Local conditions make it likely that the information feld of * received I PDUs will be ignored. Supervisory PDUs may be both sent * and received. */intllc_state_BUSY(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) if (LLC_GETFLAG(linkp, P) == 0) { 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); action = 0; } else { llc_send(linkp, LLCFT_INFO, LLC_CMD, 0); if (LLC_TIMERXPIRED(linkp, ACK) != LLC_TIMER_RUNNING) LLC_START_ACK_TIMER(linkp); action = 0; } break; case LLC_LOCAL_BUSY_CLEARED: { register int p = LLC_GETFLAG(linkp, P); register int df = LLC_GETFLAG(linkp, DATA); switch (df) { case 1: if (p == 0) { /* multiple possibilities */ llc_send(linkp, LLCFT_REJ, LLC_CMD, 1); LLC_START_REJ_TIMER(linkp); LLC_START_P_TIMER(linkp); LLC_NEWSTATE(linkp, REJECT); action = 0; } else { llc_send(linkp, LLCFT_REJ, LLC_CMD, 0); LLC_START_REJ_TIMER(linkp); LLC_NEWSTATE(linkp, REJECT); action = 0; } break; case 0: if (p == 0) { /* multiple possibilities */ llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_NEWSTATE(linkp, NORMAL); action = 0; } else { llc_send(linkp, LLCFT_RR, LLC_CMD, 0); LLC_NEWSTATE(linkp, NORMAL); action = 0; } break; case 2: if (p == 0) { /* multiple possibilities */ llc_send(linkp, LLCFT_RR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_NEWSTATE(linkp, REJECT); action = 0; } else { llc_send(linkp, LLCFT_RR, LLC_CMD, 0); LLC_NEWSTATE(linkp, 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); if (LLC_GETFLAG(linkp, DATA) == 0) LLC_SETFLAG(linkp, DATA, 1); action = 0; } else if ((cmdrsp == LLC_CMD && pollfinal == 0 && p == 0) || (cmdrsp == LLC_RSP && pollfinal == p)) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (LLC_GETFLAG(linkp, DATA) == 0) LLC_SETFLAG(linkp, DATA, 1); if (cmdrsp == LLC_RSP && pollfinal == 1) { LLC_CLEAR_REMOTE_BUSY(linkp, action); } else action = 0; } else if (pollfinal == 0 && p == 1) { llc_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (LLC_GETFLAG(linkp, DATA) == 0) LLC_SETFLAG(linkp, DATA, 1); 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_send(linkp, LLCFT_RNR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (LLC_GETFLAG(linkp, DATA) == 2) LLC_STOP_REJ_TIMER(linkp); LLC_SETFLAG(linkp, DATA, 0); action = LLC_DATA_INDICATION; } else if ((cmdrsp == LLC_CMD && pollfinal == 0 && p == 0) || (cmdrsp == LLC_RSP && pollfinal == p)) { LLC_INC(linkp->llcl_vr); llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (LLC_GETFLAG(linkp, DATA) == 2) LLC_STOP_REJ_TIMER(linkp); if (cmdrsp == LLC_RSP && pollfinal == 1) LLC_CLEAR_REMOTE_BUSY(linkp, action); action = LLC_DATA_INDICATION; } else if (pollfinal == 0 && p == 1) { LLC_INC(linkp->llcl_vr); llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (LLC_GETFLAG(linkp, DATA) == 2) LLC_STOP_REJ_TIMER(linkp); LLC_SETFLAG(linkp, DATA, 0); action = LLC_DATA_INDICATION; } break; } case LLCFT_RR + LLC_CMD: case LLCFT_RR + LLC_RSP: 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); if (frame_kind == LLCFT_RR) { LLC_CLEAR_REMOTE_BUSY(linkp, action); } else { LLC_SET_REMOTE_BUSY(linkp, action); } } else if (pollfinal = 0 || (cmdrsp == LLC_RSP && pollfinal == 1)) { LLC_UPDATE_P_FLAG(linkp, cmdrsp, pollfinal); LLC_UPDATE_NR_RECEIVED(linkp, nr); if (frame_kind == LLCFT_RR) { LLC_CLEAR_REMOTE_BUSY(linkp, action); } else { LLC_SET_REMOTE_BUSY(linkp, action); } } 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_send(linkp, LLCFT_RNR, LLC_RSP, 1); llc_resend(linkp, LLC_CMD, 0); 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_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); action = 0; } break; case LLC_P_TIMER_EXPIRED: /* multiple possibilities */ if (linkp->llcl_retry < llc_n2) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); linkp->llcl_retry++; LLC_NEWSTATE(linkp, AWAIT_BUSY); 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_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); linkp->llcl_retry++; LLC_NEWSTATE(linkp, AWAIT_BUSY); action = 0; } break; case LLC_REJ_TIMER_EXPIRED: if (linkp->llcl_retry < llc_n2) if (LLC_GETFLAG(linkp, P) == 0) { /* multiple possibilities */ llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); linkp->llcl_retry++; LLC_SETFLAG(linkp, DATA, 1); LLC_NEWSTATE(linkp, AWAIT_BUSY); action = 0; } else{ LLC_SETFLAG(linkp, DATA, 1); LLC_NEWSTATE(linkp, BUSY); action = 0; } break; } if (action == LLC_PASSITON) action = llc_state_NBRAcore(linkp, frame, frame_kind, cmdrsp, pollfinal); return action;}/* * REJECT --- A data link connection exists between the local LLC service * access point and the remote LLC service access point. The local * connection component has requested that the remote connection * component resend a specific I PDU that the local connection * componnent has detected as being out of sequence. Both I PDUs and * supervisory PDUs may be sent and received. */ intllc_state_REJECT(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, P) == 0) { 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); LLC_NEWSTATE(linkp, REJECT); action = 0; } else { llc_send(linkp, LLCFT_INFO, LLC_CMD, 0); if (LLC_TIMERXPIRED(linkp, ACK) != LLC_TIMER_RUNNING) LLC_START_ACK_TIMER(linkp); LLC_NEWSTATE(linkp, REJECT); action = 0; } break; case NL_LOCAL_BUSY_DETECTED: if (LLC_GETFLAG(linkp, P) == 0) { llc_send(linkp, LLCFT_RNR, LLC_CMD, 1); LLC_START_P_TIMER(linkp); LLC_SETFLAG(linkp, DATA, 2); LLC_NEWSTATE(linkp, BUSY); action = 0; } else { llc_send(linkp, LLCFT_RNR, LLC_CMD, 0); LLC_SETFLAG(linkp, DATA, 2); LLC_NEWSTATE(linkp, 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_RR, LLC_RSP, 1); LLC_UPDATE_NR_RECEIVED(linkp, nr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -