fixed obd2 bluetooth for bluez5
authorKevron Rees <kevron.m.rees@intel.com>
Thu, 18 Sep 2014 17:45:30 +0000 (10:45 -0700)
committerKevron Rees <kevron.m.rees@intel.com>
Thu, 18 Sep 2014 17:45:30 +0000 (10:45 -0700)
lib/abstractroutingengine.cpp
lib/abstractroutingengine.h
plugins/common/bluetooth5.cpp
plugins/common/bluetooth5.h
plugins/obd2plugin/CMakeLists.txt
plugins/obd2plugin/obd2source.cpp
plugins/obd2plugin/obd2source.h

index bf9e6e7..5012272 100644 (file)
@@ -1,19 +1,19 @@
 /*
-    Copyright (C) 2012  Intel Corporation
+  Copyright (C) 2012  Intel Corporation
 
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
 
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 
@@ -26,25 +26,34 @@ AbstractRoutingEngine::~AbstractRoutingEngine()
 }
 
 AsyncPropertyReply::AsyncPropertyReply()
-       :AsyncPropertyRequest(), value(nullptr), success(false), timeoutSource(nullptr)
+       :AsyncPropertyRequest(), value(nullptr), success(false), timeoutSource(nullptr), timedout(nullptr)
 {
        setTimeout();
 }
 
 AsyncPropertyReply::AsyncPropertyReply(const AsyncPropertyRequest &request)
-       :AsyncPropertyRequest(request), value(NULL), success(false), timeoutSource(nullptr)
+       :AsyncPropertyRequest(request), value(NULL), success(false), timeoutSource(nullptr), timedout(nullptr)
 {
        setTimeout();
 }
 
 AsyncPropertyReply::AsyncPropertyReply(const AsyncSetPropertyRequest &request)
-       :AsyncPropertyRequest(request), value(request.value), success(false), timeoutSource(nullptr)
+       :AsyncPropertyRequest(request), value(request.value), success(false), timeoutSource(nullptr), timedout(nullptr)
 {
        setTimeout();
        if(value)
                value->zone = request.zoneFilter;
 }
 
+AsyncPropertyReply::~AsyncPropertyReply()
+{
+       if(timeoutSource)
+       {
+               g_source_destroy(timeoutSource);
+               g_source_unref(timeoutSource);
+       }
+}
+
 void AsyncPropertyReply::setTimeout()
 {
        auto timeoutfunc = [](gpointer userData) {
@@ -52,6 +61,8 @@ void AsyncPropertyReply::setTimeout()
                if(thisReply->success == false)
                {
                        thisReply->error = Timeout;
+                       if(thisReply->timedout)
+                               thisReply->timedout(thisReply);
                        thisReply->completed(thisReply);
                }
                return 0;
index ccc717f..5605ef4 100644 (file)
@@ -40,6 +40,7 @@ class AsyncSetPropertyRequest;
 
 typedef std::function<void (AsyncPropertyReply*)> GetPropertyCompletedSignal;
 typedef std::function<void (AsyncRangePropertyReply*)> GetRangedPropertyCompletedSignal;
+typedef std::function<void (AsyncPropertyReply*)> TimedOutCallback;
 
 /*!
  * \brief The AsyncPropertyRequest class is used by sinks to request property values.
@@ -128,14 +129,7 @@ public:
 
        AsyncPropertyReply(const AsyncSetPropertyRequest &request);
 
-       virtual ~AsyncPropertyReply()
-       {
-               if(timeoutSource)
-               {
-                       g_source_destroy(timeoutSource);
-                       g_source_unref(timeoutSource);
-               }
-       }
+       virtual ~AsyncPropertyReply();
 
        /*!
         * \brief The Error enum
@@ -160,6 +154,12 @@ public:
        bool success;
 
        /*!
+        * \brief timed out callback is called when the reply times out.  This is so sources can avoid using this reply which
+        * may become invalid after it times out.
+        */
+       TimedOutCallback timedout;
+
+       /*!
         * \brief error contains the error if the request was not successful.\
         * \see Error
         */
index cd346c8..474955b 100644 (file)
@@ -82,7 +82,7 @@ static void handleMethodCall(GDBusConnection       *connection,
                        DebugOut() << "key " << keyPtr.get() << "value signature: " << g_variant_get_type_string(valuePtr.get()) << endl;
                }
 
