📄 rlp-common.c
字号:
frame.Header[0] |= 0xf8; frame.Header[1] |= 0x01; PackM(RLP_U_TEST); break; case RLP_FT_U_REMAP: frame.Header[0] |= 0xf8; frame.Header[1] |= 0x01; ClearPFBit; /* REMAP frames are always used with P/F-bit set to "0". */ PackM(RLP_U_REMAP); break; case RLP_FT_S_RR: frame.Header[0] |= 0xf0; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */ frame.Header[1] |= 0x01; /* 1 P/F ...N(R)... */ PackNR; PackS(RLP_S_RR); break; case RLP_FT_S_REJ: frame.Header[0] |= 0xf0; frame.Header[1] |= 0x01; PackNR; PackS(RLP_S_REJ); break; case RLP_FT_S_RNR: frame.Header[0] |= 0xf0; frame.Header[1] |= 0x01; PackNR; PackS(RLP_S_RNR); break; case RLP_FT_S_SREJ: frame.Header[0] |= 0xf0; frame.Header[1] |= 0x01; PackNR; PackS(RLP_S_SREJ); break; case RLP_FT_SI_RR: PackNR; PackNS; PackS(RLP_S_RR); break; case RLP_FT_SI_REJ: PackNR; PackNS; PackS(RLP_S_REJ); break; case RLP_FT_SI_RNR: PackNR; PackNS; PackS(RLP_S_RNR); break; case RLP_FT_SI_SREJ: PackNR; PackNS; PackS(RLP_S_SREJ); break; default: break; } /* Store FCS in the frame. */ rlp_crc24checksum_calculate((u8 *)&frame, 27, frame.FCS); /* X(&frame); */ rlpprintf("S "); RLP_DumpF96Frame(&frame); if (RLP_SendFunction) RLP_SendFunction(&frame, OutDTX);}/* Check_input_PDU in Serge's code. */void rlp_f96_frame_display(gn_rlp_f96_frame *frame){ int count; rlp_f96_header header; if (T >= 0) T--; for (count = 0; count < RLP_M; count++) if (T_RCVS[count] >= 0) T_RCVS[count]--; CurrentFrameType = RLP_FT_BAD; if (!frame) { /* no frame provided, drop through to state machine anyway */ } else if (rlp_crc24fcs_check((u8 *)frame, 30) == true) { /* Here we have correct RLP frame so we can parse the field of the header to out structure. */ rlpprintf("R "); RLP_DumpF96Frame(frame); rlp_f96_header_decode(frame, &header); switch (header.Type) { case RLP_FT_U: /* Unnumbered frames. */ switch (header.M) { case RLP_U_SABM : if (header.CR == 0 || header.PF == 0) break; CurrentFrameType = RLP_FT_U_SABM; break; case RLP_U_UA: if (header.CR == 1) break; CurrentFrameType = RLP_FT_U_UA; break; case RLP_U_DISC: if (header.CR == 0) break; CurrentFrameType = RLP_FT_U_DISC; break; case RLP_U_DM: if (header.CR == 1) break; CurrentFrameType = RLP_FT_U_DM; break; case RLP_U_UI: CurrentFrameType = RLP_FT_U_UI; break; case RLP_U_XID: CurrentFrameType = RLP_FT_U_XID; break; case RLP_U_TEST: CurrentFrameType = RLP_FT_U_TEST; break; case RLP_U_NULL: CurrentFrameType = RLP_FT_U_NULL; break; case RLP_U_REMAP: CurrentFrameType = RLP_FT_U_REMAP; break; default: CurrentFrameType = RLP_FT_BAD; break; } break; case RLP_FT_S: /* Supervisory frames. */ switch (header.S) { case RLP_S_RR: CurrentFrameType = RLP_FT_S_RR; break; case RLP_S_REJ: CurrentFrameType = RLP_FT_S_REJ; break; case RLP_S_RNR: CurrentFrameType = RLP_FT_S_RNR; break; case RLP_S_SREJ: CurrentFrameType = RLP_FT_S_SREJ; break; default: CurrentFrameType = RLP_FT_BAD; break; } break; default: switch (header.S) { case RLP_S_RR: CurrentFrameType = RLP_FT_SI_RR; break; case RLP_S_REJ: CurrentFrameType = RLP_FT_SI_REJ; break; case RLP_S_RNR: CurrentFrameType = RLP_FT_SI_RNR; break; case RLP_S_SREJ: CurrentFrameType = RLP_FT_SI_SREJ; break; default: CurrentFrameType = RLP_FT_BAD; break; } break; } } else { /* RLP Checksum failed - don't we need some statistics about these failures? Nothing is printed, because in the first stage of connection there are too many bad RLP frames... */ dprintf("Frame FCS is bad. Ignoring...\n"); } MAIN_STATE_MACHINE(frame, &header); /* Y:= outblock(); */ return;}/* FIXME: real TEST_Handling - we do not handle TEST yet. */void TEST_Handling(){ return;}/* FIXME: better XID_handling - but this will answer a XID command. */bool XID_Handling (gn_rlp_f96_frame *frame, rlp_f96_header *header){ u8 count; u8 type; u8 length; if (CurrentFrameType == RLP_FT_U_XID) { count = 0; while (frame->Data[count] != 0) { type = frame->Data[count] >> 4; length = frame->Data[count] & 0x0f; count++; switch (type) { case 0x01: /* RLP Version Number */ RLP_VersionNumber = frame->Data[count]; count += length; break; case 0x02: /* Interworking Function (IWF) to Mobile Station (MS) window size */ if (frame->Data[count] >= 1 && frame->Data[count] < RLP_M) RLP_RCV_WS = frame->Data[count]; count += length; break; case 0x03: /* MS to IWF window size */ if (frame->Data[count] >= 1 && frame->Data[count] < RLP_M) RLP_SEND_WS = frame->Data[count]; count += length; break; case 0x04: /* Acknowledgement Timer (T1). */ RLP_Timeout1_Limit = frame->Data[count]; count += length; break; case 0x05: /* Retransmission attempts (N2). */ RLP_N2 = frame->Data[count]; count += length; break; case 0x06: /* Reply delay (T2). */ RLP_T2 = frame->Data[count]; count += length; break; case 0x07: /* Compression - not yet! */ break; default: count += length; break; } } /* Now reassemble a reply */ count = 0; memset(frame->Data, 0x00, 25); /* Makes debugging easier */ /* Version Number - force to 0 for now */ RLP_VersionNumber = 0; frame->Data[count++] = 0x11; frame->Data[count++] = RLP_VersionNumber; /* Window sizes */ frame->Data[count++] = 0x21; frame->Data[count++] = RLP_RCV_WS; frame->Data[count++] = 0x31; frame->Data[count++] = RLP_SEND_WS; /* Acknowledgement Timer (T1). */ frame->Data[count++] = 0x41; frame->Data[count++] = RLP_Timeout1_Limit; /* Retransmission attempts (N2). */ frame->Data[count++] = 0x51; frame->Data[count++] = RLP_N2; /* Reply delay (T2). */ frame->Data[count++] = 0x61; frame->Data[count++] = RLP_T2; XID_R_State = _send; return true; } return false;}bool Send_TXU(gn_rlp_f96_frame *frame, rlp_f96_header *header){ dprintf("Send_TXU()\n"); dprintf("XID_R_State=%d\n", XID_R_State); /* if (RLP_UserEvent(TEST_R_State)) { RLP_SendF96Frame(RLP_FT_U_TEST, false, TEST_R_FBit, 0, 0, TEST_R_Data, false); return true; } else */ if (XID_R_State == _send && frame) { RLP_SendF96Frame(RLP_FT_U_XID, false, true, 0, 0, frame->Data, false); XID_R_State = _idle; return true; } /* else if ((XID_C_State == _send ) && (Poll_xchg == _idle)) { RLP_SendF96Frame(RLP_FT_U_XID, true, true, 0, 0, XID_C_Data, false); XID_C_State = _wait; T_XID = 1; Poll_xchg = _wait; return true; } else if (RLP_UserEvent(UI_State)) { RLP_SendF96Frame(RLP_FT_U_UI, true, false, 0, 0, NULL, false); return true; } */ return false;}/* Deliver data */void RLP_DeliverAllInSeqIF(){ int i,j; do { if ((R[VR].Data[0] & 0xE0) != LastStatus) { LastStatus = (R[VR].Data[0] & 0xE0); RLP_Passup(StatusChange, &LastStatus, 0); } j = 0; i = R[VR].Data[0] & 0x1f; if (i == 0x1e) j = 24; if (i < 0x18) j = i; /* FIXME - should check for more data in the frame */ RLP_Passup(Data, R[VR].Data+1, j); R[VR].State = _idle; VR = Incr(VR); } while (R[VR].State == _rcvd);}/* Mark any missing information frames between VR and Ns */void RLP_MarkMissingIF(u8 Ns){ u8 i; for (i = VR; i != Ns; i = Incr(i)) { if (R[i].State == _idle) R[i].State = _srej; /* bug in spec, fig A.23 */ }}/* Information frame handler */bool RLP_I_Handler(gn_rlp_f96_frame *frame, rlp_f96_header *header){ if ((header->CR) && (header->PF)) return true; /* If the window size is 61, a received frame must have a sequence number between VR and VR+60 */ if (!InWindow(header->Ns, VR, VR + RLP_RCV_WS - 1)) return true; if (header->Ns == VR) { /* This is not in the spec but I think it is necessary */ if (R[header->Ns].State == _wait) T_RCVS[header->Ns] = -1; R[VR].State = _rcvd; memcpy(R[VR].Data, frame->Data, 25); RLP_DeliverAllInSeqIF(); Ackn_State = _send; } else { /* Out of sequence, cause a SREJ */ if (R[header->Ns].State == _wait) T_RCVS[header->Ns] = -1; R[header->Ns].State = _rcvd; memcpy(R[header->Ns].Data, frame->Data, 25); RLP_MarkMissingIF(header->Ns); } return false;}/* Mark acknowledged send frames */void RLP_AdvanceVA(u8 Nr){ while (VA != Nr) { S[VA].State = _idle; VA = Incr(VA); }}/* Decrease VS back down to Nr since these have not been acknowledged */void RLP_DecreaseVS(u8 Nr){ while (VS != Nr) { VS = Decr(VS); S[VS].State = _send; }}/* Supervisory frame handling */void RLP_S_Handler(gn_rlp_f96_frame *frame, rlp_f96_header *header){ u8 i; if ((header->CR) && (header->PF)) { /* Special exchange (ie. error) - counter? */ rlpprintf("Got Poll command\n"); Ackn_State = _send; Ackn_FBit = true; for (i = 0; i < RLP_M; i++) R[i].State = _idle; ResetAllT_RCVS(); } if (Poll_State != _idle) { if (header->PF == 0) return; if ((CurrentFrameType == RLP_FT_S_SREJ) || (CurrentFrameType == RLP_FT_S_REJ) || (CurrentFrameType == RLP_FT_SI_SREJ) || (CurrentFrameType == RLP_FT_SI_REJ)) return; RLP_DecreaseVS(header->Nr); Poll_State = _idle; Poll_xchg = _idle; } switch (CurrentFrameType) { case RLP_FT_S_RR: case RLP_FT_SI_RR: RLP_AdvanceVA(header->Nr); RRReady = true; break; case RLP_FT_S_RNR: case RLP_FT_SI_RNR: RLP_AdvanceVA(header->Nr); RRReady = false; break; case RLP_FT_S_REJ: case RLP_FT_SI_REJ: RLP_AdvanceVA(header->Nr); RRReady = true; RLP_DecreaseVS(header->Nr); break; case RLP_FT_S_SREJ: case RLP_FT_SI_SREJ: S[header->Nr].State = _send; T = -1; return; default: break; } if (VA == VS) T = -1;}/* Find the first SREJ frame */bool RLP_SREJSlot(u8 *x){ u8 i; for (i = Incr(VR); i != VR; i = Incr(i)) if (R[i].State == _srej) { *x = i; return true; } return false;}/* Check if any SREJ frames need sending, if not send the next in line */bool RLP_PrepareDataToTransmit(u8 *p){ u8 i; for (i = VA; i != VS; i = Incr(i)) if (S[i].State == _send) { *p = i; S[i].State = _wait; return true; } if (S[VS].State != _send) return false; if (!InWindow(VS, VA, VA + RLP_SEND_WS - 1)) return false; *p = VS; S[VS].State = _wait; VS = Incr(VS); return true;}/* Send a SREJ command */void RLP_SendSREJ(u8 x){ u8 k; if ((Poll_xchg == _idle) && (Poll_State == _send)) { rlpprintf("Sending SREJ with poll\n"); RLP_SendF96Frame(RLP_FT_S_SREJ, true, true, x, 0, NULL, false); R[x].State = _wait; RLP_SetTimer(&T_RCVS[x]); Poll_Count++; Poll_State = _wait; Poll_xchg = _wait; RLP_SetTimer(&T); } else if (RRReady && RLP_PrepareDataToTransmit(&k)) { rlpprintf("Sending SREJ for %d along with frame %d\n", x, k); RLP_SendF96Frame(RLP_FT_SI_SREJ, true, false, x , k , S[k].Data, false); R[x].State = _wait; RLP_SetTimer(&T_RCVS[x]); RLP_SetTimer(&T); } else { rlpprintf("Sending SREJ for %d\n",x); RLP_SendF96Frame(RLP_FT_S_SREJ, true, false, x, 0, NULL, false); R[x].State = _wait; RLP_SetTimer(&T_RCVS[x]); }}/* Send a command */void RLP_Send_XX_Cmd(rlp_frame_types type){ u8 k; if ((Poll_xchg != _wait) && (Poll_State == _send)) { RLP_SendF96Frame(type, true, true, VR, 0, NULL, false); rlpprintf("Sending Comd %x with Poll\n",type); Ackn_State = _idle; Poll_Count++; Poll_State = _wait; Poll_xchg = _wait; RLP_SetTimer(&T); } else if (RRReady && RLP_PrepareDataToTransmit(&k)) { rlpprintf("Sending Comd %x with frame %d\n", type, k); RLP_SendF96Frame(type + 4, true, false, VR, k, S[k].Data, false); Ackn_State = _idle; RLP_SetTimer(&T); } else { if (type != 9) rlpprintf("Sending Comd %x\n",type); RLP_SendF96Frame(type, true, false, VR, 0, NULL, false); Ackn_State = _idle; DTX_SF = type; DTX_VR = VR; /* As v7.1.0 spec */ }}/* Send a Response */void RLP_Send_XX_Resp(rlp_frame_types type){ u8 k; if (RRReady && RLP_PrepareDataToTransmit(&k)) { rlpprintf("Sending Resp %x with frame %d\n",type+4,k); RLP_SendF96Frame(type + 4, false, true, VR, k, S[k].Data, false); Ackn_State = _idle; Ackn_FBit = false; RLP_SetTimer(&T); } else { rlpprintf("Sending Resp %x\n",type); RLP_SendF96Frame(type, false, true, VR, 0, NULL, false); Ackn_State = _idle; Ackn_FBit = false; }}/* Decide which frame to use and send it - currently only used in state 4 */void RLP_SendData(){ u8 x; if (UA_State == _send) { RLP_SendF96Frame(RLP_FT_U_UA, false, UA_FBit, 0, 0, NULL, false); UA_State = _idle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -