]> rtime.felk.cvut.cz Git - linux-lin.git/blob - lin_config/src/sllin_config.c
linconf: Basic sllin configuration.
[linux-lin.git] / lin_config / src / sllin_config.c
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <sys/ioctl.h>
4 #include <sys/uio.h>
5 #include <net/if.h>
6 #include <netinet/in.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13
14 #include <linux/can.h>
15 #include <linux/can/bcm.h>
16
17 #include "lin_config.h"
18
19 #define SLLIN_LDISC                                     25
20 struct bcm_msg {
21         struct bcm_msg_head msg_head;
22         struct can_frame frame;
23 };
24
25 struct sllin_connection {
26         int bcm_sock; // FIXME is necessary??
27         int can_sock;
28         char iface[IFNAMSIZ+1];
29 };
30
31 int sllin_bcm_config(struct linc_lin_state *linc_lin_state,
32                         struct sllin_connection *sllin_connection)
33 {
34         struct sockaddr_can caddr;
35         struct ifreq ifr;
36         struct bcm_msg msg;
37         int s;
38         int ret;
39         int i;
40
41         //printf("tty %s to netdevice %s\n", linc_lin_state->dev, sllin_connection->iface);
42
43         s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
44         if (s < 0) {
45                 perror("socket(): bcmsocket");
46                 return -1;
47         }
48
49         strcpy(ifr.ifr_name, sllin_connection->iface);
50         ioctl(s, SIOCGIFINDEX, &ifr);
51
52         memset(&caddr, 0, sizeof(caddr));
53         caddr.can_family = AF_CAN;
54         caddr.can_ifindex = ifr.ifr_ifindex;
55
56 //      ret = bind(s, (struct sockaddr*)&caddr, sizeof(caddr));
57 //      if (ret < 0) {
58 //              perror("bind()");
59 //              return -1;
60 //      }
61 //
62 //      sllin_connection->bcm_sock = s;
63
64         ret = connect(s, (struct sockaddr *)&caddr, sizeof(caddr));
65         if (ret < 0) {
66                 perror("connect()");
67                 return -1;
68         }
69
70         for (i = 0; i < linc_lin_state->scheduler_entries_cnt; i++) {
71                 memset(&msg, 0, sizeof(msg));
72                 msg.msg_head.nframes = 1;
73                 msg.msg_head.opcode = TX_SETUP;
74                 msg.msg_head.flags |= SETTIMER | STARTTIMER;
75                 //msg.msg_head.ival2.tv_sec =  // FIXME
76                 msg.msg_head.ival2.tv_usec =
77                         linc_lin_state->scheduler_entry[i].interval_ms * 1000;
78                 msg.msg_head.can_id =
79                         linc_lin_state->scheduler_entry[i].lin_id | CAN_RTR_FLAG;
80                 msg.frame.can_dlc = 0;
81
82                 sendto(s, &msg, sizeof(msg), 0,
83                         (struct sockaddr*)&caddr, sizeof(caddr));
84                 printf(".\n");
85                 //read_response(s); // FIXME
86         }
87
88         close(s);
89
90         printf("Configuration finished\n");
91         return 0;
92 }
93
94 int sllin_config(struct linc_lin_state *linc_lin_state)
95 {
96         int tty;
97         int ldisc = SLLIN_LDISC;
98         int ret;
99         struct sllin_connection sllin_connection;
100
101         tty = open(linc_lin_state->dev, O_WRONLY | O_NOCTTY);
102         if (tty < 0) {
103                 perror("open()");
104                 return -1;
105         }
106
107         /* Set sllin line discipline on given tty */
108         if (linc_lin_state->flags & SLLIN_ATTACH_fl) {
109                 ret = ioctl(tty, TIOCSETD, &ldisc);
110                 if (ret < 0) {
111                         perror("ioctl TIOCSETD");
112                         return -1;
113                 }
114
115                 /* Retrieve the name of the created CAN netdevice */
116                 ret = ioctl(tty, SIOCGIFNAME, sllin_connection.iface);
117                 if (ret < 0) {
118                         perror("ioctl SIOCGIFNAME");
119                         return -1;
120                 }
121
122                 printf("Attached tty %s to netdevice %s\n", linc_lin_state->dev, sllin_connection.iface);
123         }
124
125         if (linc_lin_state->flags & SLLIN_DETACH_fl) {
126                 ldisc = N_TTY;
127                 ret = ioctl(tty, TIOCSETD, &ldisc);
128                 if (ret < 0) {
129                         perror("ioctl");
130                         return -1;
131                 }
132
133                 printf("Detached sllin line discipline from %s\n", linc_lin_state->dev);
134                 return 0;
135         }
136
137         ret = sllin_bcm_config(linc_lin_state, &sllin_connection);
138
139         printf("Press any key to detach %s ...\n", linc_lin_state->dev);
140         getchar();
141         close(tty);
142         return ret;
143 }
144