[cangen] - use picojson. incomplete. will not compile at this time
authorKevron Rees <kevron.m.rees@intel.com>
Wed, 21 Jan 2015 19:57:06 +0000 (11:57 -0800)
committerKevron Rees <kevron.m.rees@intel.com>
Wed, 21 Jan 2015 19:57:06 +0000 (11:57 -0800)
packaging.in/automotive-message-broker.spec.in
plugins/cangenplugin/CMakeLists.txt
plugins/cangenplugin/cangenplugin.cpp
plugins/cangenplugin/cangenplugin.h
plugins/opencvlux/CMakeLists.txt
plugins/opencvlux/opencvlux.in.json [new file with mode: 0644]

index f0023a3..7d5e94b 100644 (file)
@@ -202,7 +202,16 @@ Requires:  %{name} = %{version}-%{release}
 Requires: qt5-plugin-sqldriver-sqlite
 
 %description -n bluemonkey-modules-db
-Engine for creating scriptable plugins for AMB
+Engine for creating scriptable plugins for AMB - db module
+
+%package -n bluemonkey-modules-dbus
+Summary:   javascript plugin engine dbus module
+Group:     Automotive/Libraries
+Requires:  %{name} = %{version}-%{release}
+Requires:  qt5-qtdbus
+
+%description -n bluemonkey-modules-dbus
+Engine for creating scriptable plugins for AMB - dbus module
 
 %endif
 
@@ -305,6 +314,7 @@ cp packaging/config.tizen %{buildroot}%{_sysconfdir}/ambd/
 %manifest packaging.in/amb.manifest.plugins
 %{_libdir}/%{name}/bluetoothplugin.so
 %config %{_sysconfdir}/dbus-1/system.d/ambbt.conf
+%{_bindir}/testAmbBt
 %endif
 
 %files plugins
@@ -380,6 +390,10 @@ cp packaging/config.tizen %{buildroot}%{_sysconfdir}/ambd/
 %manifest packaging.in/amb.manifest.plugins
 %{_libdir}/%{name}/bluemonkeyDbModule.so
 
+%files -n bluemonkey-modules-dbus
+%manifest packaging.in/amb.manifest.plugins
+%{_libdir}/%{name}/bluemonkeyDBusModule.so
+
 %endif
 
 %files xwalk-vehicle-extension
index 87056a5..cb50538 100644 (file)
@@ -3,7 +3,7 @@ if(cangen_plugin)
 
 pkg_check_modules(websockets REQUIRED libwebsockets)
 
-include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS})
+include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common ${Boost_INCLUDE_DIRS} )
 
 set(cangenplugin_headers cangenplugin.h websockets.h)
 set(cangenplugin_sources cangenplugin.cpp websockets.cpp)
index 73d3253..11d1987 100644 (file)
@@ -99,8 +99,11 @@ void CANGenPlugin::parseMappingTable(const std::string& table)
 
        std::string json(table);
        std::replace(json.begin(), json.end(), '\'', '"');// replace all ' to "
