Updated package changelog.
[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 "config.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     Config *conf = new Config();
36     conf->readConfig(config["configfile"]);
37     VICCommunicator *communicator = new VICCommunicator();
38     MWIF *mwif = new MWIF();
39     Converter *converter = new Converter();
40     if (!ambif->initialize(communicator, conf)) {
41         DebugOut() << "Failed to initialize AMBIF\n";
42         delete ambif;
43         delete conf;
44         delete communicator;
45         delete converter;
46         return NULL;
47     }
48     if (!communicator->initialize(ambif, mwif, converter)) {
49         DebugOut() << "Failed to initialize VICCommunicator\n";
50         delete ambif;
51         delete conf;
52         delete communicator;
53         delete converter;
54         return NULL;
55     }
56     if (!mwif->initialize(communicator, conf)) {
57         DebugOut() << "Failed to initialize MWIF\n";
58         delete ambif;
59         delete conf;
60         delete communicator;
61         delete converter;
62         return NULL;
63     }
64     if (!converter->initialize(conf)) {
65         DebugOut() << "Failed to initialize Converter\n";
66         delete ambif;
67         delete conf;
68         delete communicator;
69         delete converter;
70         return NULL;
71     }
72     return ambif;
73 }
74
75 AMBIF::AMBIF(AbstractRoutingEngine *engine,
76              std::map<std::string, std::string> config) :
77         AbstractSource(engine, config)
78 {
79 }
80
81 AMBIF::~AMBIF()
82 {
83     propertylist.clear();
84     vehicleinfoArray.clear();
85     pthread_mutex_destroy(&mutex);
86 }
87
88 void
89 AMBIF::getPropertyAsync(AsyncPropertyReply *reply)
90 {
91     reply->success = false;
92     DebugOut() << "AMBIF " << "Get Request property : " << reply->property
93                << std::endl;
94     lock();
95     AMBVehicleInfo *vehicleinfo = find(reply->property);
96     DebugOut() << "AMBIF " << "Find Data : " << reply->property << std::endl;
97     if (vehicleinfo != NULL) {
98         reply->value = vehicleinfo->value;
99         reply->success = true;
100         reply->completed(reply);
101     }
102     unLock();
103 }
104
105 AsyncPropertyReply *
106 AMBIF::setProperty(AsyncSetPropertyRequest request)
107 {
108     DebugOut() << "AMBIF" << "Set Request propety : " << request.property
109                << std::endl;
110     lock();
111     AMBVehicleInfo *vehicleinfo = find(request.property);
112     if (vehicleinfo == NULL) {
113         unLock();
114         return NULL;
115     }
116     AsyncPropertyReply *reply = new AsyncPropertyReply(request);
117     reply->success = true;
118     DebugOut(10) << "AMBIF" << "Update Value!" << std::endl;
119     delete vehicleinfo->value;
120     vehicleinfo->value = request.value->copy();
121     reply->value = vehicleinfo->value;
122     communicator->setMWVehicleInfo(vehicleinfo);
123     DebugOut() << "AMBIF setProperty " << "Set Value(" << request.property
124                << "," << reply->value->toString() << ")" << std::endl;
125     reply->completed(reply);
126     routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value,
127                                   uuid());
128     unLock();
129     return reply;
130 }
131
132 PropertyList
133 AMBIF::supported()
134 {
135     return propertylist;
136 }
137
138 int
139 AMBIF::supportedOperations()
140 {
141     return Get | Set;
142 }
143
144 string
145 AMBIF::uuid()
146 {
147     return "f68f8b9a-fafb-4284-8ced-b45b5d720185";
148 }
149
150 void
151 AMBIF::propertyChanged(VehicleProperty::Property property,
152                        AbstractPropertyType *value, std::string uuid)
153 {
154     AMBVehicleInfo *vehicleinfo = find(property);
155     lock();
156     if (vehicleinfo != NULL) {
157         delete vehicleinfo->value;
158         vehicleinfo->value = value->copy();
159     }
160     unLock();
161 }
162
163 void
164 AMBIF::setConfiguratin(std::map<std::string, std::string> config)
165 {
166 }
167
168 bool
169 AMBIF::initialize(VICCommunicator *comm, Config *conf)
170 {
171     DebugOut() << "AMBIF Initialize\n";
172     communicator = comm;
173     mutex = PTHREAD_MUTEX_INITIALIZER;
174
175     vector<VehicleInfoDefine> table;
176     table = conf->getVehicleInfoConfig();
177     for (auto itr = table.begin(); itr != table.end(); itr++) {
178         for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
179              itr2++) {
180             AMBVehicleInfo vi;
181             vi.isCustom = false;
182             vi.name = (*itr2).ambPropertyName;
183             vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
184                     vi.name, (*itr2).defaultvalue);
185             if (vi.value == nullptr) {
186                 if (!registVehicleInfo(vi.name, (*itr2).type,
187                                        (*itr2).defaultvalue)) {
188                     DebugOut() << "AMBIF Initialize Couldn't regist property[" 
189                                << vi.name << "]\n";
190                     continue;
191                 }
192                 vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
193                         vi.name, (*itr2).defaultvalue);
194                 vi.isCustom = true;
195             }
196             vehicleinfoArray.push_back(vi);
197             propertylist.push_back(vi.name);
198             DebugOut() << "AMBIF Initialize regist propertyname = " 
199                        << vi.name << "\n";
200         }
201     }
202     routingEngine->setSupported(supported(), this);
203     return true;
204 }
205
206 AMBVehicleInfo *
207 AMBIF::getPropertyRequest(std::string propertyname)
208 {
209     DebugOut() << "AMBIF getPropertyRequest(" << propertyname << ")\n";
210     AsyncPropertyRequest request;
211     request.property = propertyname;
212     request.completed = [](AsyncPropertyReply *reply) {
213         if (reply->success) {
214             DebugOut() << "AMBIF getPropertyRequest completed success!!.\n";
215         }
216         else {
217             DebugOut() << "AMBIF getPropertyRequest completed false!!.\n";
218         }
219     };
220
221     AsyncPropertyReply *reply = routingEngine->getPropertyAsync(request);
222     lock();
223     AMBVehicleInfo *vehicleinfo = find(propertyname);
224     if (vehicleinfo == NULL) {
225         delete reply;
226         unLock();
227         return NULL;
228     }
229     if (vehicleinfo->value != reply->value && reply->success) {
230         delete vehicleinfo->value;
231         vehicleinfo->value = reply->value->copy();
232     }
233     delete reply;
234     unLock();
235     DebugOut() << "AMBIF getPropertyRequest after call "
236                << vehicleinfo->value->toString() << std::endl;
237     return vehicleinfo;
238 }
239
240 void
241 AMBIF::setPropertyRequest(AMBVehicleInfo *vehicleinfo)
242 {
243     AsyncSetPropertyRequest request;
244     request.property = vehicleinfo->name;
245     request.value = vehicleinfo->value;
246     request.completed = [](AsyncPropertyReply *reply) {
247         if (reply->success) {
248             DebugOut()<<"AMBIF" << reply->property << ":" << reply->value->toString() << std::endl;
249         }
250         else {
251             DebugOut()<<"AMBIF" << reply->property << " isn't registered." << std::endl;
252         }
253     };
254     AsyncPropertyReply *reply = routingEngine->setProperty(request);
255     if (reply != NULL) {
256         delete reply;
257     }
258 }
259
260 void
261 AMBIF::updateProperty(AMBVehicleInfo *vehicleinfo)
262 {
263     routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value,
264                                   uuid());
265     AMBVehicleInfo *ambvehicleinfo = find(vehicleinfo->name);
266     lock();
267     if (ambvehicleinfo != NULL) {
268         delete ambvehicleinfo->value;
269         ambvehicleinfo->value = vehicleinfo->value->copy();
270     }
271     unLock();
272 }
273
274 void
275 AMBIF::lock()
276 {
277     pthread_mutex_lock(&mutex);
278 }
279
280 void
281 AMBIF::unLock()
282 {
283     pthread_mutex_unlock(&mutex);
284 }
285
286 void
287 AMBIF::requestUpdate(AMBVehicleInfo *vehicleinfo)
288 {
289     DebugOut() << "AMBIF requestUpdate request property name is "
290                << vehicleinfo->name << "\n";
291     if (find(vehicleinfo->name) != NULL) {
292         updateProperty(vehicleinfo);
293     }
294     else {
295         setPropertyRequest(vehicleinfo);
296     }
297 }
298
299 bool
300 AMBIF::registVehicleInfo(std::string propertyName,
301                          VehicleInfoDefine::Status::DataType type, string value)
302 {
303     DebugOut() << "AMBIF registVehicleInfo(" << propertyName 
304                << ")\n";
305     VehicleProperty::PropertyTypeFactoryCallback factory;
306     switch (type) {
307     case VehicleInfoDefine::Status::INT:
308     {
309         factory = [value]() {
310             return new BasicPropertyType<int>(value);
311         };
312         break;
313     }
314     case VehicleInfoDefine::Status::DOUBLE:
315     {
316         factory = [value]() {
317             return new BasicPropertyType<double>(value);
318         };
319         break;
320     }
321     case VehicleInfoDefine::Status::CHAR:
322     {
323         factory = [value]() {
324             return new BasicPropertyType<char>(value);
325         };
326         break;
327     }
328     case VehicleInfoDefine::Status::INT16:
329     {
330         factory = [value]() {
331             return new BasicPropertyType<int16_t>(value);
332         };
333         break;
334     }
335     case VehicleInfoDefine::Status::UINT16:
336     {
337         factory = [value]() {
338             return new BasicPropertyType<uint16_t>(value);
339         };
340         break;
341     }
342     case VehicleInfoDefine::Status::UINT32:
343     {
344         factory = [value]() {
345             return new BasicPropertyType<uint32_t>(value);
346         };
347         break;
348     }
349     case VehicleInfoDefine::Status::INT64:
350     {
351         factory = [value]() {
352             return new BasicPropertyType<int64_t>(value);
353         };
354         break;
355     }
356     case VehicleInfoDefine::Status::UINT64:
357     {
358         factory = [value]() {
359             return new BasicPropertyType<uint64_t>(value);
360         };
361         break;
362     }
363     case VehicleInfoDefine::Status::BOOL:
364     {
365         factory = [value]() {
366             return new BasicPropertyType<bool>(value);
367         };
368         break;
369     }
370     default:
371     {
372         return false;
373     }
374     }
375     return VehicleProperty::registerProperty(propertyName, factory);
376 }
377
378 AMBVehicleInfo *
379 AMBIF::find(std::string propertyName)
380 {
381     for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end();
382          itr++) {
383         if ((*itr).name == propertyName) {
384             return &(*itr);
385         }
386     }
387     return NULL;
388 }