Handle cancel active diag requet when there are no more subscribers
authorRomain Forlot <romain.forlot@iot.bzh>
Thu, 30 Mar 2017 15:19:59 +0000 (17:19 +0200)
committerRomain Forlot <romain.forlot@iot.bzh>
Tue, 11 Apr 2017 10:41:42 +0000 (12:41 +0200)
When push events if there is no more subscribers to that event then call
a function that will cleanup that request from diagnostic manager queue.

Change-Id: I8153701074453444a5bba6f1374401bdf230f7e6
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
src/can/can-bus.cpp
src/configuration.cpp
src/configuration.hpp
src/low-can-binding.cpp
src/low-can-binding.hpp

index ee70744..33f58fd 100644 (file)
@@ -185,7 +185,8 @@ void can_bus_t::can_event_push()
                                {
                                        jo = json_object_new_object();
                                        jsonify_simple(s_message, jo);
-                                       afb_event_push(s[std::string(s_message.name)], jo);
+                                       if(afb_event_push(s[std::string(s_message.name)], jo) == 0)
+                                               on_no_clients(std::string(s_message.name));
                                }
                        }
                }
index 184d468..32cb00c 100644 (file)
@@ -18,6 +18,7 @@
 #include "configuration.hpp"
 
 #include "utils/signals.hpp"
+#include "utils/openxc-utils.hpp"
 
 /// @brief Return singleton instance of configuration object.
 configuration_t& configuration_t::instance()
@@ -109,6 +110,23 @@ void configuration_t::find_diagnostic_messages(const openxc_DynamicField &key, s
        DEBUG(binder_interface, "find_diagnostic_messages: Found %d signal(s)", (int)found_signals.size());
 }
 
+diagnostic_message_t* configuration_t::get_diagnostic_message(std::string message_name) const
+{
+       std::vector<diagnostic_message_t*> found;
+       configuration_t::instance().find_diagnostic_messages(build_DynamicField(message_name), found);
+       return found.front();
+}
+
+DiagnosticRequest* configuration_t::get_request_from_diagnostic_message(diagnostic_message_t* diag_msg) const
+{
+       return new DiagnosticRequest(diag_msg->build_diagnostic_request());
+}
+
+DiagnosticRequest* configuration_t::get_request_from_diagnostic_message(std::string message_name) const
+{
+       return new DiagnosticRequest(get_diagnostic_message(message_name)->build_diagnostic_request());
+}
+
 /// @brief return signals name found searching through CAN signals list.
 ///
 /// @param[in] key - can contain numeric or string value in order to search against
index 57eeef3..017b148 100644 (file)
@@ -88,6 +88,9 @@ class configuration_t
                void set_active_message_set(uint8_t id);
 
                void find_diagnostic_messages(const openxc_DynamicField &key, std::vector<diagnostic_message_t*>& found_signals);
+               diagnostic_message_t* get_diagnostic_message(std::string message_name) const;
+               DiagnosticRequest* get_request_from_diagnostic_message(diagnostic_message_t* diag_msg) const;
+               DiagnosticRequest* get_request_from_diagnostic_message(std::string message_name) const;
 
                void find_can_signals(const openxc_DynamicField &key, std::vector<can_signal_t*>& found_signals);
 
index cee88a8..8fc143c 100644 (file)
@@ -45,6 +45,13 @@ extern "C"
 // Interface between the daemon and the binding
 const struct afb_binding_interface *binder_interface;
 
+void on_no_clients(std::string message)
+{
+       DiagnosticRequest* diag_req = configuration_t::instance().get_request_from_diagnostic_message(message);
+       active_diagnostic_request_t* adr = configuration_t::instance().get_diagnostic_manager().find_recurring_request(diag_req);
+       configuration_t::instance().get_diagnostic_manager().cleanup_request(adr, true);
+}
+
 ///******************************************************************************
 ///
 ///            Subscription and unsubscription
@@ -60,7 +67,6 @@ static int make_subscription_unsubscription(struct afb_req request, const std::s
                return 0;
        }
        return 1;
-
 }
 
 static int create_event_handle(const std::string& sig_name, std::map<std::string, struct afb_event>& s)
@@ -129,29 +135,21 @@ static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe,
        for(const std::string& sig : signals)
        {
                int ret;
+               bool to_subscribe = false;
                if (active_diagnostic_request_t::is_diagnostic_signal(sig))
                {
-                       std::vector<diagnostic_message_t*> found;
-                       configuration_t::instance().find_diagnostic_messages(build_DynamicField(sig), found);
-                       DiagnosticRequest* diag_req = new DiagnosticRequest(found.front()->build_diagnostic_request());
+                       diagnostic_message_t* diag_msg = configuration_t::instance().get_diagnostic_message(sig);
+                       DiagnosticRequest* diag_req = configuration_t::instance().get_request_from_diagnostic_message(diag_msg);
 
                        // If the requested diagnostic message isn't supported by the car then unssubcribe.
                        // no matter what we want, worse case will be a fail unsubscription but at least we don't
                        // poll a PID for nothing.
-                       if(found.front()->get_supported())
+                       if(diag_msg->get_supported() && subscribe)
                        {
-                               if(subscribe)
-                               {
-                                       float frequency = found.front()->get_frequency();
-                                       configuration_t::instance().get_diagnostic_manager().add_recurring_request(
-                                               diag_req, sig.c_str(), false, found.front()->get_decoder(), found.front()->get_callback(), (float)frequency);
+                                       float frequency = diag_msg->get_frequency();
+                                       to_subscribe = configuration_t::instance().get_diagnostic_manager().add_recurring_request(
+                                               diag_req, sig.c_str(), false, diag_msg->get_decoder(), diag_msg->get_callback(), (float)frequency);
                                                //TODO: Adding callback requesting ignition status:     diag_req, sig.c_str(), false, diagnostic_message_t::decode_obd2_response, diagnostic_message_t::check_ignition_status, frequency);
-                               }
-                               else
-                               {
-                                       active_diagnostic_request_t* adr = configuration_t::instance().get_diagnostic_manager().find_recurring_request(diag_req);
-                                       configuration_t::instance().get_diagnostic_manager().cleanup_request(adr, true);
-                               }
                        }
                        else
                        {
@@ -162,11 +160,13 @@ static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe,
                        }
                }
 
-               ret = subscribe_unsubscribe_signal(request, subscribe, sig);
-               if(ret <= 0)
-                       return ret;
-
-               rets++;
+               if(to_subscribe)
+               {
+                       ret = subscribe_unsubscribe_signal(request, subscribe, sig);
+                       if(ret <= 0)
+                               return ret;
+                       rets++;
+               }
                DEBUG(binder_interface, "Signal: %s subscribed", sig.c_str());
        }
        return rets;
index 04c7eac..ed5741d 100644 (file)
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <cstddef>
+#include <string>
 
 extern "C"
 {
@@ -27,4 +28,6 @@ extern "C"
 
 extern "C" struct afb_binding_interface;
 
-extern const struct afb_binding_interface *binder_interface;
\ No newline at end of file
+extern const struct afb_binding_interface *binder_interface;
+
+void on_no_clients(std::string message);
\ No newline at end of file