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
60 uint8_t can_message_t::get_length() const
65 void can_message_t::set_max_data_length(const struct canfd_frame& frame)
72 DEBUG(binder_interface, "convert_from_canfd_frame: Got an CAN FD frame with length %d and flags %d", frame.len, frame.flags);
73 maxdlen_ = CANFD_MAX_DLEN;
76 DEBUG(binder_interface, "convert_from_canfd_frame: Got a legacy CAN frame with length %d", frame.len);
77 maxdlen_ = CAN_MAX_DLEN;
80 ERROR(binder_interface, "convert_from_canfd_frame: unsupported CAN frame");
85 bool can_message_t::is_correct_to_send()
87 if (id_ != 0 && length_ != 0 && format_ != CanMessageFormat::ERROR)
90 for(i=0;i<CAN_MESSAGE_SIZE;i++)
97 void can_message_t::set_id_and_format(const uint32_t new_id)
102 case CanMessageFormat::STANDARD:
103 id_ = new_id & CAN_SFF_MASK;
105 case CanMessageFormat::EXTENDED:
106 id_ = new_id & CAN_EFF_MASK;
108 case CanMessageFormat::ERROR:
109 id_ = new_id & (CAN_ERR_MASK|CAN_ERR_FLAG);
112 ERROR(binder_interface, "ERROR: Can set id, not a compatible format or format not set prior to set id.");
117 void can_message_t::set_format(const CanMessageFormat new_format)
119 if(new_format == CanMessageFormat::STANDARD || new_format == CanMessageFormat::EXTENDED || new_format == CanMessageFormat::ERROR)
120 format_ = new_format;
122 ERROR(binder_interface, "ERROR: Can set format, wrong format chosen");
125 void can_message_t::set_format(const uint32_t can_id)
127 if (can_id & CAN_ERR_FLAG)
128 format_ = CanMessageFormat::ERROR;
129 else if (can_id & CAN_EFF_FLAG)
130 format_ = CanMessageFormat::EXTENDED;
132 format_ = CanMessageFormat::STANDARD;
135 void can_message_t::set_flags(const uint8_t flags)
137 flags_ = flags & 0xF;
140 void can_message_t::set_length(const uint8_t new_length)
143 length_ = new_length & 0xF;
146 length_ = (new_length > maxdlen_) ? maxdlen_ : new_length;
150 void can_message_t::set_data(const __u8 new_data[], size_t dlen)
152 if (sizeof(dlen)/sizeof(__u8) > maxdlen_)
153 ERROR(binder_interface, "Can set data, too big ! It is a CAN frame ?");
157 /* Limiting to 8 bytes message for now on 64 bytes from fd frames*/
158 for(i=0;i<CAN_MESSAGE_SIZE;i++)
160 data_[i] = new_data[i];
165 void can_message_t::convert_from_canfd_frame(const struct canfd_frame& frame)
167 set_max_data_length(frame);
168 set_length(frame.len);
169 set_id_and_format(frame.can_id);
171 /* standard CAN frames may have RTR enabled. There are no ERR frames with RTR */
172 if (frame.can_id & CAN_RTR_FLAG)
175 if(frame.len && frame.len <= CAN_MAX_DLC)
176 set_length(frame.len);
180 /* Flags field only present for CAN FD frames*/
181 if(maxdlen_ == CANFD_MAX_DLEN)
182 set_flags(frame.flags);
184 size_t dlen = sizeof(frame.data);
185 memset(data_, 0, dlen);
186 set_data(frame.data, dlen);
188 DEBUG(binder_interface, "convert_from_canfd_frame: Found id: %d, format: %d, length: %d, data %d%d%d%d%d%d%d%d", id_, format_, length_,
189 data_[0], data_[1], data_[2], data_[3], data_[4], data_[5], data_[6], data_[7]);
192 canfd_frame can_message_t::convert_to_canfd_frame()
196 if(is_correct_to_send())
198 frame.can_id = get_id();
199 frame.len = get_length();
200 ::memcpy(frame.data, get_data(), length_);
203 ERROR(binder_interface, "can_message_t not correctly initialized to be sent");