1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2000-2005  CSR Ltd.
6 *
7 *
8 *  Permission is hereby granted, free of charge, to any person obtaining
9 *  a copy of this software and associated documentation files (the
10 *  "Software"), to deal in the Software without restriction, including
11 *  without limitation the rights to use, copy, modify, merge, publish,
12 *  distribute, sublicense, and/or sell copies of the Software, and to
13 *  permit persons to whom the Software is furnished to do so, subject to
14 *  the following conditions:
15 *
16 *  The above copyright notice and this permission notice shall be included
17 *  in all copies or substantial portions of the Software.
18 *
19 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 *  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 *  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 *  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33/*****************************************************************************/
34/*****************************************************************************/
35/*****************************************************************************/
36/**                                                                         **/
37/** ubcsp,c                                                                 **/
38/**                                                                         **/
39/** MicroBCSP - a very low cost implementation of the BCSP protocol         **/
40/**                                                                         **/
41/*****************************************************************************/
42
43#include "ubcsp.h"
44
45#if SHOW_PACKET_ERRORS || SHOW_LE_STATES
46#include <stdio.h>
47#include <windows.h>
48#endif
49
50static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc);
51static uint16 ubcsp_crc_reverse (uint16);
52
53/*****************************************************************************/
54/**                                                                         **/
55/** Constant Data - ROM                                                     **/
56/**                                                                         **/
57/*****************************************************************************/
58
59/* This is the storage for the link establishment messages */
60
61static const uint8 ubcsp_le_buffer[4][4] =
62	{
63		{ 0xDA, 0xDC, 0xED, 0xED },
64		{ 0xAC, 0xAF, 0xEF, 0xEE },
65		{ 0xAD, 0xEF, 0xAC, 0xED },
66		{ 0xDE, 0xAD, 0xD0, 0xD0 },
67	};
68
69/* These are the link establishment headers */
70/* The two version are for the CRC and non-CRC varients */
71
72#if UBCSP_CRC
73static const uint8 ubcsp_send_le_header[4] =
74	{
75		0x40, 0x41, 0x00, 0x7E
76	};
77#else
78static const uint8 ubcsp_send_le_header[4] =
79	{
80		0x00, 0x41, 0x00, 0xBE
81	};
82#endif
83
84/*****************************************************************************/
85/**                                                                         **/
86/** Static Data - RAM                                                       **/
87/**                                                                         **/
88/*****************************************************************************/
89
90/* This is the storage for all state data for ubcsp */
91
92static struct ubcsp_configuration ubcsp_config;
93
94/* This is the ACK packet header - this will be overwritten when
95   we create an ack packet */
96
97static uint8 ubcsp_send_ack_header[4] =
98	{
99		0x00, 0x00, 0x00, 0x00
100	};
101
102/* This is the deslip lookup table */
103
104static const uint8 ubcsp_deslip[2] =
105	{
106		SLIP_FRAME, SLIP_ESCAPE,
107	};
108
109/* This is a state machine table for link establishment */
110
111static uint8 next_le_packet[16] =
112	{
113		ubcsp_le_sync,			// uninit
114		ubcsp_le_conf,			// init
115		ubcsp_le_none,			// active
116		ubcsp_le_none,
117		ubcsp_le_sync_resp,		// sync_resp
118		ubcsp_le_sync_resp,
119		ubcsp_le_none,
120		ubcsp_le_none,
121		ubcsp_le_none,			// conf_resp
122		ubcsp_le_conf_resp,
123		ubcsp_le_conf_resp,
124		ubcsp_le_none,
125	};
126
127/* This is the storage required for building send and crc data */
128
129static uint8 ubcsp_send_header[4];
130static uint8 ubcsp_send_crc[2];
131
132/* This is where the receive header is stored before the payload arrives */
133
134static uint8 ubcsp_receive_header[4];
135
136/*****************************************************************************/
137/**                                                                         **/
138/** Code - ROM or RAM                                                       **/
139/**                                                                         **/
140/*****************************************************************************/
141
142/*****************************************************************************/
143/**                                                                         **/
144/** ubcsp_initialize                                                        **/
145/**                                                                         **/
146/** This initializes the state of the ubcsp engine to a known values        **/
147/**                                                                         **/
148/*****************************************************************************/
149
150void ubcsp_initialize (void)
151{
152	ubcsp_config.ack_number = 0;
153	ubcsp_config.sequence_number = 0;
154	ubcsp_config.send_ptr = 0;
155	ubcsp_config.send_size = 0;
156	ubcsp_config.receive_index = -4;
157
158	ubcsp_config.delay = 0;
159
160#if SHOW_LE_STATES
161	printf ("Hello Link Uninitialized\n");
162#endif
163
164	ubcsp_config.link_establishment_state = ubcsp_le_uninitialized;
165	ubcsp_config.link_establishment_packet = ubcsp_le_sync;
166}
167
168/*****************************************************************************/
169/**                                                                         **/
170/** ubcsp_send_packet                                                       **/
171/**                                                                         **/
172/** This sends a packet structure for sending to the ubcsp engine           **/
173/** This can only be called when the activity indication from ubcsp_poll    **/
174/** indicates that a packet can be sent with UBCSP_PACKET_SENT              **/
175/**                                                                         **/
176/*****************************************************************************/
177
178void ubcsp_send_packet (struct ubcsp_packet *send_packet)
179{
180	/* Initialize the send data to the packet we want to send */
181
182	ubcsp_config.send_packet = send_packet;
183
184	/* we cannot send the packet at the moment
185	   when we can at the moment, just set things to 0 */
186
187	ubcsp_config.send_size = 0;
188	ubcsp_config.send_ptr = 0;
189}
190
191/*****************************************************************************/
192/**                                                                         **/
193/** ubcsp_receive_packet                                                    **/
194/**                                                                         **/
195/** This sends a packet structure for receiving to the ubcsp engine         **/
196/** This can only be called when the activity indication from ubcsp_poll    **/
197/** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED          **/
198/**                                                                         **/
199/*****************************************************************************/
200
201void ubcsp_receive_packet (struct ubcsp_packet *receive_packet)
202{
203	/* Initialize the receive data to the packet we want to receive */
204
205	ubcsp_config.receive_packet = receive_packet;
206
207	/* setup to receive the header first */
208
209	ubcsp_config.receive_index = -4;
210}
211
212/*****************************************************************************/
213/**                                                                         **/
214/** ubcsp_calc_crc                                                          **/
215/**                                                                         **/
216/** Takes the next 8 bit value ch, and updates the crc with this value      **/
217/**                                                                         **/
218/*****************************************************************************/
219
220
221#ifdef UBCSP_CRC
222
223static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc)
224{
225	/* Calculate the CRC using the above 16 entry lookup table */
226
227	static const uint16 crc_table[] =
228		{
229			0x0000, 0x1081, 0x2102, 0x3183,
230			0x4204, 0x5285, 0x6306, 0x7387,
231			0x8408, 0x9489, 0xa50a, 0xb58b,
232			0xc60c, 0xd68d, 0xe70e, 0xf78f
233		};
234
235	/* Do this four bits at a time - more code, less space */
236
237    crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f];
238    crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f];
239
240	return crc;
241}
242
243/*****************************************************************************/
244/**                                                                         **/
245/** ubcsp_crc_reverse                                                       **/
246/**                                                                         **/
247/** Reserves the bits in crc and returns the new value                      **/
248/**                                                                         **/
249/*****************************************************************************/
250
251static uint16 ubcsp_crc_reverse (uint16 crc)
252{
253	int32
254		b,
255		rev;
256
257	/* Reserse the bits to compute the actual CRC value */
258
259	for (b = 0, rev=0; b < 16; b++)
260	{
261		rev = rev << 1;
262		rev |= (crc & 1);
263		crc = crc >> 1;
264	}
265
266	return rev;
267}
268
269#endif
270
271/*****************************************************************************/
272/**                                                                         **/
273/** ubcsp_put_slip_uart                                                     **/
274/**                                                                         **/
275/** Outputs a single octet to the uart                                      **/
276/** If the octet needs to be escaped, then output the escape value          **/
277/** and then store the second octet to be output later                      **/
278/**                                                                         **/
279/*****************************************************************************/
280
281static void ubcsp_put_slip_uart (uint8 ch)
282{
283	/* output a single UART octet */
284
285	/* If it needs to be escaped, then output the escape octet
286	   and set the send_slip_escape so that the next time we
287	   output the second octet for the escape correctly.
288	   This is done right at the top of ubcsp_poll */
289
290	if (ch == SLIP_FRAME)
291	{
292		put_uart (SLIP_ESCAPE);
293		ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME;
294	}
295	else if (ch == SLIP_ESCAPE)
296	{
297		put_uart (SLIP_ESCAPE);
298		ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE;
299	}
300	else
301	{
302		/* Not escaped, so just output octet */
303
304		put_uart (ch);
305	}
306}
307
308/*****************************************************************************/
309/**                                                                         **/
310/** ubcsp_which_le_payload                                                  **/
311/**                                                                         **/
312/** Check the payload of this packet, and determine which of the four       **/
313/** link establishment packets this was.                                    **/
314/** Can return 5 if it is not a valid link establishment packet             **/
315/**                                                                         **/
316/*****************************************************************************/
317
318static uint32 ubcsp_which_le_payload (const uint8 *payload)
319{
320	static int32
321		octet,
322		loop;
323
324	/* Search through the various link establishment payloads to find
325	   which one we have received */
326
327	for (loop = 0; loop < 4; loop ++)
328	{
329		for (octet = 0; octet < 4; octet ++)
330		{
331			if (payload[octet] != ubcsp_le_buffer[loop][octet])
332			{
333				/* Bad match, just to loop again */
334				goto bad_match_loop;
335			}
336		}
337
338		/* All the octets matched, return the value */
339
340		return loop;
341
342		/* Jumps out of octet loop if we got a bad match */
343bad_match_loop:
344		{}
345	}
346
347	/* Non of the link establishment payloads matched - return invalid value */
348
349	return 5;
350}
351
352/*****************************************************************************/
353/**                                                                         **/
354/** ubcsp_recevied_packet                                                   **/
355/**                                                                         **/
356/** This function is called when we have a SLIP END octet and a full        **/
357/** packet header and possibly data in the receive packet                   **/
358/**                                                                         **/
359/*****************************************************************************/
360
361static uint8 ubcsp_recevied_packet (void)
362{
363	static uint8
364		receive_crc,
365		receive_seq,
366		receive_ack,
367		activity;
368
369#if UBCSP_CRC
370	static int32
371		loop;
372
373	static uint16
374		crc;
375#endif
376
377	static uint16
378		length;
379
380	/* Keep track of what activity this received packet will cause */
381
382	activity = 0;
383
384	/*** Do all error checks that we can ***/
385
386	/* First check the header checksum */
387
388	if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff)
389	{
390		/* Header Checksum Error */
391
392#if SHOW_PACKET_ERRORS
393		printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n",
394			ubcsp_receive_header[0],
395			ubcsp_receive_header[1],
396			ubcsp_receive_header[2],
397			ubcsp_receive_header[3]);
398#endif
399
400		/* If we have a header checksum error, send an ack in return
401		   this gets a packet to be resent as quickly as possible */
402
403		ubcsp_config.send_ack = 1;
404
405		return activity;
406	}
407
408	/* Decode the received packets header */
409
410	ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7;
411
412	receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6;
413	receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3;
414	receive_seq = (ubcsp_receive_header[0] & 0x07);
415
416	ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f);
417
418	length =
419		((ubcsp_receive_header[1] & 0xf0) >> 4) |
420		(ubcsp_receive_header[2] << 4);
421
422#if SHOW_PACKET_ERRORS
423	if (ubcsp_config.receive_packet->reliable)
424	{
425		printf (" : %10d         Recv SEQ: %d ACK %d\n",
426			GetTickCount () % 100000,
427			receive_seq,
428			receive_ack);
429	}
430	else if (ubcsp_config.receive_packet->channel != 1)
431	{
432		printf (" : %10d          Recv        ACK %d\n",
433			GetTickCount () % 100000,
434			receive_ack);
435	}
436#endif
437
438	/* Check for length errors */
439
440#if UBCSP_CRC
441	if (receive_crc)
442	{
443		/* If this packet had a CRC, then the length of the payload
444		   should be 2 less than the received size of the payload */
445
446		if (length + 2 != ubcsp_config.receive_index)
447		{
448			/* Slip Length Error */
449
450#if SHOW_PACKET_ERRORS
451			printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2);
452#endif
453
454			/* If we have a payload length error, send an ack in return
455			   this gets a packet to be resent as quickly as possible */
456
457			ubcsp_config.send_ack = 1;
458			return activity;
459		}
460
461		/* We have a CRC at the end of this packet */
462
463		ubcsp_config.receive_index -= 2;
464
465		/* Calculate the packet CRC */
466
467		crc = 0xffff;
468
469		/* CRC the packet header */
470
471		for (loop = 0; loop < 4; loop ++)
472		{
473			crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc);
474		}
475
476		/* CRC the packet payload - without the CRC bytes */
477
478		for (loop = 0; loop < ubcsp_config.receive_index; loop ++)
479		{
480			crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc);
481		}
482
483		/* Reverse the CRC */
484
485		crc = ubcsp_crc_reverse (crc);
486
487		/* Check the CRC is correct */
488
489		if
490		(
491			(((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) ||
492			((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1])
493		)
494		{
495#if SHOW_PACKET_ERRORS
496			printf ("\n######################## CRC Error\n");
497#endif
498
499			/* If we have a packet crc error, send an ack in return
500			   this gets a packet to be resent as quickly as possible */
501
502			ubcsp_config.send_ack = 1;
503			return activity;
504		}
505	}
506	else
507	{
508#endif
509		/* No CRC present, so just check the length of payload with that received */
510
511		if (length != ubcsp_config.receive_index)
512		{
513			/* Slip Length Error */
514
515#if SHOW_PACKET_ERRORS
516			printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index);
517#endif
518
519			/* If we have a payload length error, send an ack in return
520			   this gets a packet to be resent as quickly as possible */
521
522			ubcsp_config.send_ack = 1;
523			return activity;
524		}
525#if UBCSP_CRC
526	}
527#endif
528
529	/*** We have a fully formed packet having passed all data integrity checks ***/
530
531	/* Check if we have an ACK for the last packet we sent */
532
533	if (receive_ack != ubcsp_config.sequence_number)
534	{
535		/* Since we only have a window size of 1, if the ACK is not equal to SEQ
536		   then the packet was sent */
537
538		if
539		(
540			(ubcsp_config.send_packet) &&
541			(ubcsp_config.send_packet->reliable)
542		)
543		{
544			/* We had sent a reliable packet, so clear this packet
545			   Then increament the sequence number for the next packet */
546
547			ubcsp_config.send_packet = 0;
548			ubcsp_config.sequence_number ++;
549			ubcsp_config.delay = 0;
550
551			/* Notify the caller that we have SENT a packet */
552
553			activity |= UBCSP_PACKET_SENT;
554		}
555	}
556
557	/*** Now we can concentrate of the packet we have received ***/
558
559	/* Check for Link Establishment packets */
560
561	if (ubcsp_config.receive_packet->channel == 1)
562	{
563		/* Link Establishment */
564
565		ubcsp_config.delay = 0;
566
567		/* Find which link establishment packet this payload means
568		   This could return 5, meaning none */
569
570		switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload))
571		{
572			case 0:
573			{
574				/* SYNC Recv'd */
575
576#if SHOW_LE_STATES
577				printf ("Recv SYNC\n");
578#endif
579
580				/* If we receive a SYNC, then we respond to it with a SYNC RESP
581				   but only if we are not active.
582				   If we are active, then we have a PEER RESET */
583
584				if (ubcsp_config.link_establishment_state < ubcsp_le_active)
585				{
586					ubcsp_config.link_establishment_resp = 1;
587				}
588				else
589				{
590					/* Peer reset !!!! */
591
592#if SHOW_LE_STATES
593					printf ("\n\n\n\n\nPEER RESET\n\n");
594#endif
595
596					/* Reinitialize the link */
597
598					ubcsp_initialize ();
599
600					/* Tell the host what has happened */
601
602					return UBCSP_PEER_RESET;
603				}
604				break;
605			}
606
607			case 1:
608			{
609				/* SYNC RESP Recv'd */
610
611#if SHOW_LE_STATES
612				printf ("Recv SYNC RESP\n");
613#endif
614
615				/* If we receive a SYNC RESP, push us into the initialized state */
616
617				if (ubcsp_config.link_establishment_state < ubcsp_le_initialized)
618				{
619#if SHOW_LE_STATES
620					printf ("Link Initialized\n");
621#endif
622					ubcsp_config.link_establishment_state = ubcsp_le_initialized;
623				}
624
625				break;
626			}
627
628			case 2:
629			{
630				/* CONF Recv'd */
631
632#if SHOW_LE_STATES
633				printf ("Recv CONF\n");
634#endif
635
636				/* If we receive a CONF, and we are initialized or active
637				   then respond with a CONF RESP */
638
639				if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized)
640				{
641					ubcsp_config.link_establishment_resp = 2;
642				}
643
644				break;
645			}
646
647			case 3:
648			{
649				/* CONF RESP Recv'd */
650
651#if SHOW_LE_STATES
652				printf ("Recv CONF RESP\n");
653#endif
654
655				/* If we received a CONF RESP, then push us into the active state */
656
657				if (ubcsp_config.link_establishment_state < ubcsp_le_active)
658				{
659#if SHOW_LE_STATES
660					printf ("Link Active\n");
661#endif
662
663					ubcsp_config.link_establishment_state = ubcsp_le_active;
664					ubcsp_config.send_size = 0;
665
666					return activity | UBCSP_PACKET_SENT;
667				}
668
669				break;
670			}
671		}
672
673		/* We have finished processing Link Establishment packets */
674	}
675	else if (ubcsp_config.receive_index)
676	{
677		/* We have some payload data we need to process
678		   but only if we are active - otherwise, we just ignore it */
679
680		if (ubcsp_config.link_establishment_state == ubcsp_le_active)
681		{
682			if (ubcsp_config.receive_packet->reliable)
683			{
684				/* If the packet we've just received was reliable
685				   then send an ACK */
686
687				ubcsp_config.send_ack = 1;
688
689				/* We the sequence number we received is the same as
690				   the last ACK we sent, then we have received a packet in sequence */
691
692				if (receive_seq == ubcsp_config.ack_number)
693				{
694					/* Increase the ACK number - which will be sent in the next ACK
695					   or normal packet we send */
696
697					ubcsp_config.ack_number ++;
698
699					/* Set the values in the receive_packet structure, so the caller
700					   knows how much data we have */
701
702					ubcsp_config.receive_packet->length = length;
703					ubcsp_config.receive_packet = 0;
704
705					/* Tell the caller that we have received a packet, and that it
706					   will be ACK'ed */
707
708					activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK;
709				}
710			}
711			else
712			{
713				/* Set the values in the receive_packet structure, so the caller
714				   knows how much data we have */
715
716				ubcsp_config.receive_packet->length = length;
717				ubcsp_config.receive_packet = 0;
718
719				/* Tell the caller that we have received a packet */
720
721				activity |= UBCSP_PACKET_RECEIVED;
722			}
723		}
724	}
725
726	/* Just return any activity that occured */
727
728	return activity;
729}
730
731/*****************************************************************************/
732/**                                                                         **/
733/** ubcsp_setup_packet                                                      **/
734/**                                                                         **/
735/** This function is called to setup a packet to be sent                    **/
736/** This allows just a header, or a header and payload to be sent           **/
737/** It also allows the header checksum to be precalcuated                   **/
738/** or calculated here                                                      **/
739/** part1 is always 4 bytes                                                 **/
740/**                                                                         **/
741/*****************************************************************************/
742
743static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2)
744{
745	/* If we need to calculate the checksum, do that now */
746
747	if (calc)
748	{
749		part1[3] =
750			~(part1[0] + part1[1] + part1[2]);
751	}
752
753	/* Setup the header send pointer and size so we can clock this out */
754
755	ubcsp_config.send_ptr = part1;
756	ubcsp_config.send_size = 4;
757
758	/* Setup the payload send pointer and size */
759
760	ubcsp_config.next_send_ptr = part2;
761	ubcsp_config.next_send_size = len2;
762
763#if UBCSP_CRC
764	/* Initialize the crc as required */
765
766	ubcsp_config.send_crc = -1;
767
768	ubcsp_config.need_send_crc = 1;
769#endif
770}
771
772/*****************************************************************************/
773/**                                                                         **/
774/** ubcsp_sent_packet                                                       **/
775/**                                                                         **/
776/** Called when we have finished sending a packet                           **/
777/** If this packet was unreliable, then notify caller, and clear the data   **/
778/**                                                                         **/
779/*****************************************************************************/
780
781static uint8 ubcsp_sent_packet (void)
782{
783	if (ubcsp_config.send_packet)
784	{
785		if (!ubcsp_config.send_packet->reliable)
786		{
787			/* We had a packet sent that was unreliable */
788
789			/* Forget about this packet */
790
791			ubcsp_config.send_packet = 0;
792
793			/* Notify caller that they can send another one */
794
795			return UBCSP_PACKET_SENT;
796		}
797	}
798
799	/* We didn't have a packet, or it was reliable
800	   Must wait for ACK before allowing another packet to be sent */
801
802	return 0;
803}
804
805/*****************************************************************************/
806/**                                                                         **/
807/** ubcsp_poll                                                              **/
808/**                                                                         **/
809/** This is the main function for ubcsp                                     **/
810/** It performs a number of tasks                                           **/
811/**                                                                         **/
812/** 1) Send another octet to the UART - escaping as required                **/
813/** 2) Setup the payload to be sent after the header has been sent          **/
814/** 3) Send the CRC for the packet if required                              **/
815/**                                                                         **/
816/** 4) Calculate the next Link Establishment State                          **/
817/** 5) Send a Link Establishment packet                                     **/
818/** 6) Send a normal packet if available                                    **/
819/** 7) Send an ACK packet if required                                       **/
820/**                                                                         **/
821/** 8) Receive octets from UART and deslip them as required                 **/
822/** 9) Place received octets into receive header or receive payload buffer  **/
823/** 10) Process received packet when SLIP_END is received                   **/
824/**                                                                         **/
825/** 11) Keep track of ability of caller to delay recalling                  **/
826/**                                                                         **/
827/*****************************************************************************/
828
829uint8 ubcsp_poll (uint8 *activity)
830{
831	uint8
832		delay = UBCSP_POLL_TIME_IMMEDIATE;
833
834	uint8
835		value;
836
837	/* Assume no activity to start with */
838
839	*activity = 0;
840
841	/* If we don't have to delay, then send something if we can */
842
843	if (!ubcsp_config.delay)
844	{
845		/* Do we have something we are sending to send */
846
847		if (ubcsp_config.send_size)
848		{
849			/* We have something to send so send it */
850
851			if (ubcsp_config.send_slip_escape)
852			{
853				/* Last time we send a SLIP_ESCAPE octet
854				   this time send the second escape code */
855
856				put_uart (ubcsp_config.send_slip_escape);
857
858				ubcsp_config.send_slip_escape = 0;
859			}
860			else
861			{
862#if UBCSP_CRC
863				/* get the value to send, and calculate CRC as we go */
864
865				value = *ubcsp_config.send_ptr ++;
866
867				ubcsp_config.send_crc = ubcsp_calc_crc (value, ubcsp_config.send_crc);
868
869				/* Output the octet */
870
871				ubcsp_put_slip_uart (value);
872#else
873				/* Just output the octet*/
874
875				ubcsp_put_slip_uart (*ubcsp_config.send_ptr ++);
876#endif
877			}
878
879			/* If we did output a SLIP_ESCAPE, then don't process the end of a block */
880
881			if ((!ubcsp_config.send_slip_escape) && ((ubcsp_config.send_size = ubcsp_config.send_size - 1) == 0))
882			{
883				/*** We are at the end of a block - either header or payload ***/
884
885				/* setup the next block */
886
887				ubcsp_config.send_ptr = ubcsp_config.next_send_ptr;
888				ubcsp_config.send_size = ubcsp_config.next_send_size;
889				ubcsp_config.next_send_ptr = 0;
890				ubcsp_config.next_send_size = 0;
891
892#if UBCSP_CRC
893				/* If we have no successor block
894				   then we might need to send the CRC */
895
896				if (!ubcsp_config.send_ptr)
897				{
898					if (ubcsp_config.need_send_crc)
899					{
900						/* reverse the CRC from what we computed along the way */
901
902						ubcsp_config.need_send_crc = 0;
903
904						ubcsp_config.send_crc = ubcsp_crc_reverse (ubcsp_config.send_crc);
905
906						/* Save in the send_crc buffer */
907
908						ubcsp_send_crc[0] = (uint8) (ubcsp_config.send_crc >> 8);
909						ubcsp_send_crc[1] = (uint8) ubcsp_config.send_crc;
910
911						/* Setup to send this buffer */
912
913						ubcsp_config.send_ptr = ubcsp_send_crc;
914						ubcsp_config.send_size = 2;
915					}
916					else
917					{
918						/* We don't need to send the crc
919						   either we just have, or this packet doesn't include it */
920
921						/* Output the end of FRAME marker */
922
923						put_uart (SLIP_FRAME);
924
925						/* Check if this is an unreliable packet */
926
927						*activity |= ubcsp_sent_packet ();
928
929						/* We've sent the packet, so don't need to have be called quickly soon */
930
931						delay = UBCSP_POLL_TIME_DELAY;
932					}
933				}
934#else
935				/* If we have no successor block
936				   then we might need to send the CRC */
937
938				if (!ubcsp_config.send_ptr)
939				{
940					/* Output the end of FRAME marker */
941
942					put_uart (SLIP_FRAME);
943
944					/* Check if this is an unreliable packet */
945
946					*activity |= ubcsp_sent_packet ();
947
948					/* We've sent the packet, so don't need to have be called quickly soon */
949
950					delay = UBCSP_POLL_TIME_DELAY;
951				}
952#endif
953			}
954		}
955		else if (ubcsp_config.link_establishment_packet == ubcsp_le_none)
956		{
957			/* We didn't have something to send
958			   AND we have no Link Establishment packet to send */
959
960			if (ubcsp_config.link_establishment_resp & 2)
961			{
962				/* Send the start of FRAME packet */
963
964				put_uart (SLIP_FRAME);
965
966				/* We did require a RESP packet - so setup the send */
967
968				ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_le_conf_resp], 4);
969
970				/* We have now "sent" this packet */
971
972				ubcsp_config.link_establishment_resp = 0;
973			}
974			else if (ubcsp_config.send_packet)
975			{
976				/* There is a packet ready to be sent */
977
978				/* Send the start of FRAME packet */
979
980				put_uart (SLIP_FRAME);
981
982				/* Encode up the packet header using ACK and SEQ numbers */
983
984				ubcsp_send_header[0] =
985					(ubcsp_config.send_packet->reliable << 7) |
986#if UBCSP_CRC
987					0x40 |	/* Always use CRC's */
988#endif
989					(ubcsp_config.ack_number << 3) |
990					(ubcsp_config.sequence_number);
991
992				/* Encode up the packet header's channel and length */
993				ubcsp_send_header[1] =
994					(ubcsp_config.send_packet->channel & 0x0f) |
995					((ubcsp_config.send_packet->length << 4) & 0xf0);
996
997				ubcsp_send_header[2] =
998					(ubcsp_config.send_packet->length >> 4) & 0xff;
999
1000				/* Let the ubcsp_setup_packet function calculate the header checksum */
1001
1002				ubcsp_setup_packet ((uint8*) ubcsp_send_header, 1, ubcsp_config.send_packet->payload, ubcsp_config.send_packet->length);
1003
1004				/* Don't need to send an ACK - we just place on in this packet */
1005
1006				ubcsp_config.send_ack = 0;
1007
1008#if SHOW_PACKET_ERRORS
1009				printf (" : %10d Send %d Ack %d\n",
1010					GetTickCount () % 100000,
1011					ubcsp_config.sequence_number,
1012					ubcsp_config.ack_number);
1013#endif
1014			}
1015			else if (ubcsp_config.send_ack)
1016			{
1017				/* Send the start of FRAME packet */
1018
1019				put_uart (SLIP_FRAME);
1020
1021#if SHOW_PACKET_ERRORS
1022				printf (" : %10d Send ACK %d\n",
1023					GetTickCount () % 100000,
1024					ubcsp_config.ack_number);
1025#endif
1026
1027				/* The ack packet is already computed apart from the first octet */
1028
1029				ubcsp_send_ack_header[0] =
1030#if UBCSP_CRC
1031					0x40 |
1032#endif
1033					(ubcsp_config.ack_number << 3);
1034
1035				/* Let the ubcsp_setup_packet function calculate the header checksum */
1036
1037				ubcsp_setup_packet (ubcsp_send_ack_header, 1, 0, 0);
1038
1039				/* We've now sent the ack */
1040
1041				ubcsp_config.send_ack = 0;
1042			}
1043			else
1044			{
1045				/* We didn't have a Link Establishment response packet,
1046				   a normal packet or an ACK packet to send */
1047
1048				delay = UBCSP_POLL_TIME_DELAY;
1049			}
1050		}
1051		else
1052		{
1053#if SHOW_PACKET_ERRORS
1054//			printf (" : %10d Send LE %d\n",
1055//				GetTickCount () % 100000,
1056//				ubcsp_config.link_establishment_packet);
1057#endif
1058
1059			/* Send A Link Establishment Message */
1060
1061			put_uart (SLIP_FRAME);
1062
1063			/* Send the Link Establishment header followed by the
1064			   Link Establishment packet */
1065
1066			ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_config.link_establishment_packet], 4);
1067
1068			/* start sending immediately */
1069
1070			ubcsp_config.delay = 0;
1071
1072			/* workout what the next link establishment packet should be */
1073
1074			ubcsp_config.link_establishment_packet = next_le_packet[ubcsp_config.link_establishment_state + ubcsp_config.link_establishment_resp * 4];
1075
1076			/* We have now delt with any response packet that we needed */
1077
1078			ubcsp_config.link_establishment_resp = 0;
1079
1080			return 0;
1081		}
1082	}
1083
1084	/* We now need to receive any octets from the UART */
1085
1086	while ((ubcsp_config.receive_packet) && (get_uart (&value)))
1087	{
1088		/* If the last octet was SLIP_ESCAPE, then special processing is required */
1089
1090		if (ubcsp_config.receive_slip_escape)
1091		{
1092			/* WARNING - out of range values are not detected !!!
1093			   This will probably be caught with the checksum or CRC check */
1094
1095			value = ubcsp_deslip[value - SLIP_ESCAPE_FRAME];
1096
1097			ubcsp_config.receive_slip_escape = 0;
1098		}
1099		else
1100		{
1101			/* Check for the SLIP_FRAME octet - must be start or end of packet */
1102			if (value == SLIP_FRAME)
1103			{
1104				/* If we had a full header then we have a packet */
1105
1106				if (ubcsp_config.receive_index >= 0)
1107				{
1108					/* process the received packet */
1109
1110					*activity |= ubcsp_recevied_packet ();
1111
1112					if (*activity & UBCSP_PACKET_ACK)
1113					{
1114						/* We need to ACK this packet, then don't delay its sending */
1115						ubcsp_config.delay = 0;
1116					}
1117				}
1118
1119				/* Setup to receive the next packet */
1120
1121				ubcsp_config.receive_index = -4;
1122
1123				/* Ok, next octet */
1124
1125				goto finished_receive;
1126			}
1127			else if (value == SLIP_ESCAPE)
1128			{
1129				/* If we receive a SLIP_ESCAPE,
1130				   then remember to process the next special octet */
1131
1132				ubcsp_config.receive_slip_escape = 1;
1133
1134				goto finished_receive;
1135			}
1136		}
1137
1138		if (ubcsp_config.receive_index < 0)
1139		{
1140			/* We are still receiving the header */
1141
1142			ubcsp_receive_header[ubcsp_config.receive_index + 4] = value;
1143
1144			ubcsp_config.receive_index ++;
1145		}
1146		else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length)
1147		{
1148			/* We are receiving the payload */
1149			/* We might stop comming here if we are receiving a
1150			   packet which is longer than the receive_packet->length
1151			   given by the host */
1152
1153			ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value;
1154
1155			ubcsp_config.receive_index ++;
1156		}
1157
1158finished_receive:
1159		{
1160		}
1161	}
1162
1163	if (ubcsp_config.delay > 0)
1164	{
1165		/* We were delayed so delay some more
1166		   this could be cancelled if we received something */
1167
1168		ubcsp_config.delay --;
1169	}
1170	else
1171	{
1172		/* We had no delay, so use the delay we just decided to us */
1173
1174		ubcsp_config.delay = delay;
1175	}
1176
1177	/* Report the current delay to the user */
1178
1179	return ubcsp_config.delay;
1180}
1181