-               manager->connected(fd);
+               manager->connected_(fd);
        }
        else if(method == "RequestDisconnection")
        {
@@ -278,7 +278,7 @@ void Bluetooth5::getDeviceForAddress(std::string address, ConnectedCallback conn
        connect(connectedCallback);
 }
 
-void Bluetooth5::connected(int fd)
+void Bluetooth5::connected_(int fd)
 {
        try
        {
index 0b479c3..d540e1d 100644 (file)
@@ -14,9 +14,9 @@ public:
        bool setDevice(std::string address);
        void getDeviceForAddress(std::string address,  ConnectedCallback onnectedCallback);
 
-       void connected(int fd);
+       void connected_(int fd);
 
-       void connect( ConnectedCallback onconnectedCallback);
+       void connect(ConnectedCallback onconnectedCallback);
        void disconnect();
 
 
index 63d8902..9f3a5c5 100644 (file)
@@ -7,8 +7,8 @@ pkg_check_modules(gio-unix REQUIRED gio-unix-2.0)
 
 include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common)
 
-set(obd2sourceplugin_headers obd2source.h obdlib.h obdpid.h asyncqueuewatcher.h)
-set(obd2sourceplugin_sources obd2source.cpp obdlib.cpp obdpid.cpp asyncqueuewatcher.cpp)
+set(obd2sourceplugin_headers obd2source.h obdlib.h obdpid.h)
+set(obd2sourceplugin_sources obd2source.cpp obdlib.cpp obdpid.cpp)
 add_library(obd2sourceplugin MODULE ${obd2sourceplugin_sources})
 set_target_properties(obd2sourceplugin PROPERTIES PREFIX "")
 target_link_libraries(obd2sourceplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES} )
index aa585b5..1032ab3 100644 (file)
@@ -1,19 +1,19 @@
 /*
-       Copyright (C) 2012  Intel Corporation
+  Copyright (C) 2012  Intel Corporation
 
-       This library is free software; you can redistribute it and/or
-       modify it under the terms of the GNU Lesser General Public
-       License as published by the Free Software Foundation; either
-       version 2.1 of the License, or (at your option) any later version.
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
 
-       This library is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-       Lesser General Public License for more details.
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
 
-       You should have received a copy of the GNU Lesser General Public
-       License along with this library; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 
@@ -191,9 +191,9 @@ void threadLoop(gpointer data)
                                        if (source->m_isBluetooth)
                                        {
 #ifdef USE_BLUEZ5
-                                               bt.getDeviceForAddress(source->m_btDeviceAddress, [&obd, baud, &privStatusQueue](int fd)
+                                               bt.getDeviceForAddress(source->m_btDeviceAddress, [&obd, baud, &privStatusQueue, &connected](int fd)
                                                {
-                                                       bool connected = connect(obd, "", baud, fd);
+                                                       connected = connect(obd, "", baud, fd);
 
                                                        if(connected)
                                                        {
@@ -305,11 +305,11 @@ void threadLoop(gpointer data)
                if (reqList.size() > 0 && !connected)
                {
                        /*CommandRequest *req = new CommandRequest();
-                       req->req = "connect";
-                       req->arglist.push_back(port);
-                       req->arglist.push_back(baud);
-                       g_async_queue_push(privCommandQueue,req);
-                       continue;*/
+         req->req = "connect";
+         req->arglist.push_back(port);
+         req->arglist.push_back(baud);
+         g_async_queue_push(privCommandQueue,req);
+         continue;*/
                }
                else if (reqList.size() == 0 && connected)
                {
@@ -430,10 +430,10 @@ void threadLoop(gpointer data)
                                std::string repstr;
                                for (int i=0;i<replyVector.size();i++)
                                {
-                                 if (replyVector[i] != 13)
-                                 {
-                                 repstr += (char)replyVector[i];
-                                 }
+                                       if (replyVector[i] != 13)
+                                       {
+                                               repstr += (char)replyVector[i];
+                                       }
                                        //DebugOut(11) << replyVector[i];
                                }
                                DebugOut(11) << "Reply:" << repstr << endl;
@@ -474,13 +474,24 @@ static int updateProperties( gpointer data)
                }
                else if (reply->statusStr == "error:nodata" || reply->statusStr == "error:timeout")
                {
-                       if (src->propertyReplyMap.find(reply->property) != src->propertyReplyMap.end())
+                       AsyncPropertyReply* srcReply = nullptr;
+
+                       for(auto i : src->propertyReplyList)
+                       {
+                               if(i->property == reply->property)
+                               {
+                                       srcReply = i;
+                                       break;
+                               }
+                       }
+
+                       if (srcReply)
                        {
                                DebugOut(5) << __SMALLFILE__ <<":"<< __LINE__ << reply->statusStr << " on property:" << reply->property << endl;
-                               src->propertyReplyMap[reply->property]->success = false;
-                               src->propertyReplyMap[reply->property]->error = AsyncPropertyReply::InvalidOperation;
-                               src->propertyReplyMap[reply->property]->completed(src->propertyReplyMap[reply->property]);
-                               src->propertyReplyMap.erase(reply->property);
+                               srcReply->success = false;
+                               srcReply->error = AsyncPropertyReply::InvalidOperation;
+                               srcReply->completed(srcReply);
+                               removeOne(&src->propertyReplyList, srcReply);
 
                                /// Remove support for this pid:
                                PropertyList list = src->supported();
@@ -512,18 +523,30 @@ void OBD2Source::updateProperty(AbstractPropertyType* value)
        if(property == Obd2Connected)
                obd2Connected.setValue(value->anyValue());
 
-       if (propertyReplyMap.find(property) != propertyReplyMap.end())
+       AsyncPropertyReply* reply = nullptr;
+
+       for(auto i : propertyReplyList)
+       {
+               if(i->property == property)
+               {
+                       reply = i;
+                       break;
+               }
+       }
+
+       if (reply)
        {
-               propertyReplyMap[property]->value = value;
-               propertyReplyMap[property]->success = true;
+
+               reply->value = value;
+               reply->success = true;
                try {
-                       propertyReplyMap[property]->completed(propertyReplyMap[property]);
+                       reply->completed(reply);
                }catch(...)
                {
                        DebugOut(DebugOut::Error)<<"failed to call reply completed callback"<<endl;
                }
 
-               propertyReplyMap.erase(property);
+               removeOne(&propertyReplyList, reply);
        }
        else
        {
@@ -541,7 +564,7 @@ void OBD2Source::updateProperty(AbstractPropertyType* value)
 
                oldValueMap[property] = value->copy();
 
-               m_re->updateProperty(value,uuid());
+               m_re->updateProperty(value, uuid());
        }
 }
 
@@ -558,7 +581,7 @@ void OBD2Source::checkProperty()
 }*/
 void OBD2Source::setConfiguration(map<string, string> config)
 {
-//     //Config has been passed, let's start stuff up.
+       //      //Config has been passed, let's start stuff up.
        configuration = config;
 
        //Default values
@@ -596,20 +619,20 @@ void OBD2Source::setConfiguration(map<string, string> config)
                m_isBluetooth = true;
                ///TODO: bluetooth!!
                /*DebugOut()<<"bluetooth device?"<<endl;
-               BluetoothDevice bt;
+       BluetoothDevice bt;
 
-               std::string tempPort = bt.getDeviceForAddress(port, btadapter);
-               if(tempPort != "")
-               {
-                       DebugOut(3)<<"Using bluetooth device \""<<port<<"\" bound to: "<<tempPort<<endl;
-                       port = tempPort;
-               }
-               else
-               {
-                       DebugOut(0)<<"Device Error"<<endl;
-                       ///Don't throw here.
-                       //throw std::runtime_error("Device Error");
-               }*/
+       std::string tempPort = bt.getDeviceForAddress(port, btadapter);
+       if(tempPort != "")
+       {
+         DebugOut(3)<<"Using bluetooth device \""<<port<<"\" bound to: "<<tempPort<<endl;
+         port = tempPort;
+       }
+       else
+       {
+         DebugOut(0)<<"Device Error"<<endl;
+         ///Don't throw here.
+         //throw std::runtime_error("Device Error");
+       }*/
        }
 
        //connect(obd, port, baud);
