X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=low-can-binding%2Fbinding%2Flow-can-cb.cpp;h=edf464bcd6fa9ab9c121b021646b6969f379ae26;hb=6faef2305955b025c3cf1cfaf17a6aa073727c24;hp=a190b2a5e3231d562d36980582b970ab43dd6324;hpb=e2af4a871c6a8bcab4733193948833aed9c5ceb8;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 a190b2a5..edf464bc 100644 --- a/low-can-binding/binding/low-can-cb.cpp +++ b/low-can-binding/binding/low-can-cb.cpp @@ -17,6 +17,7 @@ */ #include "low-can-hat.hpp" +#include "low-can-apidef.h" #include #include @@ -36,7 +37,6 @@ #include "../diagnostic/diagnostic-message.hpp" #include "../utils/openxc-utils.hpp" - ///****************************************************************************** /// /// SystemD event loop Callbacks @@ -101,7 +101,10 @@ int read_message(sd_event_source *event_source, int fd, uint32_t revents, void * /// ///*******************************************************************************/ -static int make_subscription_unsubscription(struct afb_req request, std::shared_ptr& can_subscription, std::map >& s, bool subscribe) +static int make_subscription_unsubscription(struct afb_req request, + std::shared_ptr& can_subscription, + 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) @@ -112,7 +115,8 @@ static int make_subscription_unsubscription(struct afb_req request, std::shared_ return 0; } -static int create_event_handle(std::shared_ptr& can_subscription, std::map >& s) +static int create_event_handle(std::shared_ptr& can_subscription, + std::map >& s) { int sub_index = can_subscription->get_index(); can_subscription->set_event(afb_daemon_make_event(can_subscription->get_name().c_str())); @@ -128,7 +132,10 @@ static int create_event_handle(std::shared_ptr& can_subs /// @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 /// against the application framework using that event handle. -static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, std::shared_ptr& can_subscription, std::map >& s) +static int subscribe_unsubscribe_signal(struct afb_req request, + bool subscribe, + std::shared_ptr& can_subscription, + std::map >& s) { int ret = -1; int sub_index = can_subscription->get_index(); @@ -168,7 +175,11 @@ static int add_to_event_loop(std::shared_ptr& can_subscr can_subscription.get())); } -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) +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) { int rets = 0; application_t& app = application_t::instance(); @@ -223,7 +234,11 @@ static int subscribe_unsubscribe_diagnostic_messages(struct afb_req request, boo } // 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, struct event_filter_t& event_filter, std::map >& s) +static int subscribe_unsubscribe_can_signals(struct afb_req request, + bool subscribe, + std::vector > can_signals, + struct event_filter_t& event_filter, + std::map >& s) { int rets = 0; for(const auto& sig: can_signals) @@ -261,7 +276,10 @@ static int subscribe_unsubscribe_can_signals(struct afb_req request, bool subscr /// /// @return Number of correctly subscribed signal /// -static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe, const struct utils::signals_found& signals, struct event_filter_t& event_filter) +static int subscribe_unsubscribe_signals(struct afb_req request, + bool subscribe, + const struct utils::signals_found& signals, + struct event_filter_t& event_filter) { int rets = 0; utils::signals_manager_t& sm = utils::signals_manager_t::instance(); @@ -275,7 +293,10 @@ static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe, return rets; } -static int one_subscribe_unsubscribe(struct afb_req request, bool subscribe, const std::string& tag, json_object* args) +static int one_subscribe_unsubscribe(struct afb_req request, + bool subscribe, + const std::string& tag, + json_object* args) { int ret = 0; struct event_filter_t event_filter; @@ -287,22 +308,13 @@ static int one_subscribe_unsubscribe(struct afb_req request, bool subscribe, con { if (json_object_object_get_ex(filter, "frequency", &obj) && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.frequency = (float)json_object_get_double(obj); - ret += 1; - } + {event_filter.frequency = (float)json_object_get_double(obj);} if (json_object_object_get_ex(filter, "min", &obj) && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.min = (float)json_object_get_double(obj); - ret += 2; - } + {event_filter.min = (float)json_object_get_double(obj);} if (json_object_object_get_ex(filter, "max", &obj) && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.max = (float)json_object_get_double(obj); - ret += 4; - } + {event_filter.max = (float)json_object_get_double(obj);} } // subscribe or unsubscribe @@ -318,14 +330,12 @@ static int one_subscribe_unsubscribe(struct afb_req request, bool subscribe, con return ret; } - -static void do_subscribe_unsubscribe(struct afb_req request, bool subscribe) +static int process_one_subscribe_args(struct afb_req request, bool subscribe, json_object *args) { - int i, n, rc, rc2; - struct json_object *args, *event, *x; - - args = afb_req_json(request); - if (args == NULL || !json_object_object_get_ex(args, "event", &event)) + int rc = 0, rc2=0; + json_object *x = nullptr, *event = nullptr; + if(args == NULL || + !json_object_object_get_ex(args, "event", &event)) { rc = one_subscribe_unsubscribe(request, subscribe, "*", args); } @@ -335,9 +345,7 @@ static void do_subscribe_unsubscribe(struct afb_req request, bool subscribe) } else { - rc = 0; - n = json_object_array_length(event); - for (i = 0 ; i < n ; i++) + for (int i = 0 ; i < json_object_array_length(event); i++) { x = json_object_array_get_idx(event, i); rc2 = one_subscribe_unsubscribe(request, subscribe, json_object_get_string(x), args); @@ -345,6 +353,27 @@ static void do_subscribe_unsubscribe(struct afb_req request, bool subscribe) rc = rc2 >= 0 ? rc + rc2 : rc2; } } + return rc; +} + +static void do_subscribe_unsubscribe(struct afb_req request, bool subscribe) +{ + int rc = 0; + struct json_object *args, *x; + + args = afb_req_json(request); + if (json_object_get_type(args) == json_type_array) + { + for(int i = 0; i < json_object_array_length(args); i++) + { + x = json_object_array_get_idx(args, i); + rc += process_one_subscribe_args(request, subscribe, x); + } + } + else + { + rc += process_one_subscribe_args(request, subscribe, args); + } if (rc >= 0) afb_req_success(request, NULL, NULL); @@ -430,11 +459,14 @@ static int write_signal(const std::string& name, uint64_t value) if(sig->get_writable()) { cf = encoder_t::build_frame(sig, value); - const std::string bus_name = sig->get_message()->get_bus_name(); + const std::string bus_name = sig->get_message()->get_bus_device_name(); 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; + } } } @@ -463,7 +495,7 @@ void write(struct afb_req request) (json_object_object_get_ex(json_value, "can_dlc", &json_can_dlc) && (json_object_is_type(json_can_dlc, json_type_double) || json_object_is_type(json_can_dlc, json_type_int))) && (json_object_object_get_ex(json_value, "can_data", &json_can_data) && json_object_is_type(json_can_data, json_type_array) )) { - write_raw_frame(json_object_get_string(json_name), + rc = write_raw_frame(json_object_get_string(json_name), json_object_get_int(json_can_id), (uint8_t)json_object_get_int(json_can_dlc), json_can_data); @@ -479,7 +511,7 @@ void write(struct afb_req request) (json_object_object_get_ex(args, "signal_name", &json_name) && json_object_is_type(json_name, json_type_string)) && (json_object_object_get_ex(args, "signal_value", &json_value) && (json_object_is_type(json_value, json_type_double) || json_object_is_type(json_value, json_type_int)))) { - write_signal(json_object_get_string(json_name), + rc = write_signal(json_object_get_string(json_name), (uint64_t)json_object_get_double(json_value)); } else @@ -493,3 +525,135 @@ void write(struct afb_req request) else afb_req_fail(request, "error", NULL); } + +static struct json_object *get_signals_value(const std::string& name) +{ + struct utils::signals_found sf; + struct json_object *ans = nullptr; + + openxc_DynamicField search_key = build_DynamicField(name); + sf = utils::signals_manager_t::instance().find_signals(search_key); + + if (sf.can_signals.empty()) + { + AFB_WARNING("No signal(s) found for %s.", name.c_str()); + return NULL; + } + ans = json_object_new_array(); + for(const auto& sig: sf.can_signals) + { + struct json_object *jobj = json_object_new_object(); + json_object_object_add(jobj, "event", json_object_new_string(sig->get_name().c_str())); + json_object_object_add(jobj, "value", json_object_new_double(sig->get_last_value())); + json_object_array_add(ans, jobj); + } + + return ans; +} +void get(struct afb_req request) +{ + int rc = 0; + struct json_object* args = nullptr, + *json_name = nullptr; + json_object *ans = nullptr; + + args = afb_req_json(request); + + // Process about Raw CAN message on CAN bus directly + if (args != nullptr && + (json_object_object_get_ex(args, "event", &json_name) && json_object_is_type(json_name, json_type_string) )) + { + ans = get_signals_value(json_object_get_string(json_name)); + if (!ans) + rc = -1; + } + else + { + AFB_ERROR("Request argument malformed. Please use the following syntax:"); + rc = -1; + } + + if (rc >= 0) + afb_req_success(request, ans, NULL); + else + afb_req_fail(request, "error", NULL); +} + + +static struct json_object *list_can_message(const std::string& name) +{ + struct utils::signals_found sf; + struct json_object *ans = nullptr; + + openxc_DynamicField search_key = build_DynamicField(name); + sf = utils::signals_manager_t::instance().find_signals(search_key); + + if (sf.can_signals.empty() && sf.diagnostic_messages.empty()) + { + AFB_WARNING("No signal(s) found for %s.", name.c_str()); + return NULL; + } + ans = json_object_new_array(); + for(const auto& sig: sf.can_signals) + { + json_object_array_add(ans, + json_object_new_string(sig->get_name().c_str())); + } + for(const auto& sig: sf.diagnostic_messages) + { + json_object_array_add(ans, + json_object_new_string(sig->get_name().c_str())); + } + + return ans; +} + +void list(struct afb_req request) +{ + int rc = 0; + json_object *ans = nullptr; + struct json_object* args = nullptr, + *json_name = nullptr; + args = afb_req_json(request); + const char *name; + if ((args != nullptr) && + (json_object_object_get_ex(args, "event", &json_name) && json_object_is_type(json_name, json_type_string))) + { + name = json_object_get_string(json_name); + } + else + { + name = "*"; + } + + ans = list_can_message(name); + if (!ans) + rc = -1; + + if (rc >= 0) + afb_req_success(request, ans, NULL); + else + afb_req_fail(request, "error", NULL); +} + +/// @brief Initialize the binding. +/// +/// @param[in] service Structure which represent the Application Framework Binder. +/// +/// @return Exit code, zero if success. +int initv2() +{ + can_bus_t& can_bus_manager = application_t::instance().get_can_bus_manager(); + + can_bus_manager.set_can_devices(); + can_bus_manager.start_threads(); + + /// 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; + + AFB_ERROR("There was something wrong with CAN device Initialization."); + return 1; +}