X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=low-can-binding%2Fbinding%2Flow-can-hat.cpp;h=7258074424135eb7a5f56b0b79a600fbe9dbee0f;hb=HEAD;hp=7113b69a5681defe25e4f2d293e1c5786d4df2bf;hpb=32e25cbca210a359b09768537b6f443fe90a3070;p=apps%2Fagl-service-can-low-level.git diff --git a/low-can-binding/binding/low-can-hat.cpp b/low-can-binding/binding/low-can-hat.cpp index 7113b69a..72580744 100644 --- a/low-can-binding/binding/low-can-hat.cpp +++ b/low-can-binding/binding/low-can-hat.cpp @@ -1,73 +1,94 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" - * Author "Loic Collignon" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "low-can-hat.hpp" -#include "low-can-subscription.hpp" - -#include -#include #include -#include -#include +#include #include "application.hpp" +#include "../utils/signals.hpp" +#include "low-can-hat.hpp" +#include "../can/message/message.hpp" #include "../can/can-bus.hpp" -extern "C" -{ - static int initv2(); - static const struct afb_verb_v2 verbs[]= + +///****************************************************************************** +/// +/// SystemD event loop Callbacks +/// +///*******************************************************************************/ + +static void push_n_notify(std::shared_ptr m) +{ + can_bus_t& cbm = application_t::instance().get_can_bus_manager(); { - { .verb= "subscribe", .callback= subscribe, .auth= NULL, .session= AFB_SESSION_NONE}, - { .verb= "unsubscribe", .callback= unsubscribe, .auth= NULL, .session= AFB_SESSION_NONE}, - { .verb= NULL, .callback= NULL, .auth= NULL, .session= 0} - }; - - const struct afb_binding_v2 afbBindingV2 { - .api = "low-can", - .specification = NULL, - .verbs = verbs, - .preinit = NULL, - .init = initv2, - .onevent = NULL, - .noconcurrency = 0 - }; - - /// @brief Initialize the binding. - /// - /// @param[in] service Structure which represent the Application Framework Binder. - /// - /// @return Exit code, zero if success. - static int initv2() + std::lock_guard can_message_lock(cbm.get_can_message_mutex()); + cbm.push_new_can_message(m); + } + cbm.get_new_can_message_cv().notify_one(); +} + +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) { - can_bus_t& can_bus_manager = application_t::instance().get_can_bus_manager(); + 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) + { + is_permanent_recurring_request = adr->get_permanent(); + + if(! is_permanent_recurring_request) + application_t::instance().get_diagnostic_manager().cleanup_request(adr, true); + } + } + + if(! is_permanent_recurring_request) + on_no_clients(can_subscription, s); +} + + +void on_no_clients(std::shared_ptr can_subscription, std::map >& s) +{ + auto it = s.find(can_subscription->get_index()); + s.erase(it); +} + +int read_message(sd_event_source *event_source, int fd, uint32_t revents, void *userdata) +{ - can_bus_manager.set_can_devices(); - can_bus_manager.start_threads(); + low_can_subscription_t* can_subscription = (low_can_subscription_t*)userdata; - /// Initialize Diagnostic manager that will handle obd2 requests. - /// 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; - ERROR("There was something wrong with CAN device Initialization."); - return 1; + if ((revents & EPOLLIN) != 0) + { + utils::signals_manager_t& sm = utils::signals_manager_t::instance(); + std::lock_guard subscribed_signals_lock(sm.get_subscribed_signals_mutex()); + if(can_subscription->get_index() != -1) + { + std::shared_ptr s = can_subscription->get_socket(); + if(s->socket() > 0) + { + std::shared_ptr message = s->read_message(); + + // Sure we got a valid CAN message ? + if (message->get_id() && + message->get_length() && + ! (message->get_flags() & INVALID_FLAG) ) + { + if(can_subscription->get_signal() != nullptr && can_subscription->get_signal()->get_message()->get_flags() & BYTE_FRAME_IS_BIG_ENDIAN) + message->frame_swap(); + push_n_notify(message); + } + } + } + } + + // check if error or hangup + if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0) + { + sd_event_source_unref(event_source); + can_subscription->get_socket()->close(); } -}; + + return 0; +}