Implement setting last_value at message definition level.
[apps/low-level-can-service.git] / CAN-binder / low-can-binding / can / can-signals.cpp
1 /*
2  * Copyright (C) 2015, 2016 "IoT.bzh"
3  * Author "Romain Forlot" <romain.forlot@iot.bzh>
4  *
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
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 #include <fnmatch.h>
19
20 #include "can-signals.hpp"
21
22 #include "../binding/configuration.hpp"
23 #include "../utils/signals.hpp"
24 #include "can-decoder.hpp"
25 #include "can-message.hpp"
26 #include "can-bus.hpp"
27 #include "../diagnostic/diagnostic-message.hpp"
28 #include "canutil/write.h"
29
30 std::string can_signal_t::prefix_ = "messages";
31
32 can_signal_t::can_signal_t(std::uint8_t message_set_id,
33         std::uint8_t message_id,
34         std::string generic_name,
35         uint8_t bit_position,
36         uint8_t bit_size,
37         float factor,
38         float offset,
39         float min_value,
40         float max_value,
41         frequency_clock_t frequency,
42         bool send_same,
43         bool force_send_changed,
44         std::map<uint8_t, std::string> states,
45         bool writable,
46         SignalDecoder decoder,
47         SignalEncoder encoder,
48         bool received)
49         : message_set_id_{ message_set_id }
50         , message_id_{ message_id }
51         , generic_name_{ generic_name }
52         , bit_position_{ bit_position }
53         , bit_size_{ bit_size }
54         , factor_{ factor }
55         , offset_{ offset }
56         , min_value_{min_value}
57         , max_value_{max_value}
58         , frequency_{frequency}
59         , send_same_{send_same}
60         , force_send_changed_{force_send_changed}
61         , states_{states}
62         , writable_{writable}
63         , decoder_{decoder}
64         , encoder_{encoder}
65         , received_{received}
66         , last_value_{.0f}
67 {}
68
69 utils::socketcan_bcm_t can_signal_t::get_socket() const
70 {
71         return socket_;
72 }
73
74 can_message_definition_t& can_signal_t::get_message() const
75 {
76         return configuration_t::instance().get_can_message_definition(message_set_id_, message_id_);
77 }
78
79 const std::string& can_signal_t::get_generic_name() const
80 {
81         return generic_name_;
82 }
83
84 const std::string can_signal_t::get_name() const
85 {
86         return prefix_ + "." + generic_name_;
87 }
88
89 const std::string& can_signal_t::get_prefix() const
90 {
91         return prefix_;
92 }
93
94 uint8_t can_signal_t::get_bit_position() const
95 {
96         return bit_position_;
97 }
98
99 uint8_t can_signal_t::get_bit_size() const
100 {
101         return bit_size_;
102 }
103
104 float can_signal_t::get_factor() const
105 {
106         return factor_;
107 }
108
109 float can_signal_t::get_offset() const
110 {
111         return offset_;
112 }
113
114 float can_signal_t::get_min_value() const
115 {
116         return min_value_;
117 }       
118
119 float can_signal_t::get_max_value() const
120 {
121         return max_value_;
122 }
123
124 frequency_clock_t& can_signal_t::get_frequency()
125 {
126         return frequency_;
127 }
128
129 bool can_signal_t::get_send_same() const
130 {
131         return send_same_;
132 }
133
134 bool can_signal_t::get_force_send_changed() const
135 {
136         return force_send_changed_;
137 }
138
139 const std::map<uint8_t, std::string>& can_signal_t::get_states() const
140 {
141         return states_;
142 }
143
144 const std::string can_signal_t::get_states(uint8_t value)
145 {
146         if (value < states_.size())
147                 return states_[value];
148         return std::string();
149 }
150
151 size_t can_signal_t::get_state_count() const
152 {
153         return states_.size();
154 }
155
156 bool can_signal_t::get_writable() const
157 {
158         return writable_;
159 }
160
161 SignalDecoder& can_signal_t::get_decoder()
162 {
163         return decoder_;
164 }
165
166 SignalEncoder& can_signal_t::get_encoder()
167 {
168         return encoder_;
169 }
170
171 bool can_signal_t::get_received() const
172 {
173         return received_;
174 }
175 float can_signal_t::get_last_value() const
176 {
177         return last_value_;
178 }
179
180 void can_signal_t::set_prefix(std::string val)
181 {
182         prefix_ = val;
183 }
184
185 void can_signal_t::set_received(bool r)
186 {
187         received_ = r;
188 }
189
190 void can_signal_t::set_last_value(float val)
191 {
192         last_value_ = val;
193 }
194
195 /// @brief Create a RX_SETUP receive job using the BCM socket.
196 ///
197 /// @return 0 if ok else -1
198 int can_signal_t::create_rx_filter()
199 {
200         // Make sure that socket has been opened.
201         if(! socket_)
202                 socket_.open(
203                         get_message().get_bus_name());
204
205         uint32_t can_id  = get_message().get_id();
206
207         struct utils::simple_bcm_msg bcm_msg;
208         struct can_frame cfd;
209
210         memset(&cfd, 0, sizeof(cfd));
211         memset(&bcm_msg.msg_head, 0, sizeof(bcm_msg.msg_head));
212         float val = (float)(1 << bit_size_)-1;
213         float freq = frequency_.frequency_to_period();
214         if(freq <= 0)
215                 freq = 0.000001f;
216
217         bcm_msg.msg_head.opcode  = RX_SETUP;
218         bcm_msg.msg_head.can_id  = can_id;
219         bcm_msg.msg_head.flags = SETTIMER;
220         bcm_msg.msg_head.ival2.tv_sec = long(freq);
221         bcm_msg.msg_head.ival2.tv_usec = (freq - (long)freq) * 1000000;
222         bcm_msg.msg_head.nframes = 1;
223         bitfield_encode_float(val,
224                                                                                 bit_position_,
225                                                                                 bit_size_,
226                                                                                 factor_,
227                                                                                 offset_,
228                                                                                 cfd.data,
229                                                                                 CAN_MAX_DLEN);
230
231         bcm_msg.frames = cfd;
232
233         if(socket_ << bcm_msg)
234                 return 0;
235         return -1;
236 }
237
238 void can_signal_t::read_socket()
239 {
240         can_message_t msg;
241         can_bus_t& cbm = configuration_t::instance().get_can_bus_manager();
242         socket_ >> msg;
243         std::lock_guard<std::mutex> can_message_lock(cbm.get_can_message_mutex());
244         { cbm.push_new_can_message(msg); }
245         cbm.get_new_can_message_cv().notify_one();
246 }