-       std::unique_ptr<json_object, decltype(&json_object_put)> rootobject(json_tokener_parse(json.c_str()), &json_object_put);
-       if(!rootobject)
+       picojson::value rootobject;
+
+       picojson::parse(rootobject, json);
+
+       if(!rootobject.is<picojson::object>())
        {
                LOG_ERROR("Failed to parse json: " << json);
                return;
@@ -108,31 +111,18 @@ void CANGenPlugin::parseMappingTable(const std::string& table)
 
        // Success, use json_obj here.
        mappingTable.clear();
-       json_object *sources = json_object_object_get(rootobject.get(),"sources");
-       if(!sources)
-               return;
-       array_list* arraySources = json_object_get_array(sources);
-       if(!arraySources)
+       picojson::array sources = rootobject.get("sources").get<picojson::array>();
+       if(!sources.size())
                return;
-       for(int i=0; i < array_list_length(arraySources); ++i)
+       for(auto rootsource : sources)
        {
-               json_object *rootsource = static_cast<json_object*>(array_list_get_idx(arraySources,i));
-               if(!rootsource)
+               picojson::value source = rootsource.get("source");
+               const std::string guidstr = source.get("guid").to_str();
+               picojson::array signals = rootsource.get("signals").get<picojson::array>();
+               if(!signals.size())
                        continue;
-               json_object* source = json_object_object_get(rootsource, "source");
-               if(!source)
-                       continue;
-               json_object* guid = json_object_object_get(source, "guid");
-               const std::string guidstr(guid ? json_object_get_string(guid) : "");
-               json_object* signals = json_object_object_get(rootsource, "signals");
-               if(!signals)
-                       continue;
-               array_list* arraySignals = json_object_get_array(signals);
-               for(int j = 0; j < array_list_length(arraySignals); ++j)
+               for(auto signal : signals)
                {
-                       json_object *signal = static_cast<json_object*>(array_list_get_idx(arraySignals,j));
-                       if(!signal)
-                               continue;
                        mappingTable.addProperty(guidstr, signal);
                }// signals array loop
        }// sources array loop
@@ -290,66 +280,36 @@ void CANGenPlugin::dataReceived(libwebsocket* socket, const char* data, size_t l
        if(!data || len == 0)
                return;
 
-       //TODO: refactor ? copied from websocketsink
-       std::unique_ptr<json_object, decltype(&json_object_put)> rootobject(nullptr, &json_object_put);
-       std::unique_ptr<json_tokener, decltype(&json_tokener_free)> tokener(json_tokener_new(), &json_tokener_free);
-       enum json_tokener_error err;
-       do
-       {   std::unique_ptr<json_object, decltype(&json_object_put)> tmpobject(json_tokener_parse_ex(tokener.get(), data, len), &json_object_put);
-               rootobject.swap(tmpobject);
-       } while ((err = json_tokener_get_error(tokener.get())) == json_tokener_continue);
-       if (err != json_tokener_success)
-       {
-               LOG_ERROR("Error: " << json_tokener_error_desc(err) << std::endl);
-               return;
-       }
-       if(!rootobject)
+       picojson::value rootobject;
+
+       picojson::parse(rootobject, data);
+
+       if(!rootobject.is<picojson::object>())
        {
                LOG_ERROR("Failed to parse json: " << data << std::endl);
                return;
        }
 
-       if (tokener->char_offset < len) // XXX shouldn't access internal fields
-       {
-               // Handle extra characters after parsed object as desired.
-               // e.g. issue an error, parse another object from that point, etc...
-       }
-       // Success, use jobj here.
-       json_object *typeobject = json_object_object_get(rootobject.get(),"type");
-       json_object *nameobject = json_object_object_get(rootobject.get(),"name");
-       json_object *transidobject = json_object_object_get(rootobject.get(),"transactionid");
+       std::string type = rootobject.get("type").to_str();
+       std::string name = rootobject.get("name").to_str();
+       std::string id = rootobject.get("transactionid").to_str();
 
-       if(!typeobject || !nameobject || !transidobject)
+       if(typeobject.empty() || nameobject.empty() || transidobject.empty())
        {
                DebugOut(DebugOut::Warning)<<"Malformed json. aborting"<<endl;
                return;
        }
 
-       string type = string(json_object_get_string(typeobject));
-       string name = string(json_object_get_string(nameobject));
-       string id;
-       if (json_object_get_type(transidobject) == json_type_string)
-       {
-               id = string(json_object_get_string(transidobject));
-       }
-       else
-       {
-               stringstream strstr;
-               strstr << json_object_get_int(transidobject);
-               id = strstr.str();
-       }
        if (type == "method") {
 
                vector<string> propertyNames;
                list< std::tuple<string, string, string, Zone::Type, string> > propertyData;
 
-               json_object *dataobject = json_object_object_get(rootobject.get(),"data");
-               if (json_object_get_type(dataobject) == json_type_array)
+               picojson::value dataobject = rootobject.get("data");
+               if(dataobject.is<picojson::array)
                {
-                       array_list *arraylist = json_object_get_array(dataobject);
-                       for (int i=0;i<array_list_length(arraylist);i++)
+                       for (auto arrayobject : dataobject)
                        {
-                               json_object *arrayobject = (json_object*)array_list_get_idx(arraylist,i);
                                if (json_object_get_type(arrayobject) == json_type_object)
                                {
                                        json_object *interfaceobject = json_object_object_get(arrayobject,"interface");
@@ -375,92 +335,85 @@ void CANGenPlugin::dataReceived(libwebsocket* socket, const char* data, size_t l
                                        propertyNames.push_back(propertyName);
                                }
                        }
-                       //array_list_free(arraylist);
                }
                else
                {
-                       string path = json_object_get_string(dataobject);
-                       if (path != "")
+                       propertyNames.push_back();
+               }
+
+               if (name == "get")
+               {
+                       if (!propertyNames.empty())
                        {
-                               propertyNames.push_back(path);
+                               //GetProperty is going to be a singleshot sink.
+                               getValue(socket,propertyNames.front(), Zone::None,id);
+                       }
+                       else if (!propertyData.empty())
+                       {
+                               //GetProperty is going to be a singleshot sink.
+                               auto prop = propertyData.front();
+                               getValue(socket,std::get<1>(prop),std::get<3>(prop),id);
+                       }
+                       else
+                       {
+                               LOG_WARNING(" \"get\" method called with no data! Transaction ID:" << id);
                        }
                }
-               if (type == "method")
+               else if (name == "set")
                {
-                       if (name == "get")
+                       LOG_MESSAGE("set called");
+                       if (!propertyNames.empty())
                        {
-                               if (!propertyNames.empty())
-                               {
-                                       //GetProperty is going to be a singleshot sink.
-                                       getValue(socket,propertyNames.front(),Zone::None,id);
-                               }
-                               else if (!propertyData.empty())
-                               {
-                                       //GetProperty is going to be a singleshot sink.
-                                       auto prop = propertyData.front();
-                                       getValue(socket,std::get<1>(prop),std::get<3>(prop),id);
-                               }
-                               else
-                               {
-                                       LOG_WARNING(" \"get\" method called with no data! Transaction ID:" << id);
-                               }
+                               //Should not happen
                        }
-                       else if (name == "set")
+                       else if (!propertyData.empty())
                        {
-                               LOG_MESSAGE("set called");
-                               if (!propertyNames.empty())
+                               for (auto prop = propertyData.begin(); prop != propertyData.end(); ++prop)
                                {
-                                       //Should not happen
-                               }
-                               else if (!propertyData.empty())
-                               {
-                                       for (auto prop = propertyData.begin(); prop != propertyData.end(); ++prop)
-                                       {
-                                               LOG_MESSAGE("websocketsinkmanager setting " << std::get<1>(*prop) << " to " << std::get<2>(*prop) << " in zone " << std::get<3>(*prop));
-                                               setValue(socket,std::get<1>(*prop),std::get<2>(*prop),std::get<3>(*prop),std::get<0>(*prop), id);
-                                       }
+                                       LOG_MESSAGE("websocketsinkmanager setting " << std::get<1>(*prop) << " to " << std::get<2>(*prop) << " in zone " << std::get<3>(*prop));
+                                       setValue(socket,std::get<1>(*prop),std::get<2>(*prop),std::get<3>(*prop),std::get<0>(*prop), id);
                                }
                        }
-                       else if (name == "getSupportedEventTypes")
+               }
+               else if (name == "getSupportedEventTypes")
+               {
+                       //If data.front() dosen't contain a property name, return a list of properties supported.
+                       //if it does, then return the event types that particular property supports.
+                       string typessupported = "";
+                       if (propertyNames.empty())
                        {
-                               //If data.front() dosen't contain a property name, return a list of properties supported.
-                               //if it does, then return the event types that particular property supports.
-                               string typessupported = "";
-                               if (propertyNames.empty())
-                               {
-                                       //Send what properties we support
-                                       PropertyList foo(routingEngine->supported());
-                                       PropertyList::const_iterator i=foo.cbegin();
-                                       while (i != foo.cend())
-                                       {
-                                               if(i==foo.cbegin())
-                                                       typessupported.append("\"").append((*i)).append("\"");
-                                               else
-                                                       typessupported.append(",\"").append((*i)).append("\"");
-                                               ++i;
-                                       }
-                               }
-                               else
+                               //Send what properties we support
+                               PropertyList foo(routingEngine->supported());
+                               PropertyList::const_iterator i=foo.cbegin();
+                               while (i != foo.cend())
                                {
-                                       //Send what events a particular property supports
-                                       PropertyList foo(routingEngine->supported());
-                                       if (contains(foo,propertyNames.front()))
-                                       {
-                                               //sinkManager->addSingleShotSink(wsi,data.front(),id);
-                                               typessupported = "\"get\",\"getSupportedEventTypes\"";
-                                       }
+                                       if(i==foo.cbegin())
+                                               typessupported.append("\"").append((*i)).append("\"");
+                                       else
+                                               typessupported.append(",\"").append((*i)).append("\"");
+                                       ++i;
                                }
-                               stringstream s;
-                               string s2;
-                               s << "{\"type\":\"methodReply\",\"name\":\"getSupportedEventTypes\",\"data\":[" << typessupported << "],\"transactionid\":\"" << id << "\"}";
-                               string replystr = s.str();
-                               LOG_INFO(" JSON Reply: " << replystr);
-                               WebSockets::Write(socket, replystr);
                        }
                        else
                        {
-                               DebugOut(0)<<"Unknown method called."<<endl;
+                               //Send what events a particular property supports
+                               PropertyList foo(routingEngine->supported());
+                               if (contains(foo,propertyNames.front()))
+                               {
+                                       //sinkManager->addSingleShotSink(wsi,data.front(),id);
+                                       typessupported = "\"get\",\"getSupportedEventTypes\"";
+                               }
                        }
+                       stringstream s;
+                       string s2;
+                       s << "{\"type\":\"methodReply\",\"name\":\"getSupportedEventTypes\",\"data\":[" << typessupported << "],\"transactionid\":\"" << id << "\"}";
+                       string replystr = s.str();
+                       LOG_INFO(" JSON Reply: " << replystr);
+                       WebSockets::Write(socket, replystr);
+               }
+               else
+               {
+                       DebugOut(0)<<"Unknown method called."<<endl;
                }
        }
 }
index ccf0e98..ac13687 100644 (file)
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #include <canobserver.h>
 
 #include <ambpluginimpl.h>
+#include <picojson.h>
 #include "websockets.h"
 
 /*!
@@ -78,227 +79,230 @@ class CANGenPlugin: public AmbPluginImpl, public CANObserver, public WebSocketsO
 
 public:
 
-    /*!
-     * \param re AbstractRoutingEngine
-     * \param config Map of the configuration string values loaded on startup from AMB configuration file
-     * \param parent AmbPlugin instance
-     */
+       /*!
+        * \param re AbstractRoutingEngine
+        * \param config Map of the configuration string values loaded on startup from AMB configuration file
+        * \param parent AmbPlugin instance
+        */
        CANGenPlugin(AbstractRoutingEngine* re, const std::map<std::string, std::string>& config, AbstractSource &parent);
-    virtual ~CANGenPlugin(); // has to be virtual because of unit tests
+       virtual ~CANGenPlugin(); // has to be virtual because of unit tests
 
-    // from AbstractSink
+       // from AbstractSink
 public:
 
-    /*! uuid() is a unique identifier of the plugin
-     * @return a guid-style unique identifier
-     */
-    const std::string uuid() const { return "becbbef9-6cc8-4b9e-8cd7-2fbe37b9b52a"; }
+       /*! uuid() is a unique identifier of the plugin
+        * @return a guid-style unique identifier
+        */
+       const std::string uuid() const { return "becbbef9-6cc8-4b9e-8cd7-2fbe37b9b52a"; }
 
-    /*! propertyChanged is called when a subscribed to property changes.
-      * @see AbstractRoutingEngine::subscribeToPropertyChanges()
-      * \param value value of the property that changed. this is a temporary pointer that will be destroyed.
-      * Do not destroy it.  If you need to store the value use value.anyValue(), value.value<T>() or
-      * value->copy() to copy.
-      */
-    void propertyChanged(AbstractPropertyType* value);
+       /*! propertyChanged is called when a subscribed to property changes.
+         * @see AbstractRoutingEngine::subscribeToPropertyChanges()
+         * \param value value of the property that changed. this is a temporary pointer that will be destroyed.
+         * Do not destroy it.  If you need to store the value use value.anyValue(), value.value<T>() or
+         * value->copy() to copy.
+         */
+       void propertyChanged(AbstractPropertyType* value);
 
        AsyncPropertyReply* setProperty(const AsyncSetPropertyRequest &request);
 
-    // from CANObserver
+       // from CANObserver
 public:
-    /*!
-     * Called when error occurred on the bus.
-     * \fn errorOccured
-     * \param error \link CANObserver#CANError Bus error code \endlink
-     */
-    virtual void errorOccured(CANObserver::CANError error);/* socket error */
-    /*!
-     * Called when standard frame was is received from the bus.
-     * \fn standardFrameReceived
-     * \param frame Received frame
-     */
-    virtual void standardFrameReceived(const can_frame& frame);/* SFF was present */
-    /*!
-     * Called when extended frame was is received from the bus.
-     * \fn extendedFrameReceived
-     * \param frame Received frame
-     */
-    virtual void extendedFrameReceived(const can_frame& frame);/* EFF was present */
-    /*!
-     * Called when error frame was received from the bus.
-     * \fn errorFrameReceived
-     * \param frame Error frame
-     */
-    virtual void errorFrameReceived(const can_frame& frame);/* error frame */
-    /*!
-     * Called when remote transmission frame was received from the bus.
-     * \fn remoteTransmissionRequest
-     * \param frame RTR frame
-     */
-    virtual void remoteTransmissionRequest(const can_frame& frame);/* remote transmission request (SFF/EFF is still present)*/
-
-    /*!
-     * Second phase of the plugin initialization.
-     * \fn init
-     */
-    virtual void init();
-
-    // from WebSocketsObserver
-
-    /*!
-     * Called when data received from libwebsockets
-     * \fn dataReceived
-     * \param socket libwebsocket* to be used to send any reply.
-     * \param data Received data pointer.
-     * \param len Length of the data.
-     * \return None
-     */
-    void dataReceived(libwebsocket* socket, const char* data, size_t len);
+       /*!
+        * Called when error occurred on the bus.
+        * \fn errorOccured
+        * \param error \link CANObserver#CANError Bus error code \endlink
+        */
+       virtual void errorOccured(CANObserver::CANError error);/* socket error */
+       /*!
+        * Called when standard frame was is received from the bus.
+        * \fn standardFrameReceived
+        * \param frame Received frame
+        */
+       virtual void standardFrameReceived(const can_frame& frame);/* SFF was present */
+       /*!
+        * Called when extended frame was is received from the bus.
+        * \fn extendedFrameReceived
+        * \param frame Received frame
+        */
+       virtual void extendedFrameReceived(const can_frame& frame);/* EFF was present */
+       /*!
+        * Called when error frame was received from the bus.
+        * \fn errorFrameReceived
+        * \param frame Error frame
+        */
+       virtual void errorFrameReceived(const can_frame& frame);/* error frame */
+       /*!
+        * Called when remote transmission frame was received from the bus.
+        * \fn remoteTransmissionRequest
+        * \param frame RTR frame
+        */
+       virtual void remoteTransmissionRequest(const can_frame& frame);/* remote transmission request (SFF/EFF is still present)*/
+
+       /*!
+        * Second phase of the plugin initialization.
+        * \fn init
+        */
+       virtual void init();
+
+       // from WebSocketsObserver
+
+       /*!
+        * Called when data received from libwebsockets
+        * \fn dataReceived
+        * \param socket libwebsocket* to be used to send any reply.
+        * \param data Received data pointer.
+        * \param len Length of the data.
+        * \return None
+        */
+       void dataReceived(libwebsocket* socket, const char* data, size_t len);
 
 //
 // Internal methods:
 //
 private:
 
-    /*!
-     * \brief Prints received CAN frame
-     * \param frame Received CAN frame.
-     * \internal
-     * \private
-     */
-    void printFrame(const can_frame& frame) const;
-
-    /*!
-     * Parses 'MappingTable' property from CANSimPlugin.
-     * Result is stored in internal MappingTable class(AMB property and Zone to CAN Id map) which contains all properties that can be simulated.
-     * \param json Content of the 'MappingTable' property in JSON format.
-     */
-    void parseMappingTable(const std::string& json);
-
-    /*!
-     * \brief Simulator.get request handler function.
-     * Builds and sends reply with the property value, timestamp and sequence number in JSON format.
-     * \param socket libwebsocket handle to be used to send reply.
-     * \param property Name of the property.
-     * \param zone Property's zone.
-     * \param uuid Request's transaction id.
-     * \private
-     */
-    void getValue(libwebsocket* socket, const std::string& property, int zone, const std::string& uuid);
-
-    /*!
-     * \brief Simulator.set request handler function.
-     * Formats property's value as a AMB's AbstractPropertyValue and passes it to sendValue. Reply to the Simulator with reply string in JSON format.
-     * \param socket libwebsocket handle to be used to send reply.
-     * \param property Name of the property.
-     * \param value Property's new value to be simulated.
-     * \param zone Property's zone.
-     * \param interface CAN interface to be used to send CAN frame.
-     * \param transactionId Request's transaction id.
-     * \private
-     */
-    void setValue(libwebsocket* socket, const std::string& property, const std::string& value, int zone, const std::string& interface, const std::string& transactionId);
-
-    /*!
-     * \brief Build and sends CAN frame to CANSimPlugin.
-     * Finds CAN Id using mappingTable for requested property name and zone, builds CAN frame with the property's new value and tries to send it via requested CAN interface.
-     * \param interface CAN interface to be used to send CAN frame.
-     * \param value AMB's AbstractPropertyValue which encapsulates property name, zone and value.
-     * \return true if CAN frame was successfully sent, otherwise false.
-     * \private
-     */
-    bool sendValue(const std::string& interface, AbstractPropertyType* value);
-
-    /*!
-     * Internal helper class
-     * AMB property and property's zone to CAN Id map
-     * \class MappingTable
-     * \private
-     * \internal
-     *
-     */
-    class MappingTable{
-    public:
-        MappingTable()
-        {
-        }
-
-        MappingTable(const MappingTable& other) = delete;
-        MappingTable& operator=(const MappingTable& other) = delete;
-        MappingTable(MappingTable&& other) = default;
-        MappingTable& operator=(MappingTable&& other) = default;
-
-        void addProperty(const std::string& source, json_object* signal)
-        {
-            json_object* canIdObj = json_object_object_get(signal, "can_id");
-            json_object* nameObj = json_object_object_get(signal, "name");
-            if(!canIdObj || !nameObj) // mandatory
-                return;
-            Zone::Type zone(Zone::None);
-            json_object* zoneObj = json_object_object_get(signal, "zone");
-            if(zoneObj)
-                zone = json_object_get_int(zoneObj);
-
-            auto& zp = mapping[source];
-            auto& prop = zp[Zone::Type(zone)];
-            std::string name(json_object_get_string(nameObj));
-            int can_id = json_object_get_int(canIdObj);
-            prop[name] = can_id; // update an existing value
-        }
-
-        int getCanId(const std::string& source, const Zone::Type& zone, const VehicleProperty::Property& name) const
-        {
-            //return mapping[source][zone][name]; // caution! this will insert if not found. I don't want it.
-            auto sourceIt = mapping.find(source);
-            if(sourceIt == mapping.end())
-                return 0;
-            auto zoneIt = sourceIt->second.find(zone);
-            if(zoneIt == sourceIt->second.end())
-                return 0;
-            auto propIt = zoneIt->second.find(name);
-            if(propIt == zoneIt->second.end())
-                return 0;
-            else
-                return propIt->second;
-        }
-
-        void clear()
-        {
-            mapping.clear();
-        }
-
-    private:
-        typedef std::map< Zone::Type, std::map<VehicleProperty::Property, canid_t> > ZonedProperty;
-        std::map<std::string, ZonedProperty> mapping;
-    };
+       /*!
+        * \brief Prints received CAN frame
+        * \param frame Received CAN frame.
+        * \internal
+        * \private
+        */
+       void printFrame(const can_frame& frame) const;
+
+       /*!
+        * Parses 'MappingTable' property from CANSimPlugin.
+        * Result is stored in internal MappingTable class(AMB property and Zone to CAN Id map) which contains all properties that can be simulated.
+        * \param json Content of the 'MappingTable' property in JSON format.
+        */
+       void parseMappingTable(const std::string& json);
+
+       /*!
+        * \brief Simulator.get request handler function.
+        * Builds and sends reply with the property value, timestamp and sequence number in JSON format.
+        * \param socket libwebsocket handle to be used to send reply.
+        * \param property Name of the property.
+        * \param zone Property's zone.
+        * \param uuid Request's transaction id.
+        * \private
+        */
+       void getValue(libwebsocket* socket, const std::string& property, int zone, const std::string& uuid);
+
+       /*!
+        * \brief Simulator.set request handler function.
+        * Formats property's value as a AMB's AbstractPropertyValue and passes it to sendValue. Reply to the Simulator with reply string in JSON format.
+        * \param socket libwebsocket handle to be used to send reply.
+        * \param property Name of the property.
+        * \param value Property's new value to be simulated.
+        * \param zone Property's zone.
+        * \param interface CAN interface to be used to send CAN frame.
+        * \param transactionId Request's transaction id.
+        * \private
+        */
+       void setValue(libwebsocket* socket, const std::string& property, const std::string& value, int zone, const std::string& interface, const std::string& transactionId);
+
+       /*!
+        * \brief Build and sends CAN frame to CANSimPlugin.
+        * Finds CAN Id using mappingTable for requested property name and zone, builds CAN frame with the property's new value and tries to send it via requested CAN interface.
+        * \param interface CAN interface to be used to send CAN frame.
+        * \param value AMB's AbstractPropertyValue which encapsulates property name, zone and value.
+        * \return true if CAN frame was successfully sent, otherwise false.
+        * \private
+        */
+       bool sendValue(const std::string& interface, AbstractPropertyType* value);
+
+       /*!
+        * Internal helper class
+        * AMB property and property's zone to CAN Id map
+        * \class MappingTable
+        * \private
+        * \internal
+        *
+        */
+       class MappingTable{
+       public:
+               MappingTable()
+               {
+               }
+
+               MappingTable(const MappingTable& other) = delete;
+               MappingTable& operator=(const MappingTable& other) = delete;
+               MappingTable(MappingTable&& other) = default;
+               MappingTable& operator=(MappingTable&& other) = default;
+
+               void addProperty(const std::string& source, picojson::value signal)
+               {
+
+                       if(!signal.contains("can_id") || !signal.contains("name")) // mandatory
+                               return;
+                       picojson::value canIdObj = signal.get("can_id");
+                       picojson::value nameObj = signal.get("name");
+                       Zone::Type zone(Zone::None);
+
+                       if(signal.contains("zone"))
+                       {
+                               zone = signal.get("zone").get<double>();
+                       }
+
+                       auto& zp = mapping[source];
+                       auto& prop = zp[Zone::Type(zone)];
+                       std::string name(nameObj.to_str());
+                       int can_id = canIdObj.get<double>();
+                       prop[name] = can_id; // update an existing value
+               }
+
+               int getCanId(const std::string& source, const Zone::Type& zone, const VehicleProperty::Property& name) const
+               {
+                       //return mapping[source][zone][name]; // caution! this will insert if not found. I don't want it.
+                       auto sourceIt = mapping.find(source);
+                       if(sourceIt == mapping.end())
+                               return 0;
+                       auto zoneIt = sourceIt->second.find(zone);
+                       if(zoneIt == sourceIt->second.end())
+                               return 0;
+                       auto propIt = zoneIt->second.find(name);
+                       if(propIt == zoneIt->second.end())
+                               return 0;
+                       else
+                               return propIt->second;
+               }
+
+               void clear()
+               {
+                       mapping.clear();
+               }
+
+       private:
+               typedef std::map< Zone::Type, std::map<VehicleProperty::Property, canid_t> > ZonedProperty;
+               std::map<std::string, ZonedProperty> mapping;
+       };
 
 //
 // data:
 //
 
-    /*!
-     * AMB property and property's zone to CAN Id map
-     * \private
-     */
-    MappingTable mappingTable;
-
-    /*!
-     * Opened CAN interfaces used to send CAN frames
-     * \private
-     */
-    std::map<std::string, std::shared_ptr<CANBus> > interfaces;
-
-    /*!
-     * Encapsulated libwebsocket library
-     * \private
-     */
-    std::unique_ptr<WebSockets> ws;
-
-    /*!
-     * Mutex to protect mappingTable container during property 'MappingTable' parsing on change notification
-     * \private
-     */
-    interprocess_recursive_mutex mutex;
+       /*!
+        * AMB property and property's zone to CAN Id map
+        * \private
+        */
+       MappingTable mappingTable;
+
+       /*!
+        * Opened CAN interfaces used to send CAN frames
+        * \private
+        */
+       std::map<std::string, std::shared_ptr<CANBus> > interfaces;
+
+       /*!
+        * Encapsulated libwebsocket library
+        * \private
+        */
+       std::unique_ptr<WebSockets> ws;
+
+       /*!
+        * Mutex to protect mappingTable container during property 'MappingTable' parsing on change notification
+        * \private
+        */
+       interprocess_recursive_mutex mutex;
 };
 
 class SimCommand: public StringPropertyType
index 3007de0..902ad2f 100644 (file)
@@ -55,4 +55,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_BINARY_DIR}/op
 set(opencvlux_doc_files ${CMAKE_CURRENT_BINARY_DIR}/opencvlux.README.md)
 install (FILES ${opencvlux_doc_files} DESTINATION ${DOC_INSTALL_DIR}/plugins)
 
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/opencvlux.in.json ${CMAKE_CURRENT_BINARY_DIR}/opencvlux @ONLY)
+install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opencvlux DESTINATION ${PLUGIN_SEGMENT_INSTALL_PATH})
+
 endif(opencvlux_plugin)
diff --git a/plugins/opencvlux/opencvlux.in.json b/plugins/opencvlux/opencvlux.in.json
new file mode 100644 (file)
index 0000000..188b5d7
--- /dev/null
@@ -0,0 +1,17 @@
+{
+       "name" : "OpenCV LUX",
+       "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so",
+       "enabled" : false,
+       "threaded" : "true",
+       "opencl" : "true",
+       "fps" : "30",
+       "pixelLowerBound" : "18",
+       "pixelUpperBound" : "255",
+       "device" : "0",
+       "codec" : "h264",
+       "logging" : "false",
+       "logfile" : "/tmp/video.avi",
+       "ddd" : "true",
+       "faceCascade" : "/usr/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml",
+       "eyeCascade" : "/usr/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml"
+},