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