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.
18 #include "can-message.hpp"
22 #include "low-can-binding.hpp"
24 /********************************************************************************
26 * CanMessage method implementation
28 *********************************************************************************/
30 can_message_t::can_message_t()
31 : id_{0}, rtr_flag_{false}, length_{0}, flags_{0}, format_{CanMessageFormat::ERROR}
34 uint32_t can_message_t::get_id() const
39 bool can_message_t::get_rtr_flag_() const
44 int can_message_t::get_format() const
46 if (format_ != CanMessageFormat::STANDARD || format_ != CanMessageFormat::EXTENDED)
47 return CanMessageFormat::ERROR;
51 uint8_t can_message_t::get_flags() const
56 const uint8_t* can_message_t::get_data() const
61 uint8_t can_message_t::get_length() const
66 void can_message_t::set_max_data_length(const struct canfd_frame& frame)
73 DEBUG(binder_interface, "convert_from_canfd_frame: Got an CAN FD frame with length %d and flags %d", frame.len, frame.flags);
74 maxdlen_ = CANFD_MAX_DLEN;
77 DEBUG(binder_interface, "convert_from_canfd_frame: Got a legacy CAN frame with length %d", frame.len);
78 maxdlen_ = CAN_MAX_DLEN;
81 ERROR(binder_interface, "convert_from_canfd_frame: unsupported CAN frame");
86 bool can_message_t::is_correct_to_send()
88 if (id_ != 0 && length_ != 0 && format_ != CanMessageFormat::ERROR)
91 for(i=0;i<CAN_MESSAGE_SIZE;i++)
98 void can_message_t::set_id_and_format(const uint32_t new_id)
103 case CanMessageFormat::STANDARD:
104 id_ = new_id & CAN_SFF_MASK;
106 case CanMessageFormat::EXTENDED:
107 id_ = new_id & CAN_EFF_MASK;
109 case CanMessageFormat::ERROR:
110 id_ = new_id & (CAN_ERR_MASK|CAN_ERR_FLAG);
113 ERROR(binder_interface, "ERROR: Can set id, not a compatible format or format not set prior to set id.");
118 void can_message_t::set_format(const CanMessageFormat new_format)
120 if(new_format == CanMessageFormat::STANDARD || new_format == CanMessageFormat::EXTENDED || new_format == CanMessageFormat::ERROR)
121 format_ = new_format;
123 ERROR(binder_interface, "ERROR: Can set format, wrong format chosen");
126 void can_message_t::set_format(const uint32_t can_id)
128 if (can_id & CAN_ERR_FLAG)
129 format_ = CanMessageFormat::ERROR;
130 else if (can_id & CAN_EFF_FLAG)
131 format_ = CanMessageFormat::EXTENDED;
133 format_ = CanMessageFormat::STANDARD;
136 void can_message_t::set_flags(const uint8_t flags)
138 flags_ = flags & 0xF;
141 void can_message_t::set_length(const uint8_t new_length)
144 length_ = new_length & 0xF;
147 length_ = (new_length > maxdlen_) ? maxdlen_ : new_length;
151 void can_message_t::set_data(const __u8 new_data[], size_t dlen)
154 ERROR(binder_interface, "Can set data, too big ! It is a CAN frame ?");
158 /* Limiting to 8 bytes message for now, even on 64 bytes from fd frames*/
159 for(i=0;i<CAN_MESSAGE_SIZE;i++)
161 data_.push_back(new_data[i]);
166 void can_message_t::convert_from_canfd_frame(const struct canfd_frame& frame)
168 set_max_data_length(frame);
169 set_length(frame.len);
170 set_id_and_format(frame.can_id);
172 /* standard CAN frames may have RTR enabled. There are no ERR frames with RTR */
173 if (frame.can_id & CAN_RTR_FLAG)
176 if(frame.len && frame.len <= CAN_MAX_DLC)
177 set_length(frame.len);
181 /* Flags field only present for CAN FD frames*/
182 if(maxdlen_ == CANFD_MAX_DLEN)
183 set_flags(frame.flags);
185 size_t dlen = sizeof(frame.data)/sizeof(__u8);
187 set_data(frame.data, dlen);
189 DEBUG(binder_interface, "convert_from_canfd_frame: Found id: %X, format: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", id_, format_, length_,
190 data_[0], data_[1], data_[2], data_[3], data_[4], data_[5], data_[6], data_[7]);
193 canfd_frame can_message_t::convert_to_canfd_frame()
197 if(is_correct_to_send())
199 frame.can_id = get_id();
200 frame.len = get_length();
201 ::memcpy(frame.data, get_data(), length_);
204 ERROR(binder_interface, "can_message_t not correctly initialized to be sent");