2 Copyright (C) 2012 Intel Corporation
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.
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.
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
20 #ifndef ABSTRACTROUTINGENGINE_H
21 #define ABSTRACTROUTINGENGINE_H
23 #include <sys/types.h>
25 #include <boost/any.hpp>
30 #include "vehicleproperty.h"
31 #include "abstractpropertytype.h"
32 #include "propertyinfo.hpp"
36 class AsyncPropertyReply;
37 class AsyncRangePropertyReply;
38 class AsyncSetPropertyRequest;
41 typedef std::function<void (AsyncPropertyReply*)> GetPropertyCompletedSignal;
42 typedef std::function<void (AsyncRangePropertyReply*)> GetRangedPropertyCompletedSignal;
43 typedef std::function<void (AsyncPropertyReply*)> TimedOutCallback;
46 * \brief The AsyncPropertyRequest class is used by sinks to request property values.
47 * \see AbstractRoutingEngine::getPropertyAsync
48 * \see AsyncPropertyReply
50 class AsyncPropertyRequest
53 AsyncPropertyRequest()
54 :property(VehicleProperty::NoValue),zoneFilter(Zone::None), timeout(10000)
59 AsyncPropertyRequest(const AsyncPropertyRequest &request)
61 this->property = request.property;
62 this->completed = request.completed;
63 this->sourceUuidFilter = request.sourceUuidFilter;
64 this->zoneFilter = request.zoneFilter;
65 this->timeout = request.timeout;
68 AsyncPropertyRequest & operator = (const AsyncPropertyRequest & other)
70 this->property = other.property;
71 this->completed = other.completed;
72 this->sourceUuidFilter = other.sourceUuidFilter;
73 this->zoneFilter = other.zoneFilter;
74 this->timeout = other.timeout;
79 virtual ~AsyncPropertyRequest() { }
82 * \brief property property to request.
84 VehicleProperty::Property property;
87 * \brief sourceUuidFilter the requesting sink should use this to filter on a specific source or leave blank to use any source
89 std::string sourceUuidFilter;
92 * \brief zoneFilter the requesting sink should use this if he wants to filter on a specific zone
94 Zone::Type zoneFilter;
97 * \brief completed the callback when the request has been completed.
99 GetPropertyCompletedSignal completed;
102 * \brief use to specify a timeout in ms for the request. When a timeout occurs, the 'completed' callback
103 * will be called with an error. @see AsyncPropertyReply
104 * default value is: 10000 ms
109 * \brief pid requesting process id
115 * \brief The AsyncPropertyReply class is used by sources to reply to Get and Set operations.
116 * The source should set success to true if the call is successful or 'false' if the request was not successful and set 'error'
117 * to the appropriate error.
118 * \see AbstractRoutingEngine::getPropertyAsync
119 * \see AsyncPropertyReply
120 * \see AbstractSource::Operations
121 * \see AbstractSource::getPropertyAsync
123 class AsyncPropertyReply: public AsyncPropertyRequest
126 AsyncPropertyReply();
128 AsyncPropertyReply(const AsyncPropertyRequest &request);
130 AsyncPropertyReply(const AsyncSetPropertyRequest &request);
132 virtual ~AsyncPropertyReply();
135 * \brief The Error enum
146 * \brief errorToStr returns string representing the Error
148 static std::string errorToStr(Error err)
152 else if(err == Timeout)
154 else if(err == InvalidOperation)
155 return "InvalidOperation";
156 else if(err == PermissionDenied)
157 return "PermissionDenied";
158 else if(err == ZoneNotSupported)
159 return "ZoneNotSupported";
163 * \brief value of the reply. This may be null if success = false. This is owned by the source.
165 AbstractPropertyType* value;
168 * \brief success indicates if the request was successfull or not. True means success. False means fail and the 'error'
169 * member should be set.
174 * \brief timed out callback is called when the reply times out. This is so sources can avoid using this reply which
175 * may become invalid after it times out.
177 TimedOutCallback timedout;
180 * \brief error contains the error if the request was not successful.\
187 GSource* timeoutSource;
191 * \brief The AsyncSetPropertyRequest class is used by sinks to set a property to the 'value'. The source will reply
192 * with a AsyncPropertyReply containing the new value or an error.
193 * \see AbstractRoutingEngine::setProperty
194 * \see AsyncPropertyReply
196 class AsyncSetPropertyRequest: public AsyncPropertyRequest
199 AsyncSetPropertyRequest()
205 AsyncSetPropertyRequest(const AsyncPropertyRequest &request)
206 :AsyncPropertyRequest(request), value(NULL)
211 virtual ~AsyncSetPropertyRequest()
217 * \brief value the new value to set the property to.
219 AbstractPropertyType* value;
223 * \brief The AsyncRangePropertyRequest class is used by sinks to request values within a time or sequence range
224 * \see AbstractRoutingEngine::getRangePropertyAsync
226 class AsyncRangePropertyRequest
229 AsyncRangePropertyRequest()
230 :zone(Zone::None), timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
235 AsyncRangePropertyRequest(const AsyncRangePropertyRequest &request)
237 this->properties = request.properties;
238 this->completed = request.completed;
239 this->timeBegin = request.timeBegin;
240 this->timeEnd = request.timeEnd;
241 this->sequenceBegin = request.sequenceBegin;
242 this->sequenceEnd = request.sequenceEnd;
243 this->sourceUuid = request.sourceUuid;
244 this->zone = request.zone;
247 virtual ~AsyncRangePropertyRequest() {}
250 * \brief properties list of properties to request
252 PropertyList properties;
255 * \brief sourceUuid if the sink wishes to request a specific source, this should be set to the uuid of the source.
257 std::string sourceUuid;
260 * \brief zone if the sink wishes to request a specific zone, this should be set to the desired zone .
265 * \brief completed callback
266 * 'completed' is called when the ranged request is complete. The reply from this request is passed
267 * into the completed call. The completed callback must free the reply before it returns or there will be a leak.
269 GetRangedPropertyCompletedSignal completed;
273 * Set this to request values for the specified property beggining at this time. Time is seconds\
274 * since the unix epoc. Set this to '0' if you do not want values within a time range.
280 * Set this to request values for the specified property beggining at this time. Time is seconds\
281 * since the unix epoc. Set this to '0' if you do not want values within a time range.
286 * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value. Set to -1 if
287 * you don't want values within a sequence ranges.
289 int32_t sequenceBegin;
292 * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value. Set to -1 if
293 * you don't want values within a sequence ranges.
298 * \brief pid requesting process id
304 * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
305 * The source should set success to 'true' and populate the 'values' member if the request was successful.
306 * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
308 class AsyncRangePropertyReply: public AsyncRangePropertyRequest
311 AsyncRangePropertyReply(AsyncRangePropertyRequest request)
312 :AsyncRangePropertyRequest(request), success(false)
317 ~AsyncRangePropertyReply()
319 for(auto itr = values.begin(); itr != values.end(); itr++)
328 * \brief error this is set if there was an error in the request. "success" will also be set to false.
330 AsyncPropertyReply::Error error;
333 * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
335 std::list<AbstractPropertyType*> values;
338 * \brief success this will be true if the request was successful. If not, this is false and error is set.
343 class AbstractRoutingEngine
346 typedef std::function<void (AbstractPropertyType* value)> PropertyChangedType;
348 AbstractRoutingEngine(std::map<std::string, std::string> configuration):mConfig(configuration) {}
349 virtual ~AbstractRoutingEngine();
351 virtual void registerSource(AbstractSource* src) = 0;
352 virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
356 void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
358 DebugOut(DebugOut::Warning)<<"updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated. use new updateProperty(AbstractPropertyType*, const std::string &)"<<endl;
359 updateProperty(value,uuid);
362 virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
363 virtual PropertyList supported() = 0;
366 virtual void registerSink(AbstractSink* self) = 0;
367 virtual void unregisterSink(AbstractSink* self) = 0;
370 * /brief sourcesForProperty
372 * /return vector of source uuid's that support the "property"
374 virtual std::vector<std::string> sourcesForProperty(const VehicleProperty::Property & property) = 0;
377 * /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.
378 * /see AsyncPropertyRequest
379 * /see AsyncPropertyReply.
380 * /param request requested property.
381 * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
382 * /code AsyncPropertyRequest request;
383 * request.property = VehicleProperty::VehicleSpeed
384 * request.completed = [](AsyncPropertyReply* reply)
386 * //you own the reply
389 * routingEngine->getPropertyAsync(request);
392 virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
395 * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
396 * \arg request the request containing the property and other information required by the query
397 * \return a pointer to the reply.
398 * \code AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
400 * vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
401 * vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
403 * PropertyList requestList;
404 * requestList.push_back(VehicleProperty::VehicleSpeed);
405 * requestList.push_back(VehicleProperty::EngineSpeed);
407 * vehicleSpeedFromLastWeek.properties = requestList;
408 * vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
410 * std::list<AbstractPropertyType*> values = reply->values;
411 * for(auto itr = values.begin(); itr != values.end(); itr++)
414 * DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
420 * routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
423 virtual void getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
426 * \brief setProperty sets a property to a value.
427 * \see AsyncSetPropertyRequest
428 * \see AsyncPropertyReply
429 * \arg request the request containing the property and the value to set
430 * \return a pointer to the reply which is owned by the caller of this method
433 virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
436 * \brief subscribeToProperty subscribes to propertyName. Value changes will be passed to callback.
439 * \arg pid process id of the requesting application
440 * \return subscription handle
442 virtual uint subscribeToProperty(const VehicleProperty::Property & propertyName, PropertyChangedType callback, std::string pid="") = 0;
445 * \brief unsubscribeToProperty
448 virtual void unsubscribeToProperty(uint handle) = 0;
451 * \brief subscribeToProperty subscribe to changes made to a property value.
452 * \arg propertyName name of the property to request a subscription for.
453 * \arg self pointer to the sink who is subscribing.
455 * //somewhere in the sink:
456 * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
458 * //... elsewhere in the sink, this will be called when a property changes:
459 * void MySink::propertyChanged(const AbstractPropertyType* property)
461 * if(property->name == VehicleProperty::EngineSpeed)
468 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, AbstractSink* self) = 0;
471 * \brief subscribeToProperty subscribe to changes made to a property value.
472 * \arg propertyName name of the property to request a subscription for.
473 * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
474 * \arg self pointer to the sink who is subscribing.
476 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self) = 0;
479 * \brief subscribeToProperty subscribe to changes made to a property value.
480 * \arg propertyName name of the property to request a subscription for.
481 * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
482 * \arg zoneFilter zone to filter. Only updates from this zone will be passed to the sink.
483 * \arg self pointer to the sink who is subscribing.
485 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
487 virtual bool unsubscribeToProperty(const VehicleProperty::Property &, AbstractSink* self) = 0;
489 virtual PropertyInfo getPropertyInfo(const VehicleProperty::Property &, const std::string & sourceUuid) = 0;
492 std::map<std::string, std::string> mConfig;
495 #endif // ABSTRACTROUTINGENGINE_H