new amb api in 0.10 requires property names for each type
[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     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, AMBConfig *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 = " << vi.name
199                        << "\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 =
247             [](AsyncPropertyReply *reply) {
248                 if (reply->success) {
249                     DebugOut()<<"AMBIF" << reply->property << ":" << reply->value->toString() << std::endl;
250                 }
251                 else {
252                     DebugOut()<<"AMBIF" << reply->property << " isn't registered." << std::endl;
253                 }
254             };
255     AsyncPropertyReply *reply = routingEngine->setProperty(request);
256     if (reply != NULL) {
257         delete reply;
258     }
259 }
260
261 void
262 AMBIF::updateProperty(AMBVehicleInfo *vehicleinfo)
263 {
264     routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value,
265                                   uuid());
266     AMBVehicleInfo *ambvehicleinfo = find(vehicleinfo->name);
267     lock();
268     if (ambvehicleinfo != NULL) {
269         delete ambvehicleinfo->value;
270         ambvehicleinfo->value = vehicleinfo->value->copy();
271     }
272     unLock();
273 }
274
275 void
276 AMBIF::lock()
277 {
278     pthread_mutex_lock(&mutex);
279 }
280
281 void
282 AMBIF::unLock()
283 {
284     pthread_mutex_unlock(&mutex);
285 }
286
287 void
288 AMBIF::requestUpdate(AMBVehicleInfo *vehicleinfo)
289 {
290     DebugOut() << "AMBIF requestUpdate request property name is "
291                << vehicleinfo->name << "\n";
292     if (find(vehicleinfo->name) != NULL) {
293         updateProperty(vehicleinfo);
294     }
295     else {
296         setPropertyRequest(vehicleinfo);
297     }
298 }
299
300 bool
301 AMBIF::registVehicleInfo(std::string propertyName, DataType type, string value)
302 {
303     DebugOut() << "AMBIF registVehicleInfo(" << propertyName << ")\n";
304     VehicleProperty::PropertyTypeFactoryCallback factory;
305     switch (type) {
306     case INT:
307     {
308         factory = [value, propertyName]() {
309             return new BasicPropertyType<int>(propertyName, value);
310         };
311         break;
312     }
313     case DOUBLE:
314     {
315         factory = [value, propertyName]() {
316             return new BasicPropertyType<double>(propertyName, value);
317         };
318         break;
319     }
320     case CHAR:
321     {
322         factory = [value, propertyName]() {
323             return new BasicPropertyType<char>(propertyName, value);
324         };
325         break;
326     }
327     case INT16:
328     {
329         factory = [value, propertyName]() {
330             return new BasicPropertyType<int16_t>(propertyName, value);
331         };
332         break;
333     }
334     case UINT16:
335     {
336         factory = [value, propertyName]() {
337             return new BasicPropertyType<uint16_t>(propertyName, value);
338         };
339         break;
340     }
341     case UINT32:
342     {
343         factory = [value, propertyName]() {
344             return new BasicPropertyType<uint32_t>(propertyName, value);
345         };
346         break;
347     }
348     case INT64:
349     {
350         factory = [value, propertyName]() {
351             return new BasicPropertyType<int64_t>(propertyName, value);
352         };
353         break;
354     }
355     case UINT64:
356     {
357         factory = [value, propertyName]() {
358             return new BasicPropertyType<uint64_t>(propertyName, value);
359         };
360         break;
361     }
362     case BOOL:
363     {
364         factory = [value, propertyName]() {
365             return new BasicPropertyType<bool>(propertyName, value);
366         };
367         break;
368     }
369     default:
370     {
371         return false;
372     }
373     }
374     return VehicleProperty::registerProperty(propertyName, factory);
375 }
376
377 AMBVehicleInfo *
378 AMBIF::find(std::string propertyName)
379 {
380     for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end();
381             itr++) {
382         if ((*itr).name == propertyName) {
383             return &(*itr);
384         }
385     }
386     return NULL;
387 }