canbus: Add support for verifying the canbus uuid

There is a severe corner case where two mcus could potentially be
assigned the same canbus_id and thus flash commands could go to the
wrong mcu.  Add a get_canbus_id command to attempt to prevent this.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-05-09 15:20:17 -04:00 committed by Eric Callahan
parent f0a2339822
commit ae687a404d
5 changed files with 45 additions and 3 deletions

View File

@ -140,6 +140,22 @@ in the following format:
<4 byte orig_command>
```
#### Get CANbus id: `0x16`
Return the CANbus UUID (for verification of correct communication
channel).
```
<0x01><0x88><0x16><0x00><CRC><0x99><0x03>
```
Responds with [acknowledged](#acknowledged-0xa0) containing a 12 byte
payload in the following format:
```
<4 byte orig_command><6 byte UUID><0x00><0x00>
```
### Responses
#### Acknowledged: `0xa0`

View File

@ -46,7 +46,8 @@ BOOTLOADER_CMDS = {
'SEND_BLOCK': 0x12,
'SEND_EOF': 0x13,
'REQUEST_BLOCK': 0x14,
'COMPLETE': 0x15
'COMPLETE': 0x15,
'GET_CANBUS_ID': 0x16,
}
ACK_SUCCESS = 0xa0
@ -103,6 +104,13 @@ class CanFlasher:
f"MCU type: {mcu_type}"
)
async def verify_canbus_uuid(self, uuid):
output_line("Verifying canbus connection")
ret = await self.send_command('GET_CANBUS_ID')
mcu_uuid = sum([v << ((5 - i) * 8) for i, v in enumerate(ret[:6])])
if mcu_uuid != uuid:
raise FlashCanError("UUID mismatch (%s vs %s)" % (uuid, mcu_uuid))
async def send_command(
self,
cmdname: str,
@ -457,6 +465,7 @@ class CanSocket:
await asyncio.sleep(.5)
try:
await flasher.connect_btl()
await flasher.verify_canbus_uuid(uuid)
await flasher.send_file()
await flasher.verify_file()
finally:

View File

@ -48,7 +48,7 @@ static uint8_t page_pending = 0;
static uint32_t blink_time = WAIT_BLINK_TIME;
static uint8_t complete = 0;
static void
void
send_ack(uint32_t* data, uint8_t payload_len)
{
// First four bytes: 2 byte header, ack_type, data length
@ -163,6 +163,9 @@ process_command(uint8_t cmd, uint32_t* data, uint8_t data_len)
case CMD_COMPLETE:
process_complete();
break;
case CMD_GET_CANBUS_ID:
command_get_canbus_id();
break;
default:
// Unknown command or gabage data, NACK it
canboot_sendf(cerr, 8);

View File

@ -6,5 +6,9 @@
void canboot_process_rx(uint8_t *data, uint32_t len);
void canboot_sendf(uint8_t* data, uint16_t size);
void canboot_main(void);
void send_ack(uint32_t* data, uint8_t payload_len);
#define CMD_GET_CANBUS_ID 0x16
void command_get_canbus_id(void);
#endif // canboot_main.h

View File

@ -7,6 +7,7 @@
// This file may be distributed under the terms of the GNU GPLv3 license.
#include <string.h> // memcpy
#include "byteorder.h" // cpu_to_le32
#include "canbus.h" // canbus_set_uuid
#include "canboot_main.h"
@ -225,6 +226,15 @@ canbus_rx_task(void)
* Setup and shutdown
****************************************************************/
void
command_get_canbus_id(void)
{
uint32_t out[5] = {};
out[1] = cpu_to_le32(CMD_GET_CANBUS_ID);
memcpy(&out[2], canbus_uuid, 6);
send_ack(out, 3);
}
void
canbus_set_uuid(void *uuid)
{
@ -237,4 +247,4 @@ canbus_shutdown(void)
{
canbus_notify_tx();
canbus_notify_rx();
}
}