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(size_t nbytes)
73 DEBUG(binder_interface, "set_max_data_length: Got an CAN FD frame");
74 maxdlen_ = CANFD_MAX_DLEN;
77 DEBUG(binder_interface, "set_max_data_length: Got a legacy CAN frame");
78 maxdlen_ = CAN_MAX_DLEN;
81 ERROR(binder_interface, "set_max_data_length: 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)
156 /* maxdlen_ is now set at CAN_MAX_DLEN or CANFD_MAX_DLEN, respectively 8 and 64 bytes*/
157 for(i=0;i<maxdlen_;i++)
159 data_.push_back(new_data[i]);
163 void can_message_t::convert_from_canfd_frame(const std::pair<struct canfd_frame&, size_t>args)
165 // May be it's overkill to assign member of the pair... May be it will change...
166 struct canfd_frame frame = args.first;
167 size_t nbytes = args.second;
168 set_max_data_length(nbytes);
169 set_length(frame.len);
170 set_id_and_format(frame.can_id);
172 /* Overwrite lenght_ if RTR flags is detected.
173 * standard CAN frames may have RTR enabled. There are no ERR frames with RTR */
174 if (frame.can_id & CAN_RTR_FLAG)
177 if(frame.len && frame.len <= CAN_MAX_DLC)
178 set_length(frame.len);
182 /* Flags field only present for CAN FD frames*/
183 if(maxdlen_ == CANFD_MAX_DLEN)
184 set_flags(frame.flags);
186 if ( data_.capacity() < maxdlen_)
187 data_.reserve(maxdlen_);
188 set_data(frame.data);
190 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_,
191 data_[0], data_[1], data_[2], data_[3], data_[4], data_[5], data_[6], data_[7]);
194 canfd_frame can_message_t::convert_to_canfd_frame()
198 if(is_correct_to_send())
200 frame.can_id = get_id();
201 frame.len = get_length();
202 ::memcpy(frame.data, get_data(), length_);
205 ERROR(binder_interface, "can_message_t not correctly initialized to be sent");