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