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";
161 DebugOut(DebugOut::Warning) << "Could not translate error: " << err << endl;
166 * \brief strToError returns Error representing the string
168 static Error strToError(std::string err)
172 else if(err == "Timeout")
174 else if(err == "InvalidOperation")
175 return InvalidOperation;
176 else if(err == "PermissionDenied")
177 return PermissionDenied;
178 else if(err == "ZoneNotSupported")
179 return ZoneNotSupported;
181 DebugOut(DebugOut::Warning) << "Could not translate error string: " << err << endl;
186 * \brief value of the reply. This may be null if success = false. This is owned by the source.
188 AbstractPropertyType* value;
191 * \brief success indicates if the request was successfull or not. True means success. False means fail and the 'error'
192 * member should be set.
197 * \brief timed out callback is called when the reply times out. This is so sources can avoid using this reply which
198 * may become invalid after it times out.
200 TimedOutCallback timedout;
203 * \brief error contains the error if the request was not successful.\
210 GSource* timeoutSource;
214 * \brief The AsyncSetPropertyRequest class is used by sinks to set a property to the 'value'. The source will reply
215 * with a AsyncPropertyReply containing the new value or an error.
216 * \see AbstractRoutingEngine::setProperty
217 * \see AsyncPropertyReply
219 class AsyncSetPropertyRequest: public AsyncPropertyRequest
222 AsyncSetPropertyRequest()
228 AsyncSetPropertyRequest(const AsyncPropertyRequest &request)
229 :AsyncPropertyRequest(request), value(NULL)
234 virtual ~AsyncSetPropertyRequest()
240 * \brief value the new value to set the property to.
242 AbstractPropertyType* value;
246 * \brief The AsyncRangePropertyRequest class is used by sinks to request values within a time or sequence range
247 * \see AbstractRoutingEngine::getRangePropertyAsync
249 class AsyncRangePropertyRequest
252 AsyncRangePropertyRequest()
253 :zone(Zone::None), timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
258 AsyncRangePropertyRequest(const AsyncRangePropertyRequest &request)
260 this->properties = request.properties;
261 this->completed = request.completed;
262 this->timeBegin = request.timeBegin;
263 this->timeEnd = request.timeEnd;
264 this->sequenceBegin = request.sequenceBegin;
265 this->sequenceEnd = request.sequenceEnd;
266 this->sourceUuid = request.sourceUuid;
267 this->zone = request.zone;
270 virtual ~AsyncRangePropertyRequest() {}
273 * \brief properties list of properties to request
275 PropertyList properties;
278 * \brief sourceUuid if the sink wishes to request a specific source, this should be set to the uuid of the source.
280 std::string sourceUuid;
283 * \brief zone if the sink wishes to request a specific zone, this should be set to the desired zone .
288 * \brief completed callback
289 * 'completed' is called when the ranged request is complete. The reply from this request is passed
290 * into the completed call. The completed callback must free the reply before it returns or there will be a leak.
292 GetRangedPropertyCompletedSignal completed;
296 * Set this to request values for the specified property beggining at this time. Time is seconds\
297 * since the unix epoc. Set this to '0' if you do not want values within a time range.
303 * Set this to request values for the specified property beggining at this time. Time is seconds\
304 * since the unix epoc. Set this to '0' if you do not want values within a time range.
309 * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value. Set to -1 if
310 * you don't want values within a sequence ranges.
312 int32_t sequenceBegin;
315 * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value. Set to -1 if
316 * you don't want values within a sequence ranges.
321 * \brief pid requesting process id
327 * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
328 * The source should set success to 'true' and populate the 'values' member if the request was successful.
329 * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
331 class AsyncRangePropertyReply: public AsyncRangePropertyRequest
334 AsyncRangePropertyReply(AsyncRangePropertyRequest request)
335 :AsyncRangePropertyRequest(request), success(false)
340 ~AsyncRangePropertyReply()
342 for(auto itr = values.begin(); itr != values.end(); itr++)
351 * \brief error this is set if there was an error in the request. "success" will also be set to false.
353 AsyncPropertyReply::Error error;
356 * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
358 std::list<AbstractPropertyType*> values;
361 * \brief success this will be true if the request was successful. If not, this is false and error is set.
366 class AbstractRoutingEngine
369 typedef std::function<void (AbstractPropertyType* value)> PropertyChangedType;
371 AbstractRoutingEngine(std::map<std::string, std::string> configuration):mConfig(configuration) {}
372 virtual ~AbstractRoutingEngine();
374 virtual void registerSource(AbstractSource* src) = 0;
375 virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
378 ///TODO: Deprecated, remove in 0.15:
379 void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
381 throw std::runtime_error("updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated. use new updateProperty(AbstractPropertyType*, const std::string &)");
384 virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
385 virtual PropertyList supported() = 0;
388 virtual void registerSink(AbstractSink* self) = 0;
389 virtual void unregisterSink(AbstractSink* self) = 0;
392 * \brief sourcesForProperty
394 * \return vector of source uuid's that support the "property"
396 virtual std::vector<std::string> sourcesForProperty(const VehicleProperty::Property & property) = 0;
399 * /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.
400 * /see AsyncPropertyRequest
401 * /see AsyncPropertyReply.
402 * /param request requested property.
403 * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
404 * /code AsyncPropertyRequest request;
405 * request.property = VehicleProperty::VehicleSpeed
406 * request.completed = [](AsyncPropertyReply* reply)
408 * //you own the reply
411 * routingEngine->getPropertyAsync(request);
414 virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
417 * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
418 * \arg request the request containing the property and other information required by the query
419 * \return a pointer to the reply.
420 * \code AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
422 * vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
423 * vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
425 * PropertyList requestList;
426 * requestList.push_back(VehicleProperty::VehicleSpeed);
427 * requestList.push_back(VehicleProperty::EngineSpeed);
429 * vehicleSpeedFromLastWeek.properties = requestList;
430 * vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
432 * std::list<AbstractPropertyType*> values = reply->values;
433 * for(auto itr = values.begin(); itr != values.end(); itr++)
436 * DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
442 * routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
445 virtual void getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
448 * \brief setProperty sets a property to a value.
449 * \see AsyncSetPropertyRequest
450 * \see AsyncPropertyReply
451 * \arg request the request containing the property and the value to set
452 * \return a pointer to the reply which is owned by the caller of this method
455 virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
458 * \brief subscribeToProperty subscribes to propertyName. Value changes will be passed to callback.
460 * subscribeToProperty(Vehicle::EngineSpeed, [](AbstractPropertyType* property) {
466 * \arg pid process id of the requesting application
467 * \return subscription handle
469 virtual uint subscribeToProperty(const VehicleProperty::Property & propertyName, PropertyChangedType callback, std::string pid="") = 0;
472 * \brief unsubscribeToProperty
475 virtual void unsubscribeToProperty(uint handle) = 0;
478 * \brief subscribeToProperty subscribe to changes made to a property value.
479 * By default, all providers of this property will receive the subscription. If you need to filter by source, use
480 * \ref subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self)
481 * \arg propertyName name of the property to request a subscription for.
482 * \arg self pointer to the sink who is subscribing.
484 * //somewhere in the sink:
485 * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
487 * //... elsewhere in the sink, this will be called when a property changes:
488 * void MySink::propertyChanged(const AbstractPropertyType* property)
490 * if(property->name == VehicleProperty::EngineSpeed)
497 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, AbstractSink* self) = 0;
500 * \brief subscribeToProperty subscribe to changes made to a property value.
501 * \arg propertyName name of the property to request a subscription for.
502 * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
503 * \arg self pointer to the sink who is subscribing.
505 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self) = 0;
508 * \brief subscribeToProperty subscribe to changes made to a property value.
509 * \arg propertyName name of the property to request a subscription for.
510 * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
511 * \arg zoneFilter zone to filter. Only updates from this zone will be passed to the sink.
512 * \arg self pointer to the sink who is subscribing.
514 virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
516 virtual bool unsubscribeToProperty(const VehicleProperty::Property &, AbstractSink* self) = 0;
518 virtual PropertyInfo getPropertyInfo(const VehicleProperty::Property &, const std::string & sourceUuid) = 0;
521 std::map<std::string, std::string> mConfig;
524 #endif // ABSTRACTROUTINGENGINE_H