Addind missing library
[apps/agl-service-can-low-level.git] / src / can_decode_message.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 <linux/can.h>
20 #include <linux/can/raw.h>
21 #include <queue>
22 #include <sys/timeb.h>
23
24 #include <afb/afb-binding.h>
25
26 #include "can-utils.hpp"
27 #include "can-decoder.hpp"
28 #include "openxc.pb.h"
29
30 union DynamicField
31 {
32         char string[100];
33         double numeric_value;
34         bool boolean_value;
35 };
36
37 void can_decode_message(can_bus_t &can_bus)
38 {
39         can_message_t can_message;
40         std:vector <CanSignal> signals;
41         std:vector <CanSignal>::iterator signals_i;
42         openxc_VehicleMessage vehicle_message;
43         openxc_DynamicField search_key, ret;
44         bool send = true;
45         
46         decoder_t decoder();
47
48         while(true)
49         {
50                 if(can_message = can_bus.next_can_message())
51                 {
52                         /* First we have to found which CanSignal is */
53                         search_key = build_DynamicField(openxc_DynamicField_Type::openxc_DynamicField_Type_NUM, (double)can_message.get_id())
54
55                         signals = find_can_signals(search_key);
56                         
57                         /* Decoding the message ! Don't kill the messenger ! */
58                         for(const auto& sig : signals)
59                         {       
60                           subscribed_signals_i = subscribed_signals.find(sig);
61                                 
62                                 if(subscribed_signals_i != subscribed_signals.end() &&
63                                         afb_event_is_valid(subscribed_signals_i->second))
64                                 {
65                                         ret = decoder.decodeSignal(sig, can_message, getSignals(), &send);
66
67                                         s_message = build_SimpleMessage(sig.genericName, ret);
68                                                 
69                                         vehicle_message = build_VehicleMessage_with_SimpleMessage(openxc_DynamicField_Type::openxc_DynamicField_Type_NUM, s_message);
70                                         vehicle_message_q.push(vehicle_message);
71                                 }
72                         }
73                 }
74         }
75 }
76
77 /*
78  * Build a specific VehicleMessage containing a SimpleMessage.
79  */
80 openxc_VehicleMessage build_VehicleMessage_with_SimpleMessage(openxc_DynamicField_Type type,
81         const openxc_SimpleMessage& message)
82 {
83         struct timeb t_msec;
84         long long int timestamp_msec;
85         
86         openxc_VehicleMessage v = {0};
87         
88         if(!ftime(&t_msec))
89         {
90                 timestamp_msec = ((long long int) t_msec.time) * 1000ll + 
91                         (long long int) t_msec.millitm;
92
93           v.has_type = true:
94                 v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE;
95                 v.has_simple_message = true;
96                 v.simple_message =  message;
97                 v.has_timestamp = true;
98                 v.timestamp = timestamp_msec;
99                 
100           return v;
101         }
102
103         v.has_type = true,
104         v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE;
105         v.has_simple_message = true;
106         v.simple_message =  message;
107                                           
108   return v;
109 }
110
111 /*
112  * Build an openxc_SimpleMessage associating a name to an openxc_DynamicField
113  */
114 openxc_SimpleMessage build_SimpleMessage(const std::string& name, const openxc_DynamicField& value)
115 {
116   
117   openxc_SimpleMessage s = {0};
118   
119   s.has_name = true;
120   ::strncpy(s.name, name.c_str(), 100);
121         s.has_value = true;
122   s.value = value;
123   
124         return s;
125 }
126
127 /* 
128  * Build an openxc_DynamicField depending what we pass as argument
129  */
130 openxc_DynamicField build_DynamicField(const std::string& value)
131 {
132   openxc_DynamicField d = {0}
133         d.has_type = true;
134         d.type = openxc_DynamicField_Type_STRING;
135         
136         d.has_string_value = true;
137         ::strncpy(d.string_value, value.c_tr(), 100);
138         
139         return d;
140 }
141
142 /* 
143  * Build an openxc_DynamicField depending what we pass as argument
144  */
145 openxc_DynamicField build_DynamicField(double value)
146 {
147   openxc_DynamicField d = {0}
148         d.has_type = true;
149         d.type = openxc_DynamicField_Type_NUM;
150         
151         d.has_numeric_value = true;
152         d.numeric_value = field;
153         
154         return d;
155 }
156
157 /* 
158  * Build an openxc_DynamicField depending what we pass as argument
159  */
160 openxc_DynamicField build_DynamicField(bool value)
161 {
162   openxc_DynamicField d = {0}
163         d.has_type = true;
164         d.type = openxc_DynamicField_Type_BOOL;
165         
166         d.has_boolean_value = true;
167         d.boolean_value = field;
168         
169         return d;
170 }