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