]> git.enpas.org Git - revag-bap.git/blob - vw-bap-send.c
Sketch BAP sending
[revag-bap.git] / vw-bap-send.c
1 /*
2  * Copyright 2017 Max Staudt
3  *
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.
7  */
8
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <linux/can.h>
17 #include <linux/can/raw.h>
18 #include <net/if.h>
19 #include <sys/ioctl.h>
20
21 #include "vw-bap.h"
22
23
24 static unsigned hex2bin(char c) {
25         if (c >= '0' && c <= '9') {
26                 return c - '0';
27         } else if (c >= 'A' && c <= 'F') {
28                 return c + 10 - 'A';
29         } else if (c >= 'a' && c <= 'f') {
30                 return c + 10 - 'a';
31         } else {
32                 return 127;
33         }
34 }
35
36
37
38 static int net_init(char *ifname)
39 {
40         int s;
41         int recv_own_msgs;
42         struct sockaddr_can addr;
43         struct ifreq ifr;
44
45         s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
46         if (s < 0) {
47                 perror("socket");
48                 exit(1);
49         }
50
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");
56                 exit(1);
57         }
58
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) {
64                 perror("bind");
65                 return 0;
66         }
67
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));
71
72         return s;
73 }
74
75
76
77
78
79 int main(int argc, char **argv)
80 {
81         fd_set wfds;
82         int s;
83         struct BAP_TXer *bap;
84         struct BAP_Frame *bap_frame;
85         unsigned can_id;
86         unsigned bap_multiframe;
87         unsigned bap_opcode;
88         unsigned bap_node;
89         unsigned bap_function;
90
91         if (argc < 8) {
92                 printf("syntax: %s IFNAME CAN_ID multiframe bap_opcode bap_node bap_function bap_data\n", argv[0]);
93                 return 1;
94         }
95
96         /* Parse arguments */
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);
102         /* bap_data */
103
104
105         bap = vw_bap_txer_alloc();
106         if (!bap) {
107                 printf("Out of memory allocating BAP TXer struct.\n");
108                 return 1;
109         }
110
111         bap_frame = vw_bap_frame_alloc();
112         if (!bap_frame) {
113                 printf("Out of memory allocating BAP frame.\n");
114                 return 1;
115         }
116
117
118
119         /* Fill frame */
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;
124         bap_frame->len = 0;
125
126         /* Fill payload */
127         while(bap_frame->len < 4095) {
128                 unsigned high, low;
129                 unsigned i = bap_frame->len;
130
131                 if (!argv[7][2*i] || !argv[7][2*i + 1]) {
132                         break;
133                 }
134
135                 high = hex2bin(argv[7][2*i]);
136                 if (high > 15) {
137                         break;
138                 }
139                 low = hex2bin(argv[7][2*i + 1]);
140                 if (low > 15) {
141                         break;
142                 }
143
144                 bap_frame->data[i] = (high << 4) | low;
145                 bap_frame->len++;
146         }
147
148
149
150         s = net_init(argv[1]);
151
152
153         /* Fill TXer */
154
155         printf("Will send frame:\n");
156         vw_bap_frame_dump(bap_frame);
157
158
159         while (1) {
160                 int retval;
161
162                 FD_ZERO(&wfds);
163                 FD_SET(s, &wfds);
164
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 */
168                 if (retval < 0) {
169                         perror("select");
170                         return 1;
171                 } else if (!retval) {
172                         /* Timeout, we NEED to check this first */
173                 } else if (FD_ISSET(s, &wfds)) {
174                         struct can_frame frame;
175                         ssize_t ret;
176
177                         continue;
178                 }
179         }
180
181
182
183         vw_bap_txer_free(bap);
184
185         close(s);
186
187         return 0;
188 }