From 239729c759948d4574de625a84cff6f9c1338adf Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Mon, 6 Mar 2017 16:57:14 +0100 Subject: [PATCH] Change way to find signals to make it a little bit more generic. Now we have basically 3 functions : - one for subscription which return signal name into a vector - one to find from CanSignal vector - a last to find from Obd2Pid vector Name of some function has been changed. May be reworked later. Change-Id: Ie72969fd20503fc1f9291958dc2ac5d827a6be59 Signed-off-by: Romain Forlot --- openxc_example/generate_example.cpp | 2 +- src/can-signals.cpp | 54 ++++++-------- src/can-signals.hpp | 9 ++- src/low-can-binding.cpp | 74 +++++++------------ src/obd2-signals.cpp | 142 ++++++++++++++++++++++++++++++++++++ src/{obd2.hpp => obd2-signals.hpp} | 51 ++----------- src/obd2.cpp | 68 ----------------- src/signals.cpp | 33 +++++++++ src/signals.hpp | 56 ++++++++++++++ 9 files changed, 293 insertions(+), 196 deletions(-) create mode 100644 src/obd2-signals.cpp rename src/{obd2.hpp => obd2-signals.hpp} (52%) delete mode 100644 src/obd2.cpp create mode 100644 src/signals.cpp create mode 100644 src/signals.hpp diff --git a/openxc_example/generate_example.cpp b/openxc_example/generate_example.cpp index 8127a9dd..24b01df1 100644 --- a/openxc_example/generate_example.cpp +++ b/openxc_example/generate_example.cpp @@ -167,7 +167,7 @@ int openxc::signals::getMessageCount() { return getActiveMessageSet()->messageCount; } -CanSignal* openxc::signals::getSignals() { +CanSignal* openxc::signals::get_can_signals() { return SIGNALS[getActiveMessageSet()->index]; } diff --git a/src/can-signals.cpp b/src/can-signals.cpp index c9d9fac0..bf6b4a4b 100644 --- a/src/can-signals.cpp +++ b/src/can-signals.cpp @@ -19,6 +19,8 @@ #include +#include "signals.hpp" +#include "obd2-signals.hpp" #include "can-decoder.hpp" #include "low-can-binding.hpp" @@ -35,8 +37,8 @@ std::vector> CAN_MESSAGES = { */ std::vector> SIGNALS = { { - {&(CAN_MESSAGES[MESSAGE_SET_ID][0]), "can.driver_door.open", 2, 4, 1.000000, 0.000000, 0.000000, 0.000000, {10, 0, nullptr}, false, true, nullptr, 0, false, decoder_t::booleanDecoder, nullptr, false, (float)NULL}, - {&(CAN_MESSAGES[MESSAGE_SET_ID][1]), "can.driver_door.close", 0, 4, 1.000000, 0.000000, 0.000000, 0.000000, {10, 0, nullptr}, false, true, nullptr, 0, false, decoder_t::booleanDecoder, nullptr, false, (float)NULL} + {&(CAN_MESSAGES[MESSAGE_SET_ID][0]), "can.driver_door.open", 2, 4, 1.000000, 0.000000, 0.000000, 0.000000, {10, 0, nullptr}, false, true, nullptr, 0, false, decoder_t::booleanDecoder, nullptr, false, 0.0}, + {&(CAN_MESSAGES[MESSAGE_SET_ID][1]), "can.driver_door.close", 0, 4, 1.000000, 0.000000, 0.000000, 0.000000, {10, 0, nullptr}, false, true, nullptr, 0, false, decoder_t::booleanDecoder, nullptr, false, 0.0} }, }; @@ -67,7 +69,7 @@ std::map& get_subscribed_signals() return subscribed_signals; } -const std::vector& getSignals() +std::vector& get_can_signals() { return SIGNALS[MESSAGE_SET_ID]; } @@ -77,45 +79,33 @@ size_t getSignalCount() return SIGNALS[MESSAGE_SET_ID].size(); } -std::vector find_can_signals(const openxc_DynamicField &key) +uint32_t get_signal_id(const CanSignal& sig) { - std::vector found_signals = {}; - std::vector active_signals = getSignals(); - /* STL container my love ! Welcome to the printf debugging venerable technique ! - * use those DEBUG message if you need to ! - DEBUG(binder_interface, "We get %d signal(s) to process", (int)active_signals.size()); */ + return sig.message->id; +} +/** + * @fn std::vector find_signals(const openxc_DynamicField &key) + * @brief return signals name found searching through CAN_signals and OBD2 pid + * + * @param[in] const openxc_DynamicField : can contain numeric or string value in order to search against + * can signals or obd2 signals name. + * + * @return std::vector Vector of signals name found. + */ +void find_can_signals(const openxc_DynamicField& key, std::vector& found_signals) +{ switch(key.type) { case openxc_DynamicField_Type::openxc_DynamicField_Type_STRING: - for(const CanSignal& s : active_signals) - { - //DEBUG(binder_interface, "Processing signal: %s", s.generic_name); - if(::fnmatch(key.string_value, s.generic_name, FNM_CASEFOLD) == 0) - { - //DEBUG(binder_interface, "Matched signal: %s", s.generic_name); - found_signals.push_back(s); - } - } + lookup_signals_by_name(key.string_value, get_can_signals(), found_signals); break; case openxc_DynamicField_Type::openxc_DynamicField_Type_NUM: - for(const CanSignal& s : active_signals) - { - CanMessageDefinition *msg_def = s.message; - if(msg_def->id == key.numeric_value) - found_signals.push_back(s); - } + lookup_signals_by_id(key.numeric_value, get_can_signals(), found_signals); break; default: - ERROR(binder_interface, "find_can_signals: wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only."); - return found_signals; + ERROR(binder_interface, "find_signals: wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only."); break; } DEBUG(binder_interface, "Found %d signal(s)", (int)found_signals.size()); - return found_signals; } - -inline uint32_t get_CanSignal_id(const CanSignal& sig) -{ - return sig.message->id; -} \ No newline at end of file diff --git a/src/can-signals.hpp b/src/can-signals.hpp index 2443e63d..547769f4 100644 --- a/src/can-signals.hpp +++ b/src/can-signals.hpp @@ -23,6 +23,7 @@ #include #include +#include "obd2-signals.hpp" #include "timer.hpp" #include "openxc.pb.h" #include "can-bus.hpp" @@ -134,9 +135,9 @@ typedef struct CanSignal CanSignal; /* Public: Return signals from an signals array filtered on name. */ -const std::vector& getSignals(); +std::vector& get_can_signals(); -/* Public: Return the length of the array returned by getSignals(). */ +/* Public: Return the length of the array returned by get_can_signals(). */ size_t getSignalCount(); /** @@ -148,7 +149,7 @@ size_t getSignalCount(); * * @return std::vector return found CanSignal generic name vector. */ -std::vector find_can_signals(const openxc_DynamicField &key); +void find_can_signals(const openxc_DynamicField &key, std::vector& found_signals); /** * @brief Retrieve can arbitration id of a given CanSignal @@ -157,4 +158,4 @@ std::vector find_can_signals(const openxc_DynamicField &key); * * @return uint32_t - unsigned integer representing the arbitration id. */ -inline uint32_t get_CanSignal_id(const CanSignal& sig); \ No newline at end of file +uint32_t get_signal_id(const CanSignal& sig); \ No newline at end of file diff --git a/src/low-can-binding.cpp b/src/low-can-binding.cpp index 11a310b2..b9fb27df 100644 --- a/src/low-can-binding.cpp +++ b/src/low-can-binding.cpp @@ -28,8 +28,9 @@ #include #include "timer.hpp" -#include "openxc.pb.h" +#include "signals.hpp" #include "can-bus.hpp" +#include "openxc.pb.h" #include "can-signals.hpp" #include "can-message.hpp" #include "openxc-utils.hpp" @@ -52,10 +53,10 @@ can_bus_t *can_bus_handler; * *********************************************************************************/ -static int make_subscription_unsubscription(struct afb_req request, const char* sig_name, std::map& s, bool subscribe) +static int make_subscription_unsubscription(struct afb_req request, const std::string& sig_name, std::map& s, bool subscribe) { /* Make the subscription or unsubscription to the event */ - if (((subscribe ? afb_req_subscribe : afb_req_unsubscribe)(request, s[std::string(sig_name)])) < 0) + if (((subscribe ? afb_req_subscribe : afb_req_unsubscribe)(request, s[sig_name.c_str()])) < 0) { ERROR(binder_interface, "Operation goes wrong for signal: %s", sig_name); return 0; @@ -64,10 +65,10 @@ static int make_subscription_unsubscription(struct afb_req request, const char* } -static int create_event_handle(const char* sig_name, std::map& s) +static int create_event_handle(const std::string& sig_name, std::map& s) { - s[std::string(sig_name)] = afb_daemon_make_event(binder_interface->daemon, sig_name); - if (!afb_event_is_valid(s[std::string(sig_name)])) + s[sig_name] = afb_daemon_make_event(binder_interface->daemon, sig_name.c_str()); + if (!afb_event_is_valid(s[sig_name])) { ERROR(binder_interface, "Can't create an event, something goes wrong."); return 0; @@ -75,13 +76,13 @@ static int create_event_handle(const char* sig_name, std::map subscribed_signals_lock(get_subscribed_signals_mutex()); std::map& s = get_subscribed_signals(); - if (s.find(sig.generic_name) != s.end() && !afb_event_is_valid(s[std::string(sig.generic_name)])) + if (s.find(sig) != s.end() && !afb_event_is_valid(s[std::string(sig)])) { if(!subscribe) { @@ -90,14 +91,14 @@ static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, } else /* Event it isn't valid annymore, recreate it */ - ret = create_event_handle(sig.generic_name, s); + ret = create_event_handle(sig, s); } else { /* Event don't exist , so let's create it */ struct afb_event empty_event = {nullptr, nullptr}; - subscribed_signals[sig.generic_name] = empty_event; - ret = create_event_handle(sig.generic_name, s); + subscribed_signals[sig] = empty_event; + ret = create_event_handle(sig, s); } /* Check whether or not the event handler has been correctly created and @@ -105,7 +106,7 @@ static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, */ if (ret <= 0) return ret; - return make_subscription_unsubscription(request, sig.generic_name, s, subscribe); + return make_subscription_unsubscription(request, sig, s, subscribe); } /** @@ -118,57 +119,34 @@ static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, * * @return Number of correctly subscribed signal */ -static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe, const std::vector& signals) +static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe, std::vector& signals) { int rets = 0; - for(const auto& signal_i : signals) + for(auto& signal_i : signals) { int ret = subscribe_unsubscribe_signal(request, subscribe, signal_i); if(ret <= 0) return ret; rets++; - DEBUG(binder_interface, "Signal: %s subscribed", signal_i.generic_name); + DEBUG(binder_interface, "Signal: %s subscribed", signal_i.c_str()); } return rets; } -// TODO -static int subscribe_unsubscribe_all(struct afb_req request, bool subscribe) -{ - int e = 0; - - //for (const auto& sig : SIGNALS) - // e += !subscribe_unsubscribe_signals(request, subscribe, sig); - e += !subscribe_unsubscribe_signals(request, subscribe, getSignals()); - - return e == 0; -} - static int subscribe_unsubscribe_name(struct afb_req request, bool subscribe, const char *name) { - std::vector sig; + std::vector sig; int ret = 0; - if (!::strcmp(name, "*")) - ret = subscribe_unsubscribe_all(request, subscribe); - else - { - //if(obd2_handler_c.is_obd2_signal(name)) - if(false) - { - // TODO - } - else - { - openxc_DynamicField search_key = build_DynamicField(std::string(name)); - sig = find_can_signals(search_key); - if (sig.empty()) - ret = 0; - } - ret = subscribe_unsubscribe_signals(request, subscribe, sig); - NOTICE(binder_interface, "Subscribed correctly to %d/%d signal(s).", ret, (int)sig.size()); - } + openxc_DynamicField search_key = build_DynamicField(std::string(name)); + sig = find_signals(search_key); + if (sig.empty()) + ret = 0; + + ret = subscribe_unsubscribe_signals(request, subscribe, sig); + NOTICE(binder_interface, "Subscribed correctly to %d/%d signal(s).", ret, (int)sig.size()); + return ret; } @@ -180,7 +158,7 @@ static void subscribe_unsubscribe(struct afb_req request, bool subscribe) /* makes the subscription/unsubscription */ args = afb_req_json(request); if (args == NULL || !json_object_object_get_ex(args, "event", &a)) { - ok = subscribe_unsubscribe_all(request, subscribe); + ok = subscribe_unsubscribe_name(request, subscribe, "*"); } else if (json_object_get_type(a) != json_type_array) { ok = subscribe_unsubscribe_name(request, subscribe, json_object_get_string(a)); } else { diff --git a/src/obd2-signals.cpp b/src/obd2-signals.cpp new file mode 100644 index 00000000..69db5e29 --- /dev/null +++ b/src/obd2-signals.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2015, 2016 "IoT.bzh" + * Author "Romain Forlot" + * + * 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 "obd2-signals.hpp" + +#include "signals.hpp" + +const char *UNIT_NAMES[10] = { + "POURCENT", + "DEGREES_CELSIUS", + "KPA", + "RPM", + "GRAMS_SEC", + "SECONDS", + "KM", + "KM_H", + "PA", + "NM" +}; + +/* +* Pre-defined OBD-II PIDs to query for if supported by the vehicle. +*/ + std::vector OBD2_PIDS = { + { 0x04, "obd2.engine.load", 0, 100, POURCENT, 5, false}, + { 0x05, "obd2.engine.coolant.temperature", -40, 215, DEGREES_CELSIUS, 1, false}, + { 0x0a, "obd2.fuel.pressure", 0, 765, KPA, 1, false}, + { 0x0b, "obd2.intake.manifold.pressure", 0, 255, KPA, 1, false}, + { 0x0c, "obd2.engine.speed", 0, 16383, RPM, 5, false}, + { 0x0d, "obd2.vehicle.speed", 0, 255, KM_H, 5, false}, + { 0x0f, "obd2.intake.air.temperature", -40, 215, DEGREES_CELSIUS, 1, false}, + { 0x10, "obd2.mass.airflow", 0, 655, GRAMS_SEC, 5, false}, + { 0x11, "obd2.throttle.position", 0, 100, POURCENT, 5, false}, + { 0x1f, "obd2.running.time", 0, 65535, SECONDS, 1, false}, + { 0x2d, "obd2.EGR.error", -100, 99, POURCENT, 0, false}, + { 0x2f, "obd2.fuel.level", 0, 100, POURCENT, 1, false}, + { 0x33, "obd2.barometric.pressure", 0, 255, KPA, 1, false}, + { 0x4c, "obd2.commanded.throttle.position", 0, 100, POURCENT, 1, false}, + { 0x52, "obd2.ethanol.fuel.percentage", 0, 100, POURCENT, 1, false}, + { 0x5a, "obd2.accelerator.pedal.position", 0, 100, POURCENT, 5, false}, + { 0x5b, "obd2.hybrid.battery-pack.remaining.life", 0, 100, POURCENT, 5, false}, + { 0x5c, "obd2.engine.oil.temperature",-40, 210, DEGREES_CELSIUS, 1, false}, + { 0x63, "obd2.engine.torque", 0, 65535, NM, 1, false} +}; + +/** + * @fn std::vector find_signals(const openxc_DynamicField &key) + * @brief return signals name found searching through CAN_signals and OBD2 pid + * + * @param[in] const openxc_DynamicField : can contain numeric or string value in order to search against + * can signals or obd2 signals name. + * + * @return std::vector Vector of signals name found. + */ +void find_signals(const openxc_DynamicField &key, std::vector& found_signals) +{ + switch(key.type) + { + case openxc_DynamicField_Type::openxc_DynamicField_Type_STRING: + lookup_signals_by_name(key.string_value, get_obd2_signals(), found_signals); + break; + case openxc_DynamicField_Type::openxc_DynamicField_Type_NUM: + lookup_signals_by_id(key.numeric_value, get_obd2_signals(), found_signals); + break; + default: + ERROR(binder_interface, "find_signals: wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only."); + break; + } + DEBUG(binder_interface, "Found %d signal(s)", (int)found_signals.size()); +} + +std::vector& get_obd2_signals() +{ + return OBD2_PIDS; +} + +uint32_t get_signal_id(const Obd2Pid& sig) +{ + return (uint32_t)sig.pid; +} + +void shims_logger(const char* m, const struct afb_binding_interface *interface) +{ + DEBUG(interface, "%s", m); +} + +void shims_timer() +{ +} + +/* + * Will scan for supported Obd2 pids + * +obd2_handler_t::obd2_handler_t() +{ + DiagnosticShims shims_ = diagnostic_init_shims(shims_logger, can_bus.send_can_message, NULL); + + int n_pids_, i_; + + n_pids_ = size(Obd2Pid); + for(i_=0; i_<=n_pids_; i_++) + { + } +} + +void obd2_handler_t::add_request(int pid) +{ + DiagnosticRequest request = { + arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID, + mode: 0x1, has_true, pid}; +} + +bool obd2_handler_t::is_obd2_request(DiagnosticRequest* request) +{ + return request->mode == 0x1 && request->has_pid && request->pid < 0xff; +} + +bool obd2_handler_t::is_obd2_signal(const char *name) +{ + if(fnmatch("obd2.*", name, FNM_CASEFOLD) == 0) + return true; + return false; +} + +bool obd2_handler_t::decode_obd2_response(DiagnosticResponse* responce) +{ + return diagnostic_decode_obd2_pid(response); +}*/ \ No newline at end of file diff --git a/src/obd2.hpp b/src/obd2-signals.hpp similarity index 52% rename from src/obd2.hpp rename to src/obd2-signals.hpp index 05387456..5ff63f84 100644 --- a/src/obd2.hpp +++ b/src/obd2-signals.hpp @@ -18,13 +18,11 @@ #pragma once #include + #include "uds/uds.h" #include "can-bus.hpp" -extern "C" -{ - #include -} +#include "low-can-binding.hpp" enum UNIT { POURCENT, @@ -36,20 +34,8 @@ enum UNIT { KM, KM_H, PA, - NM -}; - -const char *UNIT_NAMES[10] = { - "POURCENT", - "DEGREES_CELSIUS", - "KPA", - "RPM", - "GRAMS_SEC", - "SECONDS", - "KM", - "KM_H", - "PA", - "NM" + NM, + INVALID }; /** @@ -63,7 +49,6 @@ const char *UNIT_NAMES[10] = { * frequency - The frequency to request this PID if supported by the vehicle * when automatic, recurring OBD-II requests are enabled. * supported - is it supported by the vehicle. Initialized after scan - * event - application framework event handler. */ typedef struct _Obd2Pid { uint8_t pid; @@ -75,30 +60,9 @@ typedef struct _Obd2Pid { bool supported; } Obd2Pid; -/* -* Pre-defined OBD-II PIDs to query for if supported by the vehicle. -*/ -const std::vector OBD2_PIDS { - { pid: 0x04, name: "obd2.engine.load", min:0, max: 100, unit: POURCENT, frequency: 5, supported: false}, - { pid: 0x05, name: "obd2.engine.coolant.temperature", min: -40, max: 215, unit: DEGREES_CELSIUS, frequency: 1, supported: false}, - { pid: 0x0a, name: "obd2.fuel.pressure", min: 0, max: 765, unit: KPA, frequency: 1, supported: false}, - { pid: 0x0b, name: "obd2.intake.manifold.pressure", min: 0, max: 255, unit: KPA, frequency: 1, supported: false}, - { pid: 0x0c, name: "obd2.engine.speed", min: 0, max: 16383, unit: RPM, frequency: 5, supported: false}, - { pid: 0x0d, name: "obd2.vehicle.speed", min: 0, max: 255, unit: KM_H, frequency: 5, supported: false}, - { pid: 0x0f, name: "obd2.intake.air.temperature", min: -40, max:215, unit: DEGREES_CELSIUS, frequency: 1, supported: false}, - { pid: 0x10, name: "obd2.mass.airflow", min: 0, max: 655, unit: GRAMS_SEC, frequency: 5, supported: false}, - { pid: 0x11, name: "obd2.throttle.position", min: 0, max: 100, unit: POURCENT, frequency: 5, supported: false}, - { pid: 0x1f, name: "obd2.running.time", min: 0, max: 65535, unit: SECONDS, frequency: 1, supported: false}, - { pid: 0x2d, name: "obd2.EGR.error", min: -100, max: 99, unit: POURCENT, frequency: 0, supported: false}, - { pid: 0x2f, name: "obd2.fuel.level", min: 0, max: 100, unit: POURCENT, frequency: 1, supported: false}, - { pid: 0x33, name: "obd2.barometric.pressure", min: 0, max: 255, unit: KPA, frequency: 1, supported: false}, - { pid: 0x4c, name: "obd2.commanded.throttle.position", min: 0, max: 100, unit: POURCENT, frequency: 1, supported: false}, - { pid: 0x52, name: "obd2.ethanol.fuel.percentage", min: 0, max: 100, unit: POURCENT, frequency: 1, supported: false}, - { pid: 0x5a, name: "obd2.accelerator.pedal.position", min: 0, max: 100, unit: POURCENT, frequency: 5, supported: false}, - { pid: 0x5b, name: "obd2.hybrid.battery-pack.remaining.life", min: 0, max: 100, unit: POURCENT, frequency: 5, supported: false}, - { pid: 0x5c, name: "obd2.engine.oil.temperature",min: -40, max: 210, unit: DEGREES_CELSIUS, frequency: 1, supported: false}, - { pid: 0x63, name: "obd2.engine.torque", min: 0, max: 65535, unit: NM, frequency: 1, supported: false} -}; +std::vector& get_obd2_signals(); +uint32_t get_signal_id(const Obd2Pid& sig); +void find_obd2_signals(const openxc_DynamicField &key, std::vector& found_signals); /** * @brief - Object to handle obd2 session with pre-scan of supported pid @@ -108,6 +72,7 @@ class obd2_handler_t { private: public: + obd2_handler_t(); /** * @brief: * diff --git a/src/obd2.cpp b/src/obd2.cpp deleted file mode 100644 index 536df66e..00000000 --- a/src/obd2.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" - * - * 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 "obd2.hpp" - -void shims_logger(const char* m, const struct afb_binding_interface *interface) -{ - DEBUG(interface, "%s", m); -} - -void shims_timer() -{ -} - -/* - * Will scan for supported Obd2 pids - */ -obd2_handler_t::obd2_handler_t(const struct afb_binding_interface *interface, can_bus_t can_bus) - : can_bus_{can_bus} -{ - can_bus_t can_bus_ = can_bus; - DiagnosticShims shims_ = diagnostic_init_shims(shims_logger, can_bus.send_can_message, NULL); - - int n_pids_, i_; - - n_pids_ = size(Obd2Pid); - for(i_=0; i_<=n_pids_; i_++) - { - } -} - -void obd2_handler_t::add_request(int pid) -{ - DiagnosticRequest request = { - arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID, - mode: 0x1, has_pid: true, pid: pid}; -} - -bool obd2_handler_t::is_obd2_request(DiagnosticRequest* request) -{ - return request->mode == 0x1 && request->has_pid && request->pid < 0xff; -} - -bool obd2_handler_t::is_obd2_signal(const char *name) -{ - if(fnmatch("obd2.*", name, FNM_CASEFOLD) == 0) - return true; - return false; -} - -bool obd2_handler_t::decode_obd2_response(DiagnosticResponse* responce) -{ - return diagnostic_decode_obd2_pid(response); -} diff --git a/src/signals.cpp b/src/signals.cpp new file mode 100644 index 00000000..d163c6f0 --- /dev/null +++ b/src/signals.cpp @@ -0,0 +1,33 @@ + +#include "signals.hpp" + +/** + * @fn std::vector find_signals(const openxc_DynamicField &key) + * @brief return signals name found searching through CAN_signals and OBD2 pid + * + * @param[in] const openxc_DynamicField : can contain numeric or string value in order to search against + * can signals or obd2 signals name. + * + * @return std::vector Vector of signals name found. + */ +std::vector find_signals(const openxc_DynamicField &key) +{ + std::vector found_signals_name; + + switch(key.type) + { + case openxc_DynamicField_Type::openxc_DynamicField_Type_STRING: + lookup_signals_by_name(key.string_value, get_can_signals(), found_signals_name); + lookup_signals_by_name(key.string_value, get_obd2_signals(), found_signals_name); + break; + case openxc_DynamicField_Type::openxc_DynamicField_Type_NUM: + lookup_signals_by_id(key.numeric_value, get_can_signals(), found_signals_name); + lookup_signals_by_id(key.numeric_value, get_obd2_signals(), found_signals_name); + break; + default: + ERROR(binder_interface, "find_signals: wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only."); + break; + } + DEBUG(binder_interface, "Found %d signal(s)", (int)found_signals_name.size()); + return found_signals_name; +} diff --git a/src/signals.hpp b/src/signals.hpp new file mode 100644 index 00000000..53d19d51 --- /dev/null +++ b/src/signals.hpp @@ -0,0 +1,56 @@ + +#pragma once + +#include +#include +#include + +#include "openxc.pb.h" +#include "can-signals.hpp" +#include "obd2-signals.hpp" + +template +void lookup_signals_by_name(const std::string& key, std::vector& signals, std::vector& found_signals) +{ + for(T& s : signals) + { + if(::fnmatch(key.c_str(), s.generic_name, FNM_CASEFOLD) == 0) + found_signals.push_back(&s); + } +} + +template +void lookup_signals_by_name(const std::string& key, std::vector& signals, std::vector& found_signals_name) +{ + for(const T& s : signals) + { + if(::fnmatch(key.c_str(), s.generic_name, FNM_CASEFOLD) == 0) + found_signals_name.push_back(s.generic_name); + } +} + +template +void lookup_signals_by_id(const double key, std::vector& signals, std::vector& found_signals) +{ + for(T& s : signals) + { + if(get_signal_id(s) == key) + { + found_signals.push_back(&s); + } + } +} + +template +void lookup_signals_by_id(const double key, std::vector& signals, std::vector& found_signals_name) +{ + for(T& s : signals) + { + if(get_signal_id(s) == key) + { + found_signals_name.push_back(s.generic_name); + } + } +} + +std::vector find_signals(const openxc_DynamicField &key); -- 2.16.6