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