manual merge of tripzero/master
[profile/ivi/automotive-message-broker.git] / lib / abstractroutingengine.h
1 /*
2         Copyright (C) 2012  Intel 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 #ifndef ABSTRACTROUTINGENGINE_H
21 #define ABSTRACTROUTINGENGINE_H
22
23 #include <sys/types.h>
24 #include <stdlib.h>
25 #include <boost/any.hpp>
26 #include <functional>
27 #include <string>
28 #include <time.h>
29
30 #include "vehicleproperty.h"
31 #include "abstractpropertytype.h"
32 #include "propertyinfo.hpp"
33
34 class AbstractSink;
35 class AbstractSource;
36 class AsyncPropertyReply;
37 class AsyncRangePropertyReply;
38 class AsyncSetPropertyRequest;
39
40
41 typedef std::function<void (AsyncPropertyReply*)> GetPropertyCompletedSignal;
42 typedef std::function<void (AsyncRangePropertyReply*)> GetRangedPropertyCompletedSignal;
43 typedef std::function<void (AsyncPropertyReply*)> TimedOutCallback;
44
45 /*!
46  * \brief The AsyncPropertyRequest class is used by sinks to request property values.
47  * \see AbstractRoutingEngine::getPropertyAsync
48  * \see AsyncPropertyReply
49  */
50 class AsyncPropertyRequest
51 {
52 public:
53         AsyncPropertyRequest()
54                 :property(VehicleProperty::NoValue),zoneFilter(Zone::None), timeout(10000)
55         {
56
57         }
58
59         AsyncPropertyRequest(const AsyncPropertyRequest &request)
60         {
61                 this->property = request.property;
62                 this->completed = request.completed;
63                 this->sourceUuidFilter = request.sourceUuidFilter;
64                 this->zoneFilter = request.zoneFilter;
65                 this->timeout = request.timeout;
66         }
67
68         AsyncPropertyRequest & operator = (const AsyncPropertyRequest & other)
69         {
70                 this->property = other.property;
71                 this->completed = other.completed;
72                 this->sourceUuidFilter = other.sourceUuidFilter;
73                 this->zoneFilter = other.zoneFilter;
74                 this->timeout = other.timeout;
75
76                 return *this;
77         }
78
79         virtual ~AsyncPropertyRequest() { }
80
81         /*!
82          * \brief property property to request.
83          */
84         VehicleProperty::Property property;
85
86         /*!
87          * \brief sourceUuidFilter the requesting sink should use this to filter on a specific source or leave blank to use any source
88          */
89         std::string sourceUuidFilter;
90
91         /*!
92          * \brief zoneFilter the requesting sink should use this if he wants to filter on a specific zone
93          */
94         Zone::Type zoneFilter;
95
96         /*!
97          * \brief completed the callback when the request has been completed.
98          */
99         GetPropertyCompletedSignal completed;
100
101         /*!
102          * \brief use to specify a timeout in ms for the request.  When a timeout occurs, the 'completed' callback
103          * will be called with an error.  @see AsyncPropertyReply
104          * default value is: 10000 ms
105          */
106         uint timeout;
107
108         /*!
109          * \brief pid requesting process id
110          */
111         std::string pid;
112 };
113
114 /*!
115  * \brief The AsyncPropertyReply class is used by sources to reply to Get and Set operations.  The source should
116  * set success to true if the call is successful or 'false' if the request was not successful and set 'error'
117  * to the appropriate error.
118  * \see AbstractRoutingEngine::getPropertyAsync
119  * \see AsyncPropertyReply
120  * \see AbstractSource::Operations
121  * \see AbstractSource::getPropertyAsync
122  */
123 class AsyncPropertyReply: public AsyncPropertyRequest
124 {
125 public:
126         AsyncPropertyReply();
127
128         AsyncPropertyReply(const AsyncPropertyRequest &request);
129
130         AsyncPropertyReply(const AsyncSetPropertyRequest &request);
131
132         virtual ~AsyncPropertyReply();
133
134         /*!
135          * \brief The Error enum
136          */
137         enum Error {
138                 NoError = 0,
139                 Timeout,
140                 InvalidOperation,
141                 PermissionDenied,
142                 ZoneNotSupported
143         };
144
145         static std::string errorToStr(Error err)
146         {
147                 if(err == NoError)
148                         return "NoError";
149                 else if(err == Timeout)
150                         return "Timeout";
151                 else if(err == InvalidOperation)
152                         return "InvalidOperation";
153                 else if(err == PermissionDenied)
154                         return "PermissionDenied";
155                 else if(err == ZoneNotSupported)
156                         return "ZoneNotSupported";
157         }
158
159         /*!
160          * \brief value of the reply.  This may be null if success = false.  This is owned by the source.
161          */
162         AbstractPropertyType* value;
163
164         /*!
165          * \brief success indicates if the request was successfull or not.  True means success.  False means fail and the 'error'
166          * member should be set.
167          */
168         bool success;
169
170         /*!
171          * \brief timed out callback is called when the reply times out.  This is so sources can avoid using this reply which
172          * may become invalid after it times out.
173          */
174         TimedOutCallback timedout;
175
176         /*!
177          * \brief error contains the error if the request was not successful.\
178          * \see Error
179          */
180         Error error;
181
182 private:
183         void setTimeout();
184         GSource* timeoutSource;
185 };
186
187 /*!
188  * \brief The AsyncSetPropertyRequest class is used by sinks to set a property to the 'value'.  The source will reply
189  * with a AsyncPropertyReply containing the new value or an error.
190  * \see AbstractRoutingEngine::setProperty
191  * \see AsyncPropertyReply
192  */
193 class AsyncSetPropertyRequest: public AsyncPropertyRequest
194 {
195 public:
196         AsyncSetPropertyRequest()
197                 :value(NULL)
198         {
199
200         }
201
202         AsyncSetPropertyRequest(const AsyncPropertyRequest &request)
203                 :AsyncPropertyRequest(request), value(NULL)
204         {
205
206         }
207
208         virtual ~AsyncSetPropertyRequest()
209         {
210
211         }
212
213         /*!
214          * \brief value the new value to set the property to.
215          */
216         AbstractPropertyType* value;
217 };
218
219 /*!
220  * \brief The AsyncRangePropertyRequest class is used by sinks to request values within a time or sequence range
221  * \see AbstractRoutingEngine::getRangePropertyAsync
222  */
223 class AsyncRangePropertyRequest
224 {
225 public:
226         AsyncRangePropertyRequest()
227                 :zone(Zone::None), timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
228         {
229
230         }
231
232         AsyncRangePropertyRequest(const AsyncRangePropertyRequest &request)
233         {
234                 this->properties = request.properties;
235                 this->completed = request.completed;
236                 this->timeBegin = request.timeBegin;
237                 this->timeEnd = request.timeEnd;
238                 this->sequenceBegin = request.sequenceBegin;
239                 this->sequenceEnd = request.sequenceEnd;
240                 this->sourceUuid = request.sourceUuid;
241                 this->zone = request.zone;
242         }
243
244         virtual ~AsyncRangePropertyRequest() {}
245
246         /*!
247          * \brief properties list of properties to request
248          */
249         PropertyList properties;
250
251         /*!
252          * \brief sourceUuid if the sink wishes to request a specific source, this should be set to the uuid of the source.
253          */
254         std::string sourceUuid;
255
256         /*!
257          * \brief zone if the sink wishes to request a specific zone, this should be set to the desired zone .
258          */
259         Zone::Type zone;
260
261         /*!
262          * \brief completed callback that is called when the ranged request is complete. The reply from this request is passed
263          * into the completed call.  The completed callback must free the reply before it returns or there will be a leak.
264          */
265         GetRangedPropertyCompletedSignal completed;
266
267         /*!
268          * \brief timeBegin set this to request values for the specified property beggining at this time.  Time is seconds\
269          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
270          */
271         double timeBegin;
272
273         /*!
274          * \brief timeEnd set this to request values for the specified property beggining at this time.  Time is seconds\
275          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
276          */
277         double timeEnd;
278
279         /*!
280          * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value.  Set to -1 if
281          * you don't want values within a sequence ranges.
282          */
283         int32_t sequenceBegin;
284
285         /*!
286          * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value.  Set to -1 if
287          * you don't want values within a sequence ranges.
288          */
289         int32_t sequenceEnd;
290
291         /*!
292          * \brief pid requesting process id
293          */
294         std::string pid;
295 };
296
297 /*!
298  * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
299  * the source should set success to 'true' and populate the 'values' member if the request was successful.
300  * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
301  */
302 class AsyncRangePropertyReply: public AsyncRangePropertyRequest
303 {
304 public:
305         AsyncRangePropertyReply(AsyncRangePropertyRequest request)
306                 :AsyncRangePropertyRequest(request), success(false)
307         {
308
309         }
310
311         ~AsyncRangePropertyReply()
312         {
313                 for(auto itr = values.begin(); itr != values.end(); itr++)
314                 {
315                         delete (*itr);
316                 }
317
318                 values.clear();
319         }
320
321         /*!
322          * \brief error this is set if there was an error in the request.  "success" will also be set to false.
323          */
324         AsyncPropertyReply::Error error;
325
326         /*!
327          * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
328          */
329         std::list<AbstractPropertyType*> values;
330
331         /*!
332          * \brief success this will be true if the request was successful.  If not, this is false and error is set.
333          */
334         bool success;
335 };
336
337 class AbstractRoutingEngine
338 {
339 public:
340         typedef std::function<void (AbstractPropertyType* value)> PropertyChangedType;
341
342         AbstractRoutingEngine(std::map<std::string, std::string> configuration):mConfig(configuration) {}
343         virtual ~AbstractRoutingEngine();
344
345         virtual void registerSource(AbstractSource* src) = 0;
346         virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
347
348
349         /// Deprecated:
350         void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
351         {
352                 DebugOut(DebugOut::Warning)<<"updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated.  use new updateProperty(AbstractPropertyType*, const std::string &)"<<endl;
353                 updateProperty(value,uuid);
354         }
355
356         virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
357         virtual PropertyList supported() = 0;
358
359         /// sinks:
360         virtual void registerSink(AbstractSink* self) = 0;
361         virtual void  unregisterSink(AbstractSink* self) = 0;
362
363         /**
364          * /brief sourcesForProperty
365          * /param property
366          * /return vector of source uuid's that support the "property"
367          */
368         virtual std::vector<std::string> sourcesForProperty(const VehicleProperty::Property & property) = 0;
369
370         /**
371          * /brief getPropertyAsync requests a property value from a source.  This call has a timeout and the callback specified in the request will always be called.
372          * /see AsyncPropertyRequest
373          * /see AsyncPropertyReply.
374          * /param request requested property.
375          * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
376          * /example AsyncPropertyRequest request;
377          * request.property = VehicleProperty::VehicleSpeed
378          * request.completed = [](AsyncPropertyReply* reply)
379          * {
380          *   //you own the reply
381          *   delete reply;
382          * };
383          * routingEngine->getPropertyAsync(request);
384          */
385         virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
386
387         /*!
388          * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
389          * \param request the request containing the property and other information required by the query
390          * \return a pointer to the reply.
391          * \example AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
392          *
393          *      vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
394          *      vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
395          *
396          *      PropertyList requestList;
397          *      requestList.push_back(VehicleProperty::VehicleSpeed);
398          *      requestList.push_back(VehicleProperty::EngineSpeed);
399          *
400          *      vehicleSpeedFromLastWeek.properties = requestList;
401          *      vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
402          *      {
403          *              std::list<AbstractPropertyType*> values = reply->values;
404          *              for(auto itr = values.begin(); itr != values.end(); itr++)
405          *              {
406          *                      auto val = *itr;
407          *                      DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
408          *              }
409          *
410          *              delete reply;
411          *      };
412          *
413          *      routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
414          *
415          */
416
417         virtual void getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
418
419         /*!
420          * \brief setProperty sets a property to a value.
421          * \see AsyncSetPropertyRequest
422          * \see AsyncPropertyReply
423          * \param request the request containing the property and the value to set
424          * \return a pointer to the reply which is owned by the caller of this method
425          * \example
426          */
427         virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
428
429         /*!
430          * \brief subscribeToProperty subscribes to propertyName.  Value changes will be passed to callback.
431          * \param propertyName
432          * \param callback
433          * \param pid process id of the requesting application
434          * \return subscription handle
435          */
436         virtual uint subscribeToProperty(const VehicleProperty::Property & propertyName, PropertyChangedType callback, std::string pid="") = 0;
437
438         /*!
439          * \brief unsubscribeToProperty
440          * \param handle
441          */
442         virtual void unsubscribeToProperty(uint handle) = 0;
443
444         /*!
445          * \brief subscribeToProperty subscribe to changes made to a property value.
446          * \param propertyName name of the property to request a subscription for.
447          * \param self pointer to the sink who is subscribing.
448          * \example
449          * //somewhere in the sink:
450          * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
451          *
452          * //... elsewhere in the sink, this will be called when a property changes:
453          * void MySink::propertyChanged(const AbstractPropertyType* property)
454          * {
455          *   if(property->name == VehicleProperty::EngineSpeed)
456          *   {
457          *      ...
458          *   }
459          * }
460          */
461         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, AbstractSink* self) = 0;
462
463         /*!
464          * \brief subscribeToProperty subscribe to changes made to a property value.
465          * \param propertyName name of the property to request a subscription for.
466          * \param sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
467          * \param self pointer to the sink who is subscribing.
468          */
469         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self) = 0;
470
471         /*!
472          * \brief subscribeToProperty subscribe to changes made to a property value.
473          * \param propertyName name of the property to request a subscription for.
474          * \param sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
475          * \param zoneFilter zone to filter.  Only updates from this zone will be passed to the sink.
476          * \param self pointer to the sink who is subscribing.
477          */
478         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
479
480         virtual bool unsubscribeToProperty(const VehicleProperty::Property &, AbstractSink* self) = 0;
481
482         virtual PropertyInfo getPropertyInfo(const VehicleProperty::Property &, const std::string & sourceUuid) = 0;
483
484 protected:
485         std::map<std::string, std::string> mConfig;
486 };
487
488 #endif // ABSTRACTROUTINGENGINE_H