000db2acb52149b549dee56bc63f0203d50e98e9
[apps/low-level-can-service.git] / 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 Decoder::Decoder
19 {
20         decoded_value = { .has_type = false,
21                                         .has_numeric_value = false,
22                                         .has_boolean_value = false,
23                                         .has_string_value = false };
24 }
25
26 float Decoder::parseSignalBitfield(CanSignal* signal, const CanMessage* message)
27 {
28          return bitfield_parse_float(message->data, CAN_MESSAGE_SIZE,
29                         signal->bitPosition, signal->bitSize, signal->factor,
30                         signal->offset);
31 }
32
33 openxc_DynamicField Decoder::noopDecoder(CanSignal* signal,
34         CanSignal* signals, int signalCount, float value, bool* send)
35 {
36         decoded_value = { .has_type = true,
37                                         .type = openxc_DynamicField_Type_NUM,
38                                         .has_numeric_value = true,
39                                         .numeric_value = value };
40     return decoded_value;
41 }
42
43 openxc_DynamicField Decoder::booleanDecoder(CanSignal* signal,
44         CanSignal* signals, int signalCount, float value, bool* send)
45 {
46         decoded_value = { .has_type = true,
47                                         .type = openxc_DynamicField_Type_BOOL,
48                                         .has_boolean_value = true,
49                                         .numeric_value = value == 0.0 ? false : true };
50         return decoded_value;
51 }
52
53 openxc_DynamicField Decoder::ignoreDecoder(CanSignal* signal,
54         CanSignal* signals, int signalCount, float value, bool* send)
55 {
56     *send = false;
57     openxc_DynamicField decoded_value = {0};
58     return decoded_value;
59 }
60
61 openxc_DynamicField Decoder::stateDecoder(CanSignal* signal,
62         CanSignal* signals, int signalCount, float value, bool* send)
63 {
64     openxc_DynamicField decoded_value = {0};
65     decoded_value.has_type = true;
66     decoded_value.type = openxc_DynamicField_Type_STRING;
67     decoded_value.has_string_value = true;
68
69     const CanSignalState* signalState = lookupSignalState(value, signal);
70     if(signalState != NULL) {
71         strcpy(decoded_value.string_value, signalState->name);
72     } else {
73         *send = false;
74     }
75     return decoded_value;
76 }
77
78 openxc_DynamicField Decoder::decodeSignal(CanSignal* signal,
79         float value, CanSignal* signals, int signalCount, bool* send)
80 {
81     SignalDecoder decoder = signal->decoder == NULL ?
82                                             noopDecoder : signal->decoder;
83     openxc_DynamicField decoded_value = decoder(signal, signals,
84             signalCount, value, send);
85     return decoded_value;
86 }
87
88 openxc_DynamicField Decoder::decodeSignal(CanSignal* signal,
89         const CanMessage* message, CanSignal* signals, int signalCount,
90         bool* send) {
91     float value = parseSignalBitfield(signal, message);
92     return decodeSignal(signal, value, signals, signalCount, send);
93 }