X-Git-Url: http://rtime.felk.cvut.cz/gitweb/linux-lin.git/blobdiff_plain/846aa974f9fe779e4260a0927e977a63c55bace1..5d7ddb29cf05cc4c6c49460bdc12b28d71c7b168:/lin_config/src/sllin_config.c?ds=sidebyside diff --git a/lin_config/src/sllin_config.c b/lin_config/src/sllin_config.c index 06751c5..c4b4084 100644 --- a/lin_config/src/sllin_config.c +++ b/lin_config/src/sllin_config.c @@ -2,7 +2,8 @@ #include #include #include -#include +//#include +#include #include #include #include @@ -11,10 +12,16 @@ #include #include +#include +#include +#include +#include + #include #include #include "lin_config.h" +#include "linux/lin_bus.h" #define SLLIN_LDISC 25 struct bcm_msg { @@ -34,10 +41,109 @@ void sllin_ms_to_timeval(int ms, struct timeval *tv) tv->tv_usec = (ms % 1000) * 1000; } +int sllin_interface_up(struct linc_lin_state *linc_lin_state, + struct sllin_connection *sllin_connection) +{ + struct nl_sock *s; + struct rtnl_link *request; + struct nl_cache *cache; + struct rtnl_link *link; + int ret; + + // Allocate and initialize a new netlink socket + s = nl_socket_alloc(); + + // Bind and connect the socket to a protocol, NETLINK_ROUTE in this example. + nl_connect(s, NETLINK_ROUTE); + + // The first step is to retrieve a list of all available interfaces within + // the kernel and put them into a cache. + ret = rtnl_link_alloc_cache(s, AF_UNSPEC, &cache); + // FIXME errorhandling + + // In a second step, a specific link may be looked up by either interface + // index or interface name. + link = rtnl_link_get_by_name(cache, sllin_connection->iface); + + // In order to change any attributes of an existing link, we must allocate + // a new link to hold the change requests: + request = rtnl_link_alloc(); + + // We can also shut an interface down administratively + //rtnl_link_unset_flags(request, rtnl_link_str2flags("up")); + rtnl_link_set_flags(request, rtnl_link_str2flags("up")); + + // Two ways exist to commit this change request, the first one is to + // build the required netlink message and send it out in one single + // step: + rtnl_link_change(s, link, request, 0); + + // An alternative way is to build the netlink message and send it + // out yourself using nl_send_auto_complete() + // struct nl_msg *msg = rtnl_link_build_change_request(old, request); + // nl_send_auto_complete(nl_handle, nlmsg_hdr(msg)); + // nlmsg_free(msg); + + // After successful usage, the object must be given back to the cache + rtnl_link_put(link); + nl_socket_free(s); + + return 0; +} + int sllin_cache_config(struct linc_lin_state *linc_lin_state, struct sllin_connection *sllin_connection) { + int i; + struct ifreq ifr; + struct sockaddr_can addr; + struct can_frame frame; + int s; + int ret; + + /* Create the socket */ + s = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (s < 0) { + perror("socket()"); + return -1; + } + /* Locate the interface you wish to use */ + strcpy(ifr.ifr_name, sllin_connection->iface); + ioctl(s, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled + * with that device's index */ + + /* Select that CAN interface, and bind the socket to it. */ + addr.can_family = AF_CAN; + addr.can_ifindex = ifr.ifr_ifindex; + ret = bind(s, (struct sockaddr*)&addr, sizeof(addr)); + if (ret < 0) { + perror("bind()"); + return -1; + } + + for (i = 0; i < 0x3F; i++) { + frame.can_dlc = linc_lin_state->frame_entry[i].data_len; + frame.can_id = i; /* LIN ID */ + frame.data[0] = linc_lin_state->frame_entry[i].data[0]; /* Data */ + frame.data[1] = linc_lin_state->frame_entry[i].data[1]; /* Data */ + frame.data[2] = linc_lin_state->frame_entry[i].data[2]; /* Data */ + frame.data[3] = linc_lin_state->frame_entry[i].data[3]; /* Data */ + frame.data[4] = linc_lin_state->frame_entry[i].data[4]; /* Data */ + frame.data[5] = linc_lin_state->frame_entry[i].data[5]; /* Data */ + frame.data[6] = linc_lin_state->frame_entry[i].data[6]; /* Data */ + frame.data[7] = linc_lin_state->frame_entry[i].data[7]; /* Data */ + frame.can_id |= LIN_CTRL_FRAME; + if (linc_lin_state->frame_entry[i].status == 1) { /* Is active */ + frame.can_id |= LIN_CACHE_RESPONSE; + } + ret = write(s, &frame, sizeof(frame)); + printf("configuring frame cache; ret = %d\n", ret); + //if (ret ...) + //read_response(tty); + } + + close(s); return 0; } @@ -158,6 +264,10 @@ int sllin_config(struct linc_lin_state *linc_lin_state) if (ret < 0) return ret; + ret = sllin_interface_up(linc_lin_state, &sllin_connection); + if (ret < 0) + return ret; + ret = sllin_cache_config(linc_lin_state, &sllin_connection); /* !!! Do not close "tty" to enable newly