basic working plugins
[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) = 0;
312
313         /// Deprecated:
314         void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
315         {
316                 DebugOut(DebugOut::Warning)<<"updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated.  use new updateProperty(AbstractPropertyType*, const std::string &)"<<endl;
317                 updateProperty(value,uuid);
318         }
319
320         virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
321         virtual PropertyList supported() = 0;
322
323         /// sinks:
324         virtual void registerSink(AbstractSink* self) = 0;
325         virtual void  unregisterSink(AbstractSink* self) = 0;
326
327         /**
328          * /brief sourcesForProperty
329          * /param property
330          * /return list of source uuid's that support the "property"
331          */
332         virtual std::list<std::string> sourcesForProperty(VehicleProperty::Property property) = 0;
333
334         /**
335          * /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.
336          * /see AsyncPropertyRequest
337          * /see AsyncPropertyReply.
338          * /param request requested property.
339          * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
340          * /example AsyncPropertyRequest request;
341          * request.property = VehicleProperty::VehicleSpeed
342          * request.completed = [](AsyncPropertyReply* reply)
343          * {
344          *   //you own the reply
345          *   delete reply;
346          * };
347          * routingEngine->getPropertyAsync(request);
348          */
349         virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
350
351         /*!
352          * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
353          * \param request the request containing the property and other information required by the query
354          * \return a pointer to the reply.
355          * \example AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
356          *
357          *      vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
358          *      vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
359          *
360          *      PropertyList requestList;
361          *      requestList.push_back(VehicleProperty::VehicleSpeed);
362          *      requestList.push_back(VehicleProperty::EngineSpeed);
363          *
364          *      vehicleSpeedFromLastWeek.properties = requestList;
365          *      vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
366          *      {
367          *              std::list<AbstractPropertyType*> values = reply->values;
368          *              for(auto itr = values.begin(); itr != values.end(); itr++)
369          *              {
370          *                      auto val = *itr;
371          *                      DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
372          *              }
373          *
374          *              delete reply;
375          *      };
376          *
377          *      routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
378          *
379          */
380         virtual AsyncRangePropertyReply * getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
381
382         /*!
383          * \brief setProperty sets a property to a value.
384          * \see AsyncSetPropertyRequest
385          * \see AsyncPropertyReply
386          * \param request the request containing the property and the value to set
387          * \return a pointer to the reply which is owned by the caller of this method
388          * \example 
389          */
390         virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
391
392         /*!
393          * \brief subscribeToProperty subscribe to changes made to a property value.
394          * \param propertyName name of the property to request a subscription for.
395          * \param self pointer to the sink who is subscribing.
396          * \example
397          * //somewhere in the sink:
398          * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
399          *
400          * //... elsewhere in the sink, this will be called when a property changes:
401          * void MySink::propertyChanged(const AbstractPropertyType* property)
402          * {
403          *   if(property->name == VehicleProperty::EngineSpeed)
404          *   {
405          *      ...
406          *   }
407          * }
408          */
409         virtual void subscribeToProperty(VehicleProperty::Property propertyName, AbstractSink* self) = 0;
410
411         /*!
412          * \brief subscribeToProperty subscribe to changes made to a property value.
413          * \param propertyName name of the property to request a subscription for.
414          * \param sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
415          * \param self pointer to the sink who is subscribing.
416          */
417         virtual void subscribeToProperty(VehicleProperty::Property propertyName, std::string sourceUuidFilter, AbstractSink *self) = 0;
418
419         /*!
420          * \brief subscribeToProperty subscribe to changes made to a property value.
421          * \param propertyName name of the property to request a subscription for.
422          * \param sourceUuidFilter source UUID to filter.  Only property updates from this source will be sent to the sink.
423          * \param zoneFilter zone to filter.  Only updates from this zone will be passed to the sink.
424          * \param self pointer to the sink who is subscribing.
425          */
426         virtual void subscribeToProperty(VehicleProperty::Property propertyName, std::string sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
427
428         virtual void unsubscribeToProperty(VehicleProperty::Property, AbstractSink* self) = 0;
429
430         virtual PropertyInfo getPropertyInfo(VehicleProperty::Property, std::string sourceUuid) = 0;
431 };
432
433 #endif // ABSTRACTROUTINGENGINE_H