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