It’s probably too late now, but the vesc is open source you don’t have to go through the trouble of reverse engineer anything, however you did a pretty good job figuring things out.
Message IDs are made of two parts, the lower 8 bits are for the actual node ID, while the remaining bits are the command packet IDs.
The CAN commands can be found here bldc/datatypes.h at master · vedderb/bldc · GitHub
typedef enum { CAN_PACKET_SET_DUTY = 0, CAN_PACKET_SET_CURRENT, CAN_PACKET_SET_CURRENT_BRAKE, CAN_PACKET_SET_RPM, CAN_PACKET_SET_POS, CAN_PACKET_FILL_RX_BUFFER, CAN_PACKET_FILL_RX_BUFFER_LONG, CAN_PACKET_PROCESS_RX_BUFFER, CAN_PACKET_PROCESS_SHORT_BUFFER, CAN_PACKET_STATUS, ...etc
You can also see how the message ID are composed from the different command functions: example
void comm_can_set_duty(uint8_t controller_id, float duty) { int32_t send_index = 0; uint8_t buffer[4]; buffer_append_int32(buffer, (int32_t)(duty * 100000.0), &send_index); comm_can_transmit_eid(controller_id | ((uint32_t)CAN_PACKET_SET_DUTY << 8), buffer, send_index); }
And how the message id is decoded to get the node ID and packet command ID
if (rxmsg.IDE == CAN_IDE_EXT) { uint8_t id = rxmsg.EID & 0xFF; CAN_PACKET_ID cmd = rxmsg.EID >> 8;
Everything you need is just there in the source code https://github.com/vedderb/bldc/blob/master/comm_can.c