[libamb] - added value quality, removed deprecated GetFoo call, made updateFrequency...
authorKevron Rees <tripzero.kev@gmail.com>
Wed, 15 Apr 2015 22:24:05 +0000 (15:24 -0700)
committerKevron Rees <tripzero.kev@gmail.com>
Wed, 15 Apr 2015 22:24:05 +0000 (15:24 -0700)
docs/amb.in.fidl
lib/CMakeLists.txt
lib/abstractpropertytype.h
lib/jsonhelper.cpp
lib/jsonhelper.h
lib/valuequality.h [new file with mode: 0644]
plugins/common/abstractdbusinterface.cpp
plugins/common/jsonprotocol.cpp

index 8d4ed46..398a33d 100644 (file)
 * \endcode
 *
 * \section dbus_api_vehicle_property_type Vehicle Property Type
-* Vehicle Property Type is the common interface which all Data types are derived.  This interface is as follows:
-*
-* \code
-* interface VehiclePropertyType {
-*   attribute Double Time readonly
-*   attribute Zone Zone readonly
-*   method GetHistory(Double beginTime, Double endTime) {
-*     out{ Dictionary result}
-*   }
-* }
-* \endcode
+* Vehicle Property Type (\ref VehiclePropertyType) is the common interface which all Data types are derived.
 *
 * \section dbus_api_data_types Data types
 *
index f0f04fa..f5f62a1 100644 (file)
@@ -1,5 +1,7 @@
-set(amb_sources abstractpropertytype.cpp abstractroutingengine.cpp listplusplus.cpp abstractsink.cpp vehicleproperty.cpp abstractsource.cpp debugout.cpp timestamp.cpp uuidhelper.cpp mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp ambpluginimpl.cpp ambplugin.h picojson.h jsonhelper.cpp)
-set(amb_headers_install abstractpropertytype.h nullptr.h abstractroutingengine.h listplusplus.h abstractsink.h vehicleproperty.h debugout.h abstractsource.h timestamp.h uuidhelper.h mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp ambplugin.h ambpluginimpl.h picojson.h jsonhelper.h)
+set(amb_sources abstractpropertytype.cpp abstractroutingengine.cpp listplusplus.cpp abstractsink.cpp vehicleproperty.cpp abstractsource.cpp debugout.cpp timestamp.cpp uuidhelper.cpp mappropertytype.hpp
+       propertyinfo.hpp superptr.hpp asyncqueue.hpp ambpluginimpl.cpp ambplugin.h picojson.h jsonhelper.cpp)
+set(amb_headers_install abstractpropertytype.h nullptr.h abstractroutingengine.h listplusplus.h abstractsink.h vehicleproperty.h debugout.h abstractsource.h timestamp.h uuidhelper.h mappropertytype.hpp
+       propertyinfo.hpp superptr.hpp asyncqueue.hpp ambplugin.h ambpluginimpl.h picojson.h jsonhelper.h valuequality.h)
 
 add_library(amb SHARED ${amb_sources})
 
index 6ace39f..21f3d64 100644 (file)
@@ -24,6 +24,7 @@
 #include "picojson.h"
 #include "superptr.hpp"
 #include "timestamp.h"
+#include "valuequality.h"
 
 #include <boost/algorithm/string.hpp>
 #include <boost/any.hpp>
@@ -93,7 +94,8 @@ public:
        };
 
        AbstractPropertyType(std::string property)
-               : name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal)
+               : name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal),
+                 valueQuality(amb::Quality::UncertainInitialValue)
        {
 
        }
@@ -192,11 +194,16 @@ public:
        std::string name;
 
        /*!
-        * \brief alias alias for the property name
-        * \return alias if any of name if alias has not been set
+        * \brief alias for the property name
+        * \return alias or \ref name if alias has not been set
         */
        const std::string alias() { return mAlias.empty() ? name : mAlias; }
 
