📄 ubcsp.c
字号:
/* If we have a header checksum error, send an ack in return
this gets a packet to be resent as quickly as possible */
ubcsp_config.send_ack = 1;
return activity;
}
/* Decode the received packets header */
ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7;
receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6;
receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3;
receive_seq = (ubcsp_receive_header[0] & 0x07);
ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f);
length =
((ubcsp_receive_header[1] & 0xf0) >> 4) |
(ubcsp_receive_header[2] << 4);
#if SHOW_PACKET_ERRORS
if (ubcsp_config.receive_packet->reliable)
{
printf (" : %10d Recv SEQ: %d ACK %d\n",
GetTickCount () % 100000,
receive_seq,
receive_ack);
}
else if (ubcsp_config.receive_packet->channel != 1)
{
printf (" : %10d Recv ACK %d\n",
GetTickCount () % 100000,
receive_ack);
}
#endif
/* Check for length errors */
#if UBCSP_CRC
if (receive_crc)
{
/* If this packet had a CRC, then the length of the payload
should be 2 less than the received size of the payload */
if (length + 2 != ubcsp_config.receive_index)
{
/* Slip Length Error */
#if SHOW_PACKET_ERRORS
printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2);
#endif
/* If we have a payload length error, send an ack in return
this gets a packet to be resent as quickly as possible */
ubcsp_config.send_ack = 1;
return activity;
}
/* We have a CRC at the end of this packet */
ubcsp_config.receive_index -= 2;
/* Calculate the packet CRC */
crc = 0xffff;
/* CRC the packet header */
for (loop = 0; loop < 4; loop ++)
{
crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc);
}
/* CRC the packet payload - without the CRC bytes */
for (loop = 0; loop < ubcsp_config.receive_index; loop ++)
{
crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc);
}
/* Reverse the CRC */
crc = ubcsp_crc_reverse (crc);
/* Check the CRC is correct */
if
(
(((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) ||
((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1])
)
{
#if SHOW_PACKET_ERRORS
printf ("\n######################## CRC Error\n");
#endif
/* If we have a packet crc error, send an ack in return
this gets a packet to be resent as quickly as possible */
ubcsp_config.send_ack = 1;
return activity;
}
}
else
{
#endif
/* No CRC present, so just check the length of payload with that received */
if (length != ubcsp_config.receive_index)
{
/* Slip Length Error */
#if SHOW_PACKET_ERRORS
printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index);
#endif
/* If we have a payload length error, send an ack in return
this gets a packet to be resent as quickly as possible */
ubcsp_config.send_ack = 1;
return activity;
}
#if UBCSP_CRC
}
#endif
/*** We have a fully formed packet having passed all data integrity checks ***/
/* Check if we have an ACK for the last packet we sent */
if (receive_ack != ubcsp_config.sequence_number)
{
/* Since we only have a window size of 1, if the ACK is not equal to SEQ
then the packet was sent */
if
(
(ubcsp_config.send_packet) &&
(ubcsp_config.send_packet->reliable)
)
{
/* We had sent a reliable packet, so clear this packet
Then increament the sequence number for the next packet */
ubcsp_config.send_packet = 0;
ubcsp_config.sequence_number ++;
ubcsp_config.delay = 0;
/* Notify the caller that we have SENT a packet */
activity |= UBCSP_PACKET_SENT;
}
}
/*** Now we can concentrate of the packet we have received ***/
/* Check for Link Establishment packets */
if (ubcsp_config.receive_packet->channel == 1)
{
/* Link Establishment */
ubcsp_config.delay = 0;
/* Find which link establishment packet this payload means
This could return 5, meaning none */
switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload))
{
case 0:
{
/* SYNC Recv'd */
#if SHOW_LE_STATES
printf ("Recv SYNC\n");
#endif
/* If we receive a SYNC, then we respond to it with a SYNC RESP
but only if we are not active.
If we are active, then we have a PEER RESET */
if (ubcsp_config.link_establishment_state < ubcsp_le_active)
{
ubcsp_config.link_establishment_resp = 1;
}
else
{
/* Peer reset !!!! */
#if SHOW_LE_STATES
printf ("\n\n\n\n\nPEER RESET\n\n");
#endif
/* Reinitialize the link */
ubcsp_initialize ();
/* Tell the host what has happened */
return UBCSP_PEER_RESET;
}
break;
}
case 1:
{
/* SYNC RESP Recv'd */
#if SHOW_LE_STATES
printf ("Recv SYNC RESP\n");
#endif
/* If we receive a SYNC RESP, push us into the initialized state */
if (ubcsp_config.link_establishment_state < ubcsp_le_initialized)
{
#if SHOW_LE_STATES
printf ("Link Initialized\n");
#endif
ubcsp_config.link_establishment_state = ubcsp_le_initialized;
}
break;
}
case 2:
{
/* CONF Recv'd */
#if SHOW_LE_STATES
printf ("Recv CONF\n");
#endif
/* If we receive a CONF, and we are initialized or active
then respond with a CONF RESP */
if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized)
{
ubcsp_config.link_establishment_resp = 2;
}
break;
}
case 3:
{
/* CONF RESP Recv'd */
#if SHOW_LE_STATES
printf ("Recv CONF RESP\n");
#endif
/* If we received a CONF RESP, then push us into the active state */
if (ubcsp_config.link_establishment_state < ubcsp_le_active)
{
#if SHOW_LE_STATES
printf ("Link Active\n");
#endif
ubcsp_config.link_establishment_state = ubcsp_le_active;
ubcsp_config.send_size = 0;
return activity | UBCSP_PACKET_SENT;
}
break;
}
}
/* We have finished processing Link Establishment packets */
}
else if (ubcsp_config.receive_index)
{
/* We have some payload data we need to process
but only if we are active - otherwise, we just ignore it */
if (ubcsp_config.link_establishment_state == ubcsp_le_active)
{
if (ubcsp_config.receive_packet->reliable)
{
/* If the packet we've just received was reliable
then send an ACK */
ubcsp_config.send_ack = 1;
/* We the sequence number we received is the same as
the last ACK we sent, then we have received a packet in sequence */
if (receive_seq == ubcsp_config.ack_number)
{
/* Increase the ACK number - which will be sent in the next ACK
or normal packet we send */
ubcsp_config.ack_number ++;
/* Set the values in the receive_packet structure, so the caller
knows how much data we have */
ubcsp_config.receive_packet->length = length;
ubcsp_config.receive_packet = 0;
/* Tell the caller that we have received a packet, and that it
will be ACK'ed */
activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK;
}
}
else
{
/* Set the values in the receive_packet structure, so the caller
knows how much data we have */
ubcsp_config.receive_packet->length = length;
ubcsp_config.receive_packet = 0;
/* Tell the caller that we have received a packet */
activity |= UBCSP_PACKET_RECEIVED;
}
}
}
/* Just return any activity that occured */
return activity;
}
/*****************************************************************************/
/** **/
/** ubcsp_setup_packet **/
/** **/
/** This function is called to setup a packet to be sent **/
/** This allows just a header, or a header and payload to be sent **/
/** It also allows the header checksum to be precalcuated **/
/** or calculated here **/
/** part1 is always 4 bytes **/
/** **/
/*****************************************************************************/
static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2)
{
/* If we need to calculate the checksum, do that now */
if (calc)
{
part1[3] =
~(part1[0] + part1[1] + part1[2]);
}
/* Setup the header send pointer and size so we can clock this out */
ubcsp_config.send_ptr = part1;
ubcsp_config.send_size = 4;
/* Setup the payload send pointer and size */
ubcsp_config.next_send_ptr = part2;
ubcsp_config.next_send_size = len2;
#if UBCSP_CRC
/* Initialize the crc as required */
ubcsp_config.send_crc = -1;
ubcsp_config.need_send_crc = 1;
#endif
}
/*****************************************************************************/
/** **/
/** ubcsp_sent_packet **/
/** **/
/** Called when we have finished sending a packet **/
/** If this packet was unreliable, then notify caller, and clear the data **/
/** **/
/*****************************************************************************/
static uint8 ubcsp_sent_packet (void)
{
if (ubcsp_config.send_packet)
{
if (!ubcsp_config.send_packet->reliable)
{
/* We had a packet sent that was unreliable */
/* Forget about this packet */
ubcsp_config.send_packet = 0;
/* Notify caller that they can send another one */
return UBCSP_PACKET_SENT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -