Adjust method signature to be more efficient.
[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(
33         std::string generic_name,
34         uint8_t bit_position,
35         uint8_t bit_size,
36         float factor,
37         float offset,
38         float min_value,
39         float max_value,
40         frequency_clock_t frequency,
41         bool send_same,
42         bool force_send_changed,
43         std::map<uint8_t, std::string> states,
44         bool writable,
45         SignalDecoder decoder,
46         SignalEncoder encoder,
47         bool received)
48         : parent_{nullptr},
49          generic_name_{ generic_name }
50         , bit_position_{ bit_position }
51         , bit_size_{ bit_size }
52         , factor_{ factor }
53         , offset_{ offset }
54         , min_value_{min_value}
55         , max_value_{max_value}
56         , frequency_{frequency}
57         , send_same_{send_same}
58         , force_send_changed_{force_send_changed}
59         , states_{states}
60         , writable_{writable}
61         , decoder_{decoder}
62         , encoder_{encoder}
63         , received_{received}
64         , last_value_{.0f}
65 {}
66
67 /*can_signal_t::can_signal_t(const can_signal_t& b)
68         : parent_{b.parent_},
69          generic_name_{ b.generic_name_}
70         , bit_position_{ b.bit_position_}
71         , bit_size_{ b.bit_size_}
72         , factor_{ b.factor_ }
73         , offset_{ b.offset_}
74         , min_value_{b.min_value_}
75         , max_value_{b.max_value_}
76         , frequency_{b.frequency_}
77         , send_same_{b.send_same_}
78         , force_send_changed_{b.force_send_changed_}
79         , states_{b.states_}
80         , writable_{b.writable_}
81         , decoder_{b.decoder_}
82         , encoder_{b.encoder_}
83         , received_{b.received_}
84         , last_value_{b.last_value_}
85 {}*/
86
87 utils::socketcan_bcm_t can_signal_t::get_socket() const
88 {
89         return socket_;
90 }
91
92 can_message_definition_t* can_signal_t::get_message() const
93 {
94         return parent_;
95 }
96
97 const std::string can_signal_t::get_generic_name() const
98 {
99         return generic_name_;
100 }
101
102 const std::string can_signal_t::get_name() const
103 {
104         return prefix_ + "." + generic_name_;
105 }
106
107 const std::string can_signal_t::get_prefix() const
108 {
109         return prefix_;
110 }
111
112 uint8_t can_signal_t::get_bit_position() const
113 {
114         return bit_position_;
115 }
116
117 uint8_t can_signal_t::get_bit_size() const
118 {
119         return bit_size_;
120 }
121
122 float can_signal_t::get_factor() const
123 {
124         return factor_;
125 }
126
127 float can_signal_t::get_offset() const
128 {
129         return offset_;
130 }
131
132 float can_signal_t::get_min_value() const
133 {
134         return min_value_;
135 }       
136
137 float can_signal_t::get_max_value() const
138 {
139         return max_value_;
140 }
141
142 frequency_clock_t& can_signal_t::get_frequency()
143 {
144         return frequency_;
145 }
146
147 bool can_signal_t::get_send_same() const
148 {
149         return send_same_;
150 }
151
152 bool can_signal_t::get_force_send_changed() const
153 {
154         return force_send_changed_;
155 }
156
157 const std::map<uint8_t, std::string>& can_signal_t::get_states() const
158 {
159         return states_;
160 }
161
162 const std::string can_signal_t::get_states(uint8_t value)
163 {
164         if (value < states_.size())
165                 return states_[value];
166         return std::string();
167 }
168
169 size_t can_signal_t::get_state_count() const
170 {
171         return states_.size();
172 }
173
174 bool can_signal_t::get_writable() const
175 {
176         return writable_;
177 }
178
179 SignalDecoder& can_signal_t::get_decoder()
180 {
181         return decoder_;
182 }
183
184 SignalEncoder& can_signal_t::get_encoder()
185 {
186         return encoder_;
187 }
188
189 bool can_signal_t::get_received() const
190 {
191         return received_;
192 }
193 float can_signal_t::get_last_value() const
194 {
195         return last_value_;
196 }
197
198 void can_signal_t::set_parent(can_message_definition_t* parent)
199 {
200         parent_ = parent;
201 }
202
203 void can_signal_t::set_prefix(std::string val)
204 {
205         prefix_ = val;
206 }
207
208 void can_signal_t::set_received(bool r)
209 {
210         received_ = r;
211 }
212
213 void can_signal_t::set_last_value(float val)
214 {
215         last_value_ = val;
216 }
217
218 /// @brief Create a RX_SETUP receive job used by the BCM socket.
219 ///
220 /// @return 0 if ok else -1
221 int can_signal_t::create_rx_filter()
222 {
223         // Make sure that socket has been opened.
224         if(! socket_)
225                 socket_.open(
226                         get_message()->get_bus_name());
227
228         uint32_t can_id  = get_message()->get_id();
229
230         struct utils::simple_bcm_msg bcm_msg;
231         struct can_frame cfd;
232
233         memset(&cfd, 0, sizeof(cfd));
234         memset(&bcm_msg.msg_head, 0, sizeof(bcm_msg.msg_head));
235         float val = (float)(1 << bit_size_)-1;
236         struct timeval freq = frequency_.get_timeval_from_period();
237
238         bcm_msg.msg_head.opcode  = RX_SETUP;
239         bcm_msg.msg_head.can_id  = can_id;
240         bcm_msg.msg_head.flags = SETTIMER|RX_NO_AUTOTIMER;
241         bcm_msg.msg_head.ival2.tv_sec = freq.tv_sec ;
242         bcm_msg.msg_head.ival2.tv_usec = freq.tv_usec;
243         bcm_msg.msg_head.nframes = 1;
244         bitfield_encode_float(val,
245                                                                                 bit_position_,
246                                                                                 bit_size_,
247                                                                                 factor_,
248                                                                                 offset_,
249                                                                                 cfd.data,
250                                                                                 CAN_MAX_DLEN);
251
252         bcm_msg.frames = cfd;
253
254         if(socket_ << bcm_msg)
255                 return 0;
256         return -1;
257 }