summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevron Rees <tripzero.kev@gmail.com>2014-11-24 10:19:47 -0800
committerKevron Rees <tripzero.kev@gmail.com>2014-11-24 10:19:47 -0800
commitdbe6e9c6b8bcda40d10523cc907abad46612516e (patch)
tree2d74fe14ac63ca6b2be25a066e3b0f9c3bf7aeda
parent1194d19d1544cc26f4ecceee2beac84e0d7e0fbb (diff)
parentf98edbfc335669b611499dad233fba0f3f63a2de (diff)
downloadautomotive-message-broker-dbe6e9c6b8bcda40d10523cc907abad46612516e.tar.gz
Merge pull request #32 from tripzero/master0.12.803
Availability API support.
-rw-r--r--CMakeLists.txt2
-rw-r--r--RELEASE26
-rw-r--r--TODO2
-rw-r--r--docs/amb.idl68
-rw-r--r--examples/opencvdbusconfig.in9
-rw-r--r--lib/vehicleproperty.cpp8
-rw-r--r--lib/vehicleproperty.h25
-rw-r--r--plugins/bluemonkey/CMakeLists.txt10
-rw-r--r--plugins/bluemonkey/bluemonkey.cpp6
-rw-r--r--plugins/bluemonkey/bluemonkey.h4
-rw-r--r--plugins/bluemonkey/config.js26
-rw-r--r--plugins/bluemonkey/db.cpp90
-rw-r--r--plugins/bluemonkey/db.h69
-rw-r--r--plugins/dbus/abstractdbusinterface.h35
-rw-r--r--plugins/dbus/automotivemanager.cpp43
-rw-r--r--plugins/dbus/dbusinterfacemanager.cpp4
-rw-r--r--plugins/dbus/dbusplugin.h7
-rw-r--r--plugins/dbus/maintenance.h36
-rw-r--r--plugins/gpsnmea/gpsnmea.cpp137
-rw-r--r--plugins/opencvlux/README15
-rw-r--r--plugins/opencvlux/opencvluxplugin.cpp266
-rw-r--r--plugins/opencvlux/opencvluxplugin.h11
-rw-r--r--xwalk/CMakeLists.txt13
-rw-r--r--xwalk/vehicle.cc70
-rw-r--r--xwalk/vehicle.h2
-rw-r--r--xwalk/vehicle.html4
-rw-r--r--xwalk/vehicle_api.cc2
-rw-r--r--xwalk/vehicle_api.js85
-rw-r--r--xwalk/vehicle_instance.cc34
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")
diff --git a/RELEASE b/RELEASE
index 35689225..83e6e029 100644
--- a/RELEASE
+++ b/RELEASE
@@ -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
diff --git a/TODO b/TODO
index 35687bc6..3a0f68c3 100644
--- a/TODO
+++ b/TODO
@@ -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) {