Found in "gnokii-working" directory, some November-patches version
[gnokii.git] / common / data / rlp-common.c
1 /*
2
3   $Id$
4
5   G N O K I I
6
7   A Linux/Unix toolset and driver for Nokia mobile phones.
8
9   Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
10   
11   Released under the terms of the GNU GPL, see file COPYING for more details.
12
13   The development of RLP protocol is sponsored by SuSE CR, s.r.o. (Pavel use
14   the SIM card from SuSE for testing purposes).
15
16   Actual implementation of RLP protocol. Based on GSM 04.22 version 7.1.0,
17   downloadable from www.etsi.org (if you register with them)
18
19   $Log$
20   Revision 1.1.1.3  2002/04/03 00:08:05  short
21   Found in "gnokii-working" directory, some November-patches version
22
23   Revision 1.5  2001/03/26 23:39:36  pkot
24   Minor updates:
25    - Windows INLINE patch (Manfred Jonsson)
26    - patch to configure.in to compile under FreeBSD (Panagiotis Astithas)
27    - other cleanups (me)
28
29   Revision 1.4  2001/03/13 01:23:18  pkot
30   Windows updates (Manfred Jonsson)
31
32   Revision 1.3  2001/02/21 19:57:00  chris
33   More fiddling with the directory layout
34
35   Revision 1.2  2001/02/17 22:40:51  chris
36   ATA support
37
38
39 */
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <ctype.h>
44 #include <stdlib.h>
45
46 #include "data/rlp-common.h"
47 #include "data/rlp-crc24.h"
48 #include "gsm-common.h" /* For GSM error and RLP send function. */
49 #include "misc.h" /* For u8, u32 etc. */
50
51 #ifdef WIN32
52 #define INLINE __inline
53 #else
54 #define INLINE inline
55 #endif
56
57 /* Our state machine which handles all of nine possible states of RLP
58    machine. */
59 void MAIN_STATE_MACHINE(RLP_F96Frame *frame, RLP_F96Header *header);
60
61 /* This is the type we are just handling. */
62 RLP_FrameTypes CurrentFrameType;
63
64 /* Current state of RLP state machine. */
65 RLP_State      CurrentState=RLP_S0; /* We start at ADM and Detached */
66
67 /* Next state of RLP state machine. */
68 RLP_State      NextState;
69
70 /* Pointer to Send function that sends frame to phone. */
71 bool      (*RLPSendFunction)(RLP_F96Frame *frame, bool out_dtx);
72
73 /* Pointer to Passup function which returns data/inds */
74 int      (*RLP_Passup)(RLP_UserInds ind, u8 *buffer, int length);
75
76
77 /* State variables - see GSM 04.22, Annex A, section A.1.2 */
78
79 RLP_StateVariable UA_State;
80 RLP_StateVariable UI_State;
81 RLP_StateVariable Ackn_State;
82 RLP_StateVariable Poll_State;
83 RLP_StateVariable Poll_xchg;
84 RLP_StateVariable SABM_State;
85 RLP_StateVariable DISC_State;
86 RLP_StateVariable DM_State;  /* FIXME - not handled */
87 RLP_StateVariable XI_R_State;
88 RLP_StateVariable XID_C_State;
89 RLP_StateVariable XID_R_State;
90 RLP_StateVariable TEST_R_State;
91
92 u8 VR=0;
93 u8 VA=0;
94 u8 VS=0;
95 u8 VD=0;
96 u8 DISC_Count;
97
98 u8 DTX_VR;
99 RLP_FrameTypes DTX_SF;
100
101 #define RLP_M 62
102
103 RLP_Data R[RLP_M];
104 RLP_Data S[RLP_M];
105
106 RLP_StateVariable SABM_State;
107 int SABM_Count;
108
109 RLP_UserRequestStore UserRequests;
110
111 u8 Poll_Count=0;
112
113 /* For now timing is done based on a frame reception rate of 20ms */
114 /* Serge has measured it as 18.4ms */
115 #define RLP_T_Scaling 2
116
117 /* Timers - a value of -1 means not set */
118 /* To set, timer is loaded with RLP_Timeout1_Limit/RLP_T_Scaling. */
119 /* Each received frame (including NULLS / errors) any >0 timer is decrease */
120
121 int T;
122 int T_RCVS[RLP_M];
123
124 bool UA_FBit=true;
125 bool Ackn_FBit=false;
126 bool DM_FBit=false;  /* FIXME - not handled */
127 bool RRReady=false;
128 bool LRReady=true;   /* FIXME - not handled (as if we couldn't keep up with 9600bps :-) */
129 bool DISC_PBit=false;
130
131 u8 LastStatus=0xff;   /* Last Status byte */
132
133
134 /* RLP Parameters. FIXME: Reset these - e.g. when entering state 0 */
135
136 u8 RLP_SEND_WS = RLP_M-1;
137 u8 RLP_RCV_WS = RLP_M-1;
138 u8 RLP_Timeout1_Limit = 55;
139 u8 RLP_N2 = 15; /* Maximum number of retransmisions. GSM spec says 6 here, but
140                    Nokia will XID this. */
141 u8 RLP_T2=0;
142 u8 RLP_VersionNumber=0;
143
144
145
146 /****** Externally called functions ********/
147 /*******************************************/
148
149
150 /* Function to initialise RLP code.  Main purpose for now is
151    to set the address of the RLP send function in the API code. */
152
153 void RLP_Initialise(bool (*rlp_send_function)(RLP_F96Frame *frame, bool out_dtx), int (*rlp_passup)(RLP_UserInds ind, u8 *buffer, int length))
154 {
155         int i;
156
157         RLPSendFunction = rlp_send_function;
158         RLP_Passup=rlp_passup;
159         UserRequests.Conn_Req=false;
160         UserRequests.Attach_Req=false;
161         UserRequests.Conn_Req_Neg=false;
162         UserRequests.Reset_Resp=false;
163         UserRequests.Disc_Req=false;
164         CurrentState=RLP_S0; 
165         T=-1;
166         for (i=0;i<RLP_M;i++) T_RCVS[i]=-1;
167
168         UA_FBit=true;
169         Ackn_FBit=false;
170         DISC_PBit=false;
171         LastStatus=0xff;
172         Poll_Count=0;
173         VR=0;
174         VA=0;
175         VS=0;
176         VD=0;
177
178         RLP_SEND_WS = RLP_M-1;
179         RLP_RCV_WS = RLP_M-1;
180         RLP_Timeout1_Limit = 55;
181         RLP_N2 = 15; 
182         RLP_T2=0;
183         RLP_VersionNumber=0;
184
185 }
186
187 /* Set a user event */
188 /* Called by user program for now */
189
190 void RLP_SetUserRequest(RLP_UserRequests type, bool value) {
191
192         switch (type) {
193         case Conn_Req:
194                 UserRequests.Conn_Req=value;
195                 break;
196         case Attach_Req:
197                 UserRequests.Attach_Req=value;
198                 break;
199         case Conn_Req_Neg:
200                 UserRequests.Conn_Req_Neg=value;
201                 break;
202         case Reset_Resp:
203                 UserRequests.Reset_Resp=value;
204                 break;
205         case Disc_Req:
206                 UserRequests.Disc_Req=value;
207                 break;
208         default:
209                 break;
210         }
211 }
212
213
214
215
216 /***** Internal functions **********/
217 /***********************************/
218
219
220 /* Check whether a user event is set */
221
222 bool RLP_GetUserRequest(RLP_UserRequests type) {
223
224         bool result=false, *x;
225
226         switch (type) {
227         case Conn_Req:
228                 x=&UserRequests.Conn_Req;
229                 break;
230         case Attach_Req:
231                 x=&UserRequests.Attach_Req;
232                 break;
233         case Conn_Req_Neg:
234                 x=&UserRequests.Conn_Req_Neg;
235                 break;
236         case Reset_Resp:
237                 x=&UserRequests.Reset_Resp;
238                 break;
239         case Disc_Req:
240                 x=&UserRequests.Disc_Req;
241                 break;
242         default:
243                 x=&result;
244                 break;
245         }
246
247         result=*x;
248
249         if ( *x == true )
250                 *x=false;
251
252         return result;
253 }
254
255 void RLP_SetTimer(int *timer)
256 {
257         *timer=(int)(RLP_Timeout1_Limit/RLP_T_Scaling);
258 }
259
260
261 /* Previous sequence number. */
262 static INLINE u8 Decr(u8 x)
263 {
264         if (x==0)
265                 return (RLP_M-1);
266         else
267                 return (x-1);
268 }
269
270 /* Next sequence number. */
271 static INLINE u8 Incr(u8 x)
272 {
273         if (x==RLP_M-1)
274                 return 0;
275         else
276                 return (x+1);
277 }
278
279 /* Difference between sequence numbers. */
280
281 /* FIXME: Not used now, so I have commented it out. PJ
282  * static INLINE u8 Diff(u8 x, u8 y)
283  * {
284  *   int result = x-y;
285  *   return (result >= 0) ? result : result + RLP_M;
286  * }
287 */
288
289 /* Check value is within range */
290 static bool InWindow(u8 val, u8 lower, u8 upper)
291 {
292         /* allow for one level of wrapping round */
293         if (lower>=RLP_M) lower-=RLP_M;
294         if (upper>=RLP_M) upper-=RLP_M;
295         if (val>=RLP_M)   val-=RLP_M;
296
297   /*   .......L*****U....... */
298         if (lower <= upper)
299                 return (val >= lower) && (val <= upper);
300
301   /*  ******U.........L***** */
302         return (val <= upper) || (val >= lower);
303 }
304
305 void RLP_Init_link_vars(void)
306 {
307         int i;
308   
309         Ackn_State=_idle;
310         Poll_State=_idle;
311         Poll_Count=0;
312         Poll_xchg=_idle;
313         SABM_State=_idle;
314         DISC_State=_idle;
315         RRReady=true;  /* This seems a bit strange but it's what the spec says... */
316         VA=0;
317         VR=0;
318         VS=0;
319         VD=0;  
320         LastStatus=0xff;
321
322         for(i=0;i<RLP_M;i++) {
323                 R[i].State=_idle;
324                 S[i].State=_idle;
325         }
326   
327 }
328
329
330 void RLP_AddRingBufferDataToSlots(void)
331 {
332         u8 buffer[24];
333         int size;
334
335         while ((S[VD].State==_idle)
336                && ((size=RLP_Passup(GetData,buffer,24))!=0)) {
337                 memset(S[VD].Data,0xff,25);    /* FIXME - this isn't necessary - but makes debugging easier! */
338                 if (size>23) {
339                         S[VD].Data[0]=0x1e;
340                         size=24;
341                 }
342                 else S[VD].Data[0]=size;
343     
344                 memcpy(&S[VD].Data[1],buffer,size);
345     
346                 if (size!=24) S[VD].Data[size+1]=0x1f;
347
348                 S[VD].State=_send;
349                 VD=Incr(VD);
350         }  
351 }
352
353
354 /* FIXME: Remove this after finishing. */
355
356 void X(RLP_F96Frame *frame) {
357
358         int i;
359
360         for (i=0; i<30; i++)
361                 printf("byte[%2d]: %02x\n", i, *( (u8 *)frame+i));
362    
363 }
364
365
366  
367 void ResetAllT_RCVS(void)
368 {
369
370         int i;
371         for (i=0;i<RLP_M;i++) T_RCVS[i]=-1; 
372 }
373
374
375
376 /* This function is used for sending RLP frames to the phone. */
377
378 void RLP_SendF96Frame(RLP_FrameTypes FrameType,
379                       bool OutCR, bool OutPF,
380                       u8 OutNR, u8 OutNS,
381                       u8 *OutData, u8 OutDTX)
382 {
383
384         RLP_F96Frame frame;
385         int i;
386
387         frame.Header[0]=0;
388         frame.Header[1]=0;
389
390 #define SetCRBit frame.Header[0]|=0x01;
391 #define SetPFBit frame.Header[1]|=0x02;
392
393 #define ClearCRBit frame.Header[0]&=(~0x01);
394 #define ClearPFBit frame.Header[1]&=(~0x02);
395
396         /* If Command/Response bit is set, set it in the header. */
397         if (OutCR)
398                 SetCRBit;
399
400
401         /* If Poll/Final bit is set, set it in the header. */
402         if (OutPF)
403                 SetPFBit;
404
405
406         /* If OutData is not specified (ie. is NULL) we want to clear frame.Data
407            array for the user. */
408         if (!OutData) {
409
410                 frame.Data[0]=0x00; // 0x1f
411
412                 for (i=1; i<25; i++)
413                         frame.Data[i]=0;
414         }
415         else {
416                 for (i=0; i<25; i++)
417                         frame.Data[i]=OutData[i];
418         }
419
420 #define PackM(x)  frame.Header[1]|=((x)<<2);
421 #define PackS(x)  frame.Header[0]|=((x)<<1);
422 #define PackNR frame.Header[1]|=(OutNR<<2);
423 #define PackNS frame.Header[0]|=(OutNS<<3);frame.Header[1]|=(OutNS>>5);
424
425         switch (FrameType) {
426
427                 /* Unnumbered frames. Be careful - some commands are used as commands
428                    only, so we have to set C/R bit later. We should not allow user for
429                    example to send SABM as response because in the spec is: The SABM
430                    encoding is used as command only. */
431
432         case RLPFT_U_SABM:
433
434                 frame.Header[0]|=0xf8; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
435                 frame.Header[1]|=0x01; /* 1 P/F M1 M2 M3 M4 M5 X */
436
437                 SetCRBit; /* The SABM encoding is used as a command only. */
438                 SetPFBit; /* It is always used with the P-bit set to "1". */
439
440                 PackM(RLPU_SABM);
441
442                 break;
443
444         case RLPFT_U_UA:
445
446                 frame.Header[0]|=0xf8;
447                 frame.Header[1]|=0x01;
448
449                 ClearCRBit; /* The UA encoding is used as a response only. */
450
451                 PackM(RLPU_UA);
452
453                 break;
454
455         case RLPFT_U_DISC:
456
457                 frame.Header[0]|=0xf8;
458                 frame.Header[1]|=0x01;
459
460                 SetCRBit; /* The DISC encoding is used as a command only. */
461
462                 PackM(RLPU_DISC);
463
464                 break;
465
466         case RLPFT_U_DM:
467
468                 frame.Header[0]|=0xf8;
469                 frame.Header[1]|=0x01;
470
471                 ClearCRBit; /* The DM encoding is used as a response only. */
472
473                 PackM(RLPU_DM);
474
475                 break;
476
477         case RLPFT_U_NULL:
478
479                 frame.Header[0]|=0xf8;
480                 frame.Header[1]|=0x01;
481
482                 PackM(RLPU_NULL);
483
484                 break;
485
486         case RLPFT_U_UI:
487
488                 frame.Header[0]|=0xf8;
489                 frame.Header[1]|=0x01;
490
491                 PackM(RLPU_UI);
492
493                 break;
494
495         case RLPFT_U_XID:
496
497                 frame.Header[0]|=0xf8;
498                 frame.Header[1]|=0x01;
499
500                 SetPFBit; /* XID frames are always used with the P/F-bit set to "1". */
501
502                 PackM(RLPU_XID);
503
504                 break;
505
506         case RLPFT_U_TEST:
507
508                 frame.Header[0]|=0xf8;
509                 frame.Header[1]|=0x01;
510
511                 PackM(RLPU_TEST);
512
513                 break;
514
515         case RLPFT_U_REMAP:
516
517                 frame.Header[0]|=0xf8;
518                 frame.Header[1]|=0x01;
519
520                 ClearPFBit; /* REMAP frames are always used with P/F-bit set to "0". */
521
522                 PackM(RLPU_REMAP);
523
524                 break;
525
526         case RLPFT_S_RR:
527
528                 frame.Header[0]|=0xf0;  /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
529                 frame.Header[1]|=0x01; /* 1 P/F ...N(R)... */
530
531                 PackNR;
532
533                 PackS(RLPS_RR);
534
535                 break;
536
537         case RLPFT_S_REJ:
538
539                 frame.Header[0]|=0xf0;
540                 frame.Header[1]|=0x01;
541
542                 PackNR;
543
544                 PackS(RLPS_REJ);
545
546                 break;
547
548         case RLPFT_S_RNR:
549
550                 frame.Header[0]|=0xf0;
551                 frame.Header[1]|=0x01;
552
553                 PackNR;
554
555                 PackS(RLPS_RNR);
556
557                 break;
558
559         case RLPFT_S_SREJ:
560
561                 frame.Header[0]|=0xf0;
562                 frame.Header[1]|=0x01;
563
564                 PackNR;
565
566                 PackS(RLPS_SREJ);
567
568                 break;
569
570         case RLPFT_SI_RR:
571
572                 PackNR;
573                 PackNS;
574
575                 PackS(RLPS_RR);
576
577                 break;
578
579         case RLPFT_SI_REJ:
580                 PackNR;
581                 PackNS;
582
583                 PackS(RLPS_REJ);
584
585                 break;
586
587         case RLPFT_SI_RNR:
588
589                 PackNR;
590                 PackNS;
591
592                 PackS(RLPS_RNR);
593
594                 break;
595
596         case RLPFT_SI_SREJ:
597                 PackNR;
598                 PackNS;
599
600                 PackS(RLPS_SREJ);
601
602                 break;
603
604         default:
605                 break;
606         }
607
608
609         /* Store FCS in the frame. */
610         RLP_CalculateCRC24Checksum((u8 *)&frame, 27, frame.FCS);
611
612         // X(&frame);
613
614         if (RLPSendFunction)
615                 RLPSendFunction(&frame, OutDTX);
616
617 }
618
619 /* Check_input_PDU in Serge's code. */
620
621 void RLP_DisplayF96Frame(RLP_F96Frame *frame)
622 {
623         int           count;
624         RLP_F96Header header;
625
626         if (T>=0) T--;
627         for (count=0;count<RLP_M;count++) if (T_RCVS[count]>=0) T_RCVS[count]--;
628
629         CurrentFrameType=RLPFT_BAD;
630
631         if (!frame) {
632                 /* no frame provided, drop through to state machine anyway */
633         } else if (RLP_CheckCRC24FCS((u8 *)frame, 30) == true) {
634
635                 /* Here we have correct RLP frame so we can parse the field of the header
636                    to out structure. */
637
638                 RLP_DecodeF96Header(frame, &header);
639
640                 switch (header.Type) {
641
642                 case RLPFT_U: /* Unnumbered frames. */
643
644 #ifdef RLP_DEBUG
645                         fprintf(stdout, "Unnumbered Frame [$%02x%02x] M=%02x ", frame->Header[0],
646                                 frame->Header[1],
647                                 header.M);
648 #endif
649
650                         switch (header.M) {
651
652                         case RLPU_SABM :
653                                 if (header.CR == 0 || header.PF == 0) break;
654
655 #ifdef RLP_DEBUG
656                                 fprintf(stdout, "Set Asynchronous Balanced Mode (SABM) ");
657 #endif
658
659                                 CurrentFrameType=RLPFT_U_SABM;
660
661                                 break;
662
663                         case RLPU_UA:
664                                 if (header.CR == 1) break;
665
666 #ifdef RLP_DEBUG
667                                 fprintf(stdout, "Unnumbered Acknowledge (UA) ");
668 #endif
669
670                                 CurrentFrameType=RLPFT_U_UA;
671
672                                 break;
673
674                         case RLPU_DISC:
675                                 if (header.CR == 0) break;
676
677 #ifdef RLP_DEBUG
678                                 fprintf(stdout, "Disconnect (DISC) ");
679 #endif
680
681                                 CurrentFrameType=RLPFT_U_DISC;
682
683                                 break;
684
685                         case RLPU_DM:
686                                 if (header.CR == 1) break;
687
688 #ifdef RLP_DEBUG
689                                 fprintf(stdout, "Disconnected Mode (DM) ");
690 #endif
691                                 CurrentFrameType=RLPFT_U_DM;
692
693                                 break;
694
695                         case RLPU_UI:
696
697 #ifdef RLP_DEBUG
698                                 fprintf(stdout, "Unnumbered Information (UI) ");
699 #endif
700
701                                 CurrentFrameType=RLPFT_U_UI;
702
703                                 break;
704
705                         case RLPU_XID:
706
707 #ifdef RLP_DEBUG
708                                 fprintf(stdout, "Exchange Information (XID) \n");
709                                 RLP_DisplayXID(frame->Data);
710 #endif
711
712                                 CurrentFrameType=RLPFT_U_XID;
713
714                                 break;
715
716                         case RLPU_TEST:
717
718 #ifdef DEBUG
719                                 fprintf(stdout, "Test (TEST) ");
720 #endif
721
722                                 CurrentFrameType=RLPFT_U_TEST;
723
724                                 break;
725
726                         case RLPU_NULL:
727
728 #ifdef DEBUG
729                                 fprintf(stdout, "Null information (NULL) ");
730 #endif
731
732                                 CurrentFrameType=RLPFT_U_NULL;
733
734                                 break;
735
736                         case RLPU_REMAP:
737
738 #ifdef DEBUG
739                                 fprintf(stdout, "Remap (REMAP) ");
740 #endif
741
742                                 CurrentFrameType=RLPFT_U_REMAP;
743
744                                 break;
745                     
746                         default :
747
748 #ifdef RLP_DEBUG
749                                 fprintf(stdout, _("Unknown!!! "));
750 #endif
751
752                                 CurrentFrameType=RLPFT_BAD;
753
754                                 break;
755
756                         }
757                         break;
758             
759                 case RLPFT_S: /* Supervisory frames. */
760
761 #ifdef RLP_DEBUG
762                         fprintf(stdout, "Supervisory Frame [$%02x%02x] S=0x%x N(R)=%d ",
763                                 frame->Header[0],
764                                 frame->Header[1],
765                                 header.S,
766                                 header.Nr);
767 #endif
768
769                         switch (header.S) {
770
771                         case RLPS_RR:
772
773 #ifdef RLP_DEBUG
774                                 fprintf(stdout, "RR");
775 #endif
776
777                                 CurrentFrameType=RLPFT_S_RR;
778
779                                 break;
780
781                         case RLPS_REJ:
782
783 #ifdef RLP_DEBUG
784                                 fprintf(stdout, "REJ");
785 #endif
786
787                                 CurrentFrameType=RLPFT_S_REJ;
788
789                                 break;
790
791                         case RLPS_RNR:
792
793 #ifdef RLP_DEBUG
794                                 fprintf(stdout, "RNR");
795 #endif
796
797                                 CurrentFrameType=RLPFT_S_RNR;
798
799                                 break;
800
801                         case RLPS_SREJ:
802
803 #ifdef RLP_DEBUG
804                                 fprintf(stdout, "SREJ");
805 #endif
806
807                                 CurrentFrameType=RLPFT_S_SREJ;
808
809                                 break;
810
811                         default:
812
813 #ifdef DEBUG
814                                 fprintf(stdout, _("BAD"));
815 #endif
816
817                                 CurrentFrameType=RLPFT_BAD;
818
819                                 break;
820
821                         }
822
823                         break;
824             
825                 default:
826
827 #ifdef RLP_DEBUG
828                         fprintf(stdout, "Info+Supervisory Frame [$%02x%02x] S=0x%x N(S)=%d N(R)=%d ",
829                                 frame->Header[0],
830                                 frame->Header[1],
831                                 header.S,
832                                 header.Ns,
833                                 header.Nr);
834 #endif
835
836                         switch (header.S) {
837
838                         case RLPS_RR:
839
840 #ifdef RLP_DEBUG
841                                 fprintf(stdout, "RR");
842 #endif
843
844                                 CurrentFrameType=RLPFT_SI_RR;
845
846                                 break;
847
848                         case RLPS_REJ:
849
850 #ifdef RLP_DEBUG
851                                 fprintf(stdout, "REJ");
852 #endif
853
854                                 CurrentFrameType=RLPFT_SI_REJ;
855
856                                 break;
857
858                         case RLPS_RNR:
859
860 #ifdef RLP_DEBUG
861                                 fprintf(stdout, "RNR");
862 #endif
863
864                                 CurrentFrameType=RLPFT_SI_RNR;
865
866                                 break;
867
868                         case RLPS_SREJ:
869
870 #ifdef RLP_DEBUG
871                                 fprintf(stdout, "SREJ");
872 #endif
873
874                                 CurrentFrameType=RLPFT_SI_SREJ;
875
876                                 break;
877
878                         default:
879
880 #ifdef DEBUG
881                                 fprintf(stdout, "BAD");
882 #endif
883
884                                 CurrentFrameType=RLPFT_BAD;
885
886                                 break;
887                         }
888
889                         break;
890                 }   
891
892 #ifdef RLP_DEBUG
893
894                 /* Command/Response and Poll/Final bits. */
895
896                 fprintf(stdout, " C/R=%d P/F=%d", header.CR, header.PF);
897 #endif
898
899 #ifdef DEBUG
900
901                 /* Information. */
902     
903                 if (CurrentFrameType!=RLPFT_U_NULL) {
904
905                         fprintf(stdout, "\n");
906
907                         for (count = 0; count < 25; count ++) {
908
909                                 if (isprint(frame->Data[count]))
910                                         fprintf(stdout, "[%02x%c]", frame->Data[count], frame->Data[count]);
911                                 else
912                                         fprintf(stdout, "[%02x ]", frame->Data[count]);
913
914                                 if (count == 15)
915                                         fprintf(stdout, "\n");
916                         }
917                 }
918
919 #endif
920 #ifdef RLP_DEBUG
921                 /* FCS. */
922     
923                 fprintf (stdout, " FCS: %02x %02x %02x\n\n", frame->FCS[0],
924                          frame->FCS[1],
925                          frame->FCS[2]);
926
927                 fflush(stdout);
928
929 #endif
930
931         }
932         else {
933
934                 /* RLP Checksum failed - don't we need some statistics about these
935                    failures? Nothing is printed, because in the first stage of connection
936                    there are too many bad RLP frames... */
937
938 #ifdef DEBUG
939                 fprintf(stdout, _("Frame FCS is bad. Ignoring...\n"));
940 #endif
941
942         }
943
944         MAIN_STATE_MACHINE(frame, &header);
945
946         /*
947           Y:= outblock();
948         */
949
950         return;
951 }
952
953 /* FIXME: real TEST_Handling - we do not handle TEST yet. */
954
955 void TEST_Handling() {
956 }
957
958
959
960 /* FIXME: better XID_handling - but this will answer a XID command. */
961
962 bool XID_Handling (RLP_F96Frame *frame, RLP_F96Header *header) {
963   
964         u8 count;
965         u8 type;
966         u8 length;
967
968         if (CurrentFrameType == RLPFT_U_XID) {
969     
970                 count=0;
971     
972                 while (frame->Data[count] !=0) {
973
974                         type=frame->Data[count] >> 4;
975                         length=frame->Data[count] & 0x0f;
976                         count++;
977       
978                         switch (type) {
979
980                         case 0x01: /* RLP Version Number */
981                                 RLP_VersionNumber=frame->Data[count];
982                                 count+=length;
983                                 break;  
984                         case 0x02: /* Interworking Function (IWF) to Mobile Station (MS) window size */
985                                 if (frame->Data[count]>=1 && frame->Data[count]<RLP_M)
986                                         RLP_RCV_WS=frame->Data[count];
987                                 count+=length;
988                                 break;
989                         case 0x03: /* MS to IWF window size */
990                                 if (frame->Data[count]>=1 && frame->Data[count]<RLP_M)
991                                         RLP_SEND_WS=frame->Data[count];
992                                 count+=length;
993                                 break;
994                         case 0x04: /* Acknowledgement Timer (T1). */
995                                 RLP_Timeout1_Limit=frame->Data[count];
996                                 count+=length;
997                                 break;
998                         case 0x05: /* Retransmission attempts (N2). */
999                                 RLP_N2=frame->Data[count];
1000                                 count+=length;
1001                                 break;
1002                         case 0x06: /* Reply delay (T2). */
1003                                 RLP_T2=frame->Data[count];
1004                                 count+=length;
1005                                 break;
1006                         case 0x07: /* Compression - not yet! */
1007                                 break;
1008                         default:
1009                                 count+=length;
1010                                 break;
1011                         }
1012                 }
1013
1014                 /* Now reassemble a reply */
1015     
1016                 count=0;
1017                 memset(frame->Data,0x00,25);  /* Makes debugging easier */
1018     
1019                 /* Version Number - force to 0 for now */
1020                 RLP_VersionNumber=0;
1021                 frame->Data[count++]=0x11;
1022                 frame->Data[count++]=RLP_VersionNumber;
1023     
1024                 /* Window sizes */
1025                 frame->Data[count++]=0x21;
1026                 frame->Data[count++]=RLP_RCV_WS;
1027                 frame->Data[count++]=0x31;
1028                 frame->Data[count++]=RLP_SEND_WS;
1029     
1030                 /* Acknowledgement Timer (T1). */
1031                 frame->Data[count++]=0x41;
1032                 frame->Data[count++]=RLP_Timeout1_Limit;
1033
1034                 /* Retransmission attempts (N2). */
1035                 frame->Data[count++]=0x51;
1036                 frame->Data[count++]=RLP_N2;
1037
1038                 /* Reply delay (T2). */
1039                 frame->Data[count++]=0x61;
1040                 frame->Data[count++]=RLP_T2;
1041
1042                 XID_R_State = _send;
1043
1044                 return true;
1045         }
1046
1047         return false;
1048 }
1049
1050
1051 bool Send_TXU(RLP_F96Frame *frame, RLP_F96Header *header) {
1052
1053 #ifdef DEBUG
1054         //    fprintf(stdout, _("Send_TXU()\n"));
1055         //    fprintf(stdout, _("XID_R_State=%d\n"), XID_R_State);
1056 #endif
1057
1058         /*
1059
1060           if (RLP_UserEvent(TEST_R_State)) {
1061           RLP_SendF96Frame(RLPFT_U_TEST, false, TEST_R_FBit, 0, 0, TEST_R_Data, false);
1062           return true;
1063           }
1064           else
1065
1066         */
1067
1068         if (XID_R_State == _send && frame) {
1069                 RLP_SendF96Frame(RLPFT_U_XID, false, true, 0, 0, frame->Data, false);
1070                 XID_R_State = _idle;
1071                 return true;
1072         }
1073
1074         /*
1075
1076           else if ((XID_C_State == _send ) && (Poll_xchg == _idle)) {
1077           RLP_SendF96Frame(RLPFT_U_XID, true, true, 0, 0, XID_C_Data, false);
1078           XID_C_State = _wait;
1079           T_XID = 1;
1080           Poll_xchg = _wait;
1081           return true;
1082           } else if (RLP_UserEvent(UI_State)) {
1083           RLP_SendF96Frame(RLPFT_U_UI, true, false, 0, 0, NULL, false);
1084           return true;
1085           }
1086
1087         */
1088
1089         return false;
1090 }
1091
1092
1093 /* Deliver data */
1094
1095 void RLP_DeliverAllInSeqIF()
1096 {
1097         int i,j;
1098
1099         do {
1100
1101                 if ((R[VR].Data[0] & 0xE0)!=LastStatus) {
1102                         LastStatus=(R[VR].Data[0] & 0xE0);
1103                         RLP_Passup(StatusChange,&LastStatus,0);
1104                 }
1105     
1106                 j=0;
1107                 i=R[VR].Data[0] & 0x1f;
1108                 if (i==0x1e) j=24;
1109                 if (i<0x18) j=i;
1110
1111                 /* FIXME - should check for more data in the frame */
1112     
1113                 RLP_Passup(Data,R[VR].Data+1,j);
1114  
1115                 R[VR].State=_idle;
1116                 VR=Incr(VR);
1117
1118         } while (R[VR].State==_rcvd);
1119 }
1120
1121
1122 /* Mark any missing information frames between VR and Ns*/
1123 void RLP_MarkMissingIF(u8 Ns)
1124 {
1125         u8 i;
1126         for (i=VR; i!=Ns; i=Incr(i)) {
1127                 if (R[i].State==_idle) R[i].State=_srej;  /* bug in spec, fig A.23 */
1128         }
1129 }
1130
1131
1132 /* Information frame handler */
1133
1134 bool RLP_I_Handler(RLP_F96Frame *frame, RLP_F96Header *header)
1135 {
1136
1137         if ((header->CR) && (header->PF))
1138                 return true;
1139
1140         /* If the window size is 61, a received frame must have a sequence
1141            number between VR and VR+60 */
1142
1143         if (!InWindow(header->Ns,VR,VR+RLP_RCV_WS-1))
1144                 return true;
1145
1146         if (header->Ns==VR) {
1147                 /* This is not in the spec but I think it is necessary */
1148                 if (R[header->Ns].State==_wait) T_RCVS[header->Ns]=-1;
1149                 R[VR].State=_rcvd;
1150                 memcpy(R[VR].Data,frame->Data,25);
1151                 RLP_DeliverAllInSeqIF();
1152                 Ackn_State=_send;
1153         }
1154         else {  /* Out of sequence, cause a SREJ */
1155                 if (R[header->Ns].State==_wait) T_RCVS[header->Ns]=-1;
1156                 R[header->Ns].State=_rcvd;
1157                 memcpy(R[header->Ns].Data,frame->Data,25);
1158                 RLP_MarkMissingIF(header->Ns);
1159         }
1160     
1161         return false;
1162 }
1163
1164
1165 /* Mark acknowledged send frames */
1166
1167 void RLP_AdvanceVA(u8 Nr)
1168 {
1169         while (VA!=Nr) {
1170                 S[VA].State=_idle;
1171                 VA=Incr(VA);
1172         }
1173 }
1174
1175
1176 /* Decrease VS back down to Nr since these have not been acknowledged */
1177
1178 void RLP_DecreaseVS(u8 Nr)
1179 {
1180         while (VS!=Nr) {
1181                 VS=Decr(VS);
1182                 S[VS].State=_send;
1183         }
1184 }
1185
1186 /* Supervisory frame handling */
1187
1188 void RLP_S_Handler(RLP_F96Frame *frame, RLP_F96Header *header)
1189 {
1190         u8 i;
1191
1192         if ((header->CR) && (header->PF)) {
1193                 /* Special exchange (ie. error) - counter? */
1194 #ifdef RLP_DEBUG
1195                 fprintf(stdout, "Got Poll command\n");
1196 #endif
1197                 Ackn_State=_send;
1198                 Ackn_FBit=true;
1199                 for (i=0; i<RLP_M; i++) R[i].State=_idle;
1200                 ResetAllT_RCVS();
1201         }
1202         if (Poll_State!=_idle) {
1203                 if (header->PF==0) return;
1204                 if ((CurrentFrameType==RLPFT_S_SREJ) || (CurrentFrameType==RLPFT_S_REJ) ||
1205                     (CurrentFrameType==RLPFT_SI_SREJ) || (CurrentFrameType==RLPFT_SI_REJ)) return;
1206                 RLP_DecreaseVS(header->Nr);
1207                 Poll_State=_idle;
1208                 Poll_xchg=_idle;
1209         }
1210         switch (CurrentFrameType){
1211     
1212         case RLPFT_S_RR:
1213         case RLPFT_SI_RR:
1214                 RLP_AdvanceVA(header->Nr);
1215                 RRReady=true;
1216                 break;
1217         case RLPFT_S_RNR:
1218         case RLPFT_SI_RNR:
1219                 RLP_AdvanceVA(header->Nr);
1220                 RRReady=false;
1221                 break;
1222         case RLPFT_S_REJ:
1223         case RLPFT_SI_REJ:
1224                 RLP_AdvanceVA(header->Nr);
1225                 RRReady=true;
1226                 RLP_DecreaseVS(header->Nr);
1227                 break;
1228         case RLPFT_S_SREJ:
1229         case RLPFT_SI_SREJ:
1230                 S[header->Nr].State=_send;
1231                 T=-1;
1232                 return;
1233         default:
1234                 break;
1235         }
1236
1237         if (VA==VS) T=-1;
1238
1239 }
1240
1241
1242 /* Find the first SREJ frame */
1243
1244 bool RLP_SREJSlot(u8 *x)
1245 {
1246         u8 i;
1247
1248         for (i=Incr(VR); i!=VR; i=Incr(i)) if (R[i].State==_srej) {
1249                 *x=i;
1250                 return true;
1251         }
1252   
1253         return false;
1254 }
1255
1256
1257
1258 /* Check if any SREJ frames need sending, if not send the next in line */
1259
1260 bool RLP_PrepareDataToTransmit(u8 *p)
1261 {
1262         u8 i;
1263
1264         for (i=VA; i!=VS; i=Incr(i))
1265                 if (S[i].State==_send) {
1266                         *p=i;
1267                         S[i].State=_wait;
1268                         return true;
1269                 }
1270         if (S[VS].State!=_send) return false;
1271         if (!InWindow(VS,VA,VA+RLP_SEND_WS-1))
1272                 return false;
1273         *p=VS;
1274         S[VS].State=_wait;
1275         VS=Incr(VS);
1276         return true;
1277 }
1278
1279
1280
1281 /* Send a SREJ command */
1282
1283 void RLP_SendSREJ(u8 x)
1284 {
1285         u8 k;
1286   
1287         if ((Poll_xchg==_idle) && (Poll_State==_send)) {
1288
1289 #ifdef RLP_DEBUG
1290                 fprintf(stdout, "Sending SREJ with poll\n");
1291 #endif
1292
1293                 RLP_SendF96Frame(RLPFT_S_SREJ, true, true, x , 0 , NULL, false);    
1294                 R[x].State=_wait;
1295                 RLP_SetTimer(&T_RCVS[x]);
1296                 Poll_Count++;
1297                 Poll_State=_wait;
1298                 Poll_xchg=_wait;
1299                 RLP_SetTimer(&T);
1300         }
1301         else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1302 #ifdef RLP_DEBUG
1303                 fprintf(stdout, "Sending SREJ for %d along with frame %d\n",x,k);
1304 #endif
1305                 RLP_SendF96Frame(RLPFT_SI_SREJ, true, false, x , k , S[k].Data, false); 
1306                 R[x].State=_wait;
1307                 RLP_SetTimer(&T_RCVS[x]);
1308                 RLP_SetTimer(&T);
1309         }
1310         else {
1311 #ifdef RLP_DEBUG
1312                 fprintf(stdout, "Sending SREJ for %d\n",x);
1313 #endif
1314                 RLP_SendF96Frame(RLPFT_S_SREJ, true, false, x , 0 , NULL, false); 
1315                 R[x].State=_wait;
1316                 RLP_SetTimer(&T_RCVS[x]);
1317         }
1318 }
1319
1320
1321 /* Send a command */
1322
1323 void RLP_Send_XX_Cmd(RLP_FrameTypes type)
1324 {
1325         u8 k;
1326
1327         if ((Poll_xchg!=_wait) && (Poll_State==_send)) {
1328                 RLP_SendF96Frame(type, true, true, VR , 0 , NULL, false);    
1329 #ifdef RLP_DEBUG
1330                 fprintf(stdout, "Sending Comd %x with Poll\n",type);
1331 #endif
1332                 Ackn_State=_idle;
1333                 Poll_Count++;
1334                 Poll_State=_wait;
1335                 Poll_xchg=_wait;
1336                 RLP_SetTimer(&T);
1337         }
1338         else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1339 #ifdef RLP_DEBUG
1340                 fprintf(stdout, "Sending Comd %x with frame %d\n",type,k);
1341 #endif
1342                 RLP_SendF96Frame(type+4, true, false, VR , k , S[k].Data, false); 
1343                 Ackn_State=_idle;
1344                 RLP_SetTimer(&T);
1345         }
1346         else {
1347 #ifdef RLP_DEBUG
1348                 if (type!=9)
1349                         fprintf(stdout, "Sending Comd %x\n",type);
1350 #endif
1351                 RLP_SendF96Frame(type, true, false, VR , 0 , NULL, false); 
1352                 Ackn_State=_idle;
1353                 DTX_SF=type;
1354                 DTX_VR=VR;   /* As v7.1.0 spec */
1355         }
1356 }
1357
1358
1359 /* Send a Response */
1360
1361 void RLP_Send_XX_Resp(RLP_FrameTypes type)
1362 {
1363         u8 k;
1364   
1365         if (RRReady && RLP_PrepareDataToTransmit(&k)) {
1366 #ifdef RLP_DEBUG
1367                 fprintf(stdout, "Sending Resp %x with frame %d\n",type+4,k);
1368 #endif
1369                 RLP_SendF96Frame(type+4, false, true, VR , k , S[k].Data, false); 
1370                 Ackn_State=_idle;
1371                 Ackn_FBit=false;
1372                 RLP_SetTimer(&T);
1373         }
1374         else {
1375 #ifdef RLP_DEBUG
1376                 fprintf(stdout, "Sending Resp %x\n",type);
1377 #endif
1378                 RLP_SendF96Frame(type, false, true, VR , 0 , NULL, false); 
1379                 Ackn_State=_idle;
1380                 Ackn_FBit=false;
1381         }
1382 }
1383
1384
1385 /* Decide which frame to use and send it - currently only used in state 4 */
1386
1387 void RLP_SendData()
1388 {
1389         u8 x;
1390
1391         if (UA_State==_send) {
1392                 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0 , 0 , NULL, false);    
1393                 UA_State=_idle;
1394         }
1395         else if (Ackn_FBit==true) {
1396 #ifdef RLP_DEBUG
1397                 printf("About to send Poll resp\n");
1398 #endif
1399                 if (LRReady) RLP_Send_XX_Resp(RLPFT_S_RR);
1400                 else RLP_Send_XX_Resp(RLPFT_S_RNR);
1401         }
1402         else if (RLP_SREJSlot(&x)) RLP_SendSREJ(x); 
1403         else if (LRReady) RLP_Send_XX_Cmd(RLPFT_S_RR);
1404         else RLP_Send_XX_Cmd(RLPFT_S_RNR);
1405 }
1406
1407 void MAIN_STATE_MACHINE(RLP_F96Frame *frame, RLP_F96Header *header) {
1408         int i;
1409
1410         switch (CurrentState) {
1411
1412                 /***** RLP State 0. *****/
1413
1414                 /* ADM and Detached.
1415
1416                    This is the initial state after power on.
1417
1418                    As long as the RLP entity is "Detached", DISC(P) and/or SABM at the
1419                    lower interface is acted upon by sending DM(P) or DM(1). Any other
1420                    stimulus at the lower interface is ignored.
1421
1422                    This state can be exited only with Attach_Req. */
1423
1424         case RLP_S0:
1425
1426 #ifdef DEBUG
1427                 fprintf(stdout, _("RLP state 0.\n"));
1428 #endif
1429
1430                 switch (CurrentFrameType) {
1431
1432                 case RLPFT_U_DISC:
1433                         RLP_SendF96Frame(RLPFT_U_DM, false, header->PF, 0, 0, NULL, false);
1434                         break;
1435
1436                 case RLPFT_U_SABM:
1437                         RLP_SendF96Frame(RLPFT_U_DM, false, true, 0, 0, NULL, false);
1438                         break;
1439
1440                 default:
1441                         RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1442                         if (RLP_GetUserRequest(Attach_Req)) {
1443                                 NextState=RLP_S1;
1444                                 UA_State=_idle;
1445                         }
1446                         break;
1447                 }
1448
1449                 break;
1450   
1451                 /***** RLP State 1. *****/
1452
1453                 /* ADM and Attached.
1454
1455                    The RLP entity is ready to established a connection, either by
1456                    initiating the connection itself (Conn_Req) or by responding to an
1457                    incoming connection request (SABM).
1458
1459                    Upon receiving a DISC PDU, the handling of the UA response is
1460                    initiated. */
1461
1462         case RLP_S1:
1463
1464 #ifdef DEBUG
1465                 fprintf(stdout, _("RLP state 1.\n"));
1466 #endif
1467
1468                 if (!XID_Handling(frame, header)) {
1469
1470                         switch(CurrentFrameType) {
1471
1472                         case RLPFT_U_TEST:
1473                                 TEST_Handling();
1474                                 break;
1475
1476                         case RLPFT_U_SABM:
1477                                 RLP_Passup(Conn_Ind,NULL,0);
1478                                 NextState=RLP_S3;
1479                                 break;
1480
1481                         case RLPFT_U_DISC:
1482                                 UA_State=_send;
1483                                 UA_FBit=header->PF;
1484                                 break;
1485
1486                         case RLPFT_BAD:  /* If we get a bad frame we can still respond with SABM */
1487                         default:
1488                                 if (RLP_GetUserRequest(Conn_Req)) {
1489                                         SABM_State=_send;
1490                                         SABM_Count=0;
1491                                         NextState=RLP_S2;
1492                                 }
1493                                 break;
1494                         }
1495
1496                 }
1497                 if (!Send_TXU(frame, header)) {
1498       
1499                         if (UA_State == _send) {
1500                                 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1501                                 UA_State=_idle;
1502                         }
1503                         else
1504                                 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1505                 }
1506                 break;
1507   
1508                 /***** RLP State 2. *****/
1509
1510         case RLP_S2:
1511
1512 #ifdef DEBUG
1513                 fprintf(stdout, _("RLP state 2.\n"));
1514 #endif
1515
1516                 if (!XID_Handling(frame, header)) {
1517
1518                         switch(CurrentFrameType) {
1519
1520                         case RLPFT_U_TEST:
1521                                 TEST_Handling();
1522                                 break;
1523
1524                         case RLPFT_U_SABM:
1525                                 /*
1526                                   T=0;
1527                                   Conn_Conf=true;
1528                                   UA_State=_send;
1529                                   UA_FBit=true;
1530                                   Init_Link_Vars;
1531                                   NextState=4;
1532                                 */
1533                                 break;
1534
1535                         case RLPFT_U_DISC:
1536                                 /*
1537                                   T=0;
1538                                   DISC_Ind;
1539                                   UA_State=_send;
1540                                   UA_FBit=header->PF;
1541                                   NextState=RLP_S1;
1542                                 */
1543                                 break;
1544
1545                         case RLPFT_U_UA:
1546 #ifdef DEBUG
1547                                 fprintf(stdout, _("UA received in RLP state 2.\n"));
1548 #endif
1549
1550                                 if (SABM_State == _wait && header->PF) {
1551                                         T=-1;
1552                                         // Conn_Conf=true;
1553                                         // Init_Link_Vars;
1554                                         NextState=RLP_S4;
1555                                 }
1556                                 break;
1557
1558                         case RLPFT_U_DM:
1559                                 if (SABM_State == _wait && header->PF) {
1560                                         Poll_xchg=_idle;
1561                                         // Conn_Conf_Neg=true;
1562                                         NextState=RLP_S1;
1563                                 }
1564                                 break;
1565
1566                         default:
1567                                 if (T == RLP_Timeout1_Limit) {
1568                                         Poll_xchg=_idle;
1569                                         if (SABM_Count>RLP_N2)
1570                                                 NextState=RLP_S8;
1571                                         SABM_State=_send;
1572                                 }
1573                                 break;
1574                         }
1575                 }
1576
1577                 if (!Send_TXU(frame, header)) {
1578
1579                         if (SABM_State == _send && Poll_xchg == _idle) {
1580                                 RLP_SendF96Frame(RLPFT_U_SABM, true, true, 0, 0, NULL, false);
1581                                 SABM_State=_wait;
1582                                 SABM_Count++;
1583                                 Poll_xchg=_wait;
1584                                 T=1;
1585                         } else
1586                                 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1587                 }
1588
1589                 if (RLP_GetUserRequest(Disc_Req)) {
1590                         T=-1;
1591                         DISC_State=_send;
1592                         DISC_Count=0;
1593                         DISC_PBit=(Poll_xchg==_idle);
1594                         NextState=5;
1595                 }
1596   
1597                 break;
1598
1599                 /***** RLP State 3. *****/
1600
1601         case RLP_S3:
1602
1603 #ifdef DEBUG
1604                 fprintf(stdout, _("RLP state 3.\n"));
1605 #endif
1606
1607                 if (!XID_Handling(frame, header)) {
1608     
1609                         switch(CurrentFrameType) {
1610
1611                         case RLPFT_U_TEST:
1612                                 TEST_Handling();
1613                                 break;
1614         
1615                         case RLPFT_U_DISC:
1616                                 RLP_Passup(Disc_Ind,NULL,0);
1617                                 UA_State=_send;
1618                                 UA_FBit=header->PF;
1619                                 NextState=RLP_S1;
1620                                 break;
1621
1622                         default:
1623                                 if (RLP_GetUserRequest(Conn_Req)) {
1624                                         UA_State=_send;
1625                                         UA_FBit=true;
1626                                         NextState=RLP_S4;
1627                                         RLP_Init_link_vars();
1628                                 } else if (RLP_GetUserRequest(Conn_Req_Neg)) {
1629                                         DM_State=_send;  /* FIXME - code to handle DM_State - missing from spec? */
1630                                         DM_FBit=true;
1631                                         NextState=RLP_S1;
1632                                 }
1633                                 break;
1634                         }
1635                 }
1636     
1637                 if (!Send_TXU(frame, header)) {
1638       
1639                         if (UA_State == _send) {
1640                                 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1641                                 UA_State=_idle;
1642                         }
1643                         else
1644                                 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1645                 }
1646     
1647
1648                 if (RLP_GetUserRequest(Disc_Req)) {
1649                         T=-1;
1650                         DISC_State=_send;
1651                         DISC_Count=0;
1652                         DISC_PBit=(Poll_xchg==_idle);
1653                         NextState=5;
1654                 }
1655     
1656                 break;
1657     
1658                 /***** RLP State 4. *****/
1659   
1660         case RLP_S4:
1661
1662 #ifdef DEBUG
1663                 fprintf(stdout, _("RLP state 4.\n"));
1664 #endif
1665     
1666                 if (!XID_Handling(frame, header)) {
1667
1668                         switch (CurrentFrameType) {
1669         
1670                         case RLPFT_U_TEST:
1671                                 TEST_Handling();
1672                                 break;
1673                         case RLPFT_U_DISC:
1674                                 T=-1;
1675                                 ResetAllT_RCVS();
1676                                 RLP_Passup(Disc_Ind,NULL,0);
1677                                 UA_State=_send;
1678                                 UA_FBit=header->PF;
1679                                 NextState=RLP_S1;
1680                                 break;
1681                         case RLPFT_U_SABM:
1682                                 T=-1;
1683                                 ResetAllT_RCVS();
1684                                 RLP_Passup(Reset_Ind,NULL,0);
1685                                 NextState=RLP_S7;
1686                                 break;
1687                         case RLPFT_S_RR:
1688                         case RLPFT_S_RNR:
1689                         case RLPFT_S_REJ:
1690                         case RLPFT_S_SREJ:
1691                                 /* Should check here for unsolicited Fbit */
1692                                 /* Spec says: "Nr must be within the set of not yet
1693                                    acknowledged I-frames or it must be the next possible
1694                                    frame number." That's VA..VS-1 or VS, i.e. VA..VS */
1695                                 if (!InWindow(header->Nr,VA,VS))
1696                                         break;
1697                                 RLP_S_Handler(frame,header);
1698                                 break;
1699                         case RLPFT_SI_RR:
1700                         case RLPFT_SI_RNR:
1701                         case RLPFT_SI_REJ:
1702                         case RLPFT_SI_SREJ:
1703                                 /* Should check here for unsolicited Fbit */
1704                                 if (!InWindow(header->Nr,VA,VS))
1705                                         break;
1706                                 if (!RLP_I_Handler(frame,header)) RLP_S_Handler(frame,header);
1707                                 break;
1708                         default:
1709                                 break;
1710                         }
1711                 }    
1712     
1713                 for (i=0;i<RLP_M;i++) if (T_RCVS[i]==0) {
1714 #ifdef RLP_DEBUG
1715                         fprintf(stdout, "T_RCVS[%d] Timeout in State 4\n",i);
1716 #endif
1717                         R[i].State=_srej;
1718                 }
1719                 if (T==0) {
1720                         T=-1;
1721 #ifdef RLP_DEBUG
1722                         fprintf(stdout, "T Timeout in State 4\n");
1723 #endif      
1724
1725                         Poll_xchg=_idle;
1726                         if (Poll_State==_idle) {
1727                                 Poll_State=_send;
1728                                 Poll_Count=0;
1729                         }
1730                         else {
1731                                 if (Poll_Count>RLP_N2) {
1732 #ifdef RLP_DEBUG
1733                                         fprintf(stdout, "N2 Errors in State 4\n");
1734 #endif
1735                                 }
1736                                 Poll_State=_send;
1737                                 Poll_Count++;
1738                         }
1739                 }
1740
1741                 if (!Send_TXU(frame,header)) {
1742                         if (UA_State == _send) {
1743                                 RLP_SendF96Frame(RLPFT_U_UA, false, UA_FBit, 0, 0, NULL, false);
1744                                 UA_State=_idle;
1745                         }
1746                         else  RLP_SendData();
1747                 }      
1748
1749
1750                 /* Load any data from the Send ringbuffer into the send slots */
1751                 RLP_AddRingBufferDataToSlots();
1752
1753 #ifdef RLP_DEBUG
1754                 //    if (CurrentFrameType!=RLPFT_BAD) 
1755                 fprintf(stdout, "VD=%d, VA=%d, VS=%d, VR=%d\n",VD,VA,VS,VR);
1756 #ifdef RLP_DEBUG_STATE
1757                 {
1758                         int zzz;
1759       
1760                         if(UA_State!=_idle) printf("[UA_State %d]",UA_State);
1761                         if(UI_State!=_idle) printf("[UI_State %d]",UI_State);
1762                         if(Ackn_State!=_idle) printf("[Ackn_State %d]",Ackn_State);
1763                         if(Poll_State!=_idle) printf("[Poll_State %d]",Poll_State);
1764                         if(Poll_xchg!=_idle) printf("[Poll_xchg %d]",Poll_xchg);
1765                         if(SABM_State!=_idle) printf("[SABM_State %d]",SABM_State);
1766                         if(DISC_State!=_idle) printf("[DISC_State %d]",DISC_State);
1767                         if(DM_State!=_idle) printf("[DM_State %d]",DM_State);
1768                         if(XI_R_State!=_idle) printf("[XI_R_State %d]",XI_R_State);
1769                         if(XID_C_State!=_idle) printf("[XID_C_State %d]",XID_C_State);
1770                         if(XID_R_State!=_idle) printf("[XID_R_State %d]",XID_R_State);
1771                         if(TEST_R_State!=_idle) printf("[TEST_R_State %d]",TEST_R_State);
1772
1773                         printf("S: ");
1774                         for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",S[zzz].State);
1775                         printf("\nR: ");
1776                         for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",R[zzz].State);
1777                         printf("\nT: %d, T_RCVS: ",T);
1778                         for (zzz=0; zzz<RLP_M; zzz++) printf("%d ",T_RCVS[zzz]);
1779                         printf("\n");
1780                 }
1781 #endif
1782 #endif    
1783
1784
1785                 if (RLP_GetUserRequest(Disc_Req)) {
1786                         T=-1;
1787                         ResetAllT_RCVS();
1788                         DISC_State=_send;
1789                         DISC_Count=0;
1790                         DISC_PBit=(Poll_xchg==_idle);
1791                         NextState=5;
1792                 }
1793
1794                 break;
1795     
1796
1797                 /***** RLP State 5. *****/
1798   
1799         case RLP_S5:
1800
1801 #ifdef DEBUG
1802                 fprintf(stdout, _("RLP state 5.\n"));
1803 #endif
1804     
1805                 if (!XID_Handling(frame, header)) {
1806     
1807                         switch (CurrentFrameType) {
1808     
1809                         case RLPFT_U_UA:
1810                         case RLPFT_U_DM:
1811                                 if ((DISC_State==_wait) && (DISC_PBit==header->PF)) {
1812                                         if (DISC_PBit==true) Poll_xchg=_idle;
1813                                         T=-1;
1814                                         NextState=1;
1815                                 }
1816                                 break;
1817                         case RLPFT_U_DISC:
1818                                 T=-1;
1819                                 UA_State=_send;
1820                                 UA_FBit=header->PF;
1821                                 NextState=1;
1822                                 break;
1823                         default:
1824                                 break;
1825                         }
1826                 }
1827     
1828                 if (!Send_TXU(frame,header)) {
1829                         if ((DISC_State!=_wait) && !((DISC_PBit==true) && (Poll_xchg==_wait))) {
1830                                 RLP_SendF96Frame(RLPFT_U_DISC, true, DISC_PBit, 0, 0, NULL, false);
1831                                 if (DISC_PBit==true) Poll_xchg=_wait;
1832                                 DISC_State=_wait;
1833                                 DISC_Count++;
1834                                 RLP_SetTimer(&T);
1835                         }
1836                         else
1837                                 RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1838                 }
1839  
1840                 if (T==0) {
1841                         if (DISC_PBit==1) Poll_xchg=_idle;
1842                         DISC_Count++;
1843                         if (DISC_Count>RLP_N2) {
1844
1845 #ifdef RLP_DEBUG
1846                                 fprintf(stdout, "N2 error in State 5!\n");
1847 #endif
1848       
1849                         }
1850                         DISC_State=_send;
1851                 }
1852
1853                 break;
1854
1855                 /***** RLP State 6. *****/
1856                 /* We should only get here after a Reset_Req which is not yet supported */
1857
1858         case RLP_S6:
1859
1860 #ifdef DEBUG
1861                 fprintf(stdout, _("RLP state 6 - not yet implemented!\n"));
1862 #endif
1863     
1864                 if (!XID_Handling(frame, header)) {
1865
1866                         switch (CurrentFrameType) {
1867                         default:
1868                                 break;
1869                         }
1870
1871                 }
1872
1873                 if (!Send_TXU(frame,header)) {
1874                 }
1875
1876                 if (RLP_GetUserRequest(Disc_Req)) {
1877                         T=-1;
1878                         DISC_State=_send;
1879                         DISC_Count=0;
1880                         DISC_PBit=(Poll_xchg==_idle);
1881                         NextState=5;
1882                 }
1883
1884                 break;
1885
1886
1887                 /***** RLP State 7. *****/
1888   
1889         case RLP_S7:
1890
1891 #ifdef DEBUG
1892                 fprintf(stdout, _("RLP state 7.\n"));
1893 #endif
1894     
1895                 if (!XID_Handling(frame, header)) {
1896
1897                         switch (CurrentFrameType) {
1898                         case RLPFT_U_DISC:
1899                                 RLP_Passup(Disc_Ind,NULL,0);
1900                                 UA_State=_send;
1901                                 UA_FBit=header->PF;
1902                                 NextState=RLP_S1;
1903                                 break;
1904                         default:
1905                                 break;
1906                         }
1907                 }
1908
1909                 if (RLP_GetUserRequest(Reset_Resp)){
1910                         UA_State=_send;
1911                         UA_FBit=1;
1912                         RLP_Init_link_vars();
1913                         NextState=RLP_S4;
1914                 }
1915
1916                 if (!Send_TXU(frame,header)) {
1917                         RLP_SendF96Frame(RLPFT_U_NULL, false, false, 0, 0, NULL, false);
1918                 }
1919
1920                 if (RLP_GetUserRequest(Disc_Req)) {
1921                         T=-1;
1922                         DISC_State=_send;
1923                         DISC_Count=0;
1924                         DISC_PBit=(Poll_xchg==_idle);
1925                         NextState=5;
1926                 }
1927     
1928                 break;
1929
1930
1931         default:
1932     
1933 #ifdef DEBUG
1934                 fprintf(stdout, _("DEBUG: Unknown RLP state!\n"));
1935 #endif
1936
1937                 break;
1938         }
1939
1940         CurrentState=NextState;
1941
1942 }
1943
1944 /* Given a pointer to an RLP XID frame, display contents in human readable
1945    form.  Note for now only Version 0 and 1 are supported.  Fields can appear
1946    in any order and are delimited by a zero type field. This function is the
1947    exact implementation of section 5.2.2.6, Exchange Identification, XID of
1948    the GSM specification 04.22. */
1949
1950 void RLP_DisplayXID(u8 *frame) 
1951 {
1952
1953         int count = 25;  /* Sanity check */
1954         u8  type, length;
1955     
1956         fprintf(stdout, "XID: ");
1957
1958         while ((*frame !=0) && (count >= 0)) {
1959
1960                 type = *frame >> 4;
1961                 length = *frame & 0x0f;
1962
1963                 switch (type) {
1964
1965                 case 0x01: /* RLP Version Number, probably 1 for Nokia. */
1966
1967                         frame += length;
1968                         fprintf(stdout, "Ver %d ", *frame);
1969                         break;
1970                 
1971                 case 0x02: /* IWF to MS window size */
1972
1973                         frame += length;
1974                         fprintf(stdout, "IWF-MS %d ", *frame);
1975                         break;
1976                 
1977                 case 0x03: /* MS to IWF window size. */
1978
1979                         frame += length;
1980                         fprintf(stdout, "MS-IWF %d ", *frame);
1981                         break;
1982
1983                 case 0x04: /* Acknowledgement Timer (T1). */
1984
1985                         frame += length;
1986                         fprintf(stdout, "T1 %dms ", *frame * 10);
1987                         break;
1988
1989                 case 0x05: /* Retransmission attempts (N2). */
1990
1991                         frame += length;
1992                         fprintf(stdout, "N2 %d ", *frame);
1993                         break;
1994
1995                 case 0x06: /* Reply delay (T2). */
1996
1997                         frame += length;
1998                         fprintf(stdout, "T2 %dms ", *frame * 10);
1999                         break;
2000
2001                 case 0x07: /* Compression. */
2002
2003                         frame ++;
2004                         fprintf(stdout, "Comp [Pt=%d ", (*frame >> 4) );
2005                         fprintf(stdout, "P0=%d ", (*frame & 0x03) );
2006
2007                         frame ++;
2008                         fprintf(stdout, "P1l=%d ", *frame);
2009                         frame ++;
2010                         fprintf(stdout, "P1h=%d ", *frame);
2011
2012                         frame ++;
2013                         fprintf(stdout, "P2=%d] ", *frame);
2014                         break;
2015             
2016                 default:
2017
2018                         frame += length;
2019                         fprintf(stdout, "Unknown! type=%02x, length=%02x", type, length);
2020                         break;
2021
2022                 }
2023                 count --;
2024                 frame ++;
2025         } 
2026
2027         return;
2028 }
2029
2030 /* Given a pointer to an F9.6 Frame, split data out into component parts of
2031    header and determine frame type. */
2032
2033 void RLP_DecodeF96Header(RLP_F96Frame *frame, RLP_F96Header *header)
2034 {
2035
2036         /* Poll/Final bit. */
2037
2038         if ((frame->Header[1] & 0x02))
2039                 header->PF = true;
2040         else
2041                 header->PF = false;
2042     
2043         /* Command/Response bit. */
2044
2045         if ((frame->Header[0] & 0x01))
2046                 header->CR = true;
2047         else
2048                 header->CR = false;
2049
2050         /* Send Sequence Number. */
2051
2052         header->Ns = frame->Header[0] >> 3;
2053
2054         if ((frame->Header[1] & 0x01))
2055                 header->Ns |= 0x20; /* Most significant bit. */
2056
2057         /* Determine frame type. See the section 5.2.1 in the GSM 04.22
2058            specification. */
2059
2060         switch (header->Ns) {
2061
2062         case 0x3f: /* Frames of type U, unnumbered frames. */
2063
2064                 /* U frames have M1, ..., M5 stored in the place of N(R). */
2065
2066                 header->Type = RLPFT_U;
2067                 header->M = (frame->Header[1] >> 2) & 0x1f;
2068                 return; /* For U frames, we do not need N(R) and bits S1 and S2. */
2069                     
2070         case 0x3e: /* Frames of type S, supervisory frames. */
2071
2072                 header->Type = RLPFT_S;
2073                 break;
2074                     
2075         default: /* Frames of type I+S, numbered information transfer ans
2076                     supervisory frames combined. */
2077
2078                 header->Type = RLPFT_IS;
2079                 break;
2080         }
2081
2082         /* Receive Sequence Number N(R). */
2083         header->Nr = frame->Header[1] >> 2;
2084
2085         /* Status bits (S1 and S2). */
2086         header->S = (frame->Header[0] >> 1) & 0x03;
2087
2088         return;
2089 }
2090
2091