Adding/Fix classes constructors to make them correspond
[apps/agl-service-can-low-level.git] / src / utils / openxc-utils.cpp
1 /*
2  * Copyright (C) 2015, 2016 "IoT.bzh"
3  * Author "Romain Forlot" <romain.forlot@iot.bzh>
4  * Author "Loic Collignon" <loic.collignon@iot.bzh>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include "openxc-utils.hpp"
20
21 #include "../configuration.hpp"
22
23 openxc_VehicleMessage build_VehicleMessage(active_diagnostic_request_t* request, const DiagnosticResponse& response, float parsed_value)
24 {
25         openxc_VehicleMessage message;
26
27         message.has_type = true;
28         message.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_DIAGNOSTIC;
29         message.has_diagnostic_response = true;
30         message.diagnostic_response.has_bus = true;
31         message.diagnostic_response.bus = configuration_t::instance().get_diagnostic_manager().get_can_bus_dev()->get_address();
32         message.diagnostic_response.has_message_id = true;
33
34         if(request->get_id() != OBD2_FUNCTIONAL_BROADCAST_ID)
35         {
36                 message.diagnostic_response.message_id = response.arbitration_id
37                         - DIAGNOSTIC_RESPONSE_ARBITRATION_ID_OFFSET;
38         }
39         else
40         {
41                 // must preserve responding arb ID for responses to functional broadcast
42                 // requests, as they are the actual module address and not just arb ID +
43                 // 8.
44                 message.diagnostic_response.message_id = response.arbitration_id;
45         }
46
47         message.diagnostic_response.has_mode = true;
48         message.diagnostic_response.mode = response.mode;
49         message.diagnostic_response.has_pid = response.has_pid;
50         if(message.diagnostic_response.has_pid)
51                 message.diagnostic_response.pid = response.pid;
52         message.diagnostic_response.has_success = true;
53         message.diagnostic_response.success = response.success;
54         message.diagnostic_response.has_negative_response_code = !response.success;
55         message.diagnostic_response.negative_response_code =
56                         response.negative_response_code;
57
58         if(response.payload_length > 0)
59         {
60                 if(request->get_decoder() != nullptr)
61                 {
62                         message.diagnostic_response.has_value = true;
63                         message.diagnostic_response.value = parsed_value;
64                 }
65                 else
66                 {
67                         message.diagnostic_response.has_payload = true;
68                         ::memcpy(message.diagnostic_response.payload.bytes, response.payload,
69                                         response.payload_length);
70                         message.diagnostic_response.payload.size = response.payload_length;
71                 }
72         }
73
74         return message;
75 }
76
77 openxc_VehicleMessage build_VehicleMessage(const openxc_SimpleMessage& message)
78 {
79         openxc_VehicleMessage v;
80         
81         v.has_type = true,
82         v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE;
83         v.has_simple_message = true;
84         v.simple_message =  message;
85         v.has_timestamp = true;
86         v.timestamp = system_time_ms();
87
88         return v;
89 }
90
91 openxc_SimpleMessage build_SimpleMessage(const std::string& name, const openxc_DynamicField& value)
92 {
93         openxc_SimpleMessage s;
94
95         s.has_name = true;
96         ::strncpy(s.name, name.c_str(), 100);
97         s.has_value = true;
98         s.value = value;
99
100         return s;
101 }
102
103 openxc_DynamicField build_DynamicField(const std::string& value)
104 {
105         openxc_DynamicField d;
106         d.has_type = true;
107         d.type = openxc_DynamicField_Type_STRING;
108         
109         d.has_string_value = true;
110         d.has_numeric_value = false;
111         d.has_boolean_value = false;
112         ::strncpy(d.string_value, value.c_str(), 100);
113         
114         return d;
115 }
116
117 openxc_DynamicField build_DynamicField(double value)
118 {
119         openxc_DynamicField d;
120         d.has_type = true;
121         d.type = openxc_DynamicField_Type_NUM;
122         
123         d.has_string_value = false;
124         d.has_numeric_value = true;
125         d.has_boolean_value = false;
126         d.numeric_value = value;
127         
128         return d;
129 }
130
131 openxc_DynamicField build_DynamicField(bool value)
132 {
133         openxc_DynamicField d;
134         d.has_type = true;
135         d.type = openxc_DynamicField_Type_BOOL;
136         
137         d.has_string_value = false;
138         d.has_numeric_value = false;
139         d.has_boolean_value = true;
140         d.boolean_value = value;
141         
142         return d;
143 }
144
145 openxc_SimpleMessage get_simple_message(const openxc_VehicleMessage& v_msg)
146 {
147         if (v_msg.has_simple_message)
148                 return v_msg.simple_message;
149         
150         openxc_SimpleMessage s_msg = { false, "", false, build_DynamicField(false), false, build_DynamicField(false)};
151         return s_msg;
152 }
153
154 void jsonify_DynamicField(const openxc_DynamicField& field, json_object* value)
155 {
156         if(field.has_numeric_value)
157                 json_object_object_add(value, "value", json_object_new_double(field.numeric_value));
158         else if(field.has_boolean_value)
159                 json_object_object_add(value, "value", json_object_new_boolean(field.boolean_value));
160         else if(field.has_string_value)
161                 json_object_object_add(value, "value", json_object_new_string(field.string_value));
162 }
163
164 bool jsonify_simple(const openxc_SimpleMessage& s_msg, json_object* json)
165 {
166         if(s_msg.has_name)
167         {
168                 json_object_object_add(json, "name", json_object_new_string(s_msg.name));
169                 jsonify_DynamicField(s_msg.value, json);
170                 return true;
171         }
172         json_object_object_add(json, "error", json_object_new_string("openxc_SimpleMessage doesn't have name'"));
173         return false;
174 }