remove hard coded path into CMake files
[profile/ivi/ico-vic-amb-plugin.git] / src / ambinterface.cc
1 /**
2  * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
3  * 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  * 
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  * 
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  * 
18  */
19
20 #include <memory>
21 #include <sstream>
22
23 #include "debugout.h"
24
25 #include "ambinterface.h"
26 #include "ambconfig.h"
27 #include "convert.h"
28 #include "mwinterface.h"
29 #include "viccommunicator.h"
30
31 extern "C" AbstractSource *
32 create(AbstractRoutingEngine* routingengine, map<string, string> config)
33 {
34     AMBIF *ambif = new AMBIF(routingengine, config);
35     AMBConfig *conf = new AMBConfig();
36     if (!conf->readConfig(config["configfile"])) {
37         DebugOut(DebugOut::Error) << "Failed to Load Configfile for VIC-Plugin.\n";
38         delete ambif;
39         delete conf;
40         return NULL;
41     }
42     VICCommunicator *communicator = new VICCommunicator();
43     MWIF *mwif = new MWIF();
44     Converter *converter = new Converter();
45     if (!ambif->initialize(communicator, conf)) {
46         DebugOut(DebugOut::Error) << "Failed to initialize AMBIF\n";
47         delete ambif;
48         delete conf;
49         delete communicator;
50         delete converter;
51         return NULL;
52     }
53     if (!communicator->initialize(ambif, mwif, converter)) {
54         DebugOut(DebugOut::Error) << "Failed to initialize VICCommunicator\n";
55         delete ambif;
56         delete conf;
57         delete communicator;
58         delete converter;
59         return NULL;
60     }
61     if (!mwif->initialize(communicator, conf)) {
62         DebugOut(DebugOut::Error) << "Failed to initialize MWIF\n";
63         delete ambif;
64         delete conf;
65         delete communicator;
66         delete converter;
67         return NULL;
68     }
69     if (!converter->initialize(conf)) {
70         DebugOut(DebugOut::Error) << "Failed to initialize Converter\n";
71         delete ambif;
72         delete conf;
73         delete communicator;
74         delete converter;
75         return NULL;
76     }
77     return ambif;
78 }
79
80 AMBIF::AMBIF(AbstractRoutingEngine *engine,
81              std::map<std::string, std::string> config) :
82         AbstractSource(engine, config)
83 {
84 }
85
86 AMBIF::~AMBIF()
87 {
88     propertylist.clear();
89     vehicleinfoArray.clear();
90     pthread_mutex_destroy(&mutex);
91 }
92
93 void
94 AMBIF::getPropertyAsync(AsyncPropertyReply *reply)
95 {
96     reply->success = false;
97     DebugOut(10) << "AMBIF " << "Get Request property : " << reply->property
98             << std::endl;
99     lock();
100     AMBVehicleInfo *vehicleinfo = find(reply->property);
101     DebugOut(50) << "AMBIF " << "Find Data : " << reply->property << std::endl;
102     if (vehicleinfo != NULL) {
103         reply->value = vehicleinfo->value;
104         reply->success = true;
105         reply->completed(reply);
106     }
107     unLock();
108 }
109
110 AsyncPropertyReply *
111 AMBIF::setProperty(AsyncSetPropertyRequest request)
112 {
113     DebugOut(10) << "AMBIF" << "Set Request propety : " << request.property
114                << std::endl;
115     lock();
116     AMBVehicleInfo *vehicleinfo = find(request.property);
117     if (vehicleinfo == NULL) {
118         unLock();
119         return NULL;
120     }
121     AsyncPropertyReply *reply = new AsyncPropertyReply(request);
122     reply->success = true;
123     DebugOut(50) << "AMBIF" << "Update Value!" << std::endl;
124     delete vehicleinfo->value;
125     vehicleinfo->value = request.value->copy();
126     reply->value = vehicleinfo->value;
127     communicator->setMWVehicleInfo(vehicleinfo);
128     DebugOut(50) << "AMBIF setProperty " << "Set Value(" << request.property
129                << "," << reply->value->toString() << ")" << std::endl;
130     reply->completed(reply);
131     #if LATER1024
132     routingEngine->updateProperty(vehicleinfo->value, uuid());
133     #else
134     routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value, uuid());
135     #endif
136     unLock();
137     return reply;
138 }
139
140 PropertyList
141 AMBIF::supported()
142 {
143     return propertylist;
144 }
145
146 int
147 AMBIF::supportedOperations()
148 {
149     return Get | Set;
150 }
151
152 #if LATER1024
153 const string
154 #else
155 string
156 #endif
157 AMBIF::uuid()
158 {
159     return "f68f8b9a-fafb-4284-8ced-b45b5d720185";
160 }
161
162 void
163 AMBIF::propertyChanged(VehicleProperty::Property property,
164                        AbstractPropertyType *value, std::string uuid)
165 {
166     DebugOut(1) << "INFO CHG_VIC_INF Receive notification from Core. Property is " << property << ".\n";
167     AMBVehicleInfo *vehicleinfo = find(property);
168     lock();
169     if (vehicleinfo != NULL) {
170         delete vehicleinfo->value;
171         vehicleinfo->value = value->copy();
172     }
173     unLock();
174 }
175
176 void
177 AMBIF::setConfiguratin(std::map<std::string, std::string> config)
178 {
179 }
180
181 bool
182 AMBIF::initialize(VICCommunicator *comm, AMBConfig *conf)
183 {
184     DebugOut(50) << "AMBIF Initialize\n";
185     communicator = comm;
186     mutex = PTHREAD_MUTEX_INITIALIZER;
187
188     vector<VehicleInfoDefine> table;
189     table = conf->getVehicleInfoConfig();
190     for (auto itr = table.begin(); itr != table.end(); itr++) {
191         for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
192              itr2++) {
193             AMBVehicleInfo vi;
194             vi.isCustom = false;
195             vi.name = (*itr2).ambPropertyName;
196             vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
197                     vi.name, (*itr2).defaultvalue);
198             if (vi.value == nullptr) {
199                 if (!registVehicleInfo(vi.name, (*itr2).type,
200                                        (*itr2).defaultvalue)) {
201                     DebugOut(50) << "AMBIF Initialize Couldn't regist property["
202                                << vi.name << "]\n";
203                     continue;
204                 }
205                 vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
206                         vi.name, (*itr2).defaultvalue);
207                 vi.isCustom = true;
208             }
209             vi.zone = (*itr2).zone;
210             vehicleinfoArray.push_back(vi);
211             propertylist.push_back(vi.name);
212             DebugOut(50) << "AMBIF Initialize regist propertyname = " << vi.name
213                        << "\n";
214         }
215     }
216     routingEngine->updateSupported(supported(), PropertyList(), this);
217     DebugOut(1) << "INFO CHG_VIC_INF The number of AMB vehicle info is " << vehicleinfoArray.size() << ".\n";
218     return true;
219 }
220
221 AMBVehicleInfo *
222 AMBIF::getPropertyRequest(std::string propertyname)
223 {
224     DebugOut(50) << "AMBIF getPropertyRequest(" << propertyname << ")\n";
225     AsyncPropertyRequest request;
226     request.property = propertyname;
227     request.completed = [](AsyncPropertyReply *reply) {
228         if (reply->success) {
229             DebugOut(50) << "AMBIF getPropertyRequest completed success!!.\n";
230         }
231         else {
232             DebugOut(50) << "AMBIF getPropertyRequest completed false!!.\n";
233         }
234     };
235
236     AsyncPropertyReply *reply = routingEngine->getPropertyAsync(request);
237     lock();
238     AMBVehicleInfo *vehicleinfo = find(propertyname);
239     if (vehicleinfo == NULL) {
240         delete reply;
241         unLock();
242         return NULL;
243     }
244     if (vehicleinfo->value != reply->value && reply->success) {
245         delete vehicleinfo->value;
246         vehicleinfo->value = reply->value->copy();
247     }
248     delete reply;
249     unLock();
250     DebugOut(50) << "AMBIF getPropertyRequest after call "
251                << vehicleinfo->value->toString() << std::endl;
252     return vehicleinfo;
253 }
254
255 void
256 AMBIF::setPropertyRequest(AMBVehicleInfo *vehicleinfo)
257 {
258     AsyncSetPropertyRequest request;
259     request.property = vehicleinfo->name;
260     request.value = vehicleinfo->value;
261     request.completed =
262             [](AsyncPropertyReply *reply) {
263                 if (reply->success) {
264                     DebugOut(50)<<"AMBIF" << reply->property << ":" << reply->value->toString() << std::endl;
265                 }
266                 else {
267                     DebugOut(50)<<"AMBIF" << reply->property << " isn't registered." << std::endl;
268                 }
269             };
270     AsyncPropertyReply *reply = routingEngine->setProperty(request);
271     if (reply != NULL) {
272         delete reply;
273     }
274 }
275
276 void
277 AMBIF::updateProperty(AMBVehicleInfo *vehicleinfo)
278 {
279     if (vehicleinfo->name == VehicleProperty::VehicleSpeed) {
280         static uint16_t prevspd = -1;
281         static const uint16_t unusablespd = -1;
282         uint16_t spd = vehicleinfo->value->value<uint16_t>();
283         if ((prevspd == unusablespd && spd > 0) || (prevspd == 0 && spd > 0)) {
284             DebugOut(3) << "PERF CHG_VIC_INF VIC-Plugin notify Code of update " 
285                         << vehicleinfo->name 
286                         << ". VehicleSpeed is 1km/h or more.\n";
287         }
288         else if ((prevspd == unusablespd && spd == 0) || 
289                  (prevspd > 0 && spd == 0)) {
290             DebugOut(3) << "PERF CHG_VIC_INF VIC-Plugin notify Code of update " 
291                         << vehicleinfo->name << ". VehicleSpeed is 0km/h.\n";
292         }
293         prevspd = spd;
294     }
295     #if LATER1024
296     routingEngine->updateProperty(vehicleinfo->value, uuid());
297     #else
298     routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value, uuid());
299     #endif
300     AMBVehicleInfo *ambvehicleinfo = find(vehicleinfo->name);
301     lock();
302     if (ambvehicleinfo != NULL) {
303         delete ambvehicleinfo->value;
304         ambvehicleinfo->value = vehicleinfo->value->copy();
305     }
306     unLock();
307 }
308
309 void
310 AMBIF::lock()
311 {
312     pthread_mutex_lock(&mutex);
313 }
314
315 void
316 AMBIF::unLock()
317 {
318     pthread_mutex_unlock(&mutex);
319 }
320
321 void
322 AMBIF::requestUpdate(AMBVehicleInfo *vehicleinfo)
323 {
324     DebugOut(50) << "AMBIF requestUpdate request property name is "
325                << vehicleinfo->name << "\n";
326     if (find(vehicleinfo->name) != NULL) {
327         vehicleinfo->value->zone = vehicleinfo->zone;
328         vehicleinfo->value->priority = AbstractPropertyType::Instant;
329         DebugOut(50) << "AMBIF requestUpdate request property name is "
330                    << vehicleinfo->name << ", zone is " << vehicleinfo->zone << "\n";
331         updateProperty(vehicleinfo);
332     }
333     else {
334         setPropertyRequest(vehicleinfo);
335     }
336 }
337
338 bool
339 AMBIF::registVehicleInfo(std::string propertyName, DataType type, string value)
340 {
341     DebugOut(50) << "AMBIF registVehicleInfo(" << propertyName << ")\n";
342     VehicleProperty::PropertyTypeFactoryCallback factory;
343     switch (type) {
344     case INT:
345     {
346         factory = [value, propertyName]() {
347             return new BasicPropertyType<int>(propertyName, value);
348         };
349         break;
350     }
351     case DOUBLE:
352     {
353         factory = [value, propertyName]() {
354             return new BasicPropertyType<double>(propertyName, value);
355         };
356         break;
357     }
358     case CHAR:
359     {
360         factory = [value, propertyName]() {
361             return new BasicPropertyType<char>(propertyName, value);
362         };
363         break;
364     }
365     case INT16:
366     {
367         factory = [value, propertyName]() {
368             return new BasicPropertyType<int16_t>(propertyName, value);
369         };
370         break;
371     }
372     case UINT16:
373     {
374         factory = [value, propertyName]() {
375             return new BasicPropertyType<uint16_t>(propertyName, value);
376         };
377         break;
378     }
379     case UINT32:
380     {
381         factory = [value, propertyName]() {
382             return new BasicPropertyType<uint32_t>(propertyName, value);
383         };
384         break;
385     }
386     case INT64:
387     {
388         factory = [value, propertyName]() {
389             return new BasicPropertyType<int64_t>(propertyName, value);
390         };
391         break;
392     }
393     case UINT64:
394     {
395         factory = [value, propertyName]() {
396             return new BasicPropertyType<uint64_t>(propertyName, value);
397         };
398         break;
399     }
400     case BOOL:
401     {
402         factory = [value, propertyName]() {
403             return new BasicPropertyType<bool>(propertyName, value);
404         };
405         break;
406     }
407     default:
408     {
409         return false;
410     }
411     }
412     return VehicleProperty::registerProperty(propertyName, factory);
413 }
414
415 AMBVehicleInfo *
416 AMBIF::find(std::string propertyName)
417 {
418     AMBVehicleInfo vi;
419     vi.name = propertyName;
420     std::vector<AMBVehicleInfo>::iterator itr;
421     if ((itr = std::find(vehicleinfoArray.begin(), vehicleinfoArray.end(), vi)) 
422         != vehicleinfoArray.end()) {
423         return &(*itr);
424     }
425     return NULL;
426 }
427
428 #if LATER1024
429 PropertyInfo AMBIF::getPropertyInfo(VehicleProperty::Property property) {
430     if (propertyInfoMap.find(property) != propertyInfoMap.end()) {
431         return propertyInfoMap[property];
432     }
433     std::list<Zone::Type> zones;
434     AMBVehicleInfo vi;
435     vi.name = property;
436     std::vector<AMBVehicleInfo>::iterator itr, itr_idx, itr_end;
437     itr_idx = vehicleinfoArray.begin();
438     itr_end = vehicleinfoArray.end();
439     while ((itr = std::find(itr_idx, itr_end, vi)) != itr_end) {
440         zones.push_back((*itr).zone);
441         itr_idx = (++itr);
442     }
443     if (zones.empty()) {
444         return PropertyInfo::invalid();
445     }
446     else {
447         PropertyInfo info(0, zones);
448         propertyInfoMap[vi.name] = info;
449         return propertyInfoMap[vi.name];
450     }
451 }
452 #endif