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