diff options
author | Kevron Rees <tripzero.kev@gmail.com> | 2014-11-24 10:19:47 -0800 |
---|---|---|
committer | Kevron Rees <tripzero.kev@gmail.com> | 2014-11-24 10:19:47 -0800 |
commit | dbe6e9c6b8bcda40d10523cc907abad46612516e (patch) | |
tree | 2d74fe14ac63ca6b2be25a066e3b0f9c3bf7aeda | |
parent | 1194d19d1544cc26f4ecceee2beac84e0d7e0fbb (diff) | |
parent | f98edbfc335669b611499dad233fba0f3f63a2de (diff) | |
download | automotive-message-broker-dbe6e9c6b8bcda40d10523cc907abad46612516e.tar.gz |
Merge pull request #32 from tripzero/master0.12.803
Availability API support.
29 files changed, 744 insertions, 365 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index dd98be8d..b5d8b3e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_BUILD_TYPE, Debug) include(FindPkgConfig) set(PROJECT_NAME "automotive-message-broker") -set(PROJECT_VERSION "0.12.802") +set(PROJECT_VERSION "0.12.803") set(PROJECT_CODENAME "agera") set(PROJECT_QUALITY "alpha") @@ -1,26 +1,12 @@ -Release notes for release 0.12 +Release notes for release 0.13 New features: -- Added "frequency" option to database plugin. Now periodic data can be written to the db. - this is useful for high speed data that you don't want to flood the database. -- New test tools: amb-get, amb-set and amb-get-history -- New bluetooth spp plugin -- cangen and cansim plugins simulate a real CAN network. -- New priority queue option. properties are routed according to priority. -- OpenCV plugin video logging: record video with speed overlay +- [OpenCV plugin] code updated to the new 3.0 API +- [OpenCV plugin] driver drowsiness detection test code +- [xwalk extension] implements full W3C automotive BG vehicle and data APIs +- [Bluemonkey plugin] support for zones in JS API. Changes: -- Deprecated and removed the "FooChanged" (where "Foo" is a property like "VehicleSpeed") signal -- DBus Object paths do not appear until FindObject* is called. The object path disappears with - the last pid that called FindObject* disconnects from DBus (or closes). -- Many internal stl containers have been changed to use more efficient ones. -- Some internal methods changed to const & references to avoid copies. -- DBus plugin will not cache unsubscribed values. Improves performance. -- Many DBus API changes. See new docs/amb.idl. Several interfaces are deprecated and replaced with - more w3c compliant interfaces. --- Fuel interface units changed +- OpenCV plugin experimental options for cuda and kinect are removed Fixes: -- database plugin updated to use zones -- obd-II plugin updated to use bluez5 APIs -- openCV plugin fixed crashes @@ -1,7 +1,6 @@ - Refactor obd2 plugin with AsyncQueue. Use thread safe-update property. - Rewrite websocket test html -- Implement all the DBus properties in the docs/ directory. - update json protocol to include getPropertyInfo calls - update json protocol to support rangerequests with PropertyList instead of a signel property (Verify) - update json protocol to support zones @@ -12,7 +11,6 @@ - handle badly formed messages properly (ie not crash) in websocketsink - GetHistory must filter on source - grep all the TODOs in the code and do them -- improve obd2source speed via Physical Addressing (see https://www.scantool.net/forum/index.php?topic=6661.msg25024#msg25024) - investigate and enable use of provisioning in ssl websockets - enable ambd/plugins.d/ - finish implementing openxc plugin (needs testing) diff --git a/docs/amb.idl b/docs/amb.idl index df427e4e..4ac47c5c 100644 --- a/docs/amb.idl +++ b/docs/amb.idl @@ -139,6 +139,21 @@ interface org.automotive.Manager { } } + /*! + * SupportsProperty + * \brief check whether a Property exists. + * \arg propertyName name of property of Object + * \returns true if Property exists + */ + method SupportsProperty { + in { + String propertyName + } + out { + Boolean supported + } + } + } /*! org.automotive.VehicleSpeed @@ -850,7 +865,6 @@ interface org.automotive.Odometer extends VehiclePropertyType { } - interface org.automotive.Fluid extends VehiclePropertyType { /*! Transmission @@ -860,16 +874,18 @@ interface org.automotive.Fluid extends VehiclePropertyType { /*! Brake * \brief MUST return Brake fluid level percentage. 0-100. + * TODO: Deprecated. use BrakeMaintenance::FluidLevel Remove in 0.14 */ attribute UInt16 Brake readonly /*! Washer * \brief MUST return Washer fluid level percentage. 0-100. + * TODO: Deprecated. use WasherFluid::Level. Remove in 0.14 */ attribute UInt16 Washer readonly } -/// Deprecated. Use BatteryStatus. Remove in 0.14 +///TODO: Deprecated. Use BatteryStatus. Remove in 0.14 interface org.automotive.Battery extends VehiclePropertyType { /*! Voltage @@ -1395,7 +1411,7 @@ interface org.automotive.TransmissionOil extends VehiclePropertyType { /*! * \brief must return transmission oil wear (Unit: percentage, 0: no wear, 100: completely worn). */ - attribute UInt8 Wear readonly + attribute UInt8 Wear readonly; } interface org.automotive.TransmissionClutch extends VehiclePropertyType { @@ -1403,7 +1419,51 @@ interface org.automotive.TransmissionClutch extends VehiclePropertyType { /*! * \brief must return transmission clutch wear (Unit: percentage, 0: no wear, 100: completely worn). */ - attribute UInt8 Wear readonly + attribute UInt8 Wear readonly; +} + +interface org.automotive.BrakeMaintenance extends VehiclePropertyType { + + /*! + * \brief must return brake pad wear (Unit: percentage, 0%: no wear, 100%: completely worn). + */ + attribute UInt8 PadWear readonly; + + /*! + * \brief must return brake fluid level (Unit: percentage, 0%: empty, 100%: full). + */ + attribute UInt8 FluidLevel readonly; + + /*! + * \brief must return true if brake fluid level: low (true), not low (false) + */ + attribute Boolean FluidLevelLow readonly; + + /*! + * \brief must return true if brakes are worn: worn (true), not worn (false) + */ + attribute Boolean BrakesWorn readonly; +} + +interface org.automotive.WasherFluid extends VehiclePropertyType { + + /*! + * \brief must return washer fluid level (Unit: percentage, 0%: empty, 100%: full). + */ + attribute UInt8 Level readonly; + + /*! + * \brief must return true if washer fluid level is low: low (true), not low: (false) + */ + attribute Boolean LevelLow readonly; +} + +interface org.automotive.MalfunctionIndicator extends VehiclePropertyType { + + /*! + * \brief must return true if washer fluid level is low: low (true), not low: (false) + */ + attribute Boolean On readonly; } } diff --git a/examples/opencvdbusconfig.in b/examples/opencvdbusconfig.in index b85bc4b2..0040e1a5 100644 --- a/examples/opencvdbusconfig.in +++ b/examples/opencvdbusconfig.in @@ -5,16 +5,17 @@ "name" : "OpenCV LUX", "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so", "threaded" : "false", - "cuda" : "false", "opencl" : "true", "fps" : "30", "pixelLowerBound" : "18", "pixelUpperBound" : "255", "device" : "0", - "codec" : "divx", - "logging" : "true", + "codec" : "h264", + "logging" : "false", "logfile" : "/tmp/video.avi", - "ddd" : "true" + "ddd" : "true", + "faceCascade" : "/usr/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml", + "eyeCascade" : "/usr/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml" }, { "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" diff --git a/lib/vehicleproperty.cpp b/lib/vehicleproperty.cpp index bbc74079..87230800 100644 --- a/lib/vehicleproperty.cpp +++ b/lib/vehicleproperty.cpp @@ -158,6 +158,7 @@ const VehicleProperty::Property VehicleProperty::DistanceSinceStart = "DistanceS const VehicleProperty::Property VehicleProperty::TransmissionFluidLevel = "TransmissionFluidLevel"; const VehicleProperty::Property VehicleProperty::BrakeFluidLevel = "BrakeFluidLevel"; const VehicleProperty::Property VehicleProperty::WasherFluidLevel = "WasherFluidLevel"; +const VehicleProperty::Property VehicleProperty::WasherFluidLevelLow = "WasherFluidLevelLow"; const VehicleProperty::Property VehicleProperty::SecurityAlertStatus = "SecurityAlertStatus"; const VehicleProperty::Property VehicleProperty::ParkingBrakeStatus = "ParkingBrakeStatus"; const VehicleProperty::Property VehicleProperty::ParkingLightStatus = "ParkingLightStatus"; @@ -223,6 +224,9 @@ const VehicleProperty::Property VehicleProperty::ButtonEventW3C = "ButtonEventW3 const VehicleProperty::Property VehicleProperty::TransmissionOilWear = "TransmissionOilWear"; const VehicleProperty::Property VehicleProperty::TransmissionOilTemperature = "TransmissionOilTemperature"; const VehicleProperty::Property VehicleProperty::TransmissionClutchWear = "TransmissionClutchWear"; +const VehicleProperty::Property VehicleProperty::BrakePadWear = "BrakePadWear"; +const VehicleProperty::Property VehicleProperty::BrakeFluidLevelLow = "BrakeFluidLevelLow"; +const VehicleProperty::Property VehicleProperty::MalfunctionIndicatorOn = "MalfunctionIndicatorOn"; PropertyList VehicleProperty::mCapabilities; PropertyList VehicleProperty::mCustomProperties; @@ -323,6 +327,7 @@ VehicleProperty::VehicleProperty() REGISTERPROPERTY(TransmissionFluidLevel, 0); REGISTERPROPERTY(BrakeFluidLevel, 0); REGISTERPROPERTY(WasherFluidLevel, 0); + REGISTERPROPERTY(WasherFluidLevelLow, false); REGISTERPROPERTY(SecurityAlertStatus, Security::Idle); REGISTERPROPERTY(ParkingBrakeStatus, false); REGISTERPROPERTY(ParkingLightStatus, false); @@ -399,6 +404,9 @@ VehicleProperty::VehicleProperty() REGISTERPROPERTY(TransmissionOilWear, 0); REGISTERPROPERTY(TransmissionOilTemperature, 0); REGISTERPROPERTY(TransmissionClutchWear, 0); + REGISTERPROPERTY(BrakePadWear, 0); + REGISTERPROPERTY(BrakeFluidLevelLow, false); + REGISTERPROPERTY(MalfunctionIndicatorOn, false) } void VehicleProperty::factory() diff --git a/lib/vehicleproperty.h b/lib/vehicleproperty.h index 758c7ece..1140d2d1 100644 --- a/lib/vehicleproperty.h +++ b/lib/vehicleproperty.h @@ -703,7 +703,6 @@ public: **/ static const Property TransmissionFluidLevel; PROPERTYTYPEBASIC(TransmissionFluidLevel, uint16_t) - //typedef BasicPropertyType<uint16_t> TransmissionFluidLevelType; static const Property TransmissionOilWear; PROPERTYTYPEBASIC(TransmissionOilWear, uint8_t) @@ -717,14 +716,15 @@ public: /**< Brake Fluid Level 0-100%. **/ static const Property BrakeFluidLevel; - PROPERTYTYPEBASIC(BrakeFluidLevel, uint16_t) - //typedef BasicPropertyType<uint16_t> BrakeFluidLevelType; + PROPERTYTYPEBASIC(BrakeFluidLevel, uint8_t) /**< Washer Fluid Level 0-100%. **/ static const Property WasherFluidLevel; - PROPERTYTYPEBASIC(WasherFluidLevel, uint16_t) - //typedef BasicPropertyType<uint16_t> WasherFluidLevelType; + PROPERTYTYPEBASIC(WasherFluidLevel, uint8_t) + + static const Property WasherFluidLevelLow; + PROPERTYTYPEBASIC(WasherFluidLevelLow, bool) /**< Securty Alert Status * status of security alert @@ -732,21 +732,18 @@ public: */ static const Property SecurityAlertStatus; PROPERTYTYPEBASIC(SecurityAlertStatus, Security::Status) - //typedef BasicPropertyType<Security::Status> SecurityAlertStatusType; /**< Parking Brake Status * status of parking break active (true) or inactive (false) */ static const Property ParkingBrakeStatus; PROPERTYTYPEBASIC(ParkingBrakeStatus, bool) - //typedef BasicPropertyType<bool> ParkingBrakeStatusType; /**< Parking Light Status * status of parking lights active (true) or inactive (false) */ static const Property ParkingLightStatus; PROPERTYTYPEBASIC(ParkingLightStatus,bool) - //typedef BasicPropertyType<bool> ParkingLightStatusType; /**< Hazard Lights Status * status of parking lights active (true) or inactive (false) @@ -938,6 +935,18 @@ public: static const Property YawRate; PROPERTYTYPEBASIC(YawRate, int16_t) + static const Property BrakePadWear; + PROPERTYTYPEBASIC(BrakePadWear, uint8_t) + + static const Property BrakeFluidLevelLow; + PROPERTYTYPEBASIC(BrakeFluidLevelLow, bool) + + static const Property BrakesWorn; + PROPERTYTYPEBASIC(BrakesWorn, bool) + + static const Property MalfunctionIndicatorOn; + PROPERTYTYPEBASIC(MalfunctionIndicatorOn, bool) + /** END PROPERTIES **/ diff --git a/plugins/bluemonkey/CMakeLists.txt b/plugins/bluemonkey/CMakeLists.txt index 76727386..6fdbae3d 100644 --- a/plugins/bluemonkey/CMakeLists.txt +++ b/plugins/bluemonkey/CMakeLists.txt @@ -29,6 +29,15 @@ if(communi) install(TARGETS bluemonkeyIrcModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) endif(communi) +find_package(Qt5Sql) + +if(Qt5Sql_FOUND) + message(STATUS "enabling database bluemonkey module") + add_library(bluemonkeyDbModule MODULE db.cpp) + set_target_properties(bluemonkeyDbModule PROPERTIES PREFIX "") + target_link_libraries(bluemonkeyDbModule ${link_libraries} ${QT_LIBRARIES} ${Qt5Sql_LIBRARIES}) + install(TARGETS bluemonkeyDbModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) +endif() include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${communi_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common) @@ -40,6 +49,7 @@ set_target_properties(bluemonkeyplugin PROPERTIES PREFIX "") target_link_libraries(bluemonkeyplugin dl amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${QT_LIBRARIES} ${communi_LIBRARIES} amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common) set(config_files ${CMAKE_CURRENT_SOURCE_DIR}/config.js) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.js ${CMAKE_CURRENT_BINARY_DIR}/config.js @ONLY) install(TARGETS bluemonkeyplugin LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) install (FILES ${config_files} DESTINATION /etc/ambd/bluemonkey) diff --git a/plugins/bluemonkey/bluemonkey.cpp b/plugins/bluemonkey/bluemonkey.cpp index 632f26f7..081ec317 100644 --- a/plugins/bluemonkey/bluemonkey.cpp +++ b/plugins/bluemonkey/bluemonkey.cpp @@ -102,6 +102,7 @@ BluemonkeySink::BluemonkeySink(AbstractRoutingEngine* e, map<string, string> con auth = new Authenticate(config, this); qmlRegisterType<QTimer>("", 1, 0, "QTimer"); + qmlRegisterType<QObject>("", 1, 0, "QObject"); } @@ -275,6 +276,11 @@ QObject *BluemonkeySink::createTimer() return new QTimer(this); } +QObject *BluemonkeySink::createQObject() +{ + return new QObject(this); +} + void BluemonkeySink::getHistory(QStringList properties, QDateTime begin, QDateTime end, QJSValue cbFunction) { double b = (double)begin.toMSecsSinceEpoch() / 1000.0; diff --git a/plugins/bluemonkey/bluemonkey.h b/plugins/bluemonkey/bluemonkey.h index 99cbf636..8617f7e9 100644 --- a/plugins/bluemonkey/bluemonkey.h +++ b/plugins/bluemonkey/bluemonkey.h @@ -99,8 +99,6 @@ public: virtual void propertyChanged(AbstractPropertyType* value); virtual const std::string uuid() const; - QJSEngine* engine; - virtual int supportedOperations(); private: //source privates @@ -133,6 +131,7 @@ public Q_SLOTS: void log(QString str); QObject* createTimer(); + QObject* createQObject(); void getHistory(QStringList properties, QDateTime begin, QDateTime end, QJSValue cbFunction); @@ -149,6 +148,7 @@ public Q_SLOTS: void createCustomProperty(QString name, QJSValue defaultValue, int zone); private: + QJSEngine* engine; QStringList configsToLoad; Authenticate* auth; diff --git a/plugins/bluemonkey/config.js b/plugins/bluemonkey/config.js index 7f388af7..c4a69879 100644 --- a/plugins/bluemonkey/config.js +++ b/plugins/bluemonkey/config.js @@ -1,3 +1,19 @@ +var Zone = { + None: 0, + Front: 1, + Middle : 1 << 1, + Right : 1 << 2, + Left : 1 << 3, + Rear : 1 << 4, + Center : 1 << 5, + LeftSide : 1 << 6, + RightSide : 1 << 7, + FrontSide : 1 << 8, + BackSide : 1 << 9 +}; + +bluemonkey.loadModule(""); + bluemonkey.createCustomProperty("VehicleSpeed", 10); bluemonkey.createCustomProperty("EngineSpeed", 5000); bluemonkey.createCustomProperty("PowertrainTorque", 324); @@ -57,6 +73,16 @@ bluemonkey.createCustomProperty("IgnitionTimeOff", 5000); bluemonkey.createCustomProperty("YawRate", 128); bluemonkey.createCustomProperty("WheelBrake", false); +bluemonkey.createCustomProperty("BrakesWorn", false, Zone.Front | Zone.Right) +bluemonkey.createCustomProperty("BrakeFluidLevel", 100, Zone.Front | Zone.Right) +bluemonkey.createCustomProperty("BrakeFluidLevelLow", false, Zone.Front | Zone.Right) +bluemonkey.createCustomProperty("BrakePadWear", 0, Zone.Front | Zone.Right) + +bluemonkey.createCustomProperty("WasherFluidLevel", 100); +bluemonkey.createCustomProperty("WasherFluidLevelLow", false); + +bluemonkey.createCustomProperty("MalfunctionIndicatorOn", false); + var speedProperty = bluemonkey.subscribeTo("VehicleSpeed"); var testTimer = bluemonkey.createTimer(); diff --git a/plugins/bluemonkey/db.cpp b/plugins/bluemonkey/db.cpp new file mode 100644 index 00000000..07bb9e3f --- /dev/null +++ b/plugins/bluemonkey/db.cpp @@ -0,0 +1,90 @@ +#include "db.h" + +#include <debugout.h> + +#include <QObject> +#include <QSqlError> +#include <QSqlRecord> +#include <QtQml> + +extern "C" std::map<std::string, QObject*> create(std::map<std::string, std::string> config, QObject* parent) +{ + std::map<std::string, QObject*> moduleInstances; + moduleInstances["database"] = new BluemonkeyDatabaseModule(parent); + return moduleInstances; +} + +bool Database::open(QString connectionName, QString filename) +{ + db = QSqlDatabase::addDatabase("QSQLITE", connectionName); + db.setDatabaseName(filename); + return db.open(); +} + +void Database::close() +{ + if(db.isOpen()) + { + db.close(); + } +} + +QObject *Database::exec(QString query) +{ + return new Query(db.exec(query), this); +} + +QString Database::lastError() +{ + return db.lastError().text(); +} + + +Query::Query(QSqlQuery q, QObject* parent) + :QObject(parent) +{ + query = q; +} + +Query::Query(QString connectionName) +{ + setConnectionName(connectionName); +} + +void Query::setConnectionName(QString connectionName) +{ + mConnectionName = connectionName; + db = QSqlDatabase::database(connectionName); + query = QSqlQuery(db); +} + +bool Query::exec(QString queryStr) +{ + query.setNumericalPrecisionPolicy(QSql::HighPrecision); + return query.exec(queryStr); +} + +QVariantList Query::results() +{ + QVariantList results; + + QSqlRecord r = query.record(); + + while(query.next()) + { + + QVariantMap prop; + ///iterate on the properties: + for(int i=0; i< r.count(); i++) + { + QString name = r.fieldName(i); + + QVariant val = query.value(i); + prop[name] = val; + } + + results << prop; + } + + return results; +} diff --git a/plugins/bluemonkey/db.h b/plugins/bluemonkey/db.h new file mode 100644 index 00000000..32716dfe --- /dev/null +++ b/plugins/bluemonkey/db.h @@ -0,0 +1,69 @@ +#include <QObject> +#include <QSqlDatabase> +#include <QSqlQuery> +#include <QVariant> +#include <QVariantList> + +class Database; +class Query; + +class Database: public QObject +{ + Q_OBJECT +public: + Database(QObject* parent = nullptr):QObject(parent){ } + ~Database() { close(); } + + QSqlDatabase database() { return db; } + +public Q_SLOTS: + + bool open(QString connectionName, QString filename); + void close(); + + QObject* exec(QString query); + + QString lastError(); + +private: + QSqlDatabase db; +}; + +class Query: public QObject +{ + Q_OBJECT +public: + Query(QObject* parent = nullptr):QObject(parent){} + Query(QSqlQuery q, QObject* parent = nullptr); + Q_INVOKABLE Query(QString connectionName); +public Q_SLOTS: + void setConnectionName(QString connectionName); + + bool exec(QString queryStr); + + QVariantList results(); + +private: + QSqlQuery query; + QString mConnectionName; + QSqlDatabase db; +}; + + +class BluemonkeyDatabaseModule : public QObject +{ + Q_OBJECT +public: + BluemonkeyDatabaseModule(QObject* parent = nullptr): QObject(parent) { } + +public Q_SLOTS: + QObject* createNewDatabase() + { + return new Database(this); + } + + QObject* createNewQuery() + { + return new Query(this); + } +}; diff --git a/plugins/dbus/abstractdbusinterface.h b/plugins/dbus/abstractdbusinterface.h index ff4486c5..7b13a57d 100644 --- a/plugins/dbus/abstractdbusinterface.h +++ b/plugins/dbus/abstractdbusinterface.h @@ -28,12 +28,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include <nullptr.h> #include "abstractpropertytype.h" #include <abstractroutingengine.h> +#include "varianttype.h" #include "dbussignaller.h" class AbstractProperty; const uint getPid(const char *owner); +typedef std::vector<VariantType*> PropertyDBusMap; + class AbstractDBusInterface { @@ -41,7 +44,7 @@ public: AbstractDBusInterface(std::string interfaceName, std::string objectName, GDBusConnection* connection); virtual ~AbstractDBusInterface(); - + void setDBusConnection(GDBusConnection* connection) { mConnection = connection; @@ -49,10 +52,10 @@ public: void registerObject(); void unregisterObject(); - + void addProperty(AbstractProperty* property); virtual void updateValue(AbstractProperty* property); - + static PropertyList implementedProperties() { return mimplementedProperties; } static std::list<AbstractDBusInterface *> getObjectsForProperty(std::string property); @@ -63,6 +66,25 @@ public: bool implementsProperty(std::string property); + /*! + * \brief hasPropertyDBus + * \param attributeName, name of DBus property + * \return true if attributeName is supported by this interface + */ + bool hasPropertyDBus(std::string attributeName) + { + + for(auto i : propertyDBusMap) + { + if(i->name() == attributeName) + { + return true; + } + } + + return false; + } + std::string objectPath() { return mObjectPath; } bool isSupported() { return supported; } @@ -100,23 +122,24 @@ public: protected: void startRegistration(); - + static GVariant *getProperty(GDBusConnection * connection, const gchar * sender, const gchar *objectPath, const gchar *interfaceName, const gchar * propertyName, GError** error, gpointer userData); static gboolean setProperty(GDBusConnection * connection, const gchar * sender, const gchar *objectPath, const gchar *interfaceName, const gchar * propertyName, GVariant *value, GError** error, gpointer userData); - + virtual void setProperty(std::string propertyName, GVariant * value); virtual GVariant * getProperty(std::string propertyName); void setTimeout(int timeout); - + std::unordered_map<std::string, AbstractProperty*> properties; Zone::Type zoneFilter; + PropertyDBusMap propertyDBusMap; bool supported; double mTime; diff --git a/plugins/dbus/automotivemanager.cpp b/plugins/dbus/automotivemanager.cpp index da49d9c2..6a77bc42 100644 --- a/plugins/dbus/automotivemanager.cpp +++ b/plugins/dbus/automotivemanager.cpp @@ -31,6 +31,11 @@ static const gchar introspection_xml[] = " <arg type='s' name='searchstring' direction='in'/>" " <arg type='as' name='response' direction='out'/>" " </method>" + " <method name='SupportsProperty'>" + " <arg type='s' name='objectName' direction='in'/>" + " <arg type='s' name='propertyName' direction='in'/>" + " <arg type='b' name='response' direction='out'/>" + " </method>" " </interface>" "</node>"; @@ -313,6 +318,32 @@ static void handleMethodCall(GDBusConnection *connection, g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); } + else if(method == "SupportsProperty") + { + gchar* objectName; + gchar* propertyToFindStr; + + g_variant_get(parameters,"(ss)",&objectName, &propertyToFindStr); + + auto objectNamePtr = amb::make_super(objectName); + auto propertyToFindStrPtr = amb::make_super(propertyToFindStr); + + DebugOut(6) << "Checking " << objectNamePtr.get() << " for member: " << propertyToFindStrPtr.get() << endl; + + std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(objectNamePtr.get()); + + for(auto i : interfaces) + { + if(i->hasPropertyDBus(propertyToFindStrPtr.get())) + { + DebugOut(6) << "member " << propertyToFindStrPtr.get() << " of " << objectNamePtr.get() << " was found!!" << endl; + g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", true)); + return; + } + } + DebugOut(6) << "member " << propertyToFindStrPtr.get() << " of " << objectNamePtr.get() << " was not found." << endl; + g_dbus_method_invocation_return_value(invocation,g_variant_new("(b)", false)); + } else { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method."); @@ -320,12 +351,12 @@ static void handleMethodCall(GDBusConnection *connection, } static void signalCallback( GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) { AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data); diff --git a/plugins/dbus/dbusinterfacemanager.cpp b/plugins/dbus/dbusinterfacemanager.cpp index 4200784b..ad7039b2 100644 --- a/plugins/dbus/dbusinterfacemanager.cpp +++ b/plugins/dbus/dbusinterfacemanager.cpp @@ -224,6 +224,10 @@ on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_d exportProperty<WheelTick>(iface->re, connection); exportProperty<IgnitionTime>(iface->re, connection); exportProperty<YawRate>(iface->re, connection); + exportProperty<TransmissionClutch>(iface->re, connection); + exportProperty<TransmissionOil>(iface->re, connection); + exportProperty<BrakeMaintenance>(iface->re, connection); + exportProperty<WasherFluid>(iface->re, connection); iface->registerCustomTypes(); } diff --git a/plugins/dbus/dbusplugin.h b/plugins/dbus/dbusplugin.h index 9ea38d24..897fdef1 100644 --- a/plugins/dbus/dbusplugin.h +++ b/plugins/dbus/dbusplugin.h @@ -27,9 +27,6 @@ #include <map> #include <type_traits> -typedef std::vector<VariantType*> PropertyDBusMap; -//typedef std::unordered_map<VehicleProperty::Property, VariantType*> PropertyDBusMap; - class DBusSink : public AbstractSink, public AbstractDBusInterface { @@ -96,10 +93,6 @@ protected: propertyDBusMap.push_back(new VariantType(routingEngine, ambProperty, propertyName, access)); } - PropertyDBusMap propertyDBusMap; - - - }; class DBusInterfaceManager; diff --git a/plugins/dbus/maintenance.h b/plugins/dbus/maintenance.h index a56a5c57..180b7c12 100644 --- a/plugins/dbus/maintenance.h +++ b/plugins/dbus/maintenance.h @@ -26,6 +26,7 @@ public: }; /** @interface Fluid : VehiclePropertyType **/ + class FluidProperty : public DBusSink { public: @@ -44,6 +45,7 @@ public: * @access readonly * @attributeComment \brief MUST return Brake fluid level percentage. 0-100. **/ + ///TODO: deprecated in 0.14 wantPropertyVariant(VehicleProperty::BrakeFluidLevel, "Brake", AbstractProperty::Read); /** @attributeName Washer @@ -51,6 +53,7 @@ public: * @access readonly * @attributeComment \brief MUST return Washer fluid level percentage. 0-100. **/ + ///TODO: Deprecated in 0.14 wantPropertyVariant(VehicleProperty::WasherFluidLevel, "Washer", AbstractProperty::Read); } }; @@ -152,4 +155,37 @@ public: } }; +class BrakeMaintenance: public DBusSink +{ +public: + BrakeMaintenance(AbstractRoutingEngine* re, GDBusConnection* connection) + :DBusSink("BrakeMaintenance", re, connection, map<string, string>()) + { + wantPropertyVariant(VehicleProperty::BrakePadWear, "PadWear", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::BrakeFluidLevel, "FluidLevel", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::BrakeFluidLevelLow, "FluidLevelLow", AbstractProperty::Read); + } +}; + +class WasherFluid: public DBusSink +{ +public: + WasherFluid(AbstractRoutingEngine* re, GDBusConnection* connection) + :DBusSink("WasherFluid", re, connection, map<string, string>()) + { + wantPropertyVariant(VehicleProperty::WasherFluidLevel, "Level", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::WasherFluidLevelLow, "LevelLow", AbstractProperty::Read); + } +}; + +class MalfunctionIndicator: public DBusSink +{ +public: + MalfunctionIndicator(AbstractRoutingEngine* re, GDBusConnection* connection) + :DBusSink("MalfunctionIndicator", re, connection, map<string, string>()) + { + wantPropertyVariant(VehicleProperty::MalfunctionIndicatorOn, "On", AbstractProperty::Read); + } +}; + #endif diff --git a/plugins/gpsnmea/gpsnmea.cpp b/plugins/gpsnmea/gpsnmea.cpp index 1cd8647e..2791bff2 100644 --- a/plugins/gpsnmea/gpsnmea.cpp +++ b/plugins/gpsnmea/gpsnmea.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "bluetooth.hpp" #include "bluetooth5.h" #include <listplusplus.h> +#include <superptr.hpp> #include <iostream> #include <boost/assert.hpp> @@ -35,6 +36,7 @@ using namespace std; #include "abstractpropertytype.h" #define GPSTIME "GpsTime" +#define GPSSPEED "GpsSpeed" template<typename T2> inline T2 lexical_cast(const std::string &in) { @@ -52,46 +54,46 @@ public: void parse(std::string gprmc); - VehicleProperty::LatitudeType latitude() + VehicleProperty::LatitudeType* latitude() { - return mLatitude; + return mLatitude.get(); } - VehicleProperty::LongitudeType longitude() + VehicleProperty::LongitudeType* longitude() { - return mLongitude; + return mLongitude.get(); } - VehicleProperty::AltitudeType altitude() + VehicleProperty::AltitudeType* altitude() { - return mAltitude; + return mAltitude.get(); } - VehicleProperty::DirectionType direction() + VehicleProperty::DirectionType* direction() { - return mDirection; + return mDirection.get(); } - VehicleProperty::VehicleSpeedType speed() + BasicPropertyType<uint16_t>* speed() { - return mSpeed; + return mSpeed.get(); } - BasicPropertyType<double> gpsTime() + BasicPropertyType<double>* gpsTime() { - return mGpsTime; + return mGpsTime.get(); } std::list<AbstractPropertyType*> fix() { std::list<AbstractPropertyType*> l; - l.push_back(&mLatitude); - l.push_back(&mLongitude); - l.push_back(&mAltitude); - l.push_back(&mDirection); - l.push_back(&mSpeed); - l.push_back(&mGpsTime); + l.push_back(mLatitude.get()); + l.push_back(mLongitude.get()); + l.push_back(mAltitude.get()); + l.push_back(mDirection.get()); + l.push_back(mSpeed.get()); + l.push_back(mGpsTime.get()); return l; } @@ -112,12 +114,12 @@ private: ///methods: private: - VehicleProperty::LatitudeType mLatitude; - VehicleProperty::LongitudeType mLongitude; - VehicleProperty::AltitudeType mAltitude; - VehicleProperty::DirectionType mDirection; - VehicleProperty::VehicleSpeedType mSpeed; - BasicPropertyType<double> mGpsTime; + std::unique_ptr<VehicleProperty::LatitudeType> mLatitude; + std::unique_ptr<VehicleProperty::LongitudeType> mLongitude; + std::unique_ptr<VehicleProperty::AltitudeType> mAltitude; + std::unique_ptr<VehicleProperty::DirectionType> mDirection; + std::unique_ptr<BasicPropertyType<uint16_t>> mSpeed; + std::unique_ptr<BasicPropertyType<double>> mGpsTime; bool isActive; @@ -128,9 +130,14 @@ private: }; Location::Location(AbstractRoutingEngine* re, std::string uuid) - :mLatitude(0), mLongitude(0), mAltitude(0), mDirection(0), mSpeed(0), mGpsTime(GPSTIME,0), isActive(false), routingEngine(re), mUuid(uuid) + :isActive(false), routingEngine(re), mUuid(uuid) { - + mLatitude = amb::make_unique(new VehicleProperty::LatitudeType(0)); + mLongitude = amb::make_unique(new VehicleProperty::LongitudeType(0)); + mAltitude = amb::make_unique(new VehicleProperty::AltitudeType(0)); + mDirection = amb::make_unique(new VehicleProperty::DirectionType(0)); + mSpeed = amb::make_unique(new BasicPropertyType<uint16_t>(GPSSPEED, 0)); + mGpsTime = amb::make_unique(new BasicPropertyType<double>(GPSTIME, 0)); } void Location::parse(string nmea) @@ -217,13 +224,11 @@ void Location::parseTime(string h, string m, string s, string dd, string mm, str time_t time = mktime(&t); - BasicPropertyType<double> temp(GPSTIME,(double)time); - - if(mGpsTime != temp) + if(mGpsTime->basicValue() != (double(time))) { - mGpsTime = temp; + mGpsTime->setValue(double(time)); if(routingEngine) - routingEngine->updateProperty(&mGpsTime, mUuid); + routingEngine->updateProperty(mGpsTime.get(), mUuid); } } catch(...) @@ -245,14 +250,12 @@ void Location::parseLatitude(string d, string m, string ns) if(ns == "S") dec *= -1; - VehicleProperty::LatitudeType temp(dec); - - if(mLatitude != temp) + if(mLatitude->basicValue() != dec) { - mLatitude = temp; + mLatitude->setValue(dec); if(routingEngine) - routingEngine->updateProperty(&mLatitude, mUuid); + routingEngine->updateProperty(mLatitude.get(), mUuid); } } catch(...) @@ -273,14 +276,12 @@ void Location::parseLongitude(string d, string m, string ew) if(ew == "W") dec *= -1; - VehicleProperty::LongitudeType temp(dec); - - if(mLongitude != temp) + if(mLongitude->basicValue() != dec) { - mLongitude = temp; + mLongitude->setValue(dec); if(routingEngine) - routingEngine->updateProperty(&mLongitude, mUuid); + routingEngine->updateProperty(mLongitude.get(), mUuid); } } catch(...) @@ -297,13 +298,15 @@ void Location::parseSpeed(string spd) ///to kph: s *= 1.852; - VehicleProperty::VehicleSpeedType temp(s); - if(mSpeed != temp) + + uint16_t speed = static_cast<uint16_t>(s); + + if(mSpeed->basicValue() != speed) { - mSpeed = temp; + mSpeed->setValue(speed); if(routingEngine) - routingEngine->updateProperty(&mSpeed, mUuid); + routingEngine->updateProperty(mSpeed.get(), mUuid); } } catch(...) @@ -317,12 +320,12 @@ void Location::parseDirection(string dir) try { uint16_t d = boost::lexical_cast<double>(dir); - VehicleProperty::DirectionType temp(d); - if(mDirection != temp) + if(mDirection->basicValue() != d) { - mDirection = temp; + mDirection->setValue(d); + if(routingEngine) - routingEngine->updateProperty(&mDirection, mUuid); + routingEngine->updateProperty(mDirection.get(), mUuid); } } catch(...) @@ -339,16 +342,13 @@ void Location::parseAltitude(string alt) double a = boost::lexical_cast<double>(alt); - VehicleProperty::AltitudeType temp(a); - if(mAltitude != temp) + if(mAltitude->basicValue() != a) { - mAltitude = temp; + mAltitude->setValue(a); if(routingEngine) - routingEngine->updateProperty(&mAltitude, mUuid); + routingEngine->updateProperty(mAltitude.get(), mUuid); } - - mAltitude = VehicleProperty::AltitudeType(a); } catch(...) { @@ -399,12 +399,13 @@ GpsNmeaSource::GpsNmeaSource(AbstractRoutingEngine *re, map<string, string> conf int baudrate = 0; location =new Location(re, mUuid); - VehicleProperty::registerProperty(GPSTIME,[](){ return new BasicPropertyType<double>(GPSTIME,0); }); + VehicleProperty::registerProperty(GPSTIME,[](){ return new BasicPropertyType<double>(GPSTIME, 0); }); + VehicleProperty::registerProperty(GPSSPEED,[](){ return new BasicPropertyType<uint16_t>(GPSSPEED, 0); }); addPropertySupport(VehicleProperty::Latitude, Zone::None); addPropertySupport(VehicleProperty::Longitude, Zone::None); addPropertySupport(VehicleProperty::Altitude, Zone::None); - addPropertySupport(VehicleProperty::VehicleSpeed, Zone::None); + addPropertySupport(GPSSPEED, Zone::None); addPropertySupport(VehicleProperty::Direction, Zone::None); addPropertySupport(GPSTIME, Zone::None); @@ -575,26 +576,26 @@ void GpsNmeaSource::test() Location location(nullptr, ""); location.parse("GPRMC,061211,A,2351.9605,S,15112.5239,E,000.0,053.4,170303,009.9,E*6E"); - DebugOut(0)<<"lat: "<<location.latitude().toString()<<endl; + DebugOut(0)<<"lat: "<<location.latitude()->toString()<<endl; - g_assert(location.latitude().toString() == "-23.86600833"); - g_assert(location.gpsTime().toString() == "1050585131"); + g_assert(location.latitude()->toString() == "-23.86600833"); + g_assert(location.gpsTime()->toString() == "1050585131"); location.parse("GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"); - DebugOut(0)<<"alt: "<<location.altitude().toString()<<endl; - DebugOut(0)<<"lat: "<<location.latitude().toString()<<endl; - g_assert(location.altitude().toString() == "545.4"); - g_assert(location.latitude().toString() == "48.1173"); + DebugOut(0)<<"alt: "<<location.altitude()->toString()<<endl; + DebugOut(0)<<"lat: "<<location.latitude()->toString()<<endl; + g_assert(location.altitude()->toString() == "545.4"); + g_assert(location.latitude()->toString() == "48.1173"); location.parse("GPRMC,060136.00,A,3101.40475,N,12126.87095,E,0.760,,160114,,,A*74"); - DebugOut(0)<<"lon: "<<location.longitude().toString()<<endl; - DebugOut(0)<<"lat: "<<location.latitude().toString()<<endl; + DebugOut(0)<<"lon: "<<location.longitude()->toString()<<endl; + DebugOut(0)<<"lat: "<<location.latitude()->toString()<<endl; //Test incomplete message: location.parse("GPRMC,023633.00,V,,,,,,,180314,,,N*75"); - DebugOut(0)<<"lon: "<<location.longitude().toString()<<endl; - DebugOut(0)<<"lat: "<<location.latitude().toString()<<endl; + DebugOut(0)<<"lon: "<<location.longitude()->toString()<<endl; + DebugOut(0)<<"lat: "<<location.latitude()->toString()<<endl; std::string testChecksuming = "GPRMC,195617.00,V,,,,,,,310314,,,N*74"; diff --git a/plugins/opencvlux/README b/plugins/opencvlux/README index 9d88b6f4..f8db1d2f 100644 --- a/plugins/opencvlux/README +++ b/plugins/opencvlux/README @@ -19,7 +19,6 @@ To use the OpenCV plugin, add the following to the "sources" array in /etc/ambd/ "pixelLowerBound" : "0", "pixelUpperBound" : "255", "fps" : "30", - "kinect" : "false", "opencl" : "false", "device" : "0" } @@ -50,11 +49,6 @@ How many times per second to poll image data from the camera. Default: "30" -"kinect" -Set to "true" if you are using a kinect camera. - -Default: "false" - "pixelLowerBound" Lowest calibration value for a camera. This is the average pixel intensity value the camera reports when it is completely covered. @@ -73,15 +67,6 @@ was compiled with OpenCL support. To enable openCL, pass -Docl=ON to cmake. Default: "false" -"cuda" -Use nvidia cuda gpu processing to process image data. This will only work if OpenCV was compiled with -cuda support. - -NOTE: this does not appear to have a noticable impact on processing given the way we are using it. -this does however make memory usage explode. - -Default: "false" - "logging" Turn on video logging. diff --git a/plugins/opencvlux/opencvluxplugin.cpp b/plugins/opencvlux/opencvluxplugin.cpp index b0caf1b4..ea4f2e12 100644 --- a/plugins/opencvlux/opencvluxplugin.cpp +++ b/plugins/opencvlux/opencvluxplugin.cpp @@ -22,8 +22,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include <superptr.hpp> #include <iostream> -#include <opencv2/imgproc/imgproc.hpp> -#include <opencv2/objdetect/objdetect.hpp> +#include <thread> +#include <opencv2/opencv.hpp> +#include <opencv2/core/ocl.hpp> #include <QFuture> #include <QFutureWatcher> @@ -31,11 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #ifdef OPENCL -#include <opencv2/ocl/ocl.hpp> -#endif - -#ifdef CUDA -#include <opencv2/gpu/gpu.hpp> +#include <opencv2/core/ocl.hpp> #endif using namespace std; @@ -77,7 +74,6 @@ OpenCvLuxPlugin::OpenCvLuxPlugin(AbstractRoutingEngine* re, map<string, string> shared->threaded = false; shared->kinect = false; - shared->useOpenCl = false; shared->useCuda = false; shared->loggingOn = false; shared->ddd = false; @@ -128,21 +124,14 @@ OpenCvLuxPlugin::OpenCvLuxPlugin(AbstractRoutingEngine* re, map<string, string> if(config.find("opencl") != config.end()) { -#ifdef OPENCL - shared->useOpenCl = config["opencl"] == "true"; - openCl->setValue(shared->useOpenCl); -#else - DebugOut(DebugOut::Warning) << "You really don't have openCL support. Disabling." << endl; - shared->useOpenCl = false; -#endif - - } - - if(config.find("cuda") != config.end()) - { -#ifdef CUDA - shared->useCuda = config["cuda"] == "true"; -#endif + if(cv::ocl::haveOpenCL()) + { + bool useOcl = config["opencl"] == "true"; + cv::ocl::setUseOpenCL(useOcl); + openCl->setValue(cv::ocl::useOpenCL()); + } + else + DebugOut(DebugOut::Warning) << "You really don't have openCL support." << endl; } if(config.find("ddd") != config.end()) @@ -155,82 +144,20 @@ OpenCvLuxPlugin::OpenCvLuxPlugin(AbstractRoutingEngine* re, map<string, string> shared->loggingOn = config["logging"] == "true"; } - -#ifdef OPENCL - - cv::ocl::PlatformsInfo platforms; - cv::ocl::getOpenCLPlatforms(platforms); - - for(auto p : platforms) - { - DebugOut(1)<<"platform: "<<p->platformName<<" vendor: "<<p->platformVendor<<endl; - } - - cv::ocl::DevicesInfo info; - cv::ocl::getOpenCLDevices(info, cv::ocl::CVCL_DEVICE_TYPE_ALL); - - DebugOut(1)<<"There are "<<info.size()<<" OpenCL devices on this system"<<endl; - - if(!info.size()) - { - DebugOut(1)<<"No CL devices. Disabling OpenCL"<<endl; - shared->useOpenCl = false; - } - else - { - cv::ocl::setDevice(info[0]); - } - - for(auto i : info) - { - for(auto name : i->deviceName) - { - DebugOut(1)<<"OpenCLDeviceName: "<<name<<endl; - } - } - -#endif - -#ifdef CUDA - if(shared->useCuda) - { - int devices = cv::gpu::getCudaEnabledDeviceCount(); - DebugOut()<<"There are "<<devices<<" CUDA devices on this system"<<endl; - if(devices) - { - DebugOut()<<"We will use 0 as the default device"<<endl; - cv::gpu::DeviceInfo info(0); - DebugOut()<<"Cuda Device Name: "<<info.name()<<endl; - DebugOut()<<"Version: "<<info.majorVersion()<<"major"<<info.minorVersion()<<"minor"<<endl; - DebugOut()<<"Streaming processor count: "<<info.multiProcessorCount()<<endl; - cv::gpu::setDevice(0); - } - else - { - DebugOut(DebugOut::Warning)<<"No CUDA device found. Disabling CUDA."<<endl; - shared->useCuda = false; - } - } -#endif - if(shared->ddd) { -#ifdef OPENCL - faceCascade = amb::make_unique(new cv::ocl::OclCascadeClassifier()); - eyeCascade = amb::make_unique(new cv::ocl::OclCascadeClassifier()); -#else faceCascade = amb::make_unique(new cv::CascadeClassifier()); eyeCascade = amb::make_unique(new cv::CascadeClassifier()); -#endif - std::string faceFile = CV_DATA "/haarcascades/haarcascade_frontalface_alt.xml"; + std::string faceFile = config["faceCascade"]; + if(!faceCascade->load(faceFile)) { DebugOut(DebugOut::Warning) << "Could not load face cascade: " << faceFile <<". Disabling ddd" << endl; shared->ddd = false; } - std::string eyeFile = CV_DATA "/haarcascades/haarcascade_eye_tree_eyeglasses.xml"; + std::string eyeFile = config["eyeCascade"]; if(!eyeCascade->load(eyeFile)) { @@ -370,18 +297,23 @@ static int grabImage(void *data) { OpenCvLuxPlugin::Shared* shared = static_cast<OpenCvLuxPlugin::Shared*>(data); - cv::Mat m_image; + shared->frameCount++; - if(shared->kinect) - { - shared->m_capture->grab(); - shared->m_capture->retrieve( m_image, CV_CAP_OPENNI_GRAY_IMAGE ); - } - else + if(shared->frameCount >= shared->fps) + shared->frameCount = 0; + + if(shared->frameCount % 4 != 0) { - *(shared->m_capture.get()) >> m_image; + return true; } + if(!shared->m_capture->isOpened()) + return false; + + cv::UMat m_image; + + *(shared->m_capture.get()) >> m_image; + if(shared->ddd) { try @@ -394,7 +326,7 @@ static int grabImage(void *data) } } - if(shared->threaded) + /*if(shared->threaded) { QFutureWatcher<uint> *watcher = new QFutureWatcher<uint>(); QObject::connect(watcher, &QFutureWatcher<uint>::finished, shared->parent, &OpenCvLuxPlugin::imgProcResult); @@ -418,8 +350,7 @@ static int grabImage(void *data) } //detectLight(m_image,shared); - - } + }*/ if(shared->mRequests.size()) { @@ -429,7 +360,7 @@ static int grabImage(void *data) return false; } -static uint evalImage(cv::Mat qImg, OpenCvLuxPlugin::Shared *shared) +static uint evalImage(cv::UMat qImg, OpenCvLuxPlugin::Shared *shared) { if(qImg.empty()) { @@ -439,38 +370,7 @@ static uint evalImage(cv::Mat qImg, OpenCvLuxPlugin::Shared *shared) cv::Scalar avgPixelIntensity; - - if(shared->useOpenCl) - { -#ifdef OPENCL - cv::Scalar stdDev; - cv::ocl::oclMat src(qImg), gray; - cv::ocl::cvtColor(src, gray, CV_BGR2GRAY); - cv::ocl::meanStdDev(src, avgPixelIntensity, stdDev); -#endif - } - else if(shared->useCuda) - { -#ifdef CUDA - cv::gpu::GpuMat src(qImg), dest; - cv::gpu::cvtColor(src, dest, CV_BGR2GRAY); - cv::Scalar stdDev; - try - { - - cv::gpu::meanStdDev(dest, avgPixelIntensity, stdDev); - } - catch(...) - { - DebugOut(DebugOut::Error)<<"CUDA pixel intensity calculation failed."<<endl; - } -#endif - } - else - { - avgPixelIntensity = cv::mean(qImg); - } - + avgPixelIntensity = cv::mean(qImg); double val = avgPixelIntensity.val[0]; @@ -488,11 +388,7 @@ static uint evalImage(cv::Mat qImg, OpenCvLuxPlugin::Shared *shared) bool OpenCvLuxPlugin::init() { - if(!shared->m_capture && shared->kinect) - { - shared->m_capture = amb::make_unique(new cv::VideoCapture(CV_CAP_OPENNI)); - } - else if(!shared->m_capture) + if(!shared->m_capture) { if(device == "") shared->m_capture = amb::make_unique(new cv::VideoCapture(0)); @@ -510,8 +406,8 @@ bool OpenCvLuxPlugin::init() configuration["logging"] == "true" && (!shared->mWriter || !shared->mWriter->isOpened())) { - cv::Size s = cv::Size((int) shared->m_capture->get(CV_CAP_PROP_FRAME_WIDTH), - (int) shared->m_capture->get(CV_CAP_PROP_FRAME_HEIGHT)); + cv::Size s = cv::Size((int) shared->m_capture->get(cv::CAP_PROP_FRAME_WIDTH), + (int) shared->m_capture->get(cv::CAP_PROP_FRAME_HEIGHT)); std::string codec = configuration["codec"]; @@ -527,19 +423,19 @@ bool OpenCvLuxPlugin::init() boost::algorithm::to_upper(codec); - shared->mWriter = amb::make_unique(new cv::VideoWriter(filename, CV_FOURCC(codec.at(0), codec.at(1), codec.at(2), codec.at(3)),30,s)); + shared->mWriter = amb::make_unique(new cv::VideoWriter(filename, cv::VideoWriter::fourcc(codec.at(0), codec.at(1), codec.at(2), codec.at(3)),30,s)); } - DebugOut()<<"camera frame width: "<<shared->m_capture->get(CV_CAP_PROP_FRAME_WIDTH)<<endl; - DebugOut()<<"camera frame height: "<<shared->m_capture->get(CV_CAP_PROP_FRAME_HEIGHT)<<endl; - DebugOut()<<"camera frame fps: "<<shared->m_capture->get(CV_CAP_PROP_FPS)<<endl; + DebugOut()<<"camera frame width: "<<shared->m_capture->get(cv::CAP_PROP_FRAME_WIDTH)<<endl; + DebugOut()<<"camera frame height: "<<shared->m_capture->get(cv::CAP_PROP_FRAME_HEIGHT)<<endl; + DebugOut()<<"camera frame fps: "<<shared->m_capture->get(cv::CAP_PROP_FPS)<<endl; return true; } -void OpenCvLuxPlugin::writeVideoFrame(cv::Mat f) +void OpenCvLuxPlugin::writeVideoFrame(cv::UMat f) { QMutexLocker locker(&mutex); @@ -640,27 +536,14 @@ TrafficLight::Color detectLight(cv::Mat img, OpenCvLuxPlugin::Shared *shared) cv::Mat gray; - if(shared->useOpenCl) - { -#ifdef OPENCL - cv::ocl::oclMat src(img), gray2; - cv::ocl::cvtColor(src, gray2, CV_BGR2GRAY); - cv::ocl::GaussianBlur(gray2, gray2, cv::Size(9,9), 2, 2); - - gray = gray2; -#endif - } - else - { - cv::cvtColor(img, gray, CV_BGR2GRAY); - cv::GaussianBlur(gray, gray, cv::Size(9,9), 2, 2); - } + cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY); + cv::GaussianBlur(gray, gray, cv::Size(9,9), 2, 2); std::vector<cv::Vec3f> circles; //cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, gray.rows/8, 200, 100, 0, 0); - cv::HoughCircles( gray, circles, CV_HOUGH_GRADIENT, 2, 30, 231, 50, 0, 0 ); + cv::HoughCircles( gray, circles, cv::HOUGH_GRADIENT, 2, 30, 231, 50, 0, 0 ); for(auto i = 0; i < circles.size(); i++) { @@ -701,40 +584,22 @@ TrafficLight::Color detectLight(cv::Mat img, OpenCvLuxPlugin::Shared *shared) } } - - cv::namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE ); - cv::imshow( "Hough Circle Transform Demo", img ); } -void OpenCvLuxPlugin::detectEyes(cv::Mat frame) +void OpenCvLuxPlugin::detectEyes(cv::UMat frame) { if(frame.empty()) return; bool hasEyes = false; std::vector<cv::Rect> faces; - cv::Mat frameGray; -#ifdef OPENCL - cv::ocl::oclMat gray2; -#endif + cv::UMat frameGray; - if(shared->useOpenCl) - { -#ifdef OPENCL - cv::ocl::oclMat src(frame); - cv::ocl::cvtColor(src, gray2, CV_BGR2GRAY); - cv::ocl::equalizeHist(gray2, gray2); - cv::ocl::OclCascadeClassifier* fc = static_cast<cv::ocl::OclCascadeClassifier*>(faceCascade.get()); - fc->detectMultiScale(gray2, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30)); -#endif - } - else - { - cv::cvtColor(frame, frameGray, CV_BGR2GRAY); - cv::equalizeHist(frameGray, frameGray); - faceCascade->detectMultiScale(frameGray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30)); - } + + cv::cvtColor(frame, frameGray, cv::COLOR_BGR2GRAY); + cv::equalizeHist(frameGray, frameGray); + faceCascade->detectMultiScale(frameGray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30)); for( size_t i = 0; i < faces.size(); i++ ) { @@ -743,33 +608,30 @@ void OpenCvLuxPlugin::detectEyes(cv::Mat frame) std::vector<cv::Rect> eyes; - if(shared->useOpenCl) - { -#ifdef OPENCL - cv::ocl::oclMat faceROI = gray2(faces[i]); - cv::ocl::OclCascadeClassifier* ec = static_cast<cv::ocl::OclCascadeClassifier*>(eyeCascade.get()); - ec->detectMultiScale( faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30) ); -#endif - } - else + + cv::UMat faceROI(frameGray(faces[i])); + eyeCascade->detectMultiScale( faceROI, eyes, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30) ); + + for( size_t j = 0; j < eyes.size(); j++ ) { - cv::Mat faceROI = frameGray(faces[i]); - eyeCascade->detectMultiScale( faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30) ); + cv::Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 ); + int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 ); + cv::circle( frame, center, radius, cv::Scalar( 255, 0, 0 ), 4, 8, 0 ); } if(eyes.size()) { hasEyes = true; DebugOut() << "Number of eyes: " << eyes.size() << endl; - } - for( size_t j = 0; j < eyes.size(); j++ ) + driverDrowsiness->setValue(false); + routingEngine->updateProperty(driverDrowsiness.get(), this->uuid()); + } + else { - cv::Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 ); - int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 ); - cv::circle( frame, center, radius, cv::Scalar( 255, 0, 0 ), 4, 8, 0 ); + DebugOut() << "No eyes!!!" << endl; + driverDrowsiness->setValue(true); + routingEngine->updateProperty(driverDrowsiness.get(), this->uuid()); } } - - routingEngine->updateProperty(driverDrowsiness.get(),this->uuid()); } diff --git a/plugins/opencvlux/opencvluxplugin.h b/plugins/opencvlux/opencvluxplugin.h index 7fbee9ac..550a9fb9 100644 --- a/plugins/opencvlux/opencvluxplugin.h +++ b/plugins/opencvlux/opencvluxplugin.h @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include <string> #include <memory> -#include <opencv/cv.h> +#include <opencv2/objdetect.hpp> #include <opencv2/highgui/highgui.hpp> #include <QObject> @@ -40,20 +40,21 @@ public: struct Shared { + Shared(): frameCount(0) { } std::unique_ptr<cv::VideoCapture> m_capture; std::unique_ptr<cv::VideoWriter> mWriter; PropertyList mRequests; OpenCvLuxPlugin* parent; - double fps; + int fps; bool threaded; bool kinect; - bool useOpenCl; bool useCuda; int pixelLowerBound; int pixelUpperBound; bool loggingOn; bool ddd; + int frameCount; }; OpenCvLuxPlugin(AbstractRoutingEngine* re, map<string, string> config); @@ -76,9 +77,9 @@ public: void updateProperty(uint lux); - void writeVideoFrame(cv::Mat frame); + void writeVideoFrame(cv::UMat frame); - void detectEyes(cv::Mat frame); + void detectEyes(cv::UMat frame); public Q_SLOTS: void imgProcResult(); diff --git a/xwalk/CMakeLists.txt b/xwalk/CMakeLists.txt index 3e0410d8..01cbae07 100644 --- a/xwalk/CMakeLists.txt +++ b/xwalk/CMakeLists.txt @@ -4,15 +4,20 @@ pkg_check_modules(gio REQUIRED gio-2.0) set(vehicle_api_headers vehicle.h vehicle_instance.h vehicle_extension.h common/extension.h picojson.h common/utils.h common/virtual_fs.h common/XW_Extension_EntryPoints.h common/XW_Extension.h common/XW_Permissions.h common/XW_Extension_Runtime.h common/XW_Extension_SyncMessage.h) -set(vehicle_api_sources vehicle.cc vehicle_extension.cc vehicle_instance.cc common/extension.cc vehicle_api.cc) +set(vehicle_api_sources vehicle.cc vehicle_extension.cc vehicle_instance.cc common/extension.cc) + -add_library(vehicle_extension MODULE ${vehicle_api_sources}) include_directories(${include_dirs} ${CMAKE_CURRENT_SOURCE_DIR}/) + + +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vehicle_api.cc + COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/generate_api.py ${CMAKE_CURRENT_SOURCE_DIR}/vehicle_api.js kSource_vehicle_api ${CMAKE_CURRENT_BINARY_DIR}/vehicle_api.cc ) + +add_library(vehicle_extension MODULE ${vehicle_api_sources} ${CMAKE_CURRENT_BINARY_DIR}/vehicle_api.cc) target_link_libraries(vehicle_extension ${link_libraries} amb ${gio_LIBRARIES} -L${CMAKE_CURRENT_BINARY_DIR}/lib) -add_custom_command(OUTPUT genjs2cc COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/generate_api.py ${CMAKE_CURRENT_SOURCE_DIR}/vehicle_api.js kSource_vehicle_api ${CMAKE_CURRENT_SOURCE_DIR}/vehicle_api.cc ) -add_custom_target(js3cc DEPENDS genjs2cc) +add_custom_target(js3cc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/vehicle_api.cc) add_dependencies(vehicle_extension js3cc) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/vehicle_api.js ${CMAKE_CURRENT_SOURCE_DIR}/vehicle_api.js @ONLY) diff --git a/xwalk/vehicle.cc b/xwalk/vehicle.cc index 2fa2fb65..5256a392 100644 --- a/xwalk/vehicle.cc +++ b/xwalk/vehicle.cc @@ -418,7 +418,7 @@ void Vehicle::GetZones(const std::string& object_name, double ret_id) { auto value_ptr = amb::make_super(value); int v = 0; - g_variant_get(value_ptr.get(), "(i)", &v); + g_variant_get(value_ptr.get(), "i", &v); zones_array.push_back(v); } @@ -447,15 +447,17 @@ std::string Vehicle::FindProperty(const std::string& object_name, int zone, std: auto error_ptr = amb::make_super(error); if (error_ptr) { - DebugOut() << "error calling FindObjectForZone: " + DebugOut(DebugOut::Error) << "error calling FindObjectForZone: " << error_ptr->message << endl; DebugOut() << "Could not find object in zone: " << zone << endl; + error_str = vehicle_error_invalid_operation; return ""; } if (!object_path_variant) { DebugOut() << "Could not find object in zone: " << zone << endl; + error_str = vehicle_error_invalid_operation; return ""; } @@ -693,7 +695,8 @@ void Vehicle::Set(const std::string &object_name, picojson::object value, if (set_error_ptr) { DebugOut(DebugOut::Error) << "error setting property:" << set_error_ptr->message << endl; - if(set_error_ptr->code == G_IO_ERROR_PERMISSION_DENIED || std::string(g_dbus_error_get_remote_error(set_error_ptr.get())) == "org.freedesktop.DBus.Error.AccessDenied") + if(set_error_ptr->code == G_IO_ERROR_PERMISSION_DENIED + || std::string(g_dbus_error_get_remote_error(set_error_ptr.get())) == "org.freedesktop.DBus.Error.AccessDenied") { DebugOut(DebugOut::Error) << "permission denied" << endl; PostError(&callback, vehicle_error_permission_denied); @@ -706,3 +709,64 @@ void Vehicle::Set(const std::string &object_name, picojson::object value, PostReply(&callback, picojson::value()); } + +void Vehicle::Supported(const string& object_name, double ret_id) +{ + Vehicle::CallbackInfo callback; + callback.callback_id = ret_id; + callback.method = "supported"; + callback.instance = instance_; + + GError* error(nullptr); + + auto object_path_variant = amb::make_super( + g_dbus_proxy_call_sync(manager_proxy_.get(), + "FindObject", + g_variant_new("(s)", object_name.c_str()), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error)); + + auto error_ptr = amb::make_super(error); + + if (error_ptr) { + DebugOut(DebugOut::Error) << "error calling FindObjectForZone: " + << error_ptr->message << endl; + + DebugOut() << "Could not find object for: " << object_name << endl; + PostReply(&callback, picojson::value(false)); + return; + } + + if (!object_path_variant) { + DebugOut() << "Could not find object for: " << object_name << endl; + PostReply(&callback, picojson::value(false)); + return; + } + + PostReply(&callback, picojson::value(true)); +} + +bool Vehicle::AvailableForRetrieval(const string &objectName, const string &attName) +{ + GError* error = nullptr; + + auto supportedVariant = amb::make_super( + g_dbus_proxy_call_sync(manager_proxy_.get(), + "SupportsProperty", + g_variant_new("(ss)", objectName.c_str(), attName.c_str()), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error)); + + auto error_ptr = amb::make_super(error); + + if (error_ptr) { + DebugOut(DebugOut::Error) << "error calling SupportsProperty: " + << error_ptr->message << endl; + + DebugOut() << "Could not find object for: " << objectName << endl; + return false; + } + + bool supported = false; + g_variant_get(supportedVariant.get(), "(b)", &supported); + + return supported; +} diff --git a/xwalk/vehicle.h b/xwalk/vehicle.h index 1b638457..9308b105 100644 --- a/xwalk/vehicle.h +++ b/xwalk/vehicle.h @@ -70,6 +70,8 @@ class Vehicle { void Subscribe(const std::string& property, Zone::Type zone); void Unsubscribe(const std::string& property, Zone::Type zone); void Set(const std::string& property, picojson::object value, Zone::Type zone, double ret_id); + void Supported(const std::string& property, double ret_id); + bool AvailableForRetrieval(const std::string& objectName, const std::string& attName); private: std::string FindProperty(const std::string& object_name, int zone, string &error_str); diff --git a/xwalk/vehicle.html b/xwalk/vehicle.html index 474b5f3d..59d32234 100644 --- a/xwalk/vehicle.html +++ b/xwalk/vehicle.html @@ -37,6 +37,10 @@ debug("zone1 == zone3 ? " + zone1.equals(zone3)); debug("zone1 == zone1 ? " + zone1.equals(zone1)); debug("zone1 == empty zone ? " + zone1.equals(zone4)); + +debug("testing supported"); +debug("vehicle speed supported? " + vehicle.vehicleSpeed.supported); + debug("testing subscribe()"); var subReplies = 0; diff --git a/xwalk/vehicle_api.cc b/xwalk/vehicle_api.cc deleted file mode 100644 index 0567dd42..00000000 --- a/xwalk/vehicle_api.cc +++ /dev/null @@ -1,2 +0,0 @@ -extern const char kSource_vehicle_api[]; -const char kSource_vehicle_api[] = { 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 50, 48, 49, 52, 32, 73, 110, 116, 101, 108, 32, 67, 111, 114, 112, 111, 114, 97, 116, 105, 111, 110, 46, 32, 65, 108, 108, 32, 114, 105, 103, 104, 116, 115, 32, 114, 101, 115, 101, 114, 118, 101, 100, 46, 10, 47, 47, 32, 85, 115, 101, 32, 111, 102, 32, 116, 104, 105, 115, 32, 115, 111, 117, 114, 99, 101, 32, 99, 111, 100, 101, 32, 105, 115, 32, 103, 111, 118, 101, 114, 110, 101, 100, 32, 98, 121, 32, 97, 32, 66, 83, 68, 45, 115, 116, 121, 108, 101, 32, 108, 105, 99, 101, 110, 115, 101, 32, 116, 104, 97, 116, 32, 99, 97, 110, 32, 98, 101, 10, 47, 47, 32, 102, 111, 117, 110, 100, 32, 105, 110, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 32, 102, 105, 108, 101, 46, 10, 10, 118, 97, 114, 32, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 32, 61, 32, 48, 59, 10, 118, 97, 114, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 32, 61, 32, 123, 125, 59, 10, 10, 118, 97, 114, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 32, 61, 32, 91, 93, 59, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 118, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 67, 111, 109, 109, 111, 110, 67, 111, 110, 116, 114, 117, 99, 116, 111, 114, 40, 111, 98, 106, 44, 32, 97, 116, 116, 110, 97, 109, 101, 41, 32, 123, 10, 32, 32, 111, 98, 106, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 32, 61, 32, 97, 116, 116, 110, 97, 109, 101, 59, 10, 10, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 123, 125, 59, 10, 32, 32, 109, 115, 103, 91, 39, 109, 101, 116, 104, 111, 100, 39, 93, 32, 61, 32, 39, 122, 111, 110, 101, 115, 39, 59, 10, 32, 32, 109, 115, 103, 91, 39, 110, 97, 109, 101, 39, 93, 32, 61, 32, 111, 98, 106, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 59, 10, 10, 32, 32, 111, 98, 106, 46, 95, 122, 111, 110, 101, 115, 32, 61, 32, 110, 101, 119, 32, 90, 111, 110, 101, 59, 10, 10, 32, 32, 118, 97, 114, 32, 99, 97, 108, 108, 32, 61, 32, 110, 101, 119, 32, 65, 115, 121, 110, 99, 67, 97, 108, 108, 40, 102, 117, 110, 99, 116, 105, 111, 110, 40, 100, 97, 116, 97, 41, 32, 123, 10, 32, 32, 32, 32, 111, 98, 106, 46, 95, 122, 111, 110, 101, 115, 32, 61, 32, 100, 97, 116, 97, 59, 10, 32, 32, 125, 41, 59, 10, 10, 32, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 93, 32, 61, 32, 99, 97, 108, 108, 59, 10, 32, 32, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 32, 61, 32, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 59, 10, 32, 32, 43, 43, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 59, 10, 10, 32, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110, 46, 112, 111, 115, 116, 77, 101, 115, 115, 97, 103, 101, 40, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, 103, 105, 102, 121, 40, 109, 115, 103, 41, 41, 59, 10, 10, 32, 32, 79, 98, 106, 101, 99, 116, 46, 100, 101, 102, 105, 110, 101, 80, 114, 111, 112, 101, 114, 116, 121, 40, 111, 98, 106, 44, 32, 39, 122, 111, 110, 101, 115, 39, 44, 32, 123, 32, 103, 101, 116, 58, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 41, 32, 123, 32, 114, 101, 116, 117, 114, 110, 32, 111, 98, 106, 46, 95, 122, 111, 110, 101, 115, 32, 125, 32, 125, 41, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 86, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 40, 97, 116, 116, 110, 97, 109, 101, 41, 32, 123, 10, 32, 32, 118, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 67, 111, 109, 109, 111, 110, 67, 111, 110, 116, 114, 117, 99, 116, 111, 114, 40, 116, 104, 105, 115, 44, 32, 97, 116, 116, 110, 97, 109, 101, 41, 59, 10, 125, 10, 10, 86, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 46, 103, 101, 116, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 122, 111, 110, 101, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 123, 125, 59, 10, 32, 32, 109, 115, 103, 91, 39, 109, 101, 116, 104, 111, 100, 39, 93, 32, 61, 32, 39, 103, 101, 116, 39, 59, 10, 32, 32, 109, 115, 103, 91, 39, 110, 97, 109, 101, 39, 93, 32, 61, 32, 116, 104, 105, 115, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 59, 10, 32, 32, 109, 115, 103, 91, 39, 122, 111, 110, 101, 39, 93, 32, 61, 32, 122, 111, 110, 101, 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, 99, 114, 101, 97, 116, 101, 80, 114, 111, 109, 105, 115, 101, 40, 109, 115, 103, 41, 59, 10, 125, 59, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 40, 97, 116, 116, 110, 97, 109, 101, 41, 32, 123, 10, 32, 32, 118, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 67, 111, 109, 109, 111, 110, 67, 111, 110, 116, 114, 117, 99, 116, 111, 114, 40, 116, 104, 105, 115, 44, 32, 97, 116, 116, 110, 97, 109, 101, 41, 59, 10, 125, 10, 10, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 32, 61, 32, 86, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 59, 10, 10, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 46, 115, 117, 98, 115, 99, 114, 105, 98, 101, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 99, 97, 108, 108, 98, 97, 99, 107, 44, 32, 122, 111, 110, 101, 41, 32, 123, 10, 32, 32, 105, 102, 32, 40, 33, 122, 111, 110, 101, 41, 32, 122, 111, 110, 101, 32, 61, 32, 110, 101, 119, 32, 90, 111, 110, 101, 40, 41, 59, 10, 10, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 123, 125, 59, 10, 32, 32, 109, 115, 103, 91, 39, 109, 101, 116, 104, 111, 100, 39, 93, 32, 61, 32, 39, 115, 117, 98, 115, 99, 114, 105, 98, 101, 39, 59, 10, 32, 32, 109, 115, 103, 91, 39, 110, 97, 109, 101, 39, 93, 32, 61, 32, 116, 104, 105, 115, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 59, 10, 32, 32, 109, 115, 103, 91, 39, 122, 111, 110, 101, 39, 93, 32, 61, 32, 122, 111, 110, 101, 59, 10, 10, 32, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110, 46, 112, 111, 115, 116, 77, 101, 115, 115, 97, 103, 101, 40, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, 103, 105, 102, 121, 40, 109, 115, 103, 41, 41, 59, 10, 10, 32, 32, 109, 115, 103, 91, 39, 99, 97, 108, 108, 98, 97, 99, 107, 39, 93, 32, 61, 32, 99, 97, 108, 108, 98, 97, 99, 107, 59, 10, 10, 32, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 46, 112, 117, 115, 104, 40, 109, 115, 103, 41, 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 46, 108, 101, 110, 103, 116, 104, 32, 45, 32, 49, 59, 10, 125, 59, 10, 10, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 46, 117, 110, 115, 117, 98, 115, 99, 114, 105, 98, 101, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 104, 97, 110, 100, 108, 101, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 111, 98, 106, 32, 61, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 91, 104, 97, 110, 100, 108, 101, 93, 59, 10, 32, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 46, 115, 112, 108, 105, 99, 101, 40, 104, 97, 110, 100, 108, 101, 44, 32, 49, 41, 59, 10, 10, 32, 32, 118, 97, 114, 32, 117, 110, 115, 117, 98, 115, 99, 114, 105, 98, 101, 32, 61, 32, 116, 114, 117, 101, 59, 10, 10, 32, 32, 102, 111, 114, 32, 40, 118, 97, 114, 32, 105, 32, 61, 32, 48, 59, 32, 105, 32, 60, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 43, 43, 41, 32, 123, 10, 32, 32, 32, 32, 118, 97, 114, 32, 116, 101, 115, 116, 79, 98, 106, 32, 61, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 91, 105, 93, 59, 10, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 101, 115, 116, 79, 98, 106, 46, 110, 97, 109, 101, 32, 61, 61, 61, 32, 111, 98, 106, 46, 110, 97, 109, 101, 32, 38, 38, 32, 116, 101, 115, 116, 79, 98, 106, 46, 122, 111, 110, 101, 46, 101, 113, 117, 97, 108, 115, 40, 111, 98, 106, 46, 122, 111, 110, 101, 41, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 117, 110, 115, 117, 98, 115, 99, 114, 105, 98, 101, 32, 61, 32, 102, 97, 108, 115, 101, 59, 10, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 125, 10, 10, 32, 32, 105, 102, 32, 40, 117, 110, 115, 117, 98, 115, 99, 114, 105, 98, 101, 41, 32, 123, 10, 32, 32, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 123, 125, 59, 10, 32, 32, 32, 32, 109, 115, 103, 91, 39, 109, 101, 116, 104, 111, 100, 39, 93, 32, 61, 32, 39, 117, 110, 115, 117, 98, 115, 99, 114, 105, 98, 101, 39, 59, 10, 32, 32, 32, 32, 109, 115, 103, 91, 39, 110, 97, 109, 101, 39, 93, 32, 61, 32, 116, 104, 105, 115, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 59, 10, 32, 32, 32, 32, 109, 115, 103, 91, 39, 122, 111, 110, 101, 39, 93, 32, 61, 32, 111, 98, 106, 46, 122, 111, 110, 101, 59, 10, 10, 32, 32, 32, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110, 46, 112, 111, 115, 116, 77, 101, 115, 115, 97, 103, 101, 40, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, 103, 105, 102, 121, 40, 109, 115, 103, 41, 41, 59, 10, 32, 32, 125, 10, 125, 59, 10, 10, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 46, 115, 101, 116, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 118, 97, 108, 117, 101, 44, 32, 122, 111, 110, 101, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 123, 125, 59, 10, 32, 32, 109, 115, 103, 91, 39, 109, 101, 116, 104, 111, 100, 39, 93, 32, 61, 32, 39, 115, 101, 116, 39, 59, 10, 32, 32, 109, 115, 103, 91, 39, 110, 97, 109, 101, 39, 93, 32, 61, 32, 116, 104, 105, 115, 46, 97, 116, 116, 114, 105, 98, 117, 116, 101, 78, 97, 109, 101, 59, 10, 32, 32, 109, 115, 103, 91, 39, 122, 111, 110, 101, 39, 93, 32, 61, 32, 122, 111, 110, 101, 59, 10, 32, 32, 109, 115, 103, 91, 39, 118, 97, 108, 117, 101, 39, 93, 32, 61, 32, 118, 97, 108, 117, 101, 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, 99, 114, 101, 97, 116, 101, 80, 114, 111, 109, 105, 115, 101, 40, 109, 115, 103, 41, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 65, 115, 121, 110, 99, 67, 97, 108, 108, 40, 114, 101, 115, 111, 108, 118, 101, 44, 32, 114, 101, 106, 101, 99, 116, 41, 32, 123, 10, 32, 32, 116, 104, 105, 115, 46, 114, 101, 115, 111, 108, 118, 101, 32, 61, 32, 114, 101, 115, 111, 108, 118, 101, 59, 10, 32, 32, 116, 104, 105, 115, 46, 114, 101, 106, 101, 99, 116, 32, 61, 32, 114, 101, 106, 101, 99, 116, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 99, 114, 101, 97, 116, 101, 80, 114, 111, 109, 105, 115, 101, 40, 109, 115, 103, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 112, 114, 111, 109, 105, 115, 101, 32, 61, 32, 110, 101, 119, 32, 80, 114, 111, 109, 105, 115, 101, 40, 102, 117, 110, 99, 116, 105, 111, 110, 40, 114, 101, 115, 111, 108, 118, 101, 44, 32, 114, 101, 106, 101, 99, 116, 41, 32, 123, 10, 32, 32, 32, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 93, 32, 61, 32, 110, 101, 119, 32, 65, 115, 121, 110, 99, 67, 97, 108, 108, 40, 114, 101, 115, 111, 108, 118, 101, 44, 32, 114, 101, 106, 101, 99, 116, 41, 59, 10, 32, 32, 125, 41, 59, 10, 10, 32, 32, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 32, 61, 32, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 59, 10, 32, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110, 46, 112, 111, 115, 116, 77, 101, 115, 115, 97, 103, 101, 40, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, 103, 105, 102, 121, 40, 109, 115, 103, 41, 41, 59, 10, 32, 32, 43, 43, 110, 101, 120, 116, 95, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 95, 105, 100, 59, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, 112, 114, 111, 109, 105, 115, 101, 59, 10, 125, 10, 10, 119, 105, 110, 100, 111, 119, 46, 90, 111, 110, 101, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 122, 111, 110, 101, 41, 32, 123, 10, 32, 32, 116, 104, 105, 115, 46, 118, 97, 108, 117, 101, 32, 61, 32, 122, 111, 110, 101, 32, 63, 32, 122, 111, 110, 101, 32, 58, 32, 91, 93, 59, 10, 10, 32, 32, 79, 98, 106, 101, 99, 116, 46, 100, 101, 102, 105, 110, 101, 80, 114, 111, 112, 101, 114, 116, 121, 40, 116, 104, 105, 115, 44, 32, 39, 100, 114, 105, 118, 101, 114, 39, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 123, 32, 101, 110, 117, 109, 101, 114, 97, 98, 108, 101, 58, 32, 102, 97, 108, 115, 101, 44, 32, 103, 101, 116, 58, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 110, 101, 119, 32, 90, 111, 110, 101, 40, 91, 39, 70, 114, 111, 110, 116, 39, 44, 32, 39, 76, 101, 102, 116, 39, 93, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 125, 32, 125, 41, 59, 10, 125, 59, 10, 10, 119, 105, 110, 100, 111, 119, 46, 90, 111, 110, 101, 46, 112, 114, 111, 116, 111, 116, 121, 112, 101, 46, 101, 113, 117, 97, 108, 115, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, 122, 111, 110, 101, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 105, 115, 95, 101, 113, 117, 97, 108, 32, 61, 32, 116, 114, 117, 101, 59, 10, 10, 32, 32, 102, 111, 114, 32, 40, 118, 97, 114, 32, 105, 32, 61, 32, 48, 59, 32, 105, 32, 60, 32, 122, 111, 110, 101, 46, 118, 97, 108, 117, 101, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 43, 43, 41, 32, 123, 10, 32, 32, 32, 32, 105, 115, 95, 101, 113, 117, 97, 108, 32, 38, 61, 32, 116, 104, 105, 115, 46, 118, 97, 108, 117, 101, 46, 105, 110, 100, 101, 120, 79, 102, 40, 122, 111, 110, 101, 46, 118, 97, 108, 117, 101, 91, 105, 93, 41, 32, 33, 61, 61, 32, 45, 49, 59, 10, 32, 32, 125, 10, 10, 32, 32, 102, 111, 114, 32, 40, 118, 97, 114, 32, 105, 32, 61, 32, 48, 59, 32, 105, 32, 60, 32, 116, 104, 105, 115, 46, 118, 97, 108, 117, 101, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 43, 43, 41, 32, 123, 10, 32, 32, 32, 32, 105, 115, 95, 101, 113, 117, 97, 108, 32, 38, 61, 32, 122, 111, 110, 101, 46, 118, 97, 108, 117, 101, 46, 105, 110, 100, 101, 120, 79, 102, 40, 116, 104, 105, 115, 46, 118, 97, 108, 117, 101, 91, 105, 93, 41, 32, 33, 61, 61, 32, 45, 49, 59, 10, 32, 32, 125, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, 105, 115, 95, 101, 113, 117, 97, 108, 59, 10, 125, 59, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 80, 114, 111, 112, 101, 114, 116, 121, 40, 111, 98, 106, 44, 32, 112, 114, 111, 112, 41, 32, 123, 10, 32, 32, 79, 98, 106, 101, 99, 116, 46, 100, 101, 102, 105, 110, 101, 80, 114, 111, 112, 101, 114, 116, 121, 40, 111, 98, 106, 44, 32, 112, 114, 111, 112, 44, 32, 123, 32, 101, 110, 117, 109, 101, 114, 97, 98, 108, 101, 58, 32, 116, 114, 117, 101, 44, 32, 118, 97, 108, 117, 101, 58, 32, 110, 101, 119, 32, 86, 101, 104, 105, 99, 108, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 40, 112, 114, 111, 112, 41, 32, 125, 41, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 111, 98, 106, 44, 32, 112, 114, 111, 112, 41, 32, 123, 10, 32, 32, 79, 98, 106, 101, 99, 116, 46, 100, 101, 102, 105, 110, 101, 80, 114, 111, 112, 101, 114, 116, 121, 40, 111, 98, 106, 44, 32, 112, 114, 111, 112, 44, 32, 123, 32, 101, 110, 117, 109, 101, 114, 97, 98, 108, 101, 58, 32, 116, 114, 117, 101, 44, 32, 118, 97, 108, 117, 101, 58, 32, 110, 101, 119, 32, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 73, 110, 116, 101, 114, 102, 97, 99, 101, 40, 112, 114, 111, 112, 41, 32, 125, 41, 59, 10, 125, 10, 10, 101, 120, 116, 101, 110, 115, 105, 111, 110, 46, 115, 101, 116, 77, 101, 115, 115, 97, 103, 101, 76, 105, 115, 116, 101, 110, 101, 114, 40, 102, 117, 110, 99, 116, 105, 111, 110, 40, 106, 115, 111, 110, 41, 32, 123, 10, 32, 32, 116, 114, 121, 32, 123, 10, 32, 32, 32, 32, 118, 97, 114, 32, 109, 115, 103, 32, 61, 32, 74, 83, 79, 78, 46, 112, 97, 114, 115, 101, 40, 106, 115, 111, 110, 41, 59, 10, 10, 32, 32, 32, 32, 115, 119, 105, 116, 99, 104, 32, 40, 109, 115, 103, 46, 109, 101, 116, 104, 111, 100, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 103, 101, 116, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 97, 110, 100, 108, 101, 80, 114, 111, 109, 105, 115, 101, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 122, 111, 110, 101, 115, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 97, 110, 100, 108, 101, 90, 111, 110, 101, 115, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 115, 117, 98, 115, 99, 114, 105, 98, 101, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 97, 110, 100, 108, 101, 83, 117, 98, 115, 99, 114, 105, 98, 101, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 115, 101, 116, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 97, 110, 100, 108, 101, 80, 114, 111, 109, 105, 115, 101, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 100, 101, 102, 97, 117, 108, 116, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 125, 32, 99, 97, 116, 99, 104, 32, 40, 101, 114, 114, 111, 114, 41, 32, 123, 10, 32, 32, 32, 32, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 40, 39, 69, 114, 114, 111, 114, 32, 105, 110, 32, 109, 101, 115, 115, 97, 103, 101, 32, 108, 105, 115, 116, 101, 110, 101, 114, 58, 32, 39, 32, 43, 32, 101, 114, 114, 111, 114, 41, 59, 10, 32, 32, 125, 10, 125, 41, 59, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 104, 97, 110, 100, 108, 101, 80, 114, 111, 109, 105, 115, 101, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 99, 98, 111, 98, 106, 32, 61, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 93, 59, 10, 10, 32, 32, 105, 102, 32, 40, 109, 115, 103, 46, 101, 114, 114, 111, 114, 41, 32, 123, 10, 32, 32, 32, 32, 118, 97, 114, 32, 101, 114, 114, 111, 114, 32, 61, 32, 123, 125, 59, 10, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 101, 114, 114, 111, 114, 32, 61, 32, 109, 115, 103, 46, 118, 97, 108, 117, 101, 59, 10, 32, 32, 32, 32, 115, 119, 105, 116, 99, 104, 32, 40, 109, 115, 103, 46, 118, 97, 108, 117, 101, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 95, 100, 101, 110, 105, 101, 100, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 32, 100, 101, 110, 105, 101, 100, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 105, 110, 118, 97, 108, 105, 100, 95, 111, 112, 101, 114, 97, 116, 105, 111, 110, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 73, 110, 118, 97, 108, 105, 100, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 116, 105, 109, 101, 111, 117, 116, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 79, 112, 101, 114, 97, 116, 105, 111, 110, 32, 116, 105, 109, 101, 100, 32, 111, 117, 116, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 105, 110, 118, 97, 108, 105, 100, 95, 122, 111, 110, 101, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 90, 111, 110, 101, 32, 105, 110, 118, 97, 108, 105, 100, 32, 111, 114, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 99, 97, 115, 101, 32, 39, 117, 110, 107, 110, 111, 119, 110, 39, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 65, 110, 32, 117, 110, 107, 110, 111, 119, 110, 32, 101, 114, 114, 111, 114, 32, 111, 99, 99, 117, 114, 101, 100, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 32, 32, 100, 101, 102, 97, 117, 108, 116, 58, 10, 32, 32, 32, 32, 32, 32, 32, 32, 101, 114, 114, 111, 114, 46, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 39, 85, 110, 107, 110, 111, 119, 110, 39, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 114, 101, 97, 107, 59, 10, 32, 32, 32, 32, 125, 10, 10, 32, 32, 32, 32, 99, 98, 111, 98, 106, 46, 114, 101, 106, 101, 99, 116, 40, 101, 114, 114, 111, 114, 41, 59, 10, 32, 32, 125, 32, 101, 108, 115, 101, 32, 123, 10, 32, 32, 32, 32, 99, 98, 111, 98, 106, 46, 114, 101, 115, 111, 108, 118, 101, 40, 109, 115, 103, 46, 118, 97, 108, 117, 101, 41, 59, 10, 32, 32, 125, 10, 10, 32, 32, 100, 101, 108, 101, 116, 101, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 93, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 104, 97, 110, 100, 108, 101, 90, 111, 110, 101, 115, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 32, 123, 10, 32, 32, 118, 97, 114, 32, 99, 98, 111, 98, 106, 32, 61, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 93, 59, 10, 10, 32, 32, 105, 102, 32, 40, 99, 98, 111, 98, 106, 41, 10, 32, 32, 32, 32, 99, 98, 111, 98, 106, 46, 114, 101, 115, 111, 108, 118, 101, 40, 110, 101, 119, 32, 90, 111, 110, 101, 40, 109, 115, 103, 46, 118, 97, 108, 117, 101, 41, 41, 59, 10, 125, 10, 10, 102, 117, 110, 99, 116, 105, 111, 110, 32, 104, 97, 110, 100, 108, 101, 83, 117, 98, 115, 99, 114, 105, 98, 101, 82, 101, 112, 108, 121, 40, 109, 115, 103, 41, 32, 123, 10, 32, 32, 100, 101, 108, 101, 116, 101, 32, 97, 115, 121, 110, 99, 95, 99, 97, 108, 108, 115, 91, 109, 115, 103, 46, 97, 115, 121, 110, 99, 67, 97, 108, 108, 73, 100, 93, 59, 10, 32, 32, 118, 97, 114, 32, 118, 97, 108, 117, 101, 32, 61, 32, 109, 115, 103, 46, 118, 97, 108, 117, 101, 59, 10, 32, 32, 118, 97, 108, 117, 101, 46, 122, 111, 110, 101, 32, 61, 32, 110, 101, 119, 32, 90, 111, 110, 101, 40, 118, 97, 108, 117, 101, 46, 122, 111, 110, 101, 41, 59, 10, 10, 32, 32, 102, 111, 114, 32, 40, 118, 97, 114, 32, 105, 32, 61, 32, 48, 59, 32, 105, 32, 60, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 43, 43, 41, 32, 123, 10, 32, 32, 32, 32, 118, 97, 114, 32, 105, 116, 114, 32, 61, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 91, 105, 93, 59, 10, 32, 32, 32, 32, 118, 97, 114, 32, 105, 102, 97, 99, 101, 73, 115, 32, 61, 32, 40, 118, 97, 108, 117, 101, 46, 105, 110, 116, 101, 114, 102, 97, 99, 101, 78, 97, 109, 101, 46, 116, 111, 76, 111, 119, 101, 114, 67, 97, 115, 101, 40, 41, 32, 61, 61, 61, 32, 105, 116, 114, 46, 110, 97, 109, 101, 46, 116, 111, 76, 111, 119, 101, 114, 67, 97, 115, 101, 40, 41, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 105, 102, 97, 99, 101, 73, 115, 32, 61, 61, 61, 32, 116, 114, 117, 101, 32, 38, 38, 32, 118, 97, 108, 117, 101, 46, 122, 111, 110, 101, 46, 101, 113, 117, 97, 108, 115, 40, 105, 116, 114, 46, 122, 111, 110, 101, 41, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 105, 116, 114, 46, 99, 97, 108, 108, 98, 97, 99, 107, 40, 118, 97, 108, 117, 101, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 125, 10, 125, 10, 47, 47, 47, 32, 82, 117, 110, 110, 105, 110, 103, 115, 116, 97, 116, 117, 115, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 58, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 118, 101, 104, 105, 99, 108, 101, 83, 112, 101, 101, 100, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 101, 110, 103, 105, 110, 101, 83, 112, 101, 101, 100, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 112, 111, 119, 101, 114, 116, 114, 97, 105, 110, 84, 111, 114, 113, 117, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 97, 99, 99, 101, 108, 101, 114, 97, 116, 111, 114, 80, 101, 100, 97, 108, 80, 111, 115, 105, 116, 105, 111, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 104, 114, 111, 116, 116, 108, 101, 80, 111, 115, 105, 116, 105, 111, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 114, 97, 110, 115, 109, 105, 115, 115, 105, 111, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 99, 114, 117, 105, 115, 101, 67, 111, 110, 116, 114, 111, 108, 83, 116, 97, 116, 117, 115, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 108, 105, 103, 104, 116, 83, 116, 97, 116, 117, 115, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 104, 111, 114, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 99, 104, 105, 109, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 102, 117, 101, 108, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 101, 110, 103, 105, 110, 101, 79, 105, 108, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 97, 99, 99, 101, 108, 101, 114, 97, 116, 105, 111, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 101, 110, 103, 105, 110, 101, 67, 111, 111, 108, 97, 110, 116, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 115, 116, 101, 101, 114, 105, 110, 103, 87, 104, 101, 101, 108, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 119, 104, 101, 101, 108, 84, 105, 99, 107, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 105, 103, 110, 105, 116, 105, 111, 110, 84, 105, 109, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 121, 97, 119, 82, 97, 116, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 98, 114, 97, 107, 101, 79, 112, 101, 114, 97, 116, 105, 111, 110, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 98, 117, 116, 116, 111, 110, 69, 118, 101, 110, 116, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 110, 105, 103, 104, 116, 77, 111, 100, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 100, 114, 105, 118, 105, 110, 103, 77, 111, 100, 101, 39, 41, 59, 10, 10, 47, 47, 47, 32, 77, 97, 105, 110, 116, 101, 110, 97, 110, 99, 101, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 58, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 111, 100, 111, 109, 101, 116, 101, 114, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 114, 97, 110, 115, 109, 105, 115, 115, 105, 111, 110, 79, 105, 108, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 114, 97, 110, 115, 109, 105, 115, 115, 105, 111, 110, 67, 108, 117, 116, 99, 104, 39, 41, 59, 10, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 98, 97, 116, 116, 101, 114, 121, 83, 116, 97, 116, 117, 115, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 105, 114, 101, 39, 41, 59, 10, 10, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 100, 111, 111, 114, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 116, 101, 109, 112, 101, 114, 97, 116, 117, 114, 101, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 99, 108, 105, 109, 97, 116, 101, 67, 111, 110, 116, 114, 111, 108, 39, 41, 59, 10, 95, 100, 101, 102, 105, 110, 101, 86, 101, 104, 105, 99, 108, 101, 83, 105, 103, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121, 40, 101, 120, 112, 111, 114, 116, 115, 44, 32, 39, 100, 101, 102, 114, 111, 115, 116, 39, 41, 59, 10, 10, 0 }; diff --git a/xwalk/vehicle_api.js b/xwalk/vehicle_api.js index c84eb02b..ae1dbefe 100644 --- a/xwalk/vehicle_api.js +++ b/xwalk/vehicle_api.js @@ -7,6 +7,14 @@ var async_calls = {}; var subscriptions = []; +function makeCall(call, msg) { + async_calls[next_async_call_id] = call; + msg.asyncCallId = next_async_call_id; + ++next_async_call_id; + + extension.postMessage(JSON.stringify(msg)); +} + function vehicleInterfaceCommonContructor(obj, attname) { obj.attributeName = attname; @@ -15,18 +23,26 @@ function vehicleInterfaceCommonContructor(obj, attname) { msg['name'] = obj.attributeName; obj._zones = new Zone; + obj._supported = false; var call = new AsyncCall(function(data) { obj._zones = data; }); - async_calls[next_async_call_id] = call; - msg.asyncCallId = next_async_call_id; - ++next_async_call_id; + makeCall(call, msg); - extension.postMessage(JSON.stringify(msg)); + var supportedMessage = {}; + supportedMessage['method'] = 'supported'; + supportedMessage['name'] = obj.attributeName; + + var supportedCall = new AsyncCall(function(data) { + obj._supported = data; + }); + + makeCall(supportedCall, supportedMessage); Object.defineProperty(obj, 'zones', { get: function() { return obj._zones } }); + Object.defineProperty(obj, 'supported', { get: function() { return obj._supported; } }); } function VehicleInterface(attname) { @@ -42,6 +58,24 @@ VehicleInterface.prototype.get = function(zone) { return createPromise(msg); }; +VehicleInterface.prototype.availableForRetrieval = function(attName) { + return isAvailable(this, attName); +} + +VehicleInterface.prototype.availabilityChangedListener = function(callback) { + if(this.changedListenerCount) { + this.changedListenerCount++; + } + else { + this.changedListenerCount = 0; + } + return this.changedListenerCount; +} + +VehicleInterface.prototype.removeAvailabilityChangedListener = function(handle) { + +} + function VehicleSignalInterface(attname) { vehicleInterfaceCommonContructor(this, attname); } @@ -100,6 +134,32 @@ VehicleSignalInterface.prototype.set = function (value, zone) { return createPromise(msg); } +VehicleSignalInterface.prototype.availableForSubscription = function(attName) { + return isAvailable(this, attName); +} + +VehicleSignalInterface.prototype.availableForSetting = function(attName) { + return isAvailable(this, attName); +} + +function isAvailable(obj, attName) +{ + var msg = {}; + msg["method"] = 'availableForRetrieval'; + msg["name"] = obj.attributeName; + msg["attName"] = attName; + + var reply = extension.internal.sendSyncMessage(JSON.stringify(msg)); + + + + if (reply === "true") { + return "available"; + } else { + return "not_supported"; + } +} + function AsyncCall(resolve, reject) { this.resolve = resolve; this.reject = reject; @@ -164,11 +224,15 @@ extension.setMessageListener(function(json) { case 'set': handlePromiseReply(msg); break; + case 'supported': + handleSupportedReply(msg) + break; default: break; } } catch (error) { console.log('Error in message listener: ' + error); + console.log("msg: " + JSON.stringify(msg)) } }); @@ -201,7 +265,7 @@ function handlePromiseReply(msg) { cbobj.reject(error); } else { - if (msg.value.zone) { + if (msg.value && msg.value.zone) { msg.value.zone = new Zone(msg.value.zone); } cbobj.resolve(msg.value); @@ -217,6 +281,13 @@ function handleZonesReply(msg) { cbobj.resolve(new Zone(msg.value)); } +function handleSupportedReply(msg) { + var cbobj = async_calls[msg.asyncCallId]; + + if (cbobj) + cbobj.resolve(msg.value); +} + function handleSubscribeReply(msg) { delete async_calls[msg.asyncCallId]; var value = msg.value; @@ -258,7 +329,9 @@ _defineVehicleSignalProperty(exports, 'drivingMode'); _defineVehicleSignalProperty(exports, 'odometer'); _defineVehicleSignalProperty(exports, 'transmissionOil'); _defineVehicleSignalProperty(exports, 'transmissionClutch'); - +_defineVehicleSignalProperty(exports, 'brakeMaintenance'); +_defineVehicleSignalProperty(exports, 'washerFluid'); +_defineVehicleSignalProperty(exports, 'malfunctionIndicator'); _defineVehicleSignalProperty(exports, 'batteryStatus'); _defineVehicleSignalProperty(exports, 'tire'); diff --git a/xwalk/vehicle_instance.cc b/xwalk/vehicle_instance.cc index 9a8091d8..ab9593c6 100644 --- a/xwalk/vehicle_instance.cc +++ b/xwalk/vehicle_instance.cc @@ -85,10 +85,44 @@ void VehicleInstance::HandleMessage(const char* message) { picojson::object value = v.get("value").get<picojson::object>(); vehicle_->Set(attribute, value, amb_zone, callback_id); + } else if (method == "supported") { + std::string attribute = v.get("name").to_str(); + int callback_id = v.get("asyncCallId").get<double>(); + Zone::Type amb_zone = 0; + + std::transform(attribute.begin(), attribute.begin() + 1, attribute.begin(), + ::toupper); + vehicle_->Supported(attribute, callback_id); } } void VehicleInstance::HandleSyncMessage(const char* message) { + DebugOut() << "VehicleInstance Sync message received " << message << endl; + picojson::value v; + + std::string err; + picojson::parse(v, message, message + strlen(message), &err); + if (!err.empty()) { + return; + } + + std::string method = v.get("method").to_str(); + std::string objectName = v.get("name").to_str(); + std::string attName = v.get("attName").to_str(); + + std::transform(objectName.begin(), objectName.begin() + 1, objectName.begin(), + ::toupper); + + std::transform(attName.begin(), attName.begin() + 1, attName.begin(), + ::toupper); + + if(method == "availableForRetrieval") + { + std::string reply = vehicle_->AvailableForRetrieval(objectName, attName) ? "true" : "false"; + DebugOut() << "VehicleInstance reply: " << reply << endl; + SendSyncReply(reply.c_str()); + } + } int VehicleInstance::ZoneToAMBZone(picojson::array zones) { |