[Documentation] - additional documentation improvements
[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.
116  * The source should 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         /*!
146          * \brief errorToStr returns string representing the Error
147          */
148         static std::string errorToStr(Error err)
149         {
150                 if(err == NoError)
151                         return "NoError";
152                 else if(err == Timeout)
153                         return "Timeout";
154                 else if(err == InvalidOperation)
155                         return "InvalidOperation";
156                 else if(err == PermissionDenied)
157                         return "PermissionDenied";
158                 else if(err == ZoneNotSupported)
159                         return "ZoneNotSupported";
160         }
161
162         /*!
163          * \brief value of the reply.  This may be null if success = false.  This is owned by the source.
164          */
165         AbstractPropertyType* value;
166
167         /*!
168          * \brief success indicates if the request was successfull or not.  True means success.  False means fail and the 'error'
169          * member should be set.
170          */
171         bool success;
172
173         /*!
174          * \brief timed out callback is called when the reply times out.  This is so sources can avoid using this reply which
175          * may become invalid after it times out.
176          */
177         TimedOutCallback timedout;
178
179         /*!
180          * \brief error contains the error if the request was not successful.\
181          * \see Error
182          */
183         Error error;
184
185 private:
186         void setTimeout();
187         GSource* timeoutSource;
188 };
189
190 /*!
191  * \brief The AsyncSetPropertyRequest class is used by sinks to set a property to the 'value'.  The source will reply
192  * with a AsyncPropertyReply containing the new value or an error.
193  * \see AbstractRoutingEngine::setProperty
194  * \see AsyncPropertyReply
195  */
196 class AsyncSetPropertyRequest: public AsyncPropertyRequest
197 {
198 public:
199         AsyncSetPropertyRequest()
200                 :value(NULL)
201         {
202
203         }
204
205         AsyncSetPropertyRequest(const AsyncPropertyRequest &request)
206                 :AsyncPropertyRequest(request), value(NULL)
207         {
208
209         }
210
211         virtual ~AsyncSetPropertyRequest()
212         {
213
214         }
215
216         /*!
217          * \brief value the new value to set the property to.
218          */
219         AbstractPropertyType* value;
220 };
221
222 /*!
223  * \brief The AsyncRangePropertyRequest class is used by sinks to request values within a time or sequence range
224  * \see AbstractRoutingEngine::getRangePropertyAsync
225  */
226 class AsyncRangePropertyRequest
227 {
228 public:
229         AsyncRangePropertyRequest()
230                 :zone(Zone::None), timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
231         {
232
233         }
234
235         AsyncRangePropertyRequest(const AsyncRangePropertyRequest &request)
236         {
237                 this->properties = request.properties;
238                 this->completed = request.completed;
239                 this->timeBegin = request.timeBegin;
240                 this->timeEnd = request.timeEnd;
241                 this->sequenceBegin = request.sequenceBegin;
242                 this->sequenceEnd = request.sequenceEnd;
243                 this->sourceUuid = request.sourceUuid;
244                 this->zone = request.zone;
245         }
246
247         virtual ~AsyncRangePropertyRequest() {}
248
249         /*!
250          * \brief properties list of properties to request
251          */
252         PropertyList properties;
253
254         /*!
255          * \brief sourceUuid if the sink wishes to request a specific source, this should be set to the uuid of the source.
256          */
257         std::string sourceUuid;
258
259         /*!
260          * \brief zone if the sink wishes to request a specific zone, this should be set to the desired zone .
261          */
262         Zone::Type zone;
263
264         /*!
265          * \brief completed callback
266          * 'completed' is called when the ranged request is complete. The reply from this request is passed
267          * into the completed call.  The completed callback must free the reply before it returns or there will be a leak.
268          */
269         GetRangedPropertyCompletedSignal completed;
270
271         /*!
272          * \brief timeBegin
273          * Set this to request values for the specified property beggining at this time.  Time is seconds\
274          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
275          */
276         double timeBegin;
277
278         /*!
279          * \brief timeEnd
280          * Set this to request values for the specified property beggining at this time.  Time is seconds\
281          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
282          */
283         double timeEnd;
284
285         /*!
286          * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value.  Set to -1 if
287          * you don't want values within a sequence ranges.
288          */
289         int32_t sequenceBegin;
290
291         /*!
292          * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value.  Set to -1 if
293          * you don't want values within a sequence ranges.
294          */
295         int32_t sequenceEnd;
296
297         /*!
298          * \brief pid requesting process id
299          */
300         std::string pid;
301 };
302
303 /*!
304  * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
305  * The source should set success to 'true' and populate the 'values' member if the request was successful.
306  * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
307  */
308 class AsyncRangePropertyReply: public AsyncRangePropertyRequest
309 {
310 public:
311         AsyncRangePropertyReply(AsyncRangePropertyRequest request)
312                 :AsyncRangePropertyRequest(request), success(false)
313         {
314
315         }
316
317         ~AsyncRangePropertyReply()
318         {
319                 for(auto itr = values.begin(); itr != values.end(); itr++)
320                 {
321                         delete (*itr);
322                 }
323
324                 values.clear();
325         }
326
327         /*!
328          * \brief error this is set if there was an error in the request.  "success" will also be set to false.
329          */
330         AsyncPropertyReply::Error error;
331
332         /*!
333          * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
334          */
335         std::list<AbstractPropertyType*> values;
336
337         /*!
338          * \brief success this will be true if the request was successful.  If not, this is false and error is set.
339          */
340         bool success;
341 };
342
343 class AbstractRoutingEngine
344 {
345 public:
346         typedef std::function<void (AbstractPropertyType* value)> PropertyChangedType;
347
348         AbstractRoutingEngine(std::map<std::string, std::string> configuration):mConfig(configuration) {}
349         virtual ~AbstractRoutingEngine();
350
351         virtual void registerSource(AbstractSource* src) = 0;
352         virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
353
354
355         /// Deprecated:
356         void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
357         {
358                 DebugOut(DebugOut::Warning)<<"updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated.  use new updateProperty(AbstractPropertyType*, const std::string &)"<<endl;
359                 updateProperty(value,uuid);
360         }
361
362         virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
363         virtual PropertyList supported() = 0;
364
365         /// sinks:
366         virtual void registerSink(AbstractSink* self) = 0;
367         virtual void  unregisterSink(AbstractSink* self) = 0;
368
369         /**
370          * /brief sourcesForProperty
371          * /param property
372          * /return vector of source uuid's that support the "property"
373          */
374         virtual std::vector<std::string> sourcesForProperty(const VehicleProperty::Property & property) = 0;
375
376         /**
377          * /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.
378          * /see AsyncPropertyRequest
379          * /see AsyncPropertyReply.
380          * /param request requested property.
381          * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
382          * /code AsyncPropertyRequest request;
383          * request.property = VehicleProperty::VehicleSpeed
384          * request.completed = [](AsyncPropertyReply* reply)
385          * {
386          *   //you own the reply
387          *   delete reply;
388          * };
389          * routingEngine->getPropertyAsync(request);
390          * /endcode
391          */
392         virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
393
394         /*!
395          * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
396          * \arg request the request containing the property and other information required by the query
397          * \return a pointer to the reply.
398          * \code AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
399          *
400          *      vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
401          *      vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
402          *
403          *      PropertyList requestList;
404          *      requestList.push_back(VehicleProperty::VehicleSpeed);
405          *      requestList.push_back(VehicleProperty::EngineSpeed);
406          *
407          *      vehicleSpeedFromLastWeek.properties = requestList;
408          *      vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
409          *      {
410          *              std::list<AbstractPropertyType*> values = reply->values;
411          *              for(auto itr = values.begin(); itr != values.end(); itr++)
412          *              {
413          *                      auto val = *itr;
414          *                      DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
415          *              }
416          *
417          *              delete reply;
418          *      };
419          *
420          *      routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
421          * \endcode
422          */
423         virtual void getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
424
425         /*!
426          * \brief setProperty sets a property to a value.
427          * \see AsyncSetPropertyRequest
428          * \see AsyncPropertyReply
429          * \arg request the request containing the property and the value to set
430          * \return a pointer to the reply which is owned by the caller of this method
431          * \example
432          */
433         virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
434
435         /*!
436          * \brief subscribeToProperty subscribes to propertyName.  Value changes will be passed to callback.
437          * \arg propertyName
438          * \arg callback
439          * \arg pid process id of the requesting application
440          * \return subscription handle
441          */
442         virtual uint subscribeToProperty(const VehicleProperty::Property & propertyName, PropertyChangedType callback, std::string pid="") = 0;
443
444         /*!
445          * \brief unsubscribeToProperty
446          * \arg handle
447          */
448         virtual void unsubscribeToProperty(uint handle) = 0;
449
450         /*!
451          * \brief subscribeToProperty subscribe to changes made to a property value.
452          * \arg propertyName name of the property to request a subscription for.
453          * \arg self pointer to the sink who is subscribing.
454          * \code
455          * //somewhere in the sink:
456          * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
457          *
458          * //... elsewhere in the sink, this will be called when a property changes:
459          * void MySink::propertyChanged(const AbstractPropertyType* property)
460          * {
461          *   if(property->name == VehicleProperty::EngineSpeed)
462          *   {
463          *      ...
464          *   }
465          * }
466          * \endcode
467          */
468         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, AbstractSink* self) = 0;
469
470         /*!
471          * \brief subscribeToProperty subscribe to changes made to a property value.
472          * \arg propertyName name of the property to request a subscription for.
473          * \arg sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
474          * \arg self pointer to the sink who is subscribing.
475          */
476         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self) = 0;
477
478         /*!
479          * \brief subscribeToProperty subscribe to changes made to a property value.
480          * \arg propertyName name of the property to request a subscription for.
481          * \arg sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
482          * \arg zoneFilter zone to filter.  Only updates from this zone will be passed to the sink.
483          * \arg self pointer to the sink who is subscribing.
484          */
485         virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
486
487         virtual bool unsubscribeToProperty(const VehicleProperty::Property &, AbstractSink* self) = 0;
488
489         virtual PropertyInfo getPropertyInfo(const VehicleProperty::Property &, const std::string & sourceUuid) = 0;
490
491 protected:
492         std::map<std::string, std::string> mConfig;
493 };
494
495 #endif // ABSTRACTROUTINGENGINE_H