summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevron Rees <tripzero.kev@gmail.com>2014-12-23 23:50:50 -0800
committerKevron Rees <tripzero.kev@gmail.com>2014-12-23 23:50:50 -0800
commitc6b73df909bcf61fc6f5ae19cd9a693d55e69651 (patch)
treec8b5987c02a5f8e53bd42cc692ba2a855aef7014
parent045f1495022da6773cc4c86c1abeaba466eea8a4 (diff)
downloadautomotive-message-broker-c6b73df909bcf61fc6f5ae19cd9a693d55e69651.tar.gz
[tools] ambctl test script
-rw-r--r--RELEASE1
-rw-r--r--TODO8
-rw-r--r--lib/abstractpropertytype.h2
-rw-r--r--lib/ambpluginimpl.cpp9
-rw-r--r--lib/ambpluginimpl.h2
-rw-r--r--plugins/database/CMakeLists.txt3
-rw-r--r--plugins/database/databasesink.cpp34
-rw-r--r--plugins/dbus/abstractdbusinterface.cpp7
-rw-r--r--plugins/dbus/dbusplugin.cpp1
-rw-r--r--tests/CMakeLists.txt2
-rwxr-xr-xtests/gendb.sh15
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/ambctl.py105
13 files changed, 160 insertions, 30 deletions
diff --git a/RELEASE b/RELEASE
index 42c800e1..beec7245 100644
--- a/RELEASE
+++ b/RELEASE
@@ -6,6 +6,7 @@ New features:
- [OpenCV plugin] driver drowsiness detection test code
- [Bluemonkey plugin] support for zones in JS API.
- [Bluemonkey plugin] database module.
+- [tools] new ambctl. replaces amb-get, amb-set, etc
Changes:
- OpenCV plugin experimental options for cuda and kinect are removed
diff --git a/TODO b/TODO
index 64ebecf7..0cc42f1e 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,10 @@
- Refactor obd2 plugin with AsyncQueue. Use thread safe-update property.
-- update json protocol to support rangerequests with PropertyList instead of a signel property (Verify)
-- update database to support zone column
-- general support for source and zone filtering in database plugin
+- update json protocol to support rangerequests with PropertyList instead of a singel property (Verify)
+- source export from database plugin does not reflect the source in the database
- no reason for pluginloader to track sources. core already does it.
- create docs for all plugins (README)
- 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
- investigate and enable use of provisioning in ssl websockets
- enable ambd/plugins.d/
-- finish implementing openxc plugin (needs testing)
-- Document internal source/sink plugin API
diff --git a/lib/abstractpropertytype.h b/lib/abstractpropertytype.h
index 1d299bbc..6efbee13 100644
--- a/lib/abstractpropertytype.h
+++ b/lib/abstractpropertytype.h
@@ -87,7 +87,7 @@ public:
AbstractPropertyType(std::string property)
: name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal)
{
- void*(name);
+
}
virtual ~AbstractPropertyType()
diff --git a/lib/ambpluginimpl.cpp b/lib/ambpluginimpl.cpp
index dc646857..7bf7e712 100644
--- a/lib/ambpluginimpl.cpp
+++ b/lib/ambpluginimpl.cpp
@@ -133,8 +133,10 @@ AbstractPropertyType* AmbPluginImpl::findPropertyType(const VehicleProperty::Pro
return nullptr;
}
-std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory)
+std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory, std::string sourceUuid)
{
+ if(sourceUuid.empty())
+ sourceUuid = uuid();
std::shared_ptr<AbstractPropertyType> propertyType(typeFactory());
if(!propertyType)
return propertyType;
@@ -154,9 +156,10 @@ std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Ty
propertyType.swap(registeredPropertyType);
}
propertyType->zone = zone;
- propertyType->sourceUuid = uuid();
+ propertyType->sourceUuid = sourceUuid;
+ propertyType->timestamp = amb::currentTime();
ZonePropertyType& zonePropType = properties[name];
- zonePropType.insert( make_pair(zone, propertyType));
+ zonePropType.insert(make_pair(zone, propertyType));
return propertyType;
}
diff --git a/lib/ambpluginimpl.h b/lib/ambpluginimpl.h
index d9482f0f..96080379 100644
--- a/lib/ambpluginimpl.h
+++ b/lib/ambpluginimpl.h
@@ -145,7 +145,7 @@ protected:
* \param typeFactory Function to be used to create instance of the AbstractPropertyType for registered property
* \return AbstractPropertyType* if signal exits otherwise nullptr(in this case we do not know its datatype)
*/
- std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory);
+ std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory, std::string sourceUuid="");
template <class T>
std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone)
diff --git a/plugins/database/CMakeLists.txt b/plugins/database/CMakeLists.txt
index 2564ff2c..041fb01f 100644
--- a/plugins/database/CMakeLists.txt
+++ b/plugins/database/CMakeLists.txt
@@ -6,6 +6,9 @@ pkg_check_modules(sqlite REQUIRED sqlite3)
include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${sqlite_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common)
+set(database_table_create "CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, zone INTEGER, time REAL, sequence REAL, tripId TEXT)" CACHE INTERNAL "database plugin table create command")
+add_definitions(-Ddatabase_table_create="${database_table_create}")
+
set(databasesinkplugin_headers databasesink.h utils.h basedb.hpp baseobject.h sqlitedatabase.h sqlitequery.h)
set(databasesinkplugin_sources databasesink.cpp utils.cpp sqlitedatabase.cpp sqlitequery.cpp basedb.hpp)
add_library(databasesinkplugin MODULE ${databasesinkplugin_sources})
diff --git a/plugins/database/databasesink.cpp b/plugins/database/databasesink.cpp
index f7ed7cf7..9bfe5b25 100644
--- a/plugins/database/databasesink.cpp
+++ b/plugins/database/databasesink.cpp
@@ -140,7 +140,7 @@ DatabaseSink::DatabaseSink(AbstractRoutingEngine *engine, map<std::string, std::
:AmbPluginImpl(engine, config, parent), shared(nullptr), playback(false), playbackShared(nullptr), playbackMultiplier(1)
{
tablename = "data";
- tablecreate = "CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, zone INTEGER, time REAL, sequence REAL, tripId TEXT)";
+ tablecreate = database_table_create;
if(config.find("bufferLength") != config.end())
{
@@ -341,7 +341,7 @@ void DatabaseSink::setDatabaseFileName(string filename)
{
initDb();
- vector<vector<string> > supportedStr = shared->db->select("SELECT DISTINCT key, zone FROM " + tablename);
+ vector<vector<string> > supportedStr = shared->db->select("SELECT DISTINCT key, zone, source FROM " + tablename);
for(int i=0; i < supportedStr.size(); i++)
{
@@ -350,11 +350,13 @@ void DatabaseSink::setDatabaseFileName(string filename)
if(!contains(supported(), name))
{
std::string zoneStr = supportedStr[i][1];
+ std::string sourceStr = supportedStr[i][2];
- DebugOut() << "adding property " << name << " in zone: " << zoneStr << endl;
+ DebugOut() << "adding property " << name << " in zone: " << zoneStr << "for source: " << sourceStr << endl;
Zone::Type zone = boost::lexical_cast<Zone::Type>(zoneStr);
- addPropertySupport(zone, [name]() { return VehicleProperty::getPropertyTypeForPropertyNameValue(name); });
+ auto property = addPropertySupport(zone, [name]() { return VehicleProperty::getPropertyTypeForPropertyNameValue(name); });
+ property->sourceUuid = sourceStr;
}
}
@@ -417,17 +419,18 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply)
for(auto itr = reply->properties.begin(); itr != reply->properties.end(); itr++)
{
+ DebugOut() << "prop: " << (*itr) << endl;
if(itr != reply->properties.begin())
query<<" OR ";
query<<"key='"<<(*itr)<<"'";
}
- query<<") AND";
+ query<<")";
- if(reply->timeBegin && reply->timeEnd)
+ if(reply->timeEnd)
{
- query<<" time BETWEEN "<<reply->timeBegin<<" AND "<<reply->timeEnd;
+ query<<" AND time BETWEEN "<<reply->timeBegin<<" AND "<<reply->timeEnd;
}
if(reply->sequenceBegin >= 0 && reply->sequenceEnd >=0)
@@ -444,9 +447,19 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply)
DebugOut()<<"Dataset size "<<data.size()<<endl;
- for(auto i=0;i<data.size();i++)
+ if(!data.size())
{
- if(data[i].size() != 6)
+ reply->success = false;
+ reply->error = AsyncPropertyReply::InvalidOperation;
+ }
+ else
+ {
+ reply->success = true;
+ }
+
+ for(auto i=0; i<data.size(); i++)
+ {
+ if(data[i].size() != 7)
continue;
DBObject dbobj;
@@ -456,6 +469,7 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply)
dbobj.zone = boost::lexical_cast<double>(data[i][3]);
dbobj.time = boost::lexical_cast<double>(data[i][4]);
dbobj.sequence = boost::lexical_cast<double>(data[i][5]);
+ dbobj.tripId = data[i][6];
AbstractPropertyType* property = VehicleProperty::getPropertyTypeForPropertyNameValue(dbobj.key, dbobj.value);
if(property)
@@ -467,7 +481,7 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply)
}
}
- reply->success = true;
+
reply->completed(reply);
delete db;
diff --git a/plugins/dbus/abstractdbusinterface.cpp b/plugins/dbus/abstractdbusinterface.cpp
index dce2888b..c8dcdf17 100644
--- a/plugins/dbus/abstractdbusinterface.cpp
+++ b/plugins/dbus/abstractdbusinterface.cpp
@@ -103,7 +103,8 @@ static void handleMyMethodCall(GDBusConnection *connection,
{
AbstractProperty* prop = (*itr).second;
- propertyList.push_back(prop->ambPropertyName());
+ if(!contains(propertyList, prop->ambPropertyName()))
+ propertyList.push_back(prop->ambPropertyName());
}
std::string ifaceName = iface->interfaceName();
@@ -114,7 +115,7 @@ static void handleMyMethodCall(GDBusConnection *connection,
request.timeBegin = beginTime;
request.timeEnd = endTime;
request.zone = iface->zone();
- request.sourceUuid = iface->source();
+ //request.sourceUuid = iface->source();
request.completed = [&invocation,&ifaceName](AsyncRangePropertyReply* reply)
{
@@ -247,7 +248,7 @@ void AbstractDBusInterface::addProperty(AbstractProperty* property)
"</method>"
"<signal name='" + pn + "Changed' >"
" <arg type='v' name='" + nameToLower + "' direction='out' />"
- " <arg type='d' name='timestamp' direction='out' />"
+ " <arg type='d' name='imestamp' direction='out' />"
"</signal>"
"<property type='i' name='" + property->name() + "Sequence' access='read' />";
diff --git a/plugins/dbus/dbusplugin.cpp b/plugins/dbus/dbusplugin.cpp
index da84c5d5..ed950268 100644
--- a/plugins/dbus/dbusplugin.cpp
+++ b/plugins/dbus/dbusplugin.cpp
@@ -70,6 +70,7 @@ void DBusSink::supportedChanged(const PropertyList &supportedProperties)
routingEngine->subscribeToProperty(p, mSourceFilter, this);
addProperty(prop);
supported = true;
+ mTime = amb::currentTime();
}
}
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e54f797b..8fab3da2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -6,7 +6,7 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-get.py ${CMAKE_CURRENT_BINARY_DI
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-set.py ${CMAKE_CURRENT_BINARY_DIR}/amb-set @ONLY)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-get-history.py ${CMAKE_CURRENT_BINARY_DIR}/amb-get-history @ONLY)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-listen.py ${CMAKE_CURRENT_BINARY_DIR}/amb-listen @ONLY)
-configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gen-set.py ${CMAKE_CURRENT_BINARY_DIR}/gen-set @ONLY)
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gendb.sh ${CMAKE_CURRENT_SOURCE_DIR}/gendb @ONLY)
install (PROGRAMS ${amb_tests} DESTINATION bin)
diff --git a/tests/gendb.sh b/tests/gendb.sh
index 34a1978d..9830d82d 100755
--- a/tests/gendb.sh
+++ b/tests/gendb.sh
@@ -1,23 +1,28 @@
#!/bin/bash
-TABLE="CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, time REAL, sequence REAL);"
+TABLE="@database_table_create@;"
+
+if [ -f generated.db ];
+ then
+ rm generated.db
+fi
-rm generated.db
-rm generated.db.sql
echo $TABLE > generated.db.sql
echo "BEGIN IMMEDIATE TRANSACTION;" >> generated.db.sql
-for (( i=0; i<120; i++ ))
+for (( i=0; i<130; i++ ))
do
T=$(echo 1385571956 + $i)
for (( n=1; n<1000; n++ ))
do
MS=$(echo $n \* 0.001 | bc)
TIME=$(echo $T + $MS | bc)
- echo "insert into data values('VehicleSpeed',$(( ( RANDOM % 300 ) + 1 )),'test', $TIME, -1);" >> generated.db.sql
+ echo "insert into data values('VehicleSpeed', $(( ( RANDOM % 300 ) + 1 )),'test', 0, $TIME, -1, 'alskejroanpnfansadfasdfa');" >> generated.db.sql
done
done
echo "END TRANSACTION;" >> generated.db.sql
sqlite3 generated.db < generated.db.sql
+
+exit
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 64f35086..ddba598f 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1 +1,2 @@
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/genmapping.py ${CMAKE_CURRENT_SOURCE_DIR}/genmapping @ONLY)
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/ambctl.py ${CMAKE_CURRENT_SOURCE_DIR}/ambctl @ONLY)
diff --git a/tools/ambctl.py b/tools/ambctl.py
new file mode 100644
index 00000000..e3850645
--- /dev/null
+++ b/tools/ambctl.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python
+
+import argparse
+import dbus
+import sys
+import json
+import gobject
+from dbus.mainloop.glib import DBusGMainLoop
+
+def changed(interface, properties, invalidated):
+ print json.dumps(properties, indent=2)
+
+parser = argparse.ArgumentParser(description='Process DBus mappings.')
+parser.add_argument('command', metavar='COMMAND [help]', help='amb dbus command')
+
+parser.add_argument('commandArgs', metavar='ARG', nargs='*',
+ help='amb dbus command arguments')
+
+args = parser.parse_args()
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+bus = dbus.SystemBus()
+managerObject = bus.get_object("org.automotive.message.broker", "/");
+managerInterface = dbus.Interface(managerObject, "org.automotive.Manager")
+
+if args.command == "list" :
+ supportedList = managerInterface.List();
+ for objectName in supportedList:
+ print objectName
+ sys.exit()
+
+elif args.command == "get":
+ if args.commandArgs[0] == "help":
+ print "ObjectName [ObjectName...]"
+ sys.exit()
+
+ for objectName in args.commandArgs:
+ objects = managerInterface.FindObject(objectName);
+ print objectName
+ for o in objects:
+ propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", o),"org.freedesktop.DBus.Properties")
+ print json.dumps(propertiesInterface.GetAll("org.automotive."+objectName), indent=2)
+ sys.exit()
+
+elif args.command == "listen":
+ if args.commandArgs[0] == "help":
+ print "ObjectName [ObjectName...]"
+ sys.exit()
+ for objectName in args.commandArgs:
+ objects = managerInterface.FindObject(objectName);
+ for o in objects:
+ bus.add_signal_receiver(changed,
+ dbus_interface="org.freedesktop.DBus.Properties",
+ signal_name="PropertiesChanged", path=o)
+elif args.command == "set":
+ if args.commandArgs[0] == "help":
+ print "ObjectName PropertyName VALUE [ZONE]"
+ sys.exit()
+ if len(args.commandArgs) < 3:
+ print "set requires more arguments (see set help)"
+ sys.exit()
+ objectName = args.commandArgs[0]
+ propertyName = args.commandArgs[1]
+ value = args.commandArgs[2]
+ zone = 0
+ if len(args.commandArgs) == 4:
+ zone = int(args.commandArgs[3])
+ object = managerInterface.FindObjectForZone(objectName, zone)
+ propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.freedesktop.DBus.Properties")
+ property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
+ realValue = property.__class__(value)
+ propertiesInterface.Set("org.automotive."+objectName, propertyName, realValue)
+ property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
+ if property == realValue:
+ print propertyName + " = ", property
+ else:
+ print "Error setting property"
+ sys.exit()
+elif args.command == "getHistory":
+ if args.commandArgs[0] == "help":
+ print "ObjectName [STARTTIME] [ENDTIME] [ZONE]"
+ sys.exit()
+ if len(args.commandArgs) < 1:
+ print "getHistory requires more arguments (see getHistory help)"
+ sys.exit()
+ objectName = args.commandArgs[0]
+ start = 1
+ if len(args.commandArgs) >= 2:
+ start = float(args.commandArgs[1])
+ end = 9999999999
+ if len(args.commandArgs) >= 3:
+ end = float(args.commandArgs[2])
+ zone = 0
+ if len(args.commandArgs) == 4:
+ zone = int(args.commandArgs[3])
+
+ object = managerInterface.FindObjectForZone(objectName, zone);
+ propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.automotive."+objectName)
+ print json.dumps(propertiesInterface.GetHistory(start, end), indent=2)
+ sys.exit()
+else:
+ print "unknown command"
+ sys.exit()
+loop = gobject.MainLoop()
+loop.run()