Merge pull request #13 from timkoma/MasterPropertyList
[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(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. The reply from this request is passed
236          * into the completed call.  The completed callback must free the reply before it returns or there will be a leak.
237          */
238         GetRangedPropertyCompletedSignal completed;
239
240         /*!
241          * \brief timeBegin set this to request values for the specified property beggining at this time.  Time is seconds\
242          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
243          */
244         double timeBegin;
245
246         /*!
247          * \brief timeEnd set this to request values for the specified property beggining at this time.  Time is seconds\
248          * since the unix epoc.  Set this to '0' if you do not want values within a time range.
249          */
250         double timeEnd;
251
252         /*!
253          * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value.  Set to -1 if
254          * you don't want values within a sequence ranges.
255          */
256         int32_t sequenceBegin;
257
258         /*!
259          * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value.  Set to -1 if
260          * you don't want values within a sequence ranges.
261          */
262         int32_t sequenceEnd;
263 };
264
265 /*!
266  * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
267  * the source should set success to 'true' and populate the 'values' member if the request was successful.
268  * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
269  */
270 class AsyncRangePropertyReply: public AsyncRangePropertyRequest
271 {
272 public:
273         AsyncRangePropertyReply(AsyncRangePropertyRequest request)
274                 :AsyncRangePropertyRequest(request), success(false)
275         {
276
277         }
278
279         ~AsyncRangePropertyReply()
280         {
281                 for(auto itr = values.begin(); itr != values.end(); itr++)
282                 {
283                         delete (*itr);
284                 }
285
286                 values.clear();
287         }
288
289         /*!
290          * \brief error this is set if there was an error in the request.  "success" will also be set to false.
291          */
292         AsyncPropertyReply::Error error;
293
294         /*!
295          * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
296          */
297         std::list<AbstractPropertyType*> values;
298
299         /*!
300          * \brief success this will be true if the request was successful.  If not, this is false and error is set.
301          */
302         bool success;
303 };
304
305 class AbstractRoutingEngine
306 {
307 public:
308         virtual ~AbstractRoutingEngine();
309
310         virtual void setSupported(PropertyList supported, AbstractSource* source) = 0;
311         virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
312
313
314         /// Deprecated:
315         void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
316         {
317                 DebugOut(DebugOut::Warning)<<"updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated.  use new updateProperty(AbstractPropertyType*, const std::string &)"<<endl;
318                 updateProperty(value,uuid);
319         }
320
321         virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
322         virtual PropertyList supported() = 0;
323
324         /// sinks:
325         virtual void registerSink(AbstractSink* self) = 0;
326         virtual void  unregisterSink(AbstractSink* self) = 0;
327
328         /**
329          * /brief sourcesForProperty
330          * /param property
331          * /return list of source uuid's that support the "property"
332          */
333         virtual std::list<std::string> sourcesForProperty(VehicleProperty::Property property) = 0;
334
335         /**
336          * /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.
337          * /see AsyncPropertyRequest
338          * /see AsyncPropertyReply.
339          * /param request requested property.
340          * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
341          * /example AsyncPropertyRequest request;
342          * request.property = VehicleProperty::VehicleSpeed
343          * request.completed = [](AsyncPropertyReply* reply)
344          * {
345          *   //you own the reply
346          *   delete reply;
347          * };
348          * routingEngine->getPropertyAsync(request);
349          */
350         virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
351
352         /*!
353          * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
354          * \param request the request containing the property and other information required by the query
355          * \return a pointer to the reply.
356          * \example AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
357          *
358          *      vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
359          *      vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
360          *
361          *      PropertyList requestList;
362          *      requestList.push_back(VehicleProperty::VehicleSpeed);
363          *      requestList.push_back(VehicleProperty::EngineSpeed);
364          *
365          *      vehicleSpeedFromLastWeek.properties = requestList;
366          *      vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
367          *      {
368          *              std::list<AbstractPropertyType*> values = reply->values;
369          *              for(auto itr = values.begin(); itr != values.end(); itr++)
370          *              {
371          *                      auto val = *itr;
372          *                      DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
373          *              }
374          *
375          *              delete reply;
376          *      };
377          *
378          *      routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
379          *
380          */
381         virtual AsyncRangePropertyReply * getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
382
383         /*!
384          * \brief setProperty sets a property to a value.
385          * \see AsyncSetPropertyRequest
386          * \see AsyncPropertyReply
387          * \param request the request containing the property and the value to set
388          * \return a pointer to the reply which is owned by the caller of this method
389          * \example 
390          */
391         virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
392
393         /*!
394          * \brief subscribeToProperty subscribe to changes made to a property value.
395          * \param propertyName name of the property to request a subscription for.
396          * \param self pointer to the sink who is subscribing.
397          * \example
398          * //somewhere in the sink:
399          * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
400          *
401          * //... elsewhere in the sink, this will be called when a property changes:
402          * void MySink::propertyChanged(const AbstractPropertyType* property)
403          * {
404          *   if(property->name == VehicleProperty::EngineSpeed)
405          *   {
406          *      ...
407          *   }
408          * }
409          */
410         virtual bool subscribeToProperty(VehicleProperty::Property propertyName, AbstractSink* self) = 0;
411
412         /*!
413          * \brief subscribeToProperty subscribe to changes made to a property value.
414          * \param propertyName name of the property to request a subscription for.
415          * \param sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
416          * \param self pointer to the sink who is subscribing.
417          */
418         virtual bool subscribeToProperty(VehicleProperty::Property propertyName, std::string sourceUuidFilter, 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 zoneFilter zone to filter.  Only updates from this zone will be passed to the sink.
425          * \param self pointer to the sink who is subscribing.
426          */
427         virtual bool subscribeToProperty(VehicleProperty::Property propertyName, std::string sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
428
429         virtual bool unsubscribeToProperty(VehicleProperty::Property, AbstractSink* self) = 0;
430
431         virtual PropertyInfo getPropertyInfo(VehicleProperty::Property, std::string sourceUuid) = 0;
432 };
433
434 #endif // ABSTRACTROUTINGENGINE_H