diff --git a/examples/acf-can/acf-can-listener.c b/examples/acf-can/acf-can-listener.c index 1e4503c..1a44d3c 100644 --- a/examples/acf-can/acf-can-listener.c +++ b/examples/acf-can/acf-can-listener.c @@ -181,6 +181,7 @@ static int new_packet(int sk_fd, int can_socket) { Avtp_UDP_t *udp_pdu; char stdout_string[1000] = "\0"; struct can_frame frame; + uint64_t eff; res = recv(sk_fd, pdu, MAX_PDU_SIZE, 0); @@ -226,7 +227,7 @@ static int new_packet(int sk_fd, int can_socket) { while (msg_proc_bytes < msg_length) { - acf_pdu = &pdu[proc_bytes]; + acf_pdu = &pdu[proc_bytes + msg_proc_bytes]; if (!is_valid_acf_packet(acf_pdu)) { fprintf(stderr, "Error: Invalid ACF packet.\n"); @@ -243,16 +244,33 @@ static int new_packet(int sk_fd, int can_socket) { can_payload = Avtp_Can_GetPayload((Avtp_Can_t*)acf_pdu, &payload_length, &pdu_length); msg_proc_bytes += pdu_length*4; + res = Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_EFF, &eff); + if (res < 0) { + fprintf(stderr, "Failed to get eff field: %d\n", res); + return -1; + } + + if (can_frame_id > 0x7FF && !eff) { + fprintf(stderr, "Error: CAN ID is > 0x7FF but the EFF bit is not set.\n"); + return -1; + } + if (can_socket == 0) { for (i = 0; i < payload_length; i++) { sprintf(stdout_string+(2*i), "%02x", can_payload[i]); } - fprintf(stdout, "(000000.000000) elmcan %03lx#%s\n", can_frame_id, - stdout_string); + if (eff) { + fprintf(stdout, "(000000.000000) elmcan 0000%03lx#%s\n", can_frame_id, stdout_string); + } else { + fprintf(stdout, "(000000.000000) elmcan %03lx#%s\n", can_frame_id, stdout_string); + } fflush(stdout); } else { frame.can_id = (canid_t) can_frame_id; + if (eff) { + frame.can_id |= CAN_EFF_FLAG; + } frame.can_dlc = payload_length; memcpy(frame.data, can_payload, payload_length); if (write(can_socket, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) { @@ -323,4 +341,4 @@ int main(int argc, char *argv[]) close(sk_fd); return 1; -} \ No newline at end of file +} diff --git a/examples/acf-can/acf-can-talker.c b/examples/acf-can/acf-can-talker.c index 396d4df..e147808 100644 --- a/examples/acf-can/acf-can-talker.c +++ b/examples/acf-can/acf-can-talker.c @@ -62,6 +62,7 @@ static int priority = -1; static uint8_t seq_num = 0; static uint8_t use_tscf; static uint8_t use_udp; +static uint8_t multi_can_frames = 1; static char can_ifname[IFNAMSIZ] = "STDIN\0"; static char doc[] = "\nacf-can-talker -- a program designed to send CAN messages to \ @@ -69,6 +70,8 @@ static char doc[] = "\nacf-can-talker -- a program designed to send CAN messages \vEXAMPLES\ \n\n acf-can-talker eth0 aa:bb:cc:ee:dd:ff\ \n\n (tunnel transactions from STDIN to a remote CAN bus over Ethernet)\ + \n\n acf-can-talker --count 10 eth0 aa:bb:cc:ee:dd:ff\ + \n\n (as above, but pack 10 CAN frames in one Ethernet frame)\ \n\n acf-can-talker -u 10.0.0.2:17220 vcan1\ \n\n (tunnel transactions from can1 interface to a remote CAN bus over IP)\ \n\n candump can1 | acf-can-talker -u 10.0.0.2:17220\ @@ -79,6 +82,7 @@ static char args_doc[] = "[ifname] dst-mac-address/dst-nw-address:port [can ifna static struct argp_option options[] = { {"tscf", 't', 0, 0, "Use TSCF"}, {"udp", 'u', 0, 0, "Use UDP" }, + {"count", 'c', "COUNT", 0, "Set count of CAN messages per Ethernet frame"}, {"can ifname", 0, 0, OPTION_DOC, "CAN interface (set to STDIN by default)"}, {"ifname", 0, 0, OPTION_DOC, "Network interface (If Ethernet)"}, {"dst-mac-address", 0, 0, OPTION_DOC, "Stream destination MAC address (If Ethernet)"}, @@ -98,6 +102,9 @@ static error_t parser(int key, char *arg, struct argp_state *state) case 'u': use_udp = 1; break; + case 'c': + multi_can_frames = atoi(arg); + break; case ARGP_KEY_NO_ARGS: argp_usage(state); @@ -276,6 +283,8 @@ int main(int argc, char *argv[]) if (fd < 0) return 1; + num_acf_msgs = multi_can_frames; + // Open a CAN socket for reading frames if required if (strcmp(can_ifname, "STDIN\0")) { can_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW); @@ -307,12 +316,6 @@ int main(int argc, char *argv[]) // Sending loop for(;;) { - // Get payload - res = get_payload(can_socket, payload, &frame_id, &payload_length); - if (!res) { - continue; - } - // Pack into control formats uint8_t *cf_pdu; pdu_length = 0; @@ -331,12 +334,22 @@ int main(int argc, char *argv[]) goto err; pdu_length += res; - for (int i = 0; i < num_acf_msgs; i++) { + int i = 0; + while (i < num_acf_msgs) { + // Get payload -- will 'spin' here until we get the requested number + // of CAN frames. + res = get_payload(can_socket, payload, &frame_id, &payload_length); + if (!res) { + continue; + } + uint8_t* acf_pdu = cf_pdu + pdu_length; res = prepare_acf_packet(acf_pdu, payload, payload_length, frame_id); if (res < 0) goto err; pdu_length += res; + + i++; } res = update_pdu_length(cf_pdu, pdu_length); @@ -365,4 +378,4 @@ int main(int argc, char *argv[]) close(fd); return 1; -} \ No newline at end of file +}