7 A Linux/Unix toolset and driver for Nokia mobile phones.
9 Released under the terms of the GNU GPL, see file COPYING for more details.
11 The development of RLP protocol is sponsored by SuSE CR, s.r.o. (Pavel use
12 the SIM card from SuSE for testing purposes).
14 Actual implementation of RLP protocol. Based on GSM 04.22 version 7.1.0,
15 downloadable from www.etsi.org (if you register with them)
24 #include "data/rlp-common.h"
25 #include "data/rlp-crc24.h"
26 #include "gsm-common.h" /* For GSM error and RLP send function. */
27 #include "misc.h" /* For u8, u32 etc. */
30 #define INLINE __inline
35 /* Our state machine which handles all of nine possible states of RLP
37 void MAIN_STATE_MACHINE(RLP_F96Frame *frame, RLP_F96Header *header);
39 /* This is the type we are just handling. */
40 RLP_FrameTypes CurrentFrameType;
42 /* Current state of RLP state machine. */
43 RLP_State CurrentState=RLP_S0; /* We start at ADM and Detached */
45 /* Next state of RLP state machine. */
48 /* Pointer to Send function that sends frame to phone. */
49 bool (*RLPSendFunction)(RLP_F96Frame *frame, bool out_dtx);
51 /* Pointer to Passup function which returns data/inds */
52 int (*RLP_Passup)(RLP_UserInds ind, u8 *buffer, int length);
55 /* State variables - see GSM 04.22, Annex A, section A.1.2 */
57 RLP_StateVariable UA_State;
58 RLP_StateVariable UI_State;
59 RLP_StateVariable Ackn_State;
60 RLP_StateVariable Poll_State;
61 RLP_StateVariable Poll_xchg;
62 RLP_StateVariable SABM_State;
63 RLP_StateVariable DISC_State;
64 RLP_StateVariable DM_State; /* FIXME - not handled */
65 RLP_StateVariable XI_R_State;
66 RLP_StateVariable XID_C_State;
67 RLP_StateVariable XID_R_State;
68 RLP_StateVariable TEST_R_State;
77 RLP_FrameTypes DTX_SF;
84 RLP_StateVariable SABM_State;
87 RLP_UserRequestStore UserRequests;
91 /* For now timing is done based on a frame reception rate of 20ms */
92 /* Serge has measured it as 18.4ms */
93 #define RLP_T_Scaling 2
95 /* Timers - a value of -1 means not set */
96 /* To set, timer is loaded with RLP_Timeout1_Limit/RLP_T_Scaling. */
97 /* Each received frame (including NULLS / errors) any >0 timer is decrease */
103 bool Ackn_FBit=false;
104 bool DM_FBit=false; /* FIXME - not handled */
106 bool LRReady=true; /* FIXME - not handled (as if we couldn't keep up with 9600bps :-) */
107 bool DISC_PBit=false;
109 u8 LastStatus=0xff; /* Last Status byte */
112 /* RLP Parameters. FIXME: Reset these - e.g. when entering state 0 */
114 u8 RLP_SEND_WS = RLP_M-1;
115 u8 RLP_RCV_WS = RLP_M-1;
116 u8 RLP_Timeout1_Limit = 55;
117 u8 RLP_N2 = 15; /* Maximum number of retransmisions. GSM spec says 6 here, but
118 Nokia will XID this. */
120 u8 RLP_VersionNumber=0;
124 /****** Externally called functions ********/
125 /*******************************************/
128 /* Function to initialise RLP code. Main purpose for now is
129 to set the address of the RLP send function in the API code. */
131 void RLP_Initialise(bool (*rlp_send_function)(RLP_F96Frame *frame, bool out_dtx), int (*rlp_passup)(RLP_UserInds ind, u8 *buffer, int length))
135 RLPSendFunction = rlp_send_function;
136 RLP_Passup=rlp_passup;
137 UserRequests.Conn_Req=false;
138 UserRequests.Attach_Req=false;
139 UserRequests.Conn_Req_Neg=false;
140 UserRequests.Reset_Resp=false;
141 UserRequests.Disc_Req=false;
144 for (i=0;i<RLP_M;i++) T_RCVS[i]=-1;
156 RLP_SEND_WS = RLP_M-1;
157 RLP_RCV_WS = RLP_M-1;
158 RLP_Timeout1_Limit = 55;
165 /* Set a user event */
166 /* Called by user program for now */
168 void RLP_SetUserRequest(RLP_UserRequests type, bool value) {
172 UserRequests.Conn_Req=value;
175 UserRequests.Attach_Req=value;
178 UserRequests.Conn_Req_Neg=value;
181 UserRequests.Reset_Resp=value;
184 UserRequests.Disc_Req=value;
194 /***** Internal functions **********/
195 /***********************************/
198 /* Check whether a user event is set */
200 bool RLP_GetUserRequest(RLP_UserRequests type) {
202 bool result=false, *x;
206 x=&UserRequests.Conn_Req;
209 x=&UserRequests.Attach_Req;
212 x=&UserRequests.Conn_Req_Neg;
215 x=&UserRequests.Reset_Resp;
218 x=&UserRequests.Disc_Req;
233 void RLP_SetTimer(int *timer)
235 *timer=(int)(RLP_Timeout1_Limit/RLP_T_Scaling);
239 /* Previous sequence number. */
240 static INLINE u8 Decr(u8 x)
248 /* Next sequence number. */
249 static INLINE u8 Incr(u8 x)
257 /* Difference between sequence numbers. */
259 /* FIXME: Not used now, so I have commented it out. PJ
260 * static INLINE u8 Diff(u8 x, u8 y)
263 * return (result >= 0) ? result : result + RLP_M;
267 /* Check value is within range */
268 static bool InWindow(u8 val, u8 lower, u8 upper)
270 /* allow for one level of wrapping round */
271 if (lower>=RLP_M) lower-=RLP_M;
272 if (upper>=RLP_M) upper-=RLP_M;
273 if (val>=RLP_M) val-=RLP_M;
275 /* .......L*****U....... */
277 return (val >= lower) && (val <= upper);
279 /* ******U.........L***** */
280 return (val <= upper) || (val >= lower);
283 void RLP_Init_link_vars(void)
293 RRReady=true; /* This seems a bit strange but it's what the spec says... */
300 for(i=0;i<RLP_M;i++) {
308 void RLP_AddRingBufferDataToSlots(void)
313 while ((S[VD].State==_idle)
314 && ((size=RLP_Passup(GetData,buffer,24))!=0)) {
315 memset(S[VD].Data,0xff,25); /* FIXME - this isn't necessary - but makes debugging easier! */
320 else S[VD].Data[0]=size;
322 memcpy(&S[VD].Data[1],buffer,size);
324 if (size!=24) S[VD].Data[size+1]=0x1f;
332 /* FIXME: Remove this after finishing. */
334 void X(RLP_F96Frame *frame) {
339 printf("byte[%2d]: %02x\n", i, *( (u8 *)frame+i));
345 void ResetAllT_RCVS(void)
349 for (i=0;i<RLP_M;i++) T_RCVS[i]=-1;
354 /* This function is used for sending RLP frames to the phone. */
356 void RLP_SendF96Frame(RLP_FrameTypes FrameType,
357 bool OutCR, bool OutPF,
359 u8 *OutData, u8 OutDTX)
368 #define SetCRBit frame.Header[0]|=0x01;
369 #define SetPFBit frame.Header[1]|=0x02;
371 #define ClearCRBit frame.Header[0]&=(~0x01);
372 #define ClearPFBit frame.Header[1]&=(~0x02);
374 /* If Command/Response bit is set, set it in the header. */
379 /* If Poll/Final bit is set, set it in the header. */
384 /* If OutData is not specified (ie. is NULL) we want to clear frame.Data
385 array for the user. */
388 frame.Data[0]=0x00; // 0x1f
395 frame.Data[i]=OutData[i];
398 #define PackM(x) frame.Header[1]|=((x)<<2);
399 #define PackS(x) frame.Header[0]|=((x)<<1);
400 #define PackNR frame.Header[1]|=(OutNR<<2);
401 #define PackNS frame.Header[0]|=(OutNS<<3);frame.Header[1]|=(OutNS>>5);
405 /* Unnumbered frames. Be careful - some commands are used as commands
406 only, so we have to set C/R bit later. We should not allow user for
407 example to send SABM as response because in the spec is: The SABM
408 encoding is used as command only. */
412 frame.Header[0]|=0xf8; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
413 frame.Header[1]|=0x01; /* 1 P/F M1 M2 M3 M4 M5 X */
415 SetCRBit; /* The SABM encoding is used as a command only. */
416 SetPFBit; /* It is always used with the P-bit set to "1". */
424 frame.Header[0]|=0xf8;
425 frame.Header[1]|=0x01;
427 ClearCRBit; /* The UA encoding is used as a response only. */
435 frame.Header[0]|=0xf8;
436 frame.Header[1]|=0x01;
438 SetCRBit; /* The DISC encoding is used as a command only. */
446 frame.Header[0]|=0xf8;
447 frame.Header[1]|=0x01;
449 ClearCRBit; /* The DM encoding is used as a response only. */
457 frame.Header[0]|=0xf8;
458 frame.Header[1]|=0x01;
466 frame.Header[0]|=0xf8;
467 frame.Header[1]|=0x01;
475 frame.Header[0]|=0xf8;
476 frame.Header[1]|=0x01;
478 SetPFBit; /* XID frames are always used with the P/F-bit set to "1". */
486 frame.Header[0]|=0xf8;
487 frame.Header[1]|=0x01;
495 frame.Header[0]|=0xf8;
496 frame.Header[1]|=0x01;
498 ClearPFBit; /* REMAP frames are always used with P/F-bit set to "0". */
506 frame.Header[0]|=0xf0; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
507 frame.Header[1]|=0x01; /* 1 P/F ...N(R)... */
517 frame.Header[0]|=0xf0;
518 frame.Header[1]|=0x01;
528 frame.Header[0]|=0xf0;
529 frame.Header[1]|=0x01;
539 frame.Header[0]|=0xf0;
540 frame.Header[1]|=0x01;
587 /* Store FCS in the frame. */
588 RLP_CalculateCRC24Checksum((u8 *)&frame, 27, frame.FCS);
593 RLPSendFunction(&frame, OutDTX);
597 /* Check_input_PDU in Serge's code. */
599 void RLP_DisplayF96Frame(RLP_F96Frame *frame)
602 RLP_F96Header header;
605 for (count=0;count<RLP_M;count++) if (T_RCVS[count]>=0) T_RCVS[count]--;
607 CurrentFrameType=RLPFT_BAD;
610 /* no frame provided, drop through to state machine anyway */
611 } else if (RLP_CheckCRC24FCS((u8 *)frame, 30) == true) {
613 /* Here we have correct RLP frame so we can parse the field of the header
616 RLP_DecodeF96Header(frame, &header);
618 switch (header.Type) {
620 case RLPFT_U: /* Unnumbered frames. */
623 fprintf(stdout, "Unnumbered Frame [$%02x%02x] M=%02x ", frame->Header[0],
631 if (header.CR == 0 || header.PF == 0) break;
634 fprintf(stdout, "Set Asynchronous Balanced Mode (SABM) ");
637 CurrentFrameType=RLPFT_U_SABM;
642 if (header.CR == 1) break;
645 fprintf(stdout, "Unnumbered Acknowledge (UA) ");
648 CurrentFrameType=RLPFT_U_UA;
653 if (header.CR == 0) break;
656 fprintf(stdout, "Disconnect (DISC) ");
659 CurrentFrameType=RLPFT_U_DISC;
664 if (header.CR == 1) break;
667 fprintf(stdout, "Disconnected Mode (DM) ");
669 CurrentFrameType=RLPFT_U_DM;
676 fprintf(stdout, "Unnumbered Information (UI) ");
679 CurrentFrameType=RLPFT_U_UI;
686 fprintf(stdout, "Exchange Information (XID) \n");
687 RLP_DisplayXID(frame->Data);
690 CurrentFrameType=RLPFT_U_XID;
697 fprintf(stdout, "Test (TEST) ");
700 CurrentFrameType=RLPFT_U_TEST;
707 fprintf(stdout, "Null information (NULL) ");
710 CurrentFrameType=RLPFT_U_NULL;
717 fprintf(stdout, "Remap (REMAP) ");
720 CurrentFrameType=RLPFT_U_REMAP;
727 fprintf(stdout, _("Unknown!!! "));
730 CurrentFrameType=RLPFT_BAD;
737 case RLPFT_S: /* Supervisory frames. */
740 fprintf(stdout, "Supervisory Frame [$%02x%02x] S=0x%x N(R)=%d ",
752 fprintf(stdout, "RR");
755 CurrentFrameType=RLPFT_S_RR;
762 fprintf(stdout, "REJ");
765 CurrentFrameType=RLPFT_S_REJ;
772 fprintf(stdout, "RNR");
775 CurrentFrameType=RLPFT_S_RNR;
782 fprintf(stdout, "SREJ");
785 CurrentFrameType=RLPFT_S_SREJ;
792 fprintf(stdout, _("BAD"));
795 CurrentFrameType=RLPFT_BAD;
806 fprintf(stdout, "Info+Supervisory Frame [$%02x%02x] S=0x%x N(S)=%d N(R)=%d ",
819 fprintf(stdout, "RR");
822 CurrentFrameType=RLPFT_SI_RR;
829 fprintf(stdout, "REJ");
832 CurrentFrameType=RLPFT_SI_REJ;
839 fprintf(stdout, "RNR");
842 CurrentFrameType=RLPFT_SI_RNR;
849 fprintf(stdout, "SREJ");
852 CurrentFrameType=RLPFT_SI_SREJ;
859 fprintf(stdout, "BAD");
862 CurrentFrameType=RLPFT_BAD;
872 /* Command/Response and Poll/Final bits. */
874 fprintf(stdout, " C/R=%d P/F=%d", header.CR, header.PF);
881 if (CurrentFrameType!=RLPFT_U_NULL) {
883 fprintf(stdout, "\n");
885 for (count = 0; count < 25; count ++) {
887 if (isprint(frame->Data[count]))
888 fprintf(stdout, "[%02x%c]", frame->Data[count], frame->Data[count]);
890 fprintf(stdout, "[%02x ]", frame->Data[count]);
893 fprintf(stdout, "\n");
901 fprintf (stdout, " FCS: %02x %02x %02x\n\n", frame->FCS[0],
912 /* RLP Checksum failed - don't we need some statistics about these
913 failures? Nothing is printed, because in the first stage of connection
914 there are too many bad RLP frames... */
917 fprintf(stdout, _("Frame FCS is bad. Ignoring...\n"));
922 MAIN_STATE_MACHINE(frame, &header);
931 /* FIXME: real TEST_Handling - we do not handle TEST yet. */
933 void TEST_Handling() {
938 /* FIXME: better XID_handling - but this will answer a XID command. */
940 bool XID_Handling (RLP_F96Frame *frame, RLP_F96Header *header) {
946 if (CurrentFrameType == RLPFT_U_XID) {
950 while (frame->Data[count] !=0) {
952 type=frame->Data[count] >> 4;
953 length=frame->Data[count] & 0x0f;
958 case 0x01: /* RLP Version Number */
959 RLP_VersionNumber=frame->Data[count];
962 case 0x02: /* Interworking Function (IWF) to Mobile Station (MS) window size */
963 if (frame->Data[count]>=1 && frame->Data[count]<RLP_M)
964 RLP_RCV_WS=frame->Data[count];
967 case 0x03: /* MS to IWF window size */
968 if (frame->Data[count]>=1 && frame->Data[count]<RLP_M)
969 RLP_SEND_WS=frame->Data[count];
972 case 0x04: /* Acknowledgement Timer (T1). */
973 RLP_Timeout1_Limit=frame->Data[count];
976 case 0x05: /* Retransmission attempts (N2). */
977 RLP_N2=frame->Data[count];
980 case 0x06: /* Reply delay (T2). */
981 RLP_T2=frame->Data[count];
984 case 0x07: /* Compression - not yet! */
992 /* Now reassemble a reply */
995 memset(frame->Data,0x00,25); /* Makes debugging easier */
997 /* Version Number - force to 0 for now */
999 frame->Data[count++]=0x11;
1000 frame->Data[count++]=RLP_VersionNumber;
1003 frame->Data[count++]=0x21;
1004 frame->Data[count++]=RLP_RCV_WS;
1005 frame->Data[count++]=0x31;
1006 frame->Data[count++]=RLP_SEND_WS;
1008 /* Acknowledgement Timer (T1). */
1009 frame->Data[count++]=0x41;
1010 frame->Data[count++]=RLP_Timeout1_Limit;
1012 /* Retransmission attempts (N2). */
1013 frame->Data[count++]=0x51;
1014 frame->Data[count++]=RLP_N2;
1016 /* Reply delay (T2). */
1017 frame->Data[count++]=0x61;
1018 frame->Data[count++]=RLP_T2;
1020 XID_R_State = _send;
1029 bool Send_TXU(RLP_F96Frame *frame, RLP_F96Header *header) {
1032 // fprintf(stdout, _("Send_TXU()\n"));
1033 // fprintf(stdout, _("XID_R_State=%d\n"), XID_R_State);
1038 if (RLP_UserEvent(TEST_R_State)) {
1039 RLP_SendF96Frame(RLPFT_U_TEST, false, TEST_R_FBit, 0, 0, TEST_R_Data, false);
1046 if (XID_R_State == _send && frame) {
1047 RLP_SendF96Frame(RLPFT_U_XID, false, true, 0, 0, frame->Data, false);
1048 XID_R_State = _idle;
1054 else if ((XID_C_State == _send ) && (Poll_xchg == _idle)) {
1055 RLP_SendF96Frame(RLPFT_U_XID, true, true, 0, 0, XID_C_Data, false);
1056 XID_C_State = _wait;
1060 } else if (RLP_UserEvent(UI_State)) {
1061 RLP_SendF96Frame(RLPFT_U_UI, true, false, 0, 0, NULL, false);
1073 void RLP_DeliverAllInSeqIF()
1079 if ((R[VR].Data[0] & 0xE0)!=LastStatus) {
1080 LastStatus=(R[VR].Data[0] & 0xE0);
1081 RLP_Passup(StatusChange,&LastStatus,0);
1085 i=R[VR].Data[0] & 0x1f;
1089 /* FIXME - should check for more data in the frame */
1091 RLP_Passup(Data,R[VR].Data+1,j);
1096 } while (R[VR].State==_rcvd);
1100 /* Mark any missing information frames between VR and Ns*/
1101 void RLP_MarkMissingIF(u8 Ns)
1104 for (i=VR; i!=Ns; i=Incr(i)) {
1105 if (R[i].State==_idle) R[i].State=_srej; /* bug in spec, fig A.23 */
1110 /* Information frame handler */
1112 bool RLP_I_Handler(RLP_F96Frame *frame, RLP_F96Header *header)
1115 if ((header->CR) && (header->PF))
1118 /* If the window size is 61, a received frame must have a sequence
1119 number between VR and VR+60 */
1121 if (!InWindow(header->Ns,VR,VR+RLP_RCV_WS-1))
1124 if (header->Ns==VR) {
1125 /* This is not in the spec but I think it is necessary */
1126 if (R[header->Ns].State==_wait) T_RCVS[header->Ns]=-1;
1128 memcpy(R[VR].Data,frame->Data,25);
1129 RLP_DeliverAllInSeqIF();
1132 else { /* Out of sequence, cause a SREJ */
1133 if (R[header->Ns].State==_wait) T_RCVS[header->Ns]=-1;
1134 R[header->Ns].State=_rcvd;
1135 memcpy(R[header->Ns].Data,frame->Data,25);
1136 RLP_MarkMissingIF(header->Ns);
1143 /* Mark acknowledged send frames */
1145 void RLP_AdvanceVA(u8 Nr)
1154 /* Decrease VS back down to Nr since these have not been acknowledged */
1156 void RLP_DecreaseVS(u8 Nr)
1164 /* Supervisory frame handling */
1166 void RLP_S_Handler(RLP_F96Frame *frame, RLP_F96Header *header)
1170 if ((header->CR) && (header->PF)) {
1171 /* Special exchange (ie. error) - counter? */
1173 fprintf(stdout, "Got Poll command\n");
1177 for (i=0; i<RLP_M; i++) R[i].State=_idle;
1180 if (Poll_State!=_idle) {
1181 if (header->PF==0) return;
1182 if ((CurrentFrameType==RLPFT_S_SREJ) || (CurrentFrameType==RLPFT_S_REJ) ||
1183 (CurrentFrameType==RLPFT_SI_SREJ) || (CurrentFrameType==RLPFT_SI_REJ)) return;
1184 RLP_DecreaseVS(header->Nr);
1188 switch (CurrentFrameType){
1192 RLP_AdvanceVA(header->Nr);
1197 RLP_AdvanceVA(header->Nr);
1202 RLP_AdvanceVA(header->Nr);
1204 RLP_DecreaseVS(header->Nr);
1208 S[header->Nr].State=_send;
1220 /* Find the first SREJ frame */
1222 bool RLP_SREJSlot(u8 *x)
1226 for (i=Incr(VR); i!=VR; i=Incr(i)) if (R[i].State==_srej) {
1236 /* Check if any SREJ frames need sending, if not send the next in line */
1238 bool RLP_PrepareDataToTransmit(u8 *p)
1242 for (i=VA; i!=VS; i=Incr(i))
1243 if (S[i].State==_send) {
1248 if (S[VS].State!=_send) return false;
1249 if (!InWindow(VS,VA,VA+RLP_SEND_WS-1))
1259 /* Send a SREJ command */
1261 void RLP_SendSREJ(u8 x)
1265 if ((Poll_xchg==_idle) && (Poll_State==_send)) {
1268 fprintf(stdout, "Sending SREJ with poll\n");
1271 RLP_SendF96Frame(RLPFT_S_SREJ, true, true, x , 0 , NULL, false);
1273 RLP_SetTimer(&T_RCVS[x]);
1279 else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1281 fprintf(stdout, "Sending SREJ for %d along with frame %d\n",x,k);
1283 RLP_SendF96Frame(RLPFT_SI_SREJ, true, false, x , k , S[k].Data, false);
1285 RLP_SetTimer(&T_RCVS[x]);
1290 fprintf(stdout, "Sending SREJ for %d\n",x);
1292 RLP_SendF96Frame(RLPFT_S_SREJ, true, false, x , 0 , NULL, false);
1294 RLP_SetTimer(&T_RCVS[x]);
1299 /* Send a command */
1301 void RLP_Send_XX_Cmd(RLP_FrameTypes type)
1305 if ((Poll_xchg!=_wait) && (Poll_State==_send)) {
1306 RLP_SendF96Frame(type, true, true, VR , 0 , NULL, false);
1308 fprintf(stdout, "Sending Comd %x with Poll\n",type);
1316 else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1318 fprintf(stdout, "Sending Comd %x with frame %d\n",type,k);
1320 RLP_SendF96Frame(type+4, true, false, VR , k , S[k].Data, false);
1327 fprintf(stdout, "Sending Comd %x\n",type);
1329 RLP_SendF96Frame(type, true, false, VR , 0 , NULL, false);
1332 DTX_VR=VR; /* As v7.1.0 spec */
1337 /* Send a Response */
1339 void RLP_Send_XX_Resp(RLP_FrameTypes type)
1343 if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1345 fprintf(stdout, "Sending Resp %x with frame %d\n",type+4,k);
1347 RLP_SendF96Frame(type+4, false, true, VR , k , S[k].Data, false);
1354 fprintf(stdout, "Sending Resp %x\n",type);
1356 RLP_SendF96Frame(type, false, true, VR , 0 , NULL, false);
1363 /* Decide which frame to use and send it - currently only used in state 4 */
1369 if (UA_State==_send) {
1370 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0 , 0 , NULL, false);
1373 else if (Ackn_FBit==true) {
1375 printf("About to send Poll resp\n");
1377 if (LRReady) RLP_Send_XX_Resp(RLPFT_S_RR);
1378 else RLP_Send_XX_Resp(RLPFT_S_RNR);
1380 else if (RLP_SREJSlot(&x)) RLP_SendSREJ(x);
1381 else if (LRReady) RLP_Send_XX_Cmd(RLPFT_S_RR);
1382 else RLP_Send_XX_Cmd(RLPFT_S_RNR);
1385 void MAIN_STATE_MACHINE(RLP_F96Frame *frame, RLP_F96Header *header) {
1388 switch (CurrentState) {
1390 /***** RLP State 0. *****/
1392 /* ADM and Detached.
1394 This is the initial state after power on.
1396 As long as the RLP entity is "Detached", DISC(P) and/or SABM at the
1397 lower interface is acted upon by sending DM(P) or DM(1). Any other
1398 stimulus at the lower interface is ignored.
1400 This state can be exited only with Attach_Req. */
1405 fprintf(stdout, _("RLP state 0.\n"));
1408 switch (CurrentFrameType) {
1411 RLP_SendF96Frame(RLPFT_U_DM, false, header->PF, 0, 0, NULL, false);
1415 RLP_SendF96Frame(RLPFT_U_DM, false, true, 0, 0, NULL, false);
1419 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1420 if (RLP_GetUserRequest(Attach_Req)) {
1429 /***** RLP State 1. *****/
1431 /* ADM and Attached.
1433 The RLP entity is ready to established a connection, either by
1434 initiating the connection itself (Conn_Req) or by responding to an
1435 incoming connection request (SABM).
1437 Upon receiving a DISC PDU, the handling of the UA response is
1443 fprintf(stdout, _("RLP state 1.\n"));
1446 if (!XID_Handling(frame, header)) {
1448 switch(CurrentFrameType) {
1455 RLP_Passup(Conn_Ind,NULL,0);
1464 case RLPFT_BAD: /* If we get a bad frame we can still respond with SABM */
1466 if (RLP_GetUserRequest(Conn_Req)) {
1475 if (!Send_TXU(frame, header)) {
1477 if (UA_State == _send) {
1478 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1482 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1486 /***** RLP State 2. *****/
1491 fprintf(stdout, _("RLP state 2.\n"));
1494 if (!XID_Handling(frame, header)) {
1496 switch(CurrentFrameType) {
1525 fprintf(stdout, _("UA received in RLP state 2.\n"));
1528 if (SABM_State == _wait && header->PF) {
1537 if (SABM_State == _wait && header->PF) {
1539 // Conn_Conf_Neg=true;
1545 if (T == RLP_Timeout1_Limit) {
1547 if (SABM_Count>RLP_N2)
1555 if (!Send_TXU(frame, header)) {
1557 if (SABM_State == _send && Poll_xchg == _idle) {
1558 RLP_SendF96Frame(RLPFT_U_SABM, true, true, 0, 0, NULL, false);
1564 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1567 if (RLP_GetUserRequest(Disc_Req)) {
1571 DISC_PBit=(Poll_xchg==_idle);
1577 /***** RLP State 3. *****/
1582 fprintf(stdout, _("RLP state 3.\n"));
1585 if (!XID_Handling(frame, header)) {
1587 switch(CurrentFrameType) {
1594 RLP_Passup(Disc_Ind,NULL,0);
1601 if (RLP_GetUserRequest(Conn_Req)) {
1605 RLP_Init_link_vars();
1606 } else if (RLP_GetUserRequest(Conn_Req_Neg)) {
1607 DM_State=_send; /* FIXME - code to handle DM_State - missing from spec? */
1615 if (!Send_TXU(frame, header)) {
1617 if (UA_State == _send) {
1618 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1622 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1626 if (RLP_GetUserRequest(Disc_Req)) {
1630 DISC_PBit=(Poll_xchg==_idle);
1636 /***** RLP State 4. *****/
1641 fprintf(stdout, _("RLP state 4.\n"));
1644 if (!XID_Handling(frame, header)) {
1646 switch (CurrentFrameType) {
1654 RLP_Passup(Disc_Ind,NULL,0);
1662 RLP_Passup(Reset_Ind,NULL,0);
1669 /* Should check here for unsolicited Fbit */
1670 /* Spec says: "Nr must be within the set of not yet
1671 acknowledged I-frames or it must be the next possible
1672 frame number." That's VA..VS-1 or VS, i.e. VA..VS */
1673 if (!InWindow(header->Nr,VA,VS))
1675 RLP_S_Handler(frame,header);
1681 /* Should check here for unsolicited Fbit */
1682 if (!InWindow(header->Nr,VA,VS))
1684 if (!RLP_I_Handler(frame,header)) RLP_S_Handler(frame,header);
1691 for (i=0;i<RLP_M;i++) if (T_RCVS[i]==0) {
1693 fprintf(stdout, "T_RCVS[%d] Timeout in State 4\n",i);
1700 fprintf(stdout, "T Timeout in State 4\n");
1704 if (Poll_State==_idle) {
1709 if (Poll_Count>RLP_N2) {
1711 fprintf(stdout, "N2 Errors in State 4\n");
1719 if (!Send_TXU(frame,header)) {
1720 if (UA_State == _send) {
1721 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1724 else RLP_SendData();
1728 /* Load any data from the Send ringbuffer into the send slots */
1729 RLP_AddRingBufferDataToSlots();
1732 // if (CurrentFrameType!=RLPFT_BAD)
1733 fprintf(stdout, "VD=%d, VA=%d, VS=%d, VR=%d\n",VD,VA,VS,VR);
1734 #ifdef RLP_DEBUG_STATE
1738 if(UA_State!=_idle) printf("[UA_State %d]",UA_State);
1739 if(UI_State!=_idle) printf("[UI_State %d]",UI_State);
1740 if(Ackn_State!=_idle) printf("[Ackn_State %d]",Ackn_State);
1741 if(Poll_State!=_idle) printf("[Poll_State %d]",Poll_State);
1742 if(Poll_xchg!=_idle) printf("[Poll_xchg %d]",Poll_xchg);
1743 if(SABM_State!=_idle) printf("[SABM_State %d]",SABM_State);
1744 if(DISC_State!=_idle) printf("[DISC_State %d]",DISC_State);
1745 if(DM_State!=_idle) printf("[DM_State %d]",DM_State);
1746 if(XI_R_State!=_idle) printf("[XI_R_State %d]",XI_R_State);
1747 if(XID_C_State!=_idle) printf("[XID_C_State %d]",XID_C_State);
1748 if(XID_R_State!=_idle) printf("[XID_R_State %d]",XID_R_State);
1749 if(TEST_R_State!=_idle) printf("[TEST_R_State %d]",TEST_R_State);
1752 for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",S[zzz].State);
1754 for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",R[zzz].State);
1755 printf("\nT: %d, T_RCVS: ",T);
1756 for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",T_RCVS[zzz]);
1763 if (RLP_GetUserRequest(Disc_Req)) {
1768 DISC_PBit=(Poll_xchg==_idle);
1775 /***** RLP State 5. *****/
1780 fprintf(stdout, _("RLP state 5.\n"));
1783 if (!XID_Handling(frame, header)) {
1785 switch (CurrentFrameType) {
1789 if ((DISC_State==_wait) && (DISC_PBit==header->PF)) {
1790 if (DISC_PBit==true) Poll_xchg=_idle;
1806 if (!Send_TXU(frame,header)) {
1807 if ((DISC_State!=_wait) && !((DISC_PBit==true) && (Poll_xchg==_wait))) {
1808 RLP_SendF96Frame(RLPFT_U_DISC, true, DISC_PBit, 0, 0, NULL, false);
1809 if (DISC_PBit==true) Poll_xchg=_wait;
1815 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1819 if (DISC_PBit==1) Poll_xchg=_idle;
1821 if (DISC_Count>RLP_N2) {
1824 fprintf(stdout, "N2 error in State 5!\n");
1833 /***** RLP State 6. *****/
1834 /* We should only get here after a Reset_Req which is not yet supported */
1839 fprintf(stdout, _("RLP state 6 - not yet implemented!\n"));
1842 if (!XID_Handling(frame, header)) {
1844 switch (CurrentFrameType) {
1851 if (!Send_TXU(frame,header)) {
1854 if (RLP_GetUserRequest(Disc_Req)) {
1858 DISC_PBit=(Poll_xchg==_idle);
1865 /***** RLP State 7. *****/
1870 fprintf(stdout, _("RLP state 7.\n"));
1873 if (!XID_Handling(frame, header)) {
1875 switch (CurrentFrameType) {
1877 RLP_Passup(Disc_Ind,NULL,0);
1887 if (RLP_GetUserRequest(Reset_Resp)){
1890 RLP_Init_link_vars();
1894 if (!Send_TXU(frame,header)) {
1895 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1898 if (RLP_GetUserRequest(Disc_Req)) {
1902 DISC_PBit=(Poll_xchg==_idle);
1912 fprintf(stdout, _("DEBUG: Unknown RLP state!\n"));
1918 CurrentState=NextState;
1922 /* Given a pointer to an RLP XID frame, display contents in human readable
1923 form. Note for now only Version 0 and 1 are supported. Fields can appear
1924 in any order and are delimited by a zero type field. This function is the
1925 exact implementation of section 5.2.2.6, Exchange Identification, XID of
1926 the GSM specification 04.22. */
1928 void RLP_DisplayXID(u8 *frame)
1931 int count = 25; /* Sanity check */
1934 fprintf(stdout, "XID: ");
1936 while ((*frame !=0) && (count >= 0)) {
1939 length = *frame & 0x0f;
1943 case 0x01: /* RLP Version Number, probably 1 for Nokia. */
1946 fprintf(stdout, "Ver %d ", *frame);
1949 case 0x02: /* IWF to MS window size */
1952 fprintf(stdout, "IWF-MS %d ", *frame);
1955 case 0x03: /* MS to IWF window size. */
1958 fprintf(stdout, "MS-IWF %d ", *frame);
1961 case 0x04: /* Acknowledgement Timer (T1). */
1964 fprintf(stdout, "T1 %dms ", *frame * 10);
1967 case 0x05: /* Retransmission attempts (N2). */
1970 fprintf(stdout, "N2 %d ", *frame);
1973 case 0x06: /* Reply delay (T2). */
1976 fprintf(stdout, "T2 %dms ", *frame * 10);
1979 case 0x07: /* Compression. */
1982 fprintf(stdout, "Comp [Pt=%d ", (*frame >> 4) );
1983 fprintf(stdout, "P0=%d ", (*frame & 0x03) );
1986 fprintf(stdout, "P1l=%d ", *frame);
1988 fprintf(stdout, "P1h=%d ", *frame);
1991 fprintf(stdout, "P2=%d] ", *frame);
1997 fprintf(stdout, "Unknown! type=%02x, length=%02x", type, length);
2008 /* Given a pointer to an F9.6 Frame, split data out into component parts of
2009 header and determine frame type. */
2011 void RLP_DecodeF96Header(RLP_F96Frame *frame, RLP_F96Header *header)
2014 /* Poll/Final bit. */
2016 if ((frame->Header[1] & 0x02))
2021 /* Command/Response bit. */
2023 if ((frame->Header[0] & 0x01))
2028 /* Send Sequence Number. */
2030 header->Ns = frame->Header[0] >> 3;
2032 if ((frame->Header[1] & 0x01))
2033 header->Ns |= 0x20; /* Most significant bit. */
2035 /* Determine frame type. See the section 5.2.1 in the GSM 04.22
2038 switch (header->Ns) {
2040 case 0x3f: /* Frames of type U, unnumbered frames. */
2042 /* U frames have M1, ..., M5 stored in the place of N(R). */
2044 header->Type = RLPFT_U;
2045 header->M = (frame->Header[1] >> 2) & 0x1f;
2046 return; /* For U frames, we do not need N(R) and bits S1 and S2. */
2048 case 0x3e: /* Frames of type S, supervisory frames. */
2050 header->Type = RLPFT_S;
2053 default: /* Frames of type I+S, numbered information transfer ans
2054 supervisory frames combined. */
2056 header->Type = RLPFT_IS;
2060 /* Receive Sequence Number N(R). */
2061 header->Nr = frame->Header[1] >> 2;
2063 /* Status bits (S1 and S2). */
2064 header->S = (frame->Header[0] >> 1) & 0x03;