Make decoder systematic use of openxc-utils to build
[apps/low-level-can-service.git] / src / can / can-decoder.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 "can-decoder.hpp"
19 #include "canutil/read.h"
20 #include "../utils/openxc-utils.hpp"
21
22 float decoder_t::parseSignalBitfield(can_signal_t& signal, const can_message_t& message)
23 {
24          return bitfield_parse_float(message.get_data(), CAN_MESSAGE_SIZE,
25                         signal.get_bit_position(), signal.get_bit_size(), signal.get_factor(),
26                         signal.get_offset());
27 }
28
29 openxc_DynamicField decoder_t::noopDecoder(can_signal_t& signal,
30                 const std::vector<can_signal_t>& signals, float value, bool* send)
31 {
32         openxc_DynamicField decoded_value = build_DynamicField(value);
33
34         return decoded_value;
35 }
36
37 openxc_DynamicField decoder_t::booleanDecoder(can_signal_t& signal,
38                 const std::vector<can_signal_t>& signals, float value, bool* send)
39 {
40         openxc_DynamicField decoded_value = build_DynamicField(value == 0.0 ? false : true);
41
42         return decoded_value;
43 }
44
45 openxc_DynamicField decoder_t::ignoreDecoder(can_signal_t& signal,
46                 const std::vector<can_signal_t>& signals, float value, bool* send)
47 {
48         if(send)
49           *send = false;
50         
51         openxc_DynamicField decoded_value = {0, openxc_DynamicField_Type_BOOL, 0, "", 0, 0, 0, 0};
52         
53         return decoded_value;
54 }
55
56 openxc_DynamicField decoder_t::stateDecoder(can_signal_t& signal,
57                 const std::vector<can_signal_t>& signals, float value, bool* send)
58 {
59         const std::string signal_state = signal.get_states(value);
60         openxc_DynamicField decoded_value = build_DynamicField(signal_state);
61         if(signal_state.size() <= 0)
62         {
63                 *send = false;
64                 ERROR(binder_interface, "stateDecoder: No state found with index: %d", (int)value);
65         }
66         return decoded_value;
67 }
68
69 openxc_DynamicField decoder_t::translateSignal(can_signal_t& signal, can_message_t& message,
70         const std::vector<can_signal_t>& signals)
71 {
72         if(&signal == nullptr || &message == nullptr)
73         {
74                 openxc_DynamicField ret = {0, openxc_DynamicField_Type_BOOL, 0, "", 0, 0, 0, 0};
75                 return ret;
76         }
77
78         float value = decoder_t::parseSignalBitfield(signal, message);
79         DEBUG(binder_interface, "translateSignal: Decoded message from parseSignalBitfield: %f", value);
80
81         bool send = true;
82         // Must call the decoders every time, regardless of if we are going to
83         // decide to send the signal or not.
84         openxc_DynamicField decoded_value = decoder_t::decodeSignal(signal,
85                         value, signals, &send);
86
87         signal.set_received(true);
88         signal.set_last_value(value);
89         return decoded_value;
90 }
91
92 openxc_DynamicField decoder_t::decodeSignal( can_signal_t& signal,
93                 float value, const std::vector<can_signal_t>& signals, bool* send)
94 {
95         SignalDecoder decoder = signal.get_decoder() == nullptr ?
96                                                         noopDecoder : signal.get_decoder();
97         openxc_DynamicField decoded_value = decoder(signal, signals,
98                         value, send);
99         return decoded_value;
100 }
101
102 openxc_DynamicField decoder_t::decodeSignal( can_signal_t& signal,
103                 const can_message_t& message, const std::vector<can_signal_t>& signals, bool* send)
104 {
105         float value = parseSignalBitfield(signal, message);
106         return decodeSignal(signal, value, signals, send);
107 }