+       /*!
+        * \brief setAlias sets the alias name for a property
+        * This may be useful for implementing standards where the standard name differs from the internal AMB \ref name
+        * \param a name of alias
+        */
        void setAlias(const std::string & a) { mAlias = a; }
 
        /*!
@@ -232,6 +239,19 @@ public:
        Priority priority;
 
        /*!
+        * \brief valueQuality is used to indicate the quality of the value
+        * Each AMB property is given a default value.  valueQuality is a way to describe whether the value
+        * is the default one and the system has not yet provided a valid value, bad if an error occured, or
+        * good.
+        *
+        * The default value for this is \ref amb::Quality::UncertainInitialValue indicating that the amb property value is the
+        * default value.  When \ref AbastractPropertyType::setValue is called, valueQuality is set to "Good" automatically.
+        *
+        * TODO: this may be able to provide a replacement for set and get error codes: \ref AsyncPropertyReply::Error
+        */
+       amb::Quality::ValueQuality valueQuality;
+
+       /*!
         * \brief setValue
         * \param val boost::any value.  NOTE: boost::any does not accept type coercion.  Types must match exactly
         * with native type. (ie, don't use "int" if the native type is "uint")
@@ -240,6 +260,7 @@ public:
        {
                mValue = val;
                timestamp = amb::currentTime();
+               valueQuality = amb::Quality::Good;
        }
 
        /*!
index ff1d879..b7240df 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "abstractpropertytype.h"
 #include "debugout.h"
+#include "vehicleproperty.h"
 
 const char * amb::BasicTypes::UInt16Str = "UInt16";
 const char * amb::BasicTypes::UInt32Str = "UInt32";
@@ -109,8 +110,61 @@ const std::string amb::BasicTypes::fromSignature(const string &sig)
        return "";
 }
 
+std::shared_ptr<AbstractPropertyType> amb::jsonToProperty(const picojson::value &json)
+{
+       std::string name = json.get("name").to_str();
+       std::string type = json.get("type").to_str();
+
+       auto t = VehicleProperty::getPropertyTypeForPropertyNameValue(name);
+
+       if(!t)
+       {
+               bool ret = VehicleProperty::registerProperty(name, [name, type]() -> AbstractPropertyType* {
+                       if(type == amb::BasicTypes::UInt16Str)
+                       {
+                               return new BasicPropertyType<uint16_t>(name, 0);
+                       }
+                       else if(type == amb::BasicTypes::Int16Str)
+                       {
+                               return new BasicPropertyType<int16_t>(name, 0);
+                       }
+                       else if(type == amb::BasicTypes::UInt32Str)
+                       {
+                               return new BasicPropertyType<uint32_t>(name, 0);
+                       }
+                       else if(type == amb::BasicTypes::Int32Str)
+                       {
+                               return new BasicPropertyType<int32_t>(name, 0);
+                       }
+                       else if(type == amb::BasicTypes::StringStr)
+                       {
+                               return new StringPropertyType(name);
+                       }
+                       else if(type == amb::BasicTypes::DoubleStr)
+                       {
+                               return new BasicPropertyType<double>(name, 0);
+                       }
+                       else if(type == amb::BasicTypes::BooleanStr)
+                       {
+                               return new BasicPropertyType<bool>(name, false);
+                       }
+                       DebugOut(DebugOut::Warning) << "Unknown or unsupported type: " << type << endl;
+                       return nullptr;
+               });
+
+               if(!ret)
+               {
+                       DebugOut(DebugOut::Error) << "failed to register property: " << name << endl;
+                       return nullptr;
+               }
+
+               t = VehicleProperty::getPropertyTypeForPropertyNameValue(name);
+       }
 
+       t->fromJson(json);
 
+       return std::shared_ptr<AbstractPropertyType>(t);
+}
 
 const string amb::BasicTypes::fromAbstractProperty(AbstractPropertyType *property)
 {
index 70eb286..a8f1a27 100644 (file)
@@ -32,8 +32,18 @@ extern const char * StringStr;
 extern const char * DoubleStr;
 extern const char * BooleanStr;
 
+/*!
+ * \brief fromSignature get the basic type from gvariant signature
+ * \param sig gvariant signature
+ * \return string representing the basic type
+ */
 const std::string fromSignature(std::string const & sig);
 
+/*!
+ * \brief fromAbstractProperty get the basic type from AbstractPropertType
+ * \param property
+ * \return
+ */
 const std::string fromAbstractProperty(AbstractPropertyType *property);
 
 } // BasicTypes
@@ -43,9 +53,6 @@ picojson::value gvariantToJson(GVariant* value);
 GVariant * jsonToGVariant(const picojson::value & json, const std::string & signature);
 
 std::shared_ptr<AbstractPropertyType> jsonToProperty(const picojson::value& json);
