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