2 #include <sys/socket.h>
6 #include <netinet/in.h>
14 #include <linux/can.h>
15 #include <linux/can/bcm.h>
17 #include "lin_config.h"
18 #include "linux/lin_bus.h"
20 #define SLLIN_LDISC 25
22 struct bcm_msg_head msg_head;
23 struct can_frame frame;
26 struct sllin_connection {
27 int bcm_sock; // FIXME is necessary??
29 char iface[IFNAMSIZ+1];
32 void sllin_ms_to_timeval(int ms, struct timeval *tv)
34 tv->tv_sec = (int) ms/1000;
35 tv->tv_usec = (ms % 1000) * 1000;
38 int sllin_cache_config(struct linc_lin_state *linc_lin_state,
39 struct sllin_connection *sllin_connection)
43 struct sockaddr_can addr;
44 struct can_frame frame;
48 /* Create the socket */
49 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
55 /* Locate the interface you wish to use */
56 strcpy(ifr.ifr_name, sllin_connection->iface);
57 ioctl(s, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled
58 * with that device's index */
60 /* Select that CAN interface, and bind the socket to it. */
61 addr.can_family = AF_CAN;
62 addr.can_ifindex = ifr.ifr_ifindex;
63 ret = bind(s, (struct sockaddr*)&addr, sizeof(addr));
69 for (i = 0; i < 0x3F; i++) {
70 if (linc_lin_state->frame_entry[i].status == 1) { /* Is active */
71 frame.can_dlc = linc_lin_state->frame_entry[i].data_len;
72 frame.can_id = i; /* LIN ID */
73 frame.data[0] = linc_lin_state->frame_entry[i].data[0]; /* Data */
74 frame.data[1] = linc_lin_state->frame_entry[i].data[1]; /* Data */
75 frame.data[2] = linc_lin_state->frame_entry[i].data[2]; /* Data */
76 frame.data[3] = linc_lin_state->frame_entry[i].data[3]; /* Data */
77 frame.data[4] = linc_lin_state->frame_entry[i].data[4]; /* Data */
78 frame.data[5] = linc_lin_state->frame_entry[i].data[5]; /* Data */
79 frame.data[6] = linc_lin_state->frame_entry[i].data[6]; /* Data */
80 frame.data[7] = linc_lin_state->frame_entry[i].data[7]; /* Data */
82 frame.can_id |= LIN_CTRL_FRAME | LIN_CACHE_RESPONSE;
83 ret = write(s, &frame, sizeof(frame));
84 printf("configuring frame cache; ret = %d\n", ret);
94 int sllin_bcm_config(struct linc_lin_state *linc_lin_state,
95 struct sllin_connection *sllin_connection)
97 struct sockaddr_can caddr;
104 s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
106 perror("socket(): bcmsocket");
110 strcpy(ifr.ifr_name, sllin_connection->iface);
111 ioctl(s, SIOCGIFINDEX, &ifr);
113 memset(&caddr, 0, sizeof(caddr));
114 caddr.can_family = AF_CAN;
115 caddr.can_ifindex = ifr.ifr_ifindex;
117 // ret = bind(s, (struct sockaddr*)&caddr, sizeof(caddr));
123 // sllin_connection->bcm_sock = s;
125 ret = connect(s, (struct sockaddr *)&caddr, sizeof(caddr));
131 for (i = 0; i < linc_lin_state->scheduler_entries_cnt; i++) {
133 memset(&msg, 0, sizeof(msg));
135 msg.msg_head.nframes = 1;
136 msg.msg_head.opcode = TX_SETUP;
137 msg.msg_head.flags |= SETTIMER | STARTTIMER;
139 linc_lin_state->scheduler_entry[i].interval_ms, &time);
140 msg.msg_head.ival2.tv_sec = time.tv_sec;
141 msg.msg_head.ival2.tv_usec = time.tv_usec;
142 msg.msg_head.can_id = (
143 linc_lin_state->scheduler_entry[i].lin_id | CAN_RTR_FLAG);
144 msg.frame.can_dlc = 0;
145 msg.frame.can_id = msg.msg_head.can_id;
147 //printf("tv_sec = %i, tv_usec = %i\n", time.tv_sec, time.tv_usec);
149 sendto(s, &msg, sizeof(msg), 0,
150 (struct sockaddr*)&caddr, sizeof(caddr));
151 //read_response(s); // FIXME
154 /* Do not close "s" to make BCM configuration running */
156 printf("Configuration finished\n");
160 int sllin_config(struct linc_lin_state *linc_lin_state)
163 int ldisc = SLLIN_LDISC;
165 struct sllin_connection sllin_connection;
167 tty = open(linc_lin_state->dev, O_WRONLY | O_NOCTTY);
173 /* Set sllin line discipline on given tty */
174 if (linc_lin_state->flags & SLLIN_ATTACH_fl) {
175 ret = ioctl(tty, TIOCSETD, &ldisc);
177 perror("ioctl TIOCSETD");
181 /* Retrieve the name of the created CAN netdevice */
182 ret = ioctl(tty, SIOCGIFNAME, sllin_connection.iface);
184 perror("ioctl SIOCGIFNAME");
188 printf("Attached tty %s to netdevice %s\n",
189 linc_lin_state->dev, sllin_connection.iface);
192 if (linc_lin_state->flags & SLLIN_DETACH_fl) {
194 ret = ioctl(tty, TIOCSETD, &ldisc);
200 printf("Detached sllin line discipline from %s\n",
201 linc_lin_state->dev);
207 ret = sllin_bcm_config(linc_lin_state, &sllin_connection);
211 ret = sllin_cache_config(linc_lin_state, &sllin_connection);
213 /* !!! Do not close "tty" to enable newly
214 configured tty line discipline */