2 * Copyright 2017 Max Staudt
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License 2 as published
6 * by the Free Software Foundation.
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <linux/can.h>
17 #include <linux/can/raw.h>
19 #include <sys/ioctl.h>
24 static unsigned hex2bin(char c) {
25 if (c >= '0' && c <= '9') {
27 } else if (c >= 'A' && c <= 'F') {
29 } else if (c >= 'a' && c <= 'f') {
38 static int net_init(char *ifname)
42 struct sockaddr_can addr;
45 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
51 /* Convert interface name to index */
52 memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
53 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
54 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
55 perror("SIOCGIFINDEX");
59 /* Open the CAN interface */
60 memset(&addr, 0, sizeof(addr));
61 addr.can_family = AF_CAN;
62 addr.can_ifindex = ifr.ifr_ifindex;
63 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
68 recv_own_msgs = 1; /* 0 = disabled (default), 1 = enabled */
69 setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
70 &recv_own_msgs, sizeof(recv_own_msgs));
79 int main(int argc, char **argv)
84 struct BAP_Frame *bap_frame;
86 unsigned bap_multiframe;
89 unsigned bap_function;
92 printf("syntax: %s IFNAME CAN_ID multiframe bap_opcode bap_node bap_function bap_data\n", argv[0]);
97 can_id = strtoul(argv[2], NULL, 0);
98 bap_multiframe = strtoul(argv[3], NULL, 0);
99 bap_opcode = strtoul(argv[4], NULL, 0);
100 bap_node = strtoul(argv[5], NULL, 0);
101 bap_function = strtoul(argv[6], NULL, 0);
105 bap = vw_bap_txer_alloc();
107 printf("Out of memory allocating BAP TXer struct.\n");
111 bap_frame = vw_bap_frame_alloc();
113 printf("Out of memory allocating BAP frame.\n");
120 bap_frame->is_multiframe = !(!bap_multiframe);
121 bap_frame->opcode = bap_opcode & 0x7;
122 bap_frame->node = bap_node & 0x3f;
123 bap_frame->function = bap_function & 0x3f;
127 while(bap_frame->len < 4095) {
129 unsigned i = bap_frame->len;
131 if (!argv[7][2*i] || !argv[7][2*i + 1]) {
135 high = hex2bin(argv[7][2*i]);
139 low = hex2bin(argv[7][2*i + 1]);
144 bap_frame->data[i] = (high << 4) | low;
150 s = net_init(argv[1]);
155 printf("Will send frame:\n");
156 vw_bap_frame_dump(bap_frame);
165 retval = select(s+1, NULL, &wfds, NULL, NULL);
166 /* We currently rely on Linux timeout behavior here,
167 * i.e. the timeout now reflects the remaining time */
171 } else if (!retval) {
172 /* Timeout, we NEED to check this first */
173 } else if (FD_ISSET(s, &wfds)) {
174 struct can_frame frame;
183 vw_bap_txer_free(bap);