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