~ubuntu-branches/ubuntu/wily/libsocketcan/wily

« back to all changes in this revision

Viewing changes to src/libsocketcan.c

  • Committer: Package Import Robot
  • Author(s): Alexander GQ Gerasiov
  • Date: 2014-03-18 18:47:57 UTC
  • Revision ID: package-import@ubuntu.com-20140318184757-0ri1lkf00s2mx3gd
Tags: upstream-0.0.9+git20140207
ImportĀ upstreamĀ versionĀ 0.0.9+git20140207

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libsocketcan.c
 
2
 *
 
3
 * (C) 2009 Luotao Fu <l.fu@pengutronix.de>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or modify it under
 
6
 * the terms of the GNU Lesser General Public License as published by the Free
 
7
 * Software Foundation; either version 2.1 of the License, or (at your option)
 
8
 * any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful, but WITHOUT
 
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
12
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 
13
 * details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public License
 
16
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 
17
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 */
 
19
 
 
20
/**
 
21
 * @file
 
22
 * @brief library code
 
23
 */
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <unistd.h>
 
29
#include <errno.h>
 
30
#include <fcntl.h>
 
31
#include <net/if.h>
 
32
 
 
33
#include <linux/rtnetlink.h>
 
34
#include <linux/netlink.h>
 
35
 
 
36
#include <libsocketcan.h>
 
37
 
 
38
#define parse_rtattr_nested(tb, max, rta) \
 
39
        (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
 
40
 
 
41
#define NLMSG_TAIL(nmsg) \
 
42
        ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
 
43
 
 
44
#define IFLA_CAN_MAX    (__IFLA_CAN_MAX - 1)
 
45
 
 
46
#define IF_UP 1
 
47
#define IF_DOWN 2
 
48
 
 
49
#define GET_STATE 1
 
50
#define GET_RESTART_MS 2
 
51
#define GET_BITTIMING 3
 
52
#define GET_CTRLMODE 4
 
53
#define GET_CLOCK 5
 
54
#define GET_BITTIMING_CONST 6
 
55
#define GET_BERR_COUNTER 7
 
56
#define GET_XSTATS 8
 
57
 
 
58
struct get_req {
 
59
        struct nlmsghdr n;
 
60
        struct rtgenmsg g;
 
61
};
 
62
 
 
63
struct set_req {
 
64
        struct nlmsghdr n;
 
65
        struct ifinfomsg i;
 
66
        char buf[1024];
 
67
};
 
68
 
 
69
struct req_info {
 
70
        __u8 restart;
 
71
        __u8 disable_autorestart;
 
72
        __u32 restart_ms;
 
73
        struct can_ctrlmode *ctrlmode;
 
74
        struct can_bittiming *bittiming;
 
75
};
 
76
 
 
77
static void
 
78
parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
 
79
{
 
80
        memset(tb, 0, sizeof(*tb) * max);
 
81
        while (RTA_OK(rta, len)) {
 
82
                if (rta->rta_type <= max) {
 
83
                        tb[rta->rta_type] = rta;
 
84
                }
 
85
 
 
86
                rta = RTA_NEXT(rta, len);
 
87
        }
 
88
}
 
89
 
 
90
static int addattr32(struct nlmsghdr *n, size_t maxlen, int type, __u32 data)
 
91
{
 
92
        int len = RTA_LENGTH(4);
 
93
        struct rtattr *rta;
 
94
 
 
95
        if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
 
96
                fprintf(stderr,
 
97
                        "addattr32: Error! max allowed bound %zu exceeded\n",
 
98
                        maxlen);
 
99
                return -1;
 
100
        }
 
101
 
 
102
        rta = NLMSG_TAIL(n);
 
103
        rta->rta_type = type;
 
104
        rta->rta_len = len;
 
105
        memcpy(RTA_DATA(rta), &data, 4);
 
106
        n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
 
107
 
 
108
        return 0;
 
109
}
 
110
 
 
111
static int addattr_l(struct nlmsghdr *n, size_t maxlen, int type,
 
112
                     const void *data, int alen)
 
113
{
 
114
        int len = RTA_LENGTH(alen);
 
115
        struct rtattr *rta;
 
116
 
 
117
        if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
 
118
                fprintf(stderr,
 
119
                        "addattr_l ERROR: message exceeded bound of %zu\n",
 
120
                        maxlen);
 
121
                return -1;
 
122
        }
 
123
 
 
124
        rta = NLMSG_TAIL(n);
 
125
        rta->rta_type = type;
 
126
        rta->rta_len = len;
 
127
        memcpy(RTA_DATA(rta), data, alen);
 
128
        n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
 
129
 
 
130
        return 0;
 
131
}
 
132
 
 
133
/**
 
134
 * @ingroup intern
 
135
 * @brief send_mod_request - send a linkinfo modification request
 
136
 *
 
137
 * @param fd decriptor to a priorly opened netlink socket
 
138
 * @param n netlink message containing the request
 
139
 *
 
140
 * sends a request to setup the the linkinfo to netlink layer and awaits the
 
141
 * status.
 
142
 *
 
143
 * @return 0 if success
 
144
 * @return negativ if failed
 
145
 */
 
146
static int send_mod_request(int fd, struct nlmsghdr *n)
 
