tbf
[apps/agl-service-can-low-level.git] / src / 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
21 float decoder_t::parseSignalBitfield(CanSignal& signal, const can_message_t& message)
22 {
23          return bitfield_parse_float(message.get_data(), CAN_MESSAGE_SIZE,
24                         signal.bitPosition, signal.bitSize, signal.factor,
25                         signal.offset);
26 }
27
28 openxc_DynamicField decoder_t::noopDecoder(CanSignal& signal,
29                 const std::vector<CanSignal>& signals, float value, bool* send)
30 {
31         openxc_DynamicField decoded_value;
32         decoded_value.has_type = true;
33         decoded_value.type = openxc_DynamicField_Type_NUM;
34         decoded_value.has_numeric_value = true;
35         decoded_value.numeric_value = value;
36
37         return decoded_value;
38 }
39
40 openxc_DynamicField decoder_t::booleanDecoder(CanSignal& signal,
41                 const std::vector<CanSignal>& signals, float value, bool* send)
42 {
43         openxc_DynamicField decoded_value;
44         decoded_value.has_type = true;
45         decoded_value.type = openxc_DynamicField_Type_BOOL;
46         decoded_value.has_boolean_value = true;
47         decoded_value.boolean_value = value == 0.0 ? false : true;
48
49         return decoded_value;
50 }
51
52 openxc_DynamicField decoder_t::ignoreDecoder(CanSignal& signal,
53                 const std::vector<CanSignal>& signals, float value, bool* send)
54 {
55         if(send)
56           *send = false;
57         
58         openxc_DynamicField decoded_value = {0, openxc_DynamicField_Type_BOOL, 0, "", 0, 0, 0, 0};
59         
60         return decoded_value;
61 }
62
63 openxc_DynamicField decoder_t::stateDecoder(CanSignal& signal,
64                 const std::vector<CanSignal>& signals, float value, bool* send)
65 {
66         openxc_DynamicField decoded_value = {0, openxc_DynamicField_Type_BOOL, 0, "", 0, 0, 0, 0};
67         decoded_value.has_type = true;
68         decoded_value.type = openxc_DynamicField_Type_STRING;
69         decoded_value.has_string_value = true;
70
71         /* TODO: Handle SignalState 
72         const CanSignalState* signalState = lookupSignalState(value, signal);
73         if(signalState != NULL) {
74                 ::strcpy(decoded_value.string_value, signalState->name);
75         } else {
76                 *send = false;
77         }*/
78         return decoded_value;
79 }
80
81 openxc_DynamicField decoder_t::translateSignal(CanSignal& signal, can_message_t& message,
82         const std::vector<CanSignal>& signals)
83 {
84         if(&signal == nullptr || &message == nullptr)
85         {
86                 openxc_DynamicField ret = {0, openxc_DynamicField_Type_BOOL, 0, "", 0, 0, 0, 0};
87                 return ret;
88         }
89
90         float value = parseSignalBitfield(signal, message);
91         DEBUG(binder_interface, "translateSignal: Decoded message: %f", value);
92
93         bool send = true;
94         // Must call the decoders every time, regardless of if we are going to
95         // decide to send the signal or not.
96         openxc_DynamicField decoded_value = decodeSignal(signal,
97                         value, signals, &send);
98
99         signal.received = true;
100         signal.lastValue = value;
101         return decoded_value;
102 }
103
104 openxc_DynamicField decoder_t::decodeSignal( CanSignal& signal,
105                 float value, const std::vector<CanSignal>& signals, bool* send)
106 {
107         SignalDecoder decoder = signal.decoder == NULL ?
108                                                         noopDecoder : signal.decoder;
109         openxc_DynamicField decoded_value = decoder(signal, signals,
110                         value, send);
111         return decoded_value;
112 }
113
114 openxc_DynamicField decoder_t::decodeSignal( CanSignal& signal,
115                 const can_message_t& message, const std::vector<CanSignal>& signals, bool* send)
116 {
117         float value = parseSignalBitfield(signal, message);
118         return decodeSignal(signal, value, signals, send);
119 }