/*
- Copyright (C) 2012 Intel Corporation
+ Copyright (C) 2012 Intel Corporation
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
class AbstractSource;
class AsyncPropertyReply;
class AsyncRangePropertyReply;
+class AsyncSetPropertyRequest;
typedef std::function<void (AsyncPropertyReply*)> GetPropertyCompletedSignal;
typedef std::function<void (AsyncRangePropertyReply*)> GetRangedPropertyCompletedSignal;
+typedef std::function<void (AsyncPropertyReply*)> TimedOutCallback;
+/*!
+ * \brief The AsyncPropertyRequest class is used by sinks to request property values.
+ * \see AbstractRoutingEngine::getPropertyAsync
+ * \see AsyncPropertyReply
+ */
class AsyncPropertyRequest
{
public:
AsyncPropertyRequest()
- :property(VehicleProperty::NoValue),timeout(10000)
+ :property(VehicleProperty::NoValue),zoneFilter(Zone::None), timeout(10000)
{
}
virtual ~AsyncPropertyRequest() { }
+ /*!
+ * \brief property property to request.
+ */
VehicleProperty::Property property;
+
+ /*!
+ * \brief sourceUuidFilter the requesting sink should use this to filter on a specific source or leave blank to use any source
+ */
std::string sourceUuidFilter;
+
+ /*!
+ * \brief zoneFilter the requesting sink should use this if he wants to filter on a specific zone
+ */
Zone::Type zoneFilter;
+
+ /*!
+ * \brief completed the callback when the request has been completed.
+ */
GetPropertyCompletedSignal completed;
+
+ /*!
+ * \brief use to specify a timeout in ms for the request. When a timeout occurs, the 'completed' callback
+ * will be called with an error. @see AsyncPropertyReply
+ * default value is: 10000 ms
+ */
uint timeout;
+
+ /*!
+ * \brief pid requesting process id
+ */
+ std::string pid;
};
+/*!
+ * \brief The AsyncPropertyReply class is used by sources to reply to Get and Set operations.
+ * The source should set success to true if the call is successful or 'false' if the request was not successful and set 'error'
+ * to the appropriate error.
+ * \see AbstractRoutingEngine::getPropertyAsync
+ * \see AsyncPropertyReply
+ * \see AbstractSource::Operations
+ * \see AbstractSource::getPropertyAsync
+ */
class AsyncPropertyReply: public AsyncPropertyRequest
{
public:
+ AsyncPropertyReply();
+
AsyncPropertyReply(const AsyncPropertyRequest &request);
- virtual ~AsyncPropertyReply()
- {
- if(timeoutSource)
- {
- g_source_destroy(timeoutSource);
- g_source_unref(timeoutSource);
- }
- }
+ AsyncPropertyReply(const AsyncSetPropertyRequest &request);
+
+ virtual ~AsyncPropertyReply();
+ /*!
+ * \brief The Error enum
+ */
enum Error {
NoError = 0,
Timeout,
ZoneNotSupported
};
- /**
- * @brief value of the reply. This may be null if success = false. This is owned by the source.
+ /*!
+ * \brief errorToStr returns string representing the Error
+ */
+ static std::string errorToStr(Error err)
+ {
+ if(err == NoError)
+ return "NoError";
+ else if(err == Timeout)
+ return "Timeout";
+ else if(err == InvalidOperation)
+ return "InvalidOperation";
+ else if(err == PermissionDenied)
+ return "PermissionDenied";
+ else if(err == ZoneNotSupported)
+ return "ZoneNotSupported";
+
+ DebugOut(DebugOut::Warning) << "Could not translate error: " << err << endl;
+ return "";
+ }
+
+ /*!
+ * \brief strToError returns Error representing the string
+ */
+ static Error strToError(std::string err)
+ {
+ if(err == "NoError")
+ return NoError;
+ else if(err == "Timeout")
+ return Timeout;
+ else if(err == "InvalidOperation")
+ return InvalidOperation;
+ else if(err == "PermissionDenied")
+ return PermissionDenied;
+ else if(err == "ZoneNotSupported")
+ return ZoneNotSupported;
+
+ DebugOut(DebugOut::Warning) << "Could not translate error string: " << err << endl;
+ return NoError;
+ }
+
+ /*!
+ * \brief value of the reply. This may be null if success = false. This is owned by the source.
*/
AbstractPropertyType* value;
+
+ /*!
+ * \brief success indicates if the request was successfull or not. True means success. False means fail and the 'error'
+ * member should be set.
+ */
bool success;
+
+ /*!
+ * \brief timed out callback is called when the reply times out. This is so sources can avoid using this reply which
+ * may become invalid after it times out.
+ */
+ TimedOutCallback timedout;
+
+ /*!
+ * \brief error contains the error if the request was not successful.\
+ * \see Error
+ */
Error error;
private:
+ void setTimeout();
GSource* timeoutSource;
};
+/*!
+ * \brief The AsyncSetPropertyRequest class is used by sinks to set a property to the 'value'. The source will reply
+ * with a AsyncPropertyReply containing the new value or an error.
+ * \see AbstractRoutingEngine::setProperty
+ * \see AsyncPropertyReply
+ */
class AsyncSetPropertyRequest: public AsyncPropertyRequest
{
public:
}
- virtual ~AsyncSetPropertyRequest() { }
+ virtual ~AsyncSetPropertyRequest()
+ {
+
+ }
+ /*!
+ * \brief value the new value to set the property to.
+ */
AbstractPropertyType* value;
};
+/*!
+ * \brief The AsyncRangePropertyRequest class is used by sinks to request values within a time or sequence range
+ * \see AbstractRoutingEngine::getRangePropertyAsync
+ */
class AsyncRangePropertyRequest
{
public:
AsyncRangePropertyRequest()
- :timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
+ :zone(Zone::None), timeBegin(0), timeEnd(0), sequenceBegin(-1), sequenceEnd(-1)
{
}
AsyncRangePropertyRequest(const AsyncRangePropertyRequest &request)
-
{
this->properties = request.properties;
this->completed = request.completed;
this->sequenceBegin = request.sequenceBegin;
this->sequenceEnd = request.sequenceEnd;
this->sourceUuid = request.sourceUuid;
+ this->zone = request.zone;
}
virtual ~AsyncRangePropertyRequest() {}
+ /*!
+ * \brief properties list of properties to request
+ */
PropertyList properties;
+
+ /*!
+ * \brief sourceUuid if the sink wishes to request a specific source, this should be set to the uuid of the source.
+ */
std::string sourceUuid;
+
+ /*!
+ * \brief zone if the sink wishes to request a specific zone, this should be set to the desired zone .
+ */
+ Zone::Type zone;
+
+ /*!
+ * \brief completed callback
+ * 'completed' is called when the ranged request is complete. The reply from this request is passed
+ * into the completed call. The completed callback must free the reply before it returns or there will be a leak.
+ */
GetRangedPropertyCompletedSignal completed;
+
+ /*!
+ * \brief timeBegin
+ * Set this to request values for the specified property beggining at this time. Time is seconds\
+ * since the unix epoc. Set this to '0' if you do not want values within a time range.
+ */
double timeBegin;
+
+ /*!
+ * \brief timeEnd
+ * Set this to request values for the specified property beggining at this time. Time is seconds\
+ * since the unix epoc. Set this to '0' if you do not want values within a time range.
+ */
double timeEnd;
+
+ /*!
+ * \brief sequenceBegin set this to request values with a sequence >= to the sequenceBegin value. Set to -1 if
+ * you don't want values within a sequence ranges.
+ */
int32_t sequenceBegin;
+
+ /*!
+ * \brief sequenceEnd set this to request values with a sequence <= to the sequenceEnd value. Set to -1 if
+ * you don't want values within a sequence ranges.
+ */
int32_t sequenceEnd;
+
+ /*!
+ * \brief pid requesting process id
+ */
+ std::string pid;
};
+/*!
+ * \brief The AsyncRangePropertyReply class is used by a source to reply to an AsyncRangePropertyRequest.
+ * The source should set success to 'true' and populate the 'values' member if the request was successful.
+ * If the request is not successful, 'success' should be set to 'false' and the 'error' member should be set.
+ */
class AsyncRangePropertyReply: public AsyncRangePropertyRequest
{
public:
values.clear();
}
+ /*!
+ * \brief error this is set if there was an error in the request. "success" will also be set to false.
+ */
+ AsyncPropertyReply::Error error;
+
+ /*!
+ * \brief values if the request was successful, this will contain a list of values meeting the criteria of the request.
+ */
std::list<AbstractPropertyType*> values;
+
+ /*!
+ * \brief success this will be true if the request was successful. If not, this is false and error is set.
+ */
bool success;
};
class AbstractRoutingEngine
{
public:
+ typedef std::function<void (AbstractPropertyType* value)> PropertyChangedType;
+
+ AbstractRoutingEngine(std::map<std::string, std::string> configuration):mConfig(configuration) {}
virtual ~AbstractRoutingEngine();
- virtual void setSupported(PropertyList supported, AbstractSource* source) = 0;
- virtual void updateSupported(PropertyList added, PropertyList removed) = 0;
- virtual void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid) = 0;
+ virtual void registerSource(AbstractSource* src) = 0;
+ virtual void updateSupported(PropertyList added, PropertyList removed, AbstractSource* source) = 0;
+
+
+ ///TODO: Deprecated, remove in 0.15:
+ void updateProperty(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
+ {
+ throw std::runtime_error("updateProperty(VehicleProperty::Property,AbstractPropertyType*,std::string) is deprecated. use new updateProperty(AbstractPropertyType*, const std::string &)");
+ }
+
+ virtual void updateProperty(AbstractPropertyType* value, const std::string &uuid) = 0;
virtual PropertyList supported() = 0;
/// sinks:
virtual void unregisterSink(AbstractSink* self) = 0;
/**
- * @brief sourcesForProperty
- * @param property
- * @return list of source uuid's that support the "property"
+ * \brief sourcesForProperty
+ * \param property
+ * \return vector of source uuid's that support the "property"
*/
- virtual std::list<std::string> sourcesForProperty(VehicleProperty::Property property) = 0;
+ virtual std::vector<std::string> sourcesForProperty(const VehicleProperty::Property & property) = 0;
/**
- * @brief getPropertyAsync requests a property value from a source. This call has a timeout and will always return.
- * @see AsyncPropertyRequest
- * @see AsyncPropertyReply.
- * @param request requested property.
- * @return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
- * @example AsyncPropertyRequest request;
+ * /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.
+ * /see AsyncPropertyRequest
+ * /see AsyncPropertyReply.
+ * /param request requested property.
+ * /return AsyncPropertyReply. The returned AsyncPropertyReply is owned by the caller of getPropertyAsync.
+ * /code AsyncPropertyRequest request;
* request.property = VehicleProperty::VehicleSpeed
- * request.completed = [](AsyncPropertyReply* reply) { delete reply; };
+ * request.completed = [](AsyncPropertyReply* reply)
+ * {
+ * //you own the reply
+ * delete reply;
+ * };
* routingEngine->getPropertyAsync(request);
+ * /endcode
*/
virtual AsyncPropertyReply * getPropertyAsync(AsyncPropertyRequest request) = 0;
- virtual AsyncRangePropertyReply * getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
+
+ /*!
+ * \brief getRangePropertyAsync is used for getting a range of properties that are within the specified time or sequence parameters.
+ * \arg request the request containing the property and other information required by the query
+ * \return a pointer to the reply.
+ * \code AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
+ *
+ * vehicleSpeedFromLastWeek.timeBegin = amb::currentTime() - 10;
+ * vehicleSpeedFromLastWeek.timeEnd = amb::currentTime();
+ *
+ * PropertyList requestList;
+ * requestList.push_back(VehicleProperty::VehicleSpeed);
+ * requestList.push_back(VehicleProperty::EngineSpeed);
+ *
+ * vehicleSpeedFromLastWeek.properties = requestList;
+ * vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
+ * {
+ * std::list<AbstractPropertyType*> values = reply->values;
+ * for(auto itr = values.begin(); itr != values.end(); itr++)
+ * {
+ * auto val = *itr;
+ * DebugOut(1)<<"Value from past: ("<<val->name<<"): "<<val->toString()<<" time: "<<val->timestamp<<endl;
+ * }
+ *
+ * delete reply;
+ * };
+ *
+ * routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
+ * \endcode
+ */
+ virtual void getRangePropertyAsync(AsyncRangePropertyRequest request) = 0;
+
+ /*!
+ * \brief setProperty sets a property to a value.
+ * \see AsyncSetPropertyRequest
+ * \see AsyncPropertyReply
+ * \arg request the request containing the property and the value to set
+ * \return a pointer to the reply which is owned by the caller of this method
+ * \example
+ */
virtual AsyncPropertyReply * setProperty(AsyncSetPropertyRequest request) = 0;
- virtual void subscribeToProperty(VehicleProperty::Property, AbstractSink* self) = 0;
- virtual void subscribeToProperty(VehicleProperty::Property, std::string sourceUuidFilter, AbstractSink *self) = 0;
- virtual void subscribeToProperty(VehicleProperty::Property, std::string sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
- virtual void unsubscribeToProperty(VehicleProperty::Property, AbstractSink* self) = 0;
- virtual PropertyInfo getPropertyInfo(VehicleProperty::Property, std::string sourceUuid) = 0;
- virtual std::list<std::string> getSourcesForProperty(VehicleProperty::Property) = 0;
+ /*!
+ * \brief subscribeToProperty subscribes to propertyName. Value changes will be passed to callback.
+ * \code
+ * subscribeToProperty(Vehicle::EngineSpeed, [](AbstractPropertyType* property) {
+ * ...
+ * }, this);
+ * \endcode
+ * \arg propertyName
+ * \arg callback
+ * \arg pid process id of the requesting application
+ * \return subscription handle
+ */
+ virtual uint subscribeToProperty(const VehicleProperty::Property & propertyName, PropertyChangedType callback, std::string pid="") = 0;
+
+ /*!
+ * \brief unsubscribeToProperty
+ * \arg handle
+ */
+ virtual void unsubscribeToProperty(uint handle) = 0;
+
+ /*!
+ * \brief subscribeToProperty subscribe to changes made to a property value.
+ * By default, all providers of this property will receive the subscription. If you need to filter by source, use
+ * \ref subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self)
+ * \arg propertyName name of the property to request a subscription for.
+ * \arg self pointer to the sink who is subscribing.
+ * \code
+ * //somewhere in the sink:
+ * routingEngine->subscribeToProperty(VehicleProperty::EngineSpeed, this);
+ *
+ * //... elsewhere in the sink, this will be called when a property changes:
+ * void MySink::propertyChanged(const AbstractPropertyType* property)
+ * {
+ * if(property->name == VehicleProperty::EngineSpeed)
+ * {
+ * ...
+ * }
+ * }
+ * \endcode
+ */
+ virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, AbstractSink* self) = 0;
+
+ /*!
+ * \brief subscribeToProperty subscribe to changes made to a property value.
+ * \arg propertyName name of the property to request a subscription for.
+ * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
+ * \arg self pointer to the sink who is subscribing.
+ */
+ virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, AbstractSink *self) = 0;
+
+ /*!
+ * \brief subscribeToProperty subscribe to changes made to a property value.
+ * \arg propertyName name of the property to request a subscription for.
+ * \arg sourceUuidFilter source UUID to filter. Only property updates from this source will be sent to the sink.
+ * \arg zoneFilter zone to filter. Only updates from this zone will be passed to the sink.
+ * \arg self pointer to the sink who is subscribing.
+ */
+ virtual bool subscribeToProperty(const VehicleProperty::Property & propertyName, const std::string & sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self) = 0;
+
+ virtual bool unsubscribeToProperty(const VehicleProperty::Property &, AbstractSink* self) = 0;
+
+ virtual PropertyInfo getPropertyInfo(const VehicleProperty::Property &, const std::string & sourceUuid) = 0;
+
+protected:
+ std::map<std::string, std::string> mConfig;
};
#endif // ABSTRACTROUTINGENGINE_H