@@ -764,7 +787,12 @@ void OBD2Source::getPropertyAsync(AsyncPropertyReply *reply)
                return;
        }
 
-       propertyReplyMap[reply->property] = reply;
+       propertyReplyList.push_back(reply);
+       reply->timedout = [this](AsyncPropertyReply* reply)
+       {
+               DebugOut() << "removing "<< reply->property << " from propertyReplyList" << endl;
+               removeOne(&propertyReplyList, reply);
+       };
 
        ObdPid* requ = obd2AmbInstance->createPidforProperty(property);
        g_async_queue_push(singleShotQueue,requ);
@@ -777,11 +805,9 @@ AsyncPropertyReply *OBD2Source::setProperty(AsyncSetPropertyRequest request )
 {
        AsyncPropertyReply* reply = new AsyncPropertyReply (request);
 
-
-
        if(request.property == Obd2Connected)
        {
-               propertyReplyMap[reply->property] = reply;
+               propertyReplyList.push_back(reply);
                reply->success = true;
 
                if(request.value->value<bool>() == true)
@@ -798,7 +824,6 @@ AsyncPropertyReply *OBD2Source::setProperty(AsyncSetPropertyRequest request )
                }
 
        }
-
        else
        {
                reply->success = false;
index d93f1b4..3977480 100644 (file)
@@ -180,7 +180,7 @@ public:
        bool m_isBluetooth;
        std::string m_btDeviceAddress;
        std::string m_btAdapterAddress;
-       map<VehicleProperty::Property,AsyncPropertyReply*> propertyReplyMap;
+       std::vector<AsyncPropertyReply*> propertyReplyList;
        void updateProperty(AbstractPropertyType *value);
        obdLib * obd;
        bool m_threadLive;