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