147
{
 
148
        int status;
 
149
        struct sockaddr_nl nladdr;
 
150
        struct nlmsghdr *h;
 
151
 
 
152
        struct iovec iov = {
 
153
                .iov_base = (void *)n,
 
154
                .iov_len = n->nlmsg_len
 
155
        };
 
156
        struct msghdr msg = {
 
157
                .msg_name = &nladdr,
 
158
                .msg_namelen = sizeof(nladdr),
 
159
                .msg_iov = &iov,
 
160
                .msg_iovlen = 1,
 
161
        };
 
162
        char buf[16384];
 
163
 
 
164
        memset(&nladdr, 0, sizeof(nladdr));
 
165
 
 
166
        nladdr.nl_family = AF_NETLINK;
 
167
        nladdr.nl_pid = 0;
 
168
        nladdr.nl_groups = 0;
 
169
 
 
170
        n->nlmsg_seq = 0;
 
171
        n->nlmsg_flags |= NLM_F_ACK;
 
172
 
 
173
        status = sendmsg(fd, &msg, 0);
 
174
 
 
175
        if (status < 0) {
 
176
                perror("Cannot talk to rtnetlink");
 
177
                return -1;
 
178
        }
 
179
 
 
180
        iov.iov_base = buf;
 
181
        while (1) {
 
182
                iov.iov_len = sizeof(buf);
 
183
                status = recvmsg(fd, &msg, 0);
 
184
                for (h = (struct nlmsghdr *)buf; (size_t) status >= sizeof(*h);) {
 
185
                        int len = h->nlmsg_len;
 
186
                        int l = len - sizeof(*h);
 
187
                        if (l < 0 || len > status) {
 
188
                                if (msg.msg_flags & MSG_TRUNC) {
 
189
                                        fprintf(stderr, "Truncated message\n");
 
190
                                        return -1;
 
191
                                }
 
192
                                fprintf(stderr,
 
193
                                        "!!!malformed message: len=%d\n", len);
 
194
                                return -1;
 
195
                        }
 
196
 
 
197
                        if (h->nlmsg_type == NLMSG_ERROR) {
 
198
                                struct nlmsgerr *err =
 
199
                                    (struct nlmsgerr *)NLMSG_DATA(h);
 
200
                                if ((size_t) l < sizeof(struct nlmsgerr)) {
 
201
                                        fprintf(stderr, "ERROR truncated\n");
 
202
                                } else {
 
203
                                        errno = -err->error;
 
204
                                        if (errno == 0)
 
205
                                                return 0;
 
206
 
 
207
                                        perror("RTNETLINK answers");
 
208
                                }
 
209
                                return -1;
 
210
                        }
 
211
                        status -= NLMSG_ALIGN(len);
 
212
                        h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len));
 
213
                }
 
214
        }
 
215
 
 
216
        return 0;
 
217
}
 
218
 
 
219
/**
 
220
 * @ingroup intern
 
221
 * @brief send_dump_request - send a dump linkinfo request
 
222
 *
 
223
 * @param fd decriptor to a priorly opened netlink socket
 
224
 * @param family rt_gen message family
 
225
 * @param type netlink message header type
 
226
 *
 
227
 * @return 0 if success
 
228
 * @return negativ if failed
 
229
 */
 
230
static int send_dump_request(int fd, int family, int type)
 
231
{
 
232
        struct get_req req;
 
233
 
 
234
        memset(&req, 0, sizeof(req));
 
235
 
 
236
        req.n.nlmsg_len = sizeof(req);
 
237
        req.n.nlmsg_type = type;
 
238
        req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
 
239
        req.n.nlmsg_pid = 0;
 
240
        req.n.nlmsg_seq = 0;
 
241
 
 
242
        req.g.rtgen_family = family;
 
243
 
 
244
        return send(fd, (void *)&req, sizeof(req), 0);
 
245
}
 
246
 
 
247
/**
 
248
 * @ingroup intern
 
249
 * @brief open_nl_sock - open a netlink socket
 
250
 *
 
251
 * opens a netlink socket and returns the socket descriptor
 
252
 *
 
253
 * @return 0 if success
 
254
 * @return negativ if failed
 
255
 */
 
256
static int open_nl_sock()
 
257
{
 
258
        int fd;
 
259
        int sndbuf = 32768;
 
260
        int rcvbuf = 32768;
 
261
        unsigned int addr_len;
 
262
        struct sockaddr_nl local;
 
263
 
 
264
        fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 
265
        if (fd < 0) {
 
266
                perror("Cannot open netlink socket");
 
267
                return -1;
 
268
        }
 
269
 
 
270
        setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, sizeof(sndbuf));
 
271
 
 
272
        setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, sizeof(rcvbuf));
 
273
 
 
274
        memset(&local, 0, sizeof(local));
 
275
        local.nl_family = AF_NETLINK;
 
276
        local.nl_groups = 0;
 
277
 
 
278
        if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) {
 
279
                perror("Cannot bind netlink socket");
 
280
                return -1;
 
281
        }
 
282
 
 
283
        addr_len = sizeof(local);
 
284
        if (getsockname(fd, (struct sockaddr *)&local, &addr_len) < 0) {
 
285
                perror("Cannot getsockname");
 
286
                return -1;
 
287
        }
 
288
        if (addr_len != sizeof(local)) {
 
289
                fprintf(stderr, "Wrong address length %u\n", addr_len);
 
290
                return -1;
 
291
        }
 
292
        if (local.nl_family != AF_NETLINK) {
 
293
                fprintf(stderr, "Wrong address family %d\n", local.nl_family);
 
294
                return -1;
 
295
        }
 
296
        return fd;
 
297
}
 
