X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=low-can-binding%2Fbinding%2Flow-can-cb.cpp;h=0f97404ceadfa6455b0e1bf0aeaa40db3489775c;hb=ac574c3b5a6f208dfb7ea1606ef084e6db9397c2;hp=3145065a82a7b3134e4a61a2fadda7ab3f70724a;hpb=91a8304cf1c9d7139840f95c1ad971c9603ed5bf;p=apps%2Fagl-service-can-low-level.git diff --git a/low-can-binding/binding/low-can-cb.cpp b/low-can-binding/binding/low-can-cb.cpp index 3145065a..0f97404c 100644 --- a/low-can-binding/binding/low-can-cb.cpp +++ b/low-can-binding/binding/low-can-cb.cpp @@ -45,15 +45,23 @@ void on_no_clients(std::shared_ptr can_subscription, uint32_t pid, std::map >& s) { + bool is_permanent_recurring_request = false; + if( ! can_subscription->get_diagnostic_message().empty() && can_subscription->get_diagnostic_message(pid) != nullptr) { DiagnosticRequest diag_req = can_subscription->get_diagnostic_message(pid)->build_diagnostic_request(); active_diagnostic_request_t* adr = application_t::instance().get_diagnostic_manager().find_recurring_request(diag_req); if( adr != nullptr) - application_t::instance().get_diagnostic_manager().cleanup_request(adr, true); + { + is_permanent_recurring_request = adr->get_permanent(); + + if(! is_permanent_recurring_request) + application_t::instance().get_diagnostic_manager().cleanup_request(adr, true); + } } - on_no_clients(can_subscription, s); + if(! is_permanent_recurring_request) + on_no_clients(can_subscription, s); } void on_no_clients(std::shared_ptr can_subscription, std::map >& s) @@ -106,8 +114,9 @@ static int make_subscription_unsubscription(struct afb_req request, std::map >& s, bool subscribe) { - /* Make the subscription or unsubscription to the event */ - if (((subscribe ? afb_req_subscribe : afb_req_unsubscribe)(request, s[can_subscription->get_index()]->get_event())) < 0) + /* Make the subscription or unsubscription to the event (if request contents are not null) */ + if(request.itf && request.closure && + ((subscribe ? afb_req_subscribe : afb_req_unsubscribe)(request, s[can_subscription->get_index()]->get_event())) < 0) { AFB_ERROR("Operation goes wrong for signal: %s", can_subscription->get_name().c_str()); return -1; @@ -129,8 +138,8 @@ static int create_event_handle(std::shared_ptr& can_subs return 0; } -/// @brief Will determine if it is needed or not to create the event handle and checks it to be sure that -/// we got a valid afb_event to get subscribe or unsubscribe. Then launch the subscription or unsubscription +/// @brief This will determine if an event handle needs to be created and checks if +/// we got a valid afb_event to get subscribe or unsubscribe. After that launch the subscription or unsubscription /// against the application framework using that event handle. static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, @@ -157,8 +166,8 @@ static int subscribe_unsubscribe_signal(struct afb_req request, ret = create_event_handle(can_subscription, s); } - // Check whether or not the event handler has been correctly created and - // make the subscription/unsubscription operation is so. + // Checks if the event handler is correctly created, if it is, it + // performs the subscription or unsubscription operations. if (ret < 0) return ret; return make_subscription_unsubscription(request, can_subscription, s, subscribe); @@ -179,7 +188,8 @@ static int subscribe_unsubscribe_diagnostic_messages(struct afb_req request, bool subscribe, std::vector > diagnostic_messages, struct event_filter_t& event_filter, - std::map >& s) + std::map >& s, + bool perm_rec_diag_req) { int rets = 0; application_t& app = application_t::instance(); @@ -188,20 +198,22 @@ static int subscribe_unsubscribe_diagnostic_messages(struct afb_req request, for(const auto& sig : diagnostic_messages) { DiagnosticRequest* diag_req = new DiagnosticRequest(sig->build_diagnostic_request()); - event_filter.frequency = std::isnan(event_filter.frequency) ? sig->get_frequency() : event_filter.frequency; + event_filter.frequency = event_filter.frequency == 0 ? sig->get_frequency() : event_filter.frequency; std::shared_ptr can_subscription; auto it = std::find_if(s.begin(), s.end(), [&sig](std::pair > sub){ return (! sub.second->get_diagnostic_message().empty());}); can_subscription = it != s.end() ? it->second : std::make_shared(low_can_subscription_t(event_filter)); - // If the requested diagnostic message isn't supported by the car then unsubcribe it - // no matter what we want, worse case will be a fail unsubscription but at least we don't + // If the requested diagnostic message is not supported by the car then unsubcribe it + // no matter what we want, worst case will be a failed unsubscription but at least we won't // poll a PID for nothing. - //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); if(sig->get_supported() && subscribe) { - diag_m.add_recurring_request(diag_req, sig->get_name().c_str(), false, sig->get_decoder(), sig->get_callback(), event_filter.frequency); + if (!app.isEngineOn()) + AFB_WARNING("signal: Engine is off, %s won't received responses until it's on", sig->get_name().c_str()); + + diag_m.add_recurring_request(diag_req, sig->get_name().c_str(), false, sig->get_decoder(), sig->get_callback(), event_filter.frequency, perm_rec_diag_req); if(can_subscription->create_rx_filter(sig) < 0) {return -1;} AFB_DEBUG("Signal: %s subscribed", sig->get_name().c_str()); @@ -233,7 +245,6 @@ static int subscribe_unsubscribe_diagnostic_messages(struct afb_req request, return rets; } -// TODO: Create separate subscrition object if event_filter isn't the same. static int subscribe_unsubscribe_can_signals(struct afb_req request, bool subscribe, std::vector > can_signals, @@ -243,7 +254,7 @@ static int subscribe_unsubscribe_can_signals(struct afb_req request, int rets = 0; for(const auto& sig: can_signals) { - auto it = std::find_if(s.begin(), s.end(), [&sig](std::pair > sub){ return sub.second->get_can_signal() == sig; }); + auto it = std::find_if(s.begin(), s.end(), [&sig, &event_filter](std::pair > sub){ return sub.second->is_signal_subscription_corresponding(sig, event_filter) ; }); std::shared_ptr can_subscription; if(it != s.end()) { @@ -270,8 +281,8 @@ static int subscribe_unsubscribe_can_signals(struct afb_req request, /// /// @brief subscribe to all signals in the vector signals /// -/// @param[in] afb_req request : contain original request use to subscribe or unsubscribe -/// @param[in] subscribe boolean value used to chose between a subscription operation or an unsubscription +/// @param[in] afb_req request : contains original request use to subscribe or unsubscribe +/// @param[in] subscribe boolean value, which chooses between a subscription operation or an unsubscription /// @param[in] signals - struct containing vectors with can_signal_t and diagnostic_messages to subscribe /// /// @return Number of correctly subscribed signal @@ -287,7 +298,7 @@ static int subscribe_unsubscribe_signals(struct afb_req request, std::lock_guard subscribed_signals_lock(sm.get_subscribed_signals_mutex()); std::map >& s = sm.get_subscribed_signals(); - rets += subscribe_unsubscribe_diagnostic_messages(request, subscribe, signals.diagnostic_messages, event_filter, s); + rets += subscribe_unsubscribe_diagnostic_messages(request, subscribe, signals.diagnostic_messages, event_filter, s, false); rets += subscribe_unsubscribe_can_signals(request, subscribe, signals.can_signals, event_filter, s); return rets; @@ -418,7 +429,7 @@ static int write_raw_frame(const std::string& bus_name, uint32_t can_id, uint8_t cf.can_dlc = can_dlc; struct json_object *x; - int n = json_object_array_length(can_data); + size_t n = json_object_array_length(can_data); if(n <= 8) { for (int i = 0 ; i < n ; i++) @@ -463,7 +474,10 @@ static int write_signal(const std::string& name, uint64_t value) rc = send_frame(bus_name, cf); } else - {AFB_NOTICE("%s isn't writable. Message not sent.", sig->get_name().c_str());} + { + AFB_WARNING("%s isn't writable. Message not sent.", sig->get_name().c_str()); + return -1; + } } } @@ -640,6 +654,7 @@ void list(struct afb_req request) /// @return Exit code, zero if success. int initv2() { + uint32_t ret = 1; can_bus_t& can_bus_manager = application_t::instance().get_can_bus_manager(); can_bus_manager.set_can_devices(); @@ -649,8 +664,29 @@ int initv2() /// We pass by default the first CAN bus device to its Initialization. /// TODO: be able to choose the CAN bus device that will be use as Diagnostic bus. if(application_t::instance().get_diagnostic_manager().initialize()) - return 0; + ret = 0; - AFB_ERROR("There was something wrong with CAN device Initialization."); - return 1; + // Add a recurring dignostic message request to get engine speed at all times. + openxc_DynamicField search_key = build_DynamicField("diagnostic_messages.engine.speed"); + struct utils::signals_found sf = utils::signals_manager_t::instance().find_signals(search_key); + + if(sf.can_signals.empty() && sf.diagnostic_messages.size() == 1) + { + struct afb_req request; + request.itf = nullptr; + request.closure = nullptr; + + struct event_filter_t event_filter; + event_filter.frequency = sf.diagnostic_messages.front()->get_frequency(); + + utils::signals_manager_t& sm = utils::signals_manager_t::instance(); + std::map >& s = sm.get_subscribed_signals(); + + subscribe_unsubscribe_diagnostic_messages(request, true, sf.diagnostic_messages, event_filter, s, true); + } + + if(ret) + AFB_ERROR("There was something wrong with CAN device Initialization."); + + return ret; }