diff options
author | Kevron Rees <tripzero.kev@gmail.com> | 2015-06-08 15:10:57 -0700 |
---|---|---|
committer | Kevron Rees <tripzero.kev@gmail.com> | 2015-06-08 15:10:57 -0700 |
commit | 58569fac42bb8b6e1ad208caef5db8a51befc87f (patch) | |
tree | c0b00050934c567e09e2ab7bc3601ea321360836 | |
parent | 8fd4eaa770c873418dbd25746440f25995d453a1 (diff) | |
parent | 6caa07f9e3e0093ddbd8979455b87c1f59b84652 (diff) | |
download | automotive-message-broker-58569fac42bb8b6e1ad208caef5db8a51befc87f.tar.gz |
Merge pull request #58 from tripzero/master
Version bump and Value Quality
Merging as-is for now
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | docs/amb.in.fidl | 12 | ||||
-rw-r--r-- | docs/ambd.in.md | 6 | ||||
-rw-r--r-- | lib/CMakeLists.txt | 6 | ||||
-rw-r--r-- | lib/abstractpropertytype.h | 27 | ||||
-rw-r--r-- | lib/jsonhelper.cpp | 54 | ||||
-rw-r--r-- | lib/jsonhelper.h | 13 | ||||
-rw-r--r-- | lib/valuequality.h | 41 | ||||
-rw-r--r-- | plugins/common/abstractdbusinterface.cpp | 104 | ||||
-rw-r--r-- | plugins/common/jsonprotocol.cpp | 58 | ||||
-rw-r--r-- | plugins/dbus/custompropertyinterface.cpp | 11 | ||||
-rw-r--r-- | plugins/dbus/custompropertyinterface.h | 1 | ||||
-rw-r--r-- | tools/ambctl.py | 9 |
14 files changed, 207 insertions, 143 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f92b391..0c61454a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(PROJECT_NAME "automotive-message-broker") set(PROJECT_PRETTY_NAME "Automotive Message Broker") set(PROJECT_SERIES "0.15") set(PROJECT_MAJOR_VERSION "0.14") -set(PROJECT_MINOR_VERSION "801") +set(PROJECT_MINOR_VERSION "802") set(PROJECT_VERSION "${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}") set(PROJECT_CODENAME "") set(PROJECT_QUALITY "alpha") @@ -1,6 +1,6 @@ # Automotive Message Broker Daemon {#ambd} -Version 0.14.801 +Version 0.15 ## Introduction @@ -11,7 +11,7 @@ Automotive Message Broker is built using CMake and requires libltdl (libtool), l ## Git About the Git Tree: -master is expected to be unstable and may not even compile. If you want something more stable, checkout one of the +'master' is expected to be unstable and may not even compile. If you want something more stable, checkout one of the release branches (ie, 0.9.0, 0.10, etc) ## Building @@ -60,7 +60,7 @@ You will also need to edit your config to enable the Qt-based mainloop: ~~~~~~~~~~~~~{.json} { - "mainloop" : "/usr/lib/i386-linux-gnu/automotive-message-broker/qtmainloopplugin.so", + "mainloop" : "/PLUGIN_INSTALL_PATH/qtmainloopplugin.so", "plugins" : "/etc/ambd/plugins.d" } ~~~~~~~~~~~~~ diff --git a/docs/amb.in.fidl b/docs/amb.in.fidl index 8d4ed46b..398a33de 100644 --- a/docs/amb.in.fidl +++ b/docs/amb.in.fidl @@ -67,17 +67,7 @@ * \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 * diff --git a/docs/ambd.in.md b/docs/ambd.in.md index 020454c5..326a50d4 100644 --- a/docs/ambd.in.md +++ b/docs/ambd.in.md @@ -1,6 +1,6 @@ # Automotive Message Broker Daemon {#ambd} -Version @PROJECT_VERSION@ +Version @PROJECT_SERIES@ ## Introduction @@ -11,7 +11,7 @@ Automotive Message Broker is built using CMake and requires libltdl (libtool), l ## Git About the Git Tree: -master is expected to be unstable and may not even compile. If you want something more stable, checkout one of the +'master' is expected to be unstable and may not even compile. If you want something more stable, checkout one of the release branches (ie, 0.9.0, 0.10, etc) ## Building @@ -60,7 +60,7 @@ You will also need to edit your config to enable the Qt-based mainloop: ~~~~~~~~~~~~~{.json} { - "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", + "mainloop" : "/PLUGIN_INSTALL_PATH/qtmainloopplugin.so", "plugins" : "@PLUGIN_SEGMENT_INSTALL_PATH@" } ~~~~~~~~~~~~~ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f0f04fa7..f5f62a1f 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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}) diff --git a/lib/abstractpropertytype.h b/lib/abstractpropertytype.h index 6ace39f7..21f3d648 100644 --- a/lib/abstractpropertytype.h +++ b/lib/abstractpropertytype.h @@ -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; } /*! diff --git a/lib/jsonhelper.cpp b/lib/jsonhelper.cpp index ff1d8798..b7240df2 100644 --- a/lib/jsonhelper.cpp +++ b/lib/jsonhelper.cpp @@ -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) { diff --git a/lib/jsonhelper.h b/lib/jsonhelper.h index 70eb286c..a8f1a27e 100644 --- a/lib/jsonhelper.h +++ b/lib/jsonhelper.h @@ -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 index 00000000..d182f5ea --- /dev/null +++ b/lib/valuequality.h @@ -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 +}; +} +} diff --git a/plugins/common/abstractdbusinterface.cpp b/plugins/common/abstractdbusinterface.cpp index 85940a04..8dcba0cd 100644 --- a/plugins/common/abstractdbusinterface.cpp +++ b/plugins/common/abstractdbusinterface.cpp @@ -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()) { diff --git a/plugins/common/jsonprotocol.cpp b/plugins/common/jsonprotocol.cpp index 88ef3b56..a5349006 100644 --- a/plugins/common/jsonprotocol.cpp +++ b/plugins/common/jsonprotocol.cpp @@ -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) { diff --git a/plugins/dbus/custompropertyinterface.cpp b/plugins/dbus/custompropertyinterface.cpp index 3c93db3f..b765a888 100644 --- a/plugins/dbus/custompropertyinterface.cpp +++ b/plugins/dbus/custompropertyinterface.cpp @@ -17,14 +17,15 @@ CustomPropertyInterface::CustomPropertyInterface(VehicleProperty::Property prop, throw std::runtime_error("Cannot create custom property: " + prop); } - GVariant* var = temp->toVariant(); - std::string signature = g_variant_get_type_string(var); - g_variant_unref(var); - - propertyDBusMap.push_back( new VariantType(re, prop, prop, VariantType::ReadWrite)); + ///TODO: Deprecated. Remove in 0.17. Use "Value" instead. + propertyDBusMap.push_back(new VariantType(re, prop, prop, VariantType::ReadWrite)); + propertyDBusMap.push_back(new VariantType(re, prop, "Value", VariantType::ReadWrite)); delete temp; } +} +CustomPropertyInterface::~CustomPropertyInterface() +{ } diff --git a/plugins/dbus/custompropertyinterface.h b/plugins/dbus/custompropertyinterface.h index 39eb383e..8c0f8d50 100644 --- a/plugins/dbus/custompropertyinterface.h +++ b/plugins/dbus/custompropertyinterface.h @@ -7,6 +7,7 @@ class CustomPropertyInterface: public DBusSink { public: CustomPropertyInterface(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection); + virtual ~CustomPropertyInterface(); }; diff --git a/tools/ambctl.py b/tools/ambctl.py index 94777232..cb091a73 100644 --- a/tools/ambctl.py +++ b/tools/ambctl.py @@ -4,12 +4,11 @@ import argparse import dbus import sys import json -import gobject import fileinput import termios, fcntl, os -import glib import curses.ascii import traceback +from gi.repository import GObject, GLib from dbus.mainloop.glib import DBusGMainLoop @@ -546,14 +545,14 @@ if args.command == "stdin": oldflags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) - io_stdin = glib.IOChannel(fd) - io_stdin.add_watch(glib.IO_IN, handle_keyboard, data) + io_stdin = GLib.IOChannel(fd) + io_stdin.add_watch(GLib.IO_IN, handle_keyboard, data) try: erase_line() display_prompt() sys.stdout.flush() - main_loop = gobject.MainLoop(None, False) + main_loop = GObject.MainLoop() main_loop.run() except KeyboardInterrupt: sys.exit() |