-
-picojson::value propertyToJson(std::shared_ptr<AbstractPropertyType> property);
-
 }
 
 #endif
diff --git a/lib/valuequality.h b/lib/valuequality.h
new file mode 100644 (file)
index 0000000..d182f5e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+       Copyright (C) 2015  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 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
+*/
+
+namespace amb {
+namespace Quality {
+
+/*!
+ * \brief The ValueQuality enum describes the quality of an AbstractPropertyType
+ * These codes are cherry picked from the OPC UA Quality Code specification
+ */
+enum ValueQuality {
+       Good = 0x00000000,
+       GoodNoData = 0x00A50000,
+       Uncertain = 0x40000000,
+       UncertainSensorNotAccurate = 0x40930000,
+       UncertainInitialValue = 0x40920000,
+       Bad = 0x80000000,
+       BadUnexpectedError = 0x80010000,
+       BadInternalError = 0x80020000,
+       BadTimeout = 0x800A0000,
+       BadServiceUnsupported = 0x800B0000,
+       BadSecurityChecksFailed = 0x80130000,
+       BadUserAccessDenied = 0x801F0000
+};
+}
+}
index 85940a0..8dcba0c 100644 (file)
@@ -128,6 +128,12 @@ void AbstractDBusInterface::handleMyMethodCall(GDBusConnection       *connection
                                //sequence
                                auto sequence = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"Sequence").c_str(), &error, iface);
                                g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"Sequence").c_str(), g_variant_new("v", sequence));
+
+                               auto quality = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"ValueQuality").c_str(), &error, iface);
+                               g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"ValueQuality").c_str(), g_variant_new("v", quality));
+
+                               auto freq = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"UpdateFrequency").c_str(), &error, iface);
+                               g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"UpdateFrequency").c_str(), g_variant_new("v", freq));
                        }
 
                        auto time = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, "Time", nullptr, iface);
@@ -226,44 +232,6 @@ void AbstractDBusInterface::handleMyMethodCall(GDBusConnection       *connection
                return;
        }
 
-       ///TODO: Deprecated in 0.15
-       else if(boost::algorithm::starts_with(method, "Get"))
-       {
-               amb::deprecateMethod(method, "0.15");
-               std::string propertyName = method.substr(3);
-               auto propertyMap = iface->getProperties();
-               if(propertyMap.find(propertyName) == propertyMap.end())
-               {
-                       g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method.");
-                       return;
-               }
-
-               VariantType * property = propertyMap[propertyName];
-
-               GError *error = NULL;
-
-               GVariant **params = g_new(GVariant*,4);
-               GVariant *val = g_variant_ref(property->value()->toVariant());
-               params[0] = g_variant_new("v", val);
-               params[1] = g_variant_new("d",property->timestamp());
-               params[2] = g_variant_new("i",property->value()->sequence);
-               params[3] = g_variant_new("i",property->updateFrequency());
-
-               GVariant *tuple_variant = g_variant_new_tuple(params,4);
-
-               g_dbus_method_invocation_return_value(invocation, tuple_variant);
-
-               g_free(params);
-               g_variant_unref(val);
-
-               if(error)
-               {
-                       DebugOut(DebugOut::Error)<<error->message<<endl;
-                       g_error_free(error);
-               }
-               return;
-       }
-
        g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method.");
 }
 
@@ -315,15 +283,9 @@ void AbstractDBusInterface::addProperty(VariantType * property)
        ///see which properties are supported:
        introspectionXml +=
                        "<property type='"+ string(property->signature()) + "' name='"+ pn +"' access='"+access+"' />"
-                       "<!-- 'GetFoo' is deprecated as of 0.14 -->"
-                       /// TODO: remove GetFoo in 0.15
-                       "<method name='Get" + pn + "'>"
-                       "       <arg type='v' direction='out' name='value' />"
-                       "       <arg type='d' direction='out' name='timestamp' />"
-                       "       <arg type='i' direction='out' name='sequence' />"
-                       "   <arg type='i' direction='out' name='updateFrequency' />"
-                       "</method>"
-                       "<property type='i' name='" + pn + "Sequence' access='read' />";
+                       "<property type='i' name='" + pn + "Sequence' access='read' />"
+                       "<property type='i' name='" + pn + "ValueQuality' access='read' />"
+                       "<property type='i' name='" + pn + "UpdateFrequency' access='read' />";
 
        properties[pn] = property;
 
