2 * Copyright (C) 2015, 2016 "IoT.bzh"
3 * Author "Romain Forlot" <romain.forlot@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 /********************************************************************************
22 * CanBus method implementation
24 *********************************************************************************/
28 const int canfd_on = 1;
30 struct timeval timeout = {1, 0};
32 DEBUG(interface, "open_can_dev: CAN Handler socket : %d", socket);
36 socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
39 ERROR(interface, "open_can_dev: socket could not be created");
43 /* Set timeout for read */
44 setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
45 /* try to switch the socket into CAN_FD mode */
46 if (setsockopt(socket, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on)) < 0)
48 NOTICE(interface, "open_can_dev: Can not switch into CAN Extended frame format.");
54 /* Attempts to open a socket to CAN bus */
55 strcpy(ifr.ifr_name, device);
56 if(ioctl(socket, SIOCGIFINDEX, &ifr) < 0)
57 ERROR(interface, "open_can_dev: ioctl failed");
60 txAddress.can_family = AF_CAN;
61 txAddress.can_ifindex = ifr.ifr_ifindex;
63 /* And bind it to txAddress */
64 if (bind(socket, (struct sockaddr *)&txAddress, sizeof(txAddress)) < 0)
66 ERROR(interface, "open_can_dev: bind failed");
70 fcntl(socket, F_SETFL, O_NONBLOCK);
86 void CanBus_c::start_threads()
88 std::queue <CanMessage_t> can_message_q;
90 th_reading = std::thread(can_reader, interface, socket, can_message_q);
91 th_decoding = std::thread(can_decoder, interface, can_message_q, can_message_queue);
92 th_pushing = std::thread(can_event_push, interface, can_message_queue);
95 /********************************************************************************
97 * CanMessage method implementation
99 *********************************************************************************/
101 uint32_t CanMessage_c::get_id()
106 int CanMessage_c::get_format()
111 uint8_t CanMessage_c::get_data()
115 uint8_t CanMessage_c::get_lenght()
120 void CanMessage_c::set_id(uint32_t new_id)
124 id = new_id & CAN_SFF_MASK;
126 id = new_id & CAN_EFF_MASK;
128 ERROR(interface, "ERROR: Can set id, not a compatible format or format not set prior to set id.");
131 void CanMessage_c::set_format(CanMessageFormat new_format)
133 if(new_format == SIMPLE || new_format == EXTENDED)
136 ERROR(interface, "ERROR: Can set format, wrong format chosen");
139 void CanMessage_c::set_data(uint8_t new_data)
144 void CanMessage_c::set_lenght(uint8_t new_length)
150 * This is the prefered way to initialize a CanMessage object
151 * from a read canfd_frame message.
153 * params: canfd_frame pointer
155 void CanMessage_c::convert_canfd_frame_to_CanMessage(canfd_frame *frame)
158 lenght = (canfd_frame->len > maxdlen) ? maxdlen : canfd_frame->len;
160 switch (canfd_frame->can_id):
161 case (canfd_frame->can_id & CAN_ERR_FLAG):
162 id = canfd_frame->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG);
164 case (canfd_frame->can_id & CAN_EFF_FLAG):
165 id = canfd_frame->can_id & CAN_EFF_MASK;
170 id = canfd_frame->can_id & CAN_SFF_MASK;
173 if (sizeof(canfd_frame->data) <= sizeof(data))
175 for (i = 0; i < lenght; i++)
176 can_message->data.bytes[i] = canfd_frame->data[i];
178 } else if (sizeof(canfd_frame->data) >= CAN_MAX_DLEN)
179 ERROR(interface, "CanMessage_c: canfd_frame data too long to be stored into CanMessage object");