298
 
 
299
/**
 
300
 * @ingroup intern
 
301
 * @brief do_get_nl_link - get linkinfo
 
302
 *
 
303
 * @param fd socket file descriptor to a priorly opened netlink socket
 
304
 * @param acquire  which parameter we want to get
 
305
 * @param name name of the can device. This is the netdev name, as ifconfig -a
 
306
 * shows in your system. usually it contains prefix "can" and the numer of the
 
307
 * can line. e.g. "can0"
 
308
 * @param res pointer to store the result
 
309
 *
 
310
 * This callback send a dump request into the netlink layer, collect the packet
 
311
 * containing the linkinfo and fill the pointer res points to depending on the
 
312
 * acquire mode set in param acquire.
 
313
 *
 
314
 * @return 0 if success
 
315
 * @return -1 if failed
 
316
 */
 
317
 
 
318
static int do_get_nl_link(int fd, __u8 acquire, const char *name, void *res)
 
319
{
 
320
        struct sockaddr_nl peer;
 
321
 
 
322
        char cbuf[64];
 
323
        char nlbuf[1024 * 8];
 
324
 
 
325
        int ret = -1;
 
326
        int done = 0;
 
327
 
 
328
        struct iovec iov = {
 
329
                .iov_base = (void *)nlbuf,
 
330
                .iov_len = sizeof(nlbuf),
 
331
        };
 
332
 
 
333
        struct msghdr msg = {
 
334
                .msg_name = (void *)&peer,
 
335
                .msg_namelen = sizeof(peer),
 
336
                .msg_iov = &iov,
 
337
                .msg_iovlen = 1,
 
338
                .msg_control = &cbuf,
 
339
                .msg_controllen = sizeof(cbuf),
 
340
                .msg_flags = 0,
 
341
        };
 
342
        struct nlmsghdr *nl_msg;
 
343
        ssize_t msglen;
 
344
 
 
345
        struct rtattr *linkinfo[IFLA_INFO_MAX + 1];
 
346
        struct rtattr *can_attr[IFLA_CAN_MAX + 1];
 
347
 
 
348
        if (send_dump_request(fd, AF_PACKET, RTM_GETLINK) < 0) {
 
349
                perror("Cannot send dump request");
 
350
                return ret;
 
351
        }
 
352
 
 
353
        while (!done && (msglen = recvmsg(fd, &msg, 0)) > 0) {
 
354
                size_t u_msglen = (size_t) msglen;
 
355
                /* Check to see if the buffers in msg get truncated */
 
356
                if (msg.msg_namelen != sizeof(peer) ||
 
357
                    (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
 
358
                        fprintf(stderr, "Uhoh... truncated message.\n");
 
359
                        return -1;
 
360
                }
 
361
 
 
362
                for (nl_msg = (struct nlmsghdr *)nlbuf;
 
363
                     NLMSG_OK(nl_msg, u_msglen);
 
364
                     nl_msg = NLMSG_NEXT(nl_msg, u_msglen)) {
 
365
                        int type = nl_msg->nlmsg_type;
 
366
                        int len;
 
367
 
 
368
                        if (type == NLMSG_DONE) {
 
369
                                done++;
 
370
                                continue;
 
371
                        }
 
372
                        if (type != RTM_NEWLINK)
 
373
                                continue;
 
374
 
 
375
                        struct ifinfomsg *ifi = NLMSG_DATA(nl_msg);
 
376
                        struct rtattr *tb[IFLA_MAX + 1];
 
377
 
 
378
                        len =
 
379
                                nl_msg->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
 
380
                        parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 
381
 
 
382
                        if (strcmp
 
383
                            ((char *)RTA_DATA(tb[IFLA_IFNAME]), name) != 0)
 
384
                                continue;
 
385
 
 
386
                        if (tb[IFLA_LINKINFO])
 
387
                                parse_rtattr_nested(linkinfo,
 
388
                                                    IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
 
389
                        else
 
390
                                continue;
 
391
 
 
392
                        if (acquire == GET_XSTATS) {
 
393
                                if (!linkinfo[IFLA_INFO_XSTATS])
 
394
                                        fprintf(stderr, "no can statistics found\n");
 
395
                                else {
 
396
                                        memcpy(res, RTA_DATA(linkinfo[IFLA_INFO_XSTATS]),
 
397
                                               sizeof(struct can_device_stats));
 
398
                                        ret = 0;
 
399
                                }
 
400
                                continue;
 
401
                        }
 
402
 
 
403
                        if (!linkinfo[IFLA_INFO_DATA]) {
 
404
                                fprintf(stderr, "no link data found\n");
 
405
                                return ret;
 
406
                        }
 
407
 
 
408
                        parse_rtattr_nested(can_attr, IFLA_CAN_MAX,
 
409
                                            linkinfo[IFLA_INFO_DATA]);
 
410
 
 
411
                        switch (acquire) {
 
412
                        case GET_STATE:
 
413
                                if (can_attr[IFLA_CAN_STATE]) {
 
414
                                        *((int *)res) = *((__u32 *)
 
415
                                                          RTA_DATA(can_attr
 
416
                                                                   [IFLA_CAN_STATE]));
 
417
                                        ret = 0;
 
418
                                } else {
 
419
                                        fprintf(stderr, "no state data found\n");
 
420
                                }
 
421
 
 
422
                                break;
 
423
                        case GET_RESTART_MS:
 
424
                                if (can_attr[IFLA_CAN_RESTART_MS]) {
 
425
                                        *((__u32 *) res) = *((__u32 *)
 
426
                                                             RTA_DATA(can_attr
 
427
                                                                      [IFLA_CAN_RESTART_MS]));
 
428
                                        ret = 0;
 
429
                                } else
 
430
                                        fprintf(stderr, "no restart_ms data found\n");
 
431
 
 
432
                                break;
 
433
                        case GET_BITTIMING:
 
434
                                if (can_attr[IFLA_CAN_BITTIMING]) {
 
435
                                        memcpy(res,
 
436
                                               RTA_DATA(can_attr[IFLA_CAN_BITTIMING]),
 
437
                                               sizeof(struct can_bittiming));
 
438
                                        ret = 0;
 
439
                                } else
 
440
                                        fprintf(stderr, "no bittiming data found\n");
 
441
 
 
442
                                break;
 
443
                        case GET_CTRLMODE:
 
444
                                if (can_attr[IFLA_CAN_CTRLMODE]) {
 
445
                                        memcpy(res,
 
446
                                               RTA_DATA(can_attr[IFLA_CAN_CTRLMODE]),
 
447
                                               sizeof(struct can_ctrlmode));
 
448
                                        ret = 0;
 
449
                                } else
 
450
                                        fprintf(stderr, "no ctrlmode data found\n");
 
451
 
 
452
                                break;
 
453
                        case GET_CLOCK:
 
454
                                if (can_attr[IFLA_CAN_CLOCK]) {
 
455
                                        memcpy(res,
 
456
                                               RTA_DATA(can_attr[IFLA_CAN_CLOCK]),
 
457
                                               sizeof(struct can_clock));
 
458
                                        ret = 0;
 
459
                                } else
 
460
                                        fprintf(stderr,
 
461
                                                "no clock parameter data found\n");
 
462
 
 
463
                                break;
 
464
                        case GET_BITTIMING_CONST:
 
465
                                if (can_attr[IFLA_CAN_BITTIMING_CONST]) {
 
466
                                        memcpy(res,
 
467
                                               RTA_DATA(can_attr[IFLA_CAN_BITTIMING_CONST]),
 
468
                                               sizeof(struct can_bittiming_const));
 
469
                                        ret = 0;
 
470
                                } else
 
471
                                        fprintf(stderr, "no bittiming_const data found\n");
 
472
 
 
473
                                break;
 
474
                        case GET_BERR_COUNTER:
 
475
                                if (can_attr[IFLA_CAN_BERR_COUNTER]) {
 
476
                                        memcpy(res,
 
477
                                               RTA_DATA(can_attr[IFLA_CAN_BERR_COUNTER]),
 
478
                                               sizeof(struct can_berr_counter));
 
479
                                        ret = 0;
 
480
                                } else
 
481
                                        fprintf(stderr, "no berr_counter data found\n");
 
482
 
 
483
                                break;
 
484
 
 
485
                        default:
 
486
                                fprintf(stderr, "unknown acquire mode\n");
 
487
                        }
 
488
                }
 
489
        }
 
490
 
 
491
        return ret;
 
492
}
 
493
 
 
494
/**
 
495
 * @ingroup intern
 
496
 * @brief get_link - get linkinfo
 
497
 *
 
498
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
499
 * in your system. usually it contains prefix "can" and the numer of the can
 
500
 * line. e.g. "can0"
 
501
 * @param acquire which parameter we want to get
 
502
 * @param res pointer to store the result
 
503
 *
 
504
 * This is a wrapper for do_get_nl_link
 
505
 *
 
506
 * @return 0 if success
 
507
 * @return -1 if failed
 
508
 */
 
509
static int get_link(const char *name, __u8 acquire, void *res)
 
510
{
 
511
        int err, fd;
 
512
 
 
513
        fd = open_nl_sock();
 
514
        if (fd < 0)
 
515
                return -1;
 
516
 
 
517
        err = do_get_nl_link(fd, acquire, name, res);
 
518
        close(fd);
 
519
 
 
520
        return err;
 
521
 
 
522
}
 
523
 
 
524
/**
 
525
 * @ingroup intern
 
526
 * @brief do_set_nl_link - setup linkinfo
 
527
 *
 
528
 * @param fd socket file descriptor to a priorly opened netlink socket
 
529
 * @param if_state state of the interface we want to put the device into. this
 
530
 * parameter is only set if you want to use the callback to driver up/down the
 
531
 * device
 
532
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
533
 * in your system. usually it contains prefix "can" and the numer of the can
 
534
 * line. e.g. "can0"
 
535
 * @param req_info request parameters
 
536
 *
 
537
 * This callback can do two different tasks:
 
538
 * - bring up/down the interface
 
539
 * - set up a netlink packet with request, as set up in req_info
 
540
 * Which task this callback will do depends on which parameters are set.
 
541
 *
 
542
 * @return 0 if success
 
543
 * @return -1 if failed
 
544
 */
 
545
static int do_set_nl_link(int fd, __u8 if_state, const char *name,
 
546
                          struct req_info *req_info)
 
547
{
 
548
        struct set_req req;
 
549
 
 
550
        const char *type = "can";
 
551
 
 
552
        memset(&req, 0, sizeof(req));
 
553
 
 
554
        req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
 
555
        req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 
556
        req.n.nlmsg_type = RTM_NEWLINK;
 
557
        req.i.ifi_family = 0;
 
558
 
 
559
        req.i.ifi_index = if_nametoindex(name);
 
560
        if (req.i.ifi_index == 0) {
 
561
                fprintf(stderr, "Cannot find device \"%s\"\n", name);
 
562
                return -1;
 
563
        }
 
564
 
 
565
        if (if_state) {
 
566
                switch (if_state) {
 
567
                case IF_DOWN:
 
568
                        req.i.ifi_change |= IFF_UP;
 
569
                        req.i.ifi_flags &= ~IFF_UP;
 
570
                        break;
 
571
                case IF_UP:
 
572
                        req.i.ifi_change |= IFF_UP;
 
573
                        req.i.ifi_flags |= IFF_UP;
 
574
                        break;
 
575
                default:
 
576
                        fprintf(stderr, "unknown state\n");
 
577
                        return -1;
 
578
                }
 
579
        }
 
580
 
 
581
        if (req_info != NULL) {
 
582
                /* setup linkinfo section */
 
583
                struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
 
584
                addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
 
585
                addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type,
 
586
                          strlen(type));
 
587
                /* setup data section */
 
588
                struct rtattr *data = NLMSG_TAIL(&req.n);
 
589
                addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0);
 
590
 
 
591
                if (req_info->restart_ms > 0 || req_info->disable_autorestart)
 
592
                        addattr32(&req.n, 1024, IFLA_CAN_RESTART_MS,
 
593
                                  req_info->restart_ms);
 
594
 
 
595
                if (req_info->restart)
 
596
                        addattr32(&req.n, 1024, IFLA_CAN_RESTART, 1);
 
597
 
 
598
                if (req_info->bittiming != NULL) {
 
599
                        addattr_l(&req.n, 1024, IFLA_CAN_BITTIMING,
 
600
                                  req_info->bittiming,
 
601
                                  sizeof(struct can_bittiming));
 
602
                }
 
603
 
 
604
                if (req_info->ctrlmode != NULL) {
 
605
                        addattr_l(&req.n, 1024, IFLA_CAN_CTRLMODE,
 
606
                                  req_info->ctrlmode,
 
607
                                  sizeof(struct can_ctrlmode));
 
608
                }
 
609
 
 
610
                /* mark end of data section */
 
611
                data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;
 
612
 
 
613
                /* mark end of link info section */
 
614
                linkinfo->rta_len =
 
615
                    (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
 
616
        }
 
617
 
 
618
        return send_mod_request(fd, &req.n);
 
619
}
 
620
 
 
621
/**
 
622
 * @ingroup intern
 
623
 * @brief set_link - open a netlink socket and setup linkinfo
 
624
 *
 
625
 * @param name name of the can device. This is the netdev name, as ifconfig -a
 
626
 * shows in your system. usually it contains prefix "can" and the numer of the
 
627
 * can line. e.g. "can0"
 
628
 * @param if_state state of the interface we want to put the device into. this
 
629
 * parameter is only set if you want to use the callback to driver up/down the
 
630
 * device
 
631
 * @param req_info request parameters
 
632
 *
 
633
 * This is a wrapper for do_set_nl_link. It opens a netlink socket and sends
 
634
 * down the requests.
 
635
 *
 
636
 * @return 0 if success
 
637
 * @return -1 if failed
 
638
 */
 
639
static int set_link(const char *name, __u8 if_state, struct req_info *req_info)
 
640
{
 
641
        int err, fd;
 
642
 
 
643
        fd = open_nl_sock();
 
644
        if (fd < 0)
 
645
                return -1;
 
646
 
 
647
        err = do_set_nl_link(fd, if_state, name, req_info);
 
648
        close(fd);
 
649
 
 
650
        return err;
 
651
}
 
652
 
 
653
/**
 
654
 * @ingroup extern
 
655
 * can_do_start - start the can interface
 
656
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
657
 * in your system. usually it contains prefix "can" and the numer of the can
 
658
 * line. e.g. "can0"
 
659
 *
 
660
 * This starts the can interface with the given name. It simply changes the if
 
661
 * state of the interface to up. All initialisation works will be done in
 
662
 * kernel. The if state can also be queried by a simple ifconfig.
 
663
 *
 
664
 * @return 0 if success
 
665
 * @return -1 if failed
 
666
 */
 
667
int can_do_start(const char *name)
 
668
{
 
669
        return set_link(name, IF_UP, NULL);
 
670
}
 
671
 
 
672
/**
 
673
 * @ingroup extern
 
674
 * can_do_stop - stop the can interface
 
675
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
676
 * in your system. usually it contains prefix "can" and the numer of the can
 
677
 * line. e.g. "can0"
 
678
 *
 
679
 * This stops the can interface with the given name. It simply changes the if
 
680
 * state of the interface to down. Any running communication would be stopped.
 
681
 *
 
682
 * @return 0 if success
 
683
 * @return -1 if failed
 
684
 */
 
685
int can_do_stop(const char *name)
 
686
{
 
687
        return set_link(name, IF_DOWN, NULL);
 
688
}
 
689
 
 
690
/**
 
691
 * @ingroup extern
 
692
 * can_do_restart - restart the can interface
 
693
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
694
 * in your system. usually it contains prefix "can" and the numer of the can
 
695
 * line. e.g. "can0"
 
696
 *
 
697
 * This triggers the start mode of the can device.
 
698
 *
 
699
 * NOTE:
 
700
 * - restart mode can only be triggerd if the device is in BUS_OFF and the auto
 
701
 * restart not turned on (restart_ms == 0)
 
702
 *
 
703
 * @return 0 if success
 
704
 * @return -1 if failed
 
705
 */
 
706
int can_do_restart(const char *name)
 
707
{
 
708
        int state;
 
709
        __u32 restart_ms;
 
710
 
 
711
        /* first we check if we can restart the device at all */
 
712
        if ((can_get_state(name, &state)) < 0) {
 
713
                fprintf(stderr, "cannot get bustate, "
 
714
                        "something is seriously wrong\n");
 
715
                return -1;
 
716
        } else if (state != CAN_STATE_BUS_OFF) {
 
717
                fprintf(stderr,
 
718
                        "Device is not in BUS_OFF," " no use to restart\n");
 
719
                return -1;
 
720
        }
 
721
 
 
722
        if ((can_get_restart_ms(name, &restart_ms)) < 0) {
 
723
                fprintf(stderr, "cannot get restart_ms, "
 
724
                        "something is seriously wrong\n");
 
725
                return -1;
 
726
        } else if (restart_ms > 0) {
 
727
                fprintf(stderr,
 
728
                        "auto restart with %ums interval is turned on,"
 
729
                        " no use to restart\n", restart_ms);
 
730
                return -1;
 
731
        }
 
732
 
 
733
        struct req_info req_info = {
 
734
                .restart = 1,
 
735
        };
 
736
 
 
737
        return set_link(name, 0, &req_info);
 
738
}
 
739
 
 
740
/**
 
741
 * @ingroup extern
 
742
 * can_set_restart_ms - set interval of auto restart.
 
743
 *
 
744
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
745
 * in your system. usually it contains prefix "can" and the numer of the can
 
746
 * line. e.g. "can0"
 
747
 * @param restart_ms interval of auto restart in milliseconds
 
748
 *
 
749
 * This sets how often the device shall automatically restart the interface in
 
750
 * case that a bus_off is detected.
 
751
 *
 
752
 * @return 0 if success
 
753
 * @return -1 if failed
 
754
 */
 
755
int can_set_restart_ms(const char *name, __u32 restart_ms)
 
756
{
 
757
        struct req_info req_info = {
 
758
                .restart_ms = restart_ms,
 
759
        };
 
760
 
 
761
        if (restart_ms == 0)
 
762
                req_info.disable_autorestart = 1;
 
763
 
 
764
        return set_link(name, 0, &req_info);
 
765
}
 
766
 
 
767
/**
 
768
 * @ingroup extern
 
769
 * can_set_ctrlmode - setup the control mode.
 
770
 *
 
771
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
772
 * in your system. usually it contains prefix "can" and the numer of the can
 
773
 * line. e.g. "can0"
 
774
 *
 
775
 * @param cm pointer of a can_ctrlmode struct
 
776
 *
 
777
 * This sets the control mode of the can device. There're currently three
 
778
 * different control modes:
 
779
 * - LOOPBACK
 
780
 * - LISTEN_ONLY
 
781
 * - TRIPPLE_SAMPLING
 
782
 *
 
783
 * You have to define the control mode struct yourself. a can_ctrlmode struct
 
784
 * is declared as:
 
785
 *
 
786
 * @code
 
787
 * struct can_ctrlmode {
 
788
 *      __u32 mask;
 
789
 *      __u32 flags;
 
790
 * }
 
791
 * @endcode
 
792
 *
 
793
 * You can use mask to select modes you want to control and flags to determine
 
794
 * if you want to turn the selected mode(s) on or off. Every control mode is
 
795
 * mapped to an own macro
 
796
 *
 
797
 * @code
 
798
 * #define CAN_CTRLMODE_LOOPBACK   0x1
 
799
 * #define CAN_CTRLMODE_LISTENONLY 0x2
 
800
 * #define CAN_CTRLMODE_3_SAMPLES  0x4
 
801
 * @endcode
 
802
 *
 
803
 * e.g. the following pseudocode
 
804
 *
 
805
 * @code
 
806
 * struct can_ctrlmode cm;
 
807
 * memset(&cm, 0, sizeof(cm));
 
808
 * cm.mask = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
 
809
 * cm.flags = CAN_CTRLMODE_LOOPBACK;
 
810
 * can_set_ctrlmode(candev, &cm);
 
811
 * @endcode
 
812
 *
 
813
 * will turn the loopback mode on and listenonly mode off.
 
814
 *
 
815
 * @return 0 if success
 
816
 * @return -1 if failed
 
817
 */
 
818
 
 
819
int can_set_ctrlmode(const char *name, struct can_ctrlmode *cm)
 
820
{
 
821
        struct req_info req_info = {
 
822
                .ctrlmode = cm,
 
823
        };
 
824
 
 
825
        return set_link(name, 0, &req_info);
 
826
}
 
827
 
 
828
/**
 
829
 * @ingroup extern
 
830
 * can_set_bittiming - setup the bittiming.
 
831
 *
 
832
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
833
 * in your system. usually it contains prefix "can" and the numer of the can
 
834
 * line. e.g. "can0"
 
835
 * @param bt pointer to a can_bittiming struct
 
836
 *
 
837
 * This sets the bittiming of the can device. This is for advantage usage. In
 
838
 * normal cases you should use can_set_bitrate to simply define the bitrate and
 
839
 * let the driver automatically calculate the bittiming. You will only need this
 
840
 * function if you wish to define the bittiming in expert mode with fully
 
841
 * manually defined timing values.
 
842
 * You have to define the bittiming struct yourself. a can_bittiming struct
 
843
 * consists of:
 
844
 *
 
845
 * @code
 
846
 * struct can_bittiming {
 
847
 *      __u32 bitrate;
 
848
 *      __u32 sample_point;
 
849
 *      __u32 tq;
 
850
 *      __u32 prop_seg;
 
851
 *      __u32 phase_seg1;
 
852
 *      __u32 phase_seg2;
 
853
 *      __u32 sjw;
 
854
 *      __u32 brp;
 
855
 * }
 
856
 * @endcode
 
857
 *
 
858
 * to define a customized bittiming, you have to define tq, prop_seq,
 
859
 * phase_seg1, phase_seg2 and sjw. See http://www.can-cia.org/index.php?id=88
 
860
 * for more information about bittiming and synchronizations on can bus.
 
861
 *
 
862
 * @return 0 if success
 
863
 * @return -1 if failed
 
864
 */
 
865
 
 
866
int can_set_bittiming(const char *name, struct can_bittiming *bt)
 
867
{
 
868
        struct req_info req_info = {
 
869
                .bittiming = bt,
 
870
        };
 
871
 
 
872
        return set_link(name, 0, &req_info);
 
873
}
 
874
 
 
875
/**
 
876
 * @ingroup extern
 
877
 * can_set_bitrate - setup the bitrate.
 
878
 *
 
879
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
880
 * in your system. usually it contains prefix "can" and the numer of the can
 
881
 * line. e.g. "can0"
 
882
 * @param bitrate bitrate of the can bus
 
883
 *
 
884
 * This is the recommended way to setup the bus bit timing. You only have to
 
885
 * give a bitrate value here. The exact bit timing will be calculated
 
886
 * automatically. To use this function, make sure that CONFIG_CAN_CALC_BITTIMING
 
887
 * is set to y in your kernel configuration. bitrate can be a value between
 
888
 * 1000(1kbit/s) and 1000000(1000kbit/s).
 
889
 *
 
890
 * @return 0 if success
 
891
 * @return -1 if failed
 
892
 */
 
893
 
 
894
int can_set_bitrate(const char *name, __u32 bitrate)
 
895
{
 
896
        struct can_bittiming bt;
 
897
 
 
898
        memset(&bt, 0, sizeof(bt));
 
899
        bt.bitrate = bitrate;
 
900
 
 
901
        return can_set_bittiming(name, &bt);
 
902
}
 
903
 
 
904
/**
 
905
 * @ingroup extern
 
906
 * can_set_bitrate_samplepoint - setup the bitrate.
 
907
 *
 
908
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
909
 * in your system. usually it contains prefix "can" and the numer of the can
 
910
 * line. e.g. "can0"
 
911
 * @param bitrate bitrate of the can bus
 
912
 * @param sample_point sample point value
 
913
 *
 
914
 * This one is similar to can_set_bitrate, only you can additionally set up the
 
915
 * time point for sampling (sample point) customly instead of using the
 
916
 * CIA recommended value. sample_point can be a value between 0 and 999.
 
917
 *
 
918
 * @return 0 if success
 
919
 * @return -1 if failed
 
920
 */
 
921
int can_set_bitrate_samplepoint(const char *name, __u32 bitrate,
 
922
                                __u32 sample_point)
 
923
{
 
924
        struct can_bittiming bt;
 
925
 
 
926
        memset(&bt, 0, sizeof(bt));
 
927
        bt.bitrate = bitrate;
 
928
        bt.sample_point = sample_point;
 
929
 
 
930
        return can_set_bittiming(name, &bt);
 
931
}
 
932
 
 
933
/**
 
934
 * @ingroup extern
 
935
 * can_get_state - get the current state of the device
 
936
 *
 
937
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
938
 * in your system. usually it contains prefix "can" and the numer of the can
 
939
 * line. e.g. "can0"
 
940
 * @param state pointer to store the state
 
941
 *
 
942
 * This one stores the current state of the can interface into the given
 
943
 * pointer. Valid states are:
 
944
 * - CAN_STATE_ERROR_ACTIVE
 
945
 * - CAN_STATE_ERROR_WARNING
 
946
 * - CAN_STATE_ERROR_PASSIVE
 
947
 * - CAN_STATE_BUS_OFF
 
948
 * - CAN_STATE_STOPPED
 
949
 * - CAN_STATE_SLEEPING
 
950
 *
 
951
 * The first four states is determined by the value of RX/TX error counter.
 
952
 * Please see relevant can specification for more information about this. A
 
953
 * device in STATE_STOPPED is an inactive device. STATE_SLEEPING is not
 
954
 * implemented on all devices.
 
955
 *
 
956
 * @return 0 if success
 
957
 * @return -1 if failed
 
958
 */
 
959
 
 
960
int can_get_state(const char *name, int *state)
 
961
{
 
962
        return get_link(name, GET_STATE, state);
 
963
}
 
964
 
 
965
/**
 
966
 * @ingroup extern
 
967
 * can_get_restart_ms - get the current interval of auto restarting.
 
968
 *
 
969
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
970
 * in your system. usually it contains prefix "can" and the numer of the can
 
971
 * line. e.g. "can0"
 
972
 * @param restart_ms pointer to store the value.
 
973
 *
 
974
 * This one stores the current interval of auto restarting into the given
 
975
 * pointer.
 
976
 *
 
977
 * The socketcan framework can automatically restart a device if it is in
 
978
 * bus_off in a given interval. This function gets this value in milliseconds.
 
979
 * restart_ms == 0 means that autorestarting is turned off.
 
980
 *
 
981
 * @return 0 if success
 
982
 * @return -1 if failed
 
983
 */
 
984
 
 
985
int can_get_restart_ms(const char *name, __u32 *restart_ms)
 
986
{
 
987
        return get_link(name, GET_RESTART_MS, restart_ms);
 
988
}
 
989
 
 
990
/**
 
991
 * @ingroup extern
 
992
 * can_get_bittiming - get the current bittimnig configuration.
 
993
 *
 
994
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
995
 * in your system. usually it contains prefix "can" and the numer of the can
 
996
 * line. e.g. "can0"
 
997
 * @param bt pointer to the bittiming struct.
 
998
 *
 
999
 * This one stores the current bittiming configuration.
 
1000
 *
 
1001
 * Please see can_set_bittiming for more information about bit timing.
 
1002
 *
 
1003
 * @return 0 if success
 
1004
 * @return -1 if failed
 
1005
 */
 
1006
int can_get_bittiming(const char *name, struct can_bittiming *bt)
 
1007
{
 
1008
        return get_link(name, GET_BITTIMING, bt);
 
1009
}
 
1010
 
 
1011
/**
 
1012
 * @ingroup extern
 
1013
 * can_get_ctrlmode - get the current control mode.
 
1014
 *
 
1015
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
1016
 * in your system. usually it contains prefix "can" and the numer of the can
 
1017
 * line. e.g. "can0"
 
1018
 * @param cm pointer to the ctrlmode struct.
 
1019
 *
 
1020
 * This one stores the current control mode configuration.
 
1021
 *
 
1022
 * Please see can_set_ctrlmode for more information about control modes.
 
1023
 *
 
1024
 * @return 0 if success
 
1025
 * @return -1 if failed
 
1026
 */
 
1027
 
 
1028
int can_get_ctrlmode(const char *name, struct can_ctrlmode *cm)
 
1029
{
 
1030
        return get_link(name, GET_CTRLMODE, cm);
 
1031
}
 
1032
 
 
1033
/**
 
1034
 * @ingroup extern
 
1035
 * can_get_clock - get the current clock struct.
 
1036
 *
 
1037
 * @param name: name of the can device. This is the netdev name, as ifconfig -a shows
 
1038
 * in your system. usually it contains prefix "can" and the numer of the can
 
1039
 * line. e.g. "can0"
 
1040
 * @param clock pointer to the clock struct.
 
1041
 *
 
1042
 * This one stores the current clock configuration. At the time of writing the
 
1043
 * can_clock struct only contains information about the clock frequecy. This
 
1044
 * information is e.g. essential while setting up the bit timing.
 
1045
 *
 
1046
 * @return 0 if success
 
1047
 * @return -1 if failed
 
1048
 */
 
1049
int can_get_clock(const char *name, struct can_clock *clock)
 
1050
{
 
1051
        return get_link(name, GET_CLOCK, clock);
 
1052
}
 
1053
 
 
1054
/**
 
1055
 * @ingroup extern
 
1056
 * can_get_bittiming_const - get the current bittimnig constant.
 
1057
 *
 
1058
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
1059
 * in your system. usually it contains prefix "can" and the numer of the can
 
1060
 * line. e.g. "can0"
 
1061
 * @param btc pointer to the bittiming constant struct.
 
1062
 *
 
1063
 * This one stores the hardware dependent bittiming constant. The
 
1064
 * can_bittiming_const struct consists:
 
1065
 *
 
1066
 * @code
 
1067
 * struct can_bittiming_const {
 
1068
 *      char name[16];
 
1069
 *      __u32 tseg1_min;
 
1070
 *      __u32 tseg1_max;
 
1071
 *      __u32 tseg2_min;
 
1072
 *      __u32 tseg2_max;
 
1073
 *      __u32 sjw_max;
 
1074
 *      __u32 brp_min;
 
1075
 *      __u32 brp_max;
 
1076
 *      __u32 brp_inc;
 
1077
 *      };
 
1078
 * @endcode
 
1079
 *
 
1080
 * The information in this struct is used to calculate the bus bit timing
 
1081
 * automatically.
 
1082
 *
 
1083
 * @return 0 if success
 
1084
 * @return -1 if failed
 
1085
 */
 
1086
int can_get_bittiming_const(const char *name, struct can_bittiming_const *btc)
 
1087
{
 
1088
        return get_link(name, GET_BITTIMING_CONST, btc);
 
1089
}
 
1090
 
 
1091
 
 
1092
/**
 
1093
 * @ingroup extern
 
1094
 * can_get_berr_counter - get the tx/rx error counter.
 
1095
 *
 
1096
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
1097
 * in your system. usually it contains prefix "can" and the numer of the can
 
1098
 * line. e.g. "can0"
 
1099
 * @param bc pointer to the error counter struct..
 
1100
 *
 
1101
 * This one gets the current rx/tx error counter from the hardware.
 
1102
 *
 
1103
 * @code
 
1104
 * struct can_berr_counter {
 
1105
 *      __u16 txerr;
 
1106
 *      __u16 rxerr;
 
1107
 *      };
 
1108
 * @endcode
 
1109
 *
 
1110
 * @return 0 if success
 
1111
 * @return -1 if failed
 
1112
 */
 
1113
int can_get_berr_counter(const char *name, struct can_berr_counter *bc)
 
1114
{
 
1115
        return get_link(name, GET_BERR_COUNTER, bc);
 
1116
}
 
1117
 
 
1118
/**
 
1119
 * @ingroup extern
 
1120
 * can_get_device_stats - get the can_device_stats.
 
1121
 *
 
1122
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 
1123
 * in your system. usually it contains prefix "can" and the numer of the can
 
1124
 * line. e.g. "can0"
 
1125
 * @param bc pointer to the error counter struct..
 
1126
 *
 
1127
 * This one gets the current can_device_stats.
 
1128
 *
 
1129
 * Please see struct can_device_stats for more information.
 
1130
 *
 
1131
 * @return 0 if success
 
1132
 * @return -1 if failed
 
1133
 */
 
1134
int can_get_device_stats(const char *name, struct can_device_stats *cds)
 
1135
{
 
1136
        return get_link(name, GET_XSTATS, cds);
 
1137
}