@@ -520,7 +482,7 @@ GVariant* AbstractDBusInterface::getProperty(GDBusConnection* connection, const
                return value;
        }
 
-       if(boost::ends_with(pn, "Sequence"))
+       else if(boost::ends_with(pn, "Sequence"))
        {
                AbstractDBusInterface* t = static_cast<AbstractDBusInterface*>(userData);
 
@@ -542,7 +504,51 @@ GVariant* AbstractDBusInterface::getProperty(GDBusConnection* connection, const
                return value;
        }
 
-       if(pn == "Zone")
+       else if(boost::ends_with(pn, "ValueQuality"))
+       {
+               AbstractDBusInterface* t = static_cast<AbstractDBusInterface*>(userData);
+
+               int pos = pn.find("ValueQuality");
+
+               std::string p = pn.substr(0, pos);
+
+               VariantType * theProperty = t->property(p);
+
+               if(!theProperty)
+               {
+                       DebugOut(DebugOut::Error)<<"Invalid ValueQuality property: "<<p<<endl;
+                       return nullptr;
+               }
+
+               int quality = theProperty->value()->valueQuality;
+
+               GVariant* value = g_variant_new("i", quality);
+               return value;
+       }
+
+       else if(boost::ends_with(pn, "UpdateFrequency"))
+       {
+               AbstractDBusInterface* t = static_cast<AbstractDBusInterface*>(userData);
+
+               int pos = pn.find("UpdateFrequency");
+
+               std::string p = pn.substr(0, pos);
+
+               VariantType * theProperty = t->property(p);
+
+               if(!theProperty)
+               {
+                       DebugOut(DebugOut::Error)<<"Invalid UpdateFrequency property: "<<p<<endl;
+                       return nullptr;
+               }
+
+               int freq = theProperty->updateFrequency();
+
+               GVariant* value = g_variant_new("i", freq);
+               return value;
+       }
+
+       else if(pn == "Zone")
        {
                if(objectMap.find(objectPath) == objectMap.end())
                {
index 88ef3b5..a534900 100644 (file)
@@ -457,64 +457,6 @@ bool amb::MethodCall::fromJson(const picojson::value &json)
        return true;
 }
 
-
-std::shared_ptr<AbstractPropertyType> amb::jsonToProperty(const picojson::value &json)
-{
-       std::string name = json.get("name").to_str();
-       std::string type = json.get("type").to_str();
-
-       auto t = VehicleProperty::getPropertyTypeForPropertyNameValue(name);
-
-       if(!t)
-       {
-               bool ret = VehicleProperty::registerProperty(name, [name, type]() -> AbstractPropertyType* {
-                       if(type == amb::BasicTypes::UInt16Str)
-                       {
-                               return new BasicPropertyType<uint16_t>(name, 0);
-                       }
-                       else if(type == amb::BasicTypes::Int16Str)
-                       {
-                               return new BasicPropertyType<int16_t>(name, 0);
-                       }
-                       else if(type == amb::BasicTypes::UInt32Str)
-                       {
-                               return new BasicPropertyType<uint32_t>(name, 0);
-                       }
-                       else if(type == amb::BasicTypes::Int32Str)
-                       {
-                               return new BasicPropertyType<int32_t>(name, 0);
-                       }
-                       else if(type == amb::BasicTypes::StringStr)
-                       {
-                               return new StringPropertyType(name);
-                       }
-                       else if(type == amb::BasicTypes::DoubleStr)
-                       {
-                               return new BasicPropertyType<double>(name, 0);
-                       }
-                       else if(type == amb::BasicTypes::BooleanStr)
-                       {
-                               return new BasicPropertyType<bool>(name, false);
-                       }
-                       DebugOut(DebugOut::Warning) << "Unknown or unsupported type: " << type << endl;
-                       return nullptr;
-               });
-
-               if(!ret)
-               {
-                       DebugOut(DebugOut::Error) << "failed to register property: " << name << endl;
-                       return nullptr;
-               }
-
-               t = VehicleProperty::getPropertyTypeForPropertyNameValue(name);
-       }
-
-       t->fromJson(json);
-
-       return std::shared_ptr<AbstractPropertyType>(t);
-}
-
-
 amb::AmbRemoteServer::AmbRemoteServer(AbstractIo *io, AbstractRoutingEngine *re)
        :BaseJsonMessageReader(io), routingEngine(re)
 {