From 04a9b9bc48c8c6d26be9d6d6cc30e598b6acd3b7 Mon Sep 17 00:00:00 2001 From: Avijit Dey Date: Fri, 19 May 2023 15:28:24 +0200 Subject: [PATCH] Add example with use of vehicle discovery --- examples/CMakeLists.txt | 3 + examples/README.md | 6 +- examples/example_1/src/main.cpp | 2 +- examples/example_2/CMakeLists.txt | 41 ++++++++ .../example_2/etc/diag_client_config.json | 35 +++++++ examples/example_2/src/main.cpp | 93 +++++++++++++++++++ examples/example_2/src/uds_message.h | 43 +++++++++ 7 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 examples/example_2/CMakeLists.txt create mode 100644 examples/example_2/etc/diag_client_config.json create mode 100644 examples/example_2/src/main.cpp create mode 100644 examples/example_2/src/uds_message.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5fc51a75..97997d37 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -9,3 +9,6 @@ cmake_minimum_required(VERSION 3.5) # build example_1 add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/example_1) + +# build example_2 +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/example_2) diff --git a/examples/README.md b/examples/README.md index 27a8fd57..fcf14405 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,8 @@ # Examples - This folder contains several examples of applications using the diag client library. ## Example1: -Minimal example to use diag client library \ No newline at end of file +Example to connect to multiple ECU by creating multiple diagnostic tester instance. + +## Example2: +Example to find available ECU in a network through vehicle discovery and connecting to it. diff --git a/examples/example_1/src/main.cpp b/examples/example_1/src/main.cpp index 57477412..4d6ef1fb 100644 --- a/examples/example_1/src/main.cpp +++ b/examples/example_1/src/main.cpp @@ -17,7 +17,7 @@ /* * Main Entry point of diag client example - * This example explains how to use the diag client library efficiently + * Example to connect to multiple ECU by creating multiple diagnostic tester instance. */ int main() { // Create the Diagnostic client and pass the config for creating internal properties diff --git a/examples/example_2/CMakeLists.txt b/examples/example_2/CMakeLists.txt new file mode 100644 index 00000000..529a70fe --- /dev/null +++ b/examples/example_2/CMakeLists.txt @@ -0,0 +1,41 @@ +# Diagnostic Client library CMake File +# Copyright (C) 2023 Avijit Dey +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +cmake_minimum_required(VERSION 3.5) + +project(diag-client-example-2 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# find needed packages +find_package(Threads REQUIRED) + +#find main sources +file(GLOB MAIN_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") + +add_executable(${PROJECT_NAME} + ${MAIN_SRCS} + ) + +# diag client lib headers +set(diag_client_header_path ${CMAKE_CURRENT_SOURCE_DIR}/../diag_client_lib/build-bin/diag-client/lib/include) + +# Src headers +set(src_header_path src) + + +target_include_directories(${PROJECT_NAME} PRIVATE + ${src_header_path} + ${diag_client_header_path} + ) + +# link all dynamic libraries +target_link_libraries(${PROJECT_NAME} PRIVATE + diag-client + Threads::Threads + ) diff --git a/examples/example_2/etc/diag_client_config.json b/examples/example_2/etc/diag_client_config.json new file mode 100644 index 00000000..96cacde9 --- /dev/null +++ b/examples/example_2/etc/diag_client_config.json @@ -0,0 +1,35 @@ +{ + "UdpIpAddress": "172.16.25.127", + "UdpBroadcastAddress": "172.16.255.255", + "Conversation": { + "NumberOfConversation": 2, + "ConversationProperty": [ + { + "p2ClientMax": 1000, + "p2StarClientMax": 5000, + "RxBufferSize": 4095, + "SourceAddress": 1, + "TargetAddressType": "Physical", + "Network": { + "ProtocolKind": "DoIP", + "TcpIpAddress": "172.16.25.127", + "TLS": false + }, + "ConversationName": "DiagTesterOne" + }, + { + "p2ClientMax": 2000, + "p2StarClientMax": 5000, + "RxBufferSize": 4095, + "SourceAddress": 2, + "TargetAddressType": "Functional", + "Network": { + "ProtocolKind": "DoIP", + "TcpIpAddress": "172.16.25.127", + "TLS": false + }, + "ConversationName": "DiagTesterTwo" + } + ] + } +} \ No newline at end of file diff --git a/examples/example_2/src/main.cpp b/examples/example_2/src/main.cpp new file mode 100644 index 00000000..6ed1662e --- /dev/null +++ b/examples/example_2/src/main.cpp @@ -0,0 +1,93 @@ +/* Diagnostic Client library +* Copyright (C) 2023 Avijit Dey +* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#include + +#include "uds_message.h" + +// includes from diag-client library +#include "include/create_diagnostic_client.h" +#include "include/diagnostic_client.h" +#include "include/diagnostic_client_uds_message_type.h" +#include "include/diagnostic_client_vehicle_info_message_type.h" + +/* + * Main Entry point of diag client example + * Example to find available ECU in a network through vehicle discovery and connecting to it. + */ +int main() { + // Create the Diagnostic client and pass the config for creating internal properties + std::unique_ptr diag_client{ + diag::client::CreateDiagnosticClient("etc/diag_client_config.json")}; + + // Initialize the Diagnostic Client library + diag_client->Initialize(); + + // Get conversation for tester one by providing the conversation name configured + // in diag_client_config file passed while creating the diag client + diag::client::conversation::DiagClientConversation &diag_client_conversation { + diag_client->GetDiagnosticClientConversation("DiagTesterOne")}; + + // Start the conversation for tester one + diag_client_conversation.Startup(); + + // Create a vehicle info request for finding ECU with matching VIN - ABCDEFGH123456789 + diag::client::vehicle_info::VehicleInfoListRequestType + vehicle_info_request{1U, "ABCDEFGH123456789"}; + // Send Vehicle Identification request and get the response with available ECU information + std::pair + vehicle_response_result{diag_client->SendVehicleIdentificationRequest(vehicle_info_request)}; + + + // Valid vehicle discovery response must be received before connecting to ECU + if(vehicle_response_result.first == diag::client::DiagClient::VehicleResponseResult::kStatusOk && + (vehicle_response_result.second)) { + // Get the list of all vehicle available with matching VIN + diag::client::vehicle_info::VehicleInfoMessage::VehicleInfoListResponseType vehicle_response_collection{ + vehicle_response_result.second->GetVehicleList()}; + + // Create an uds message using first vehicle available in the list of response collection + std::string remote_ecu_ip_address{vehicle_response_collection[0].ip_address}; // Remote ECU ip address + std::uint16_t remote_ecu_server_logical_address{vehicle_response_collection[0].logical_address}; // Remote ECU logical address + + diag::client::uds_message::UdsRequestMessagePtr uds_message{ + std::make_unique(remote_ecu_ip_address, UdsMessage::ByteVector{0x10, 0x01})}; + + // Connect Tester One to remote ECU + diag::client::conversation::DiagClientConversation::ConnectResult connect_result{ + diag_client_conversation.ConnectToDiagServer(remote_ecu_server_logical_address, + uds_message->GetHostIpAddress())}; + + if(connect_result == diag::client::conversation::DiagClientConversation::ConnectResult::kConnectSuccess) { + // Use Tester One to send the diagnostic message to remote ECU + std::pair + diag_response{diag_client_conversation.SendDiagnosticRequest(std::move(uds_message))}; + + if (diag_response.first == diag::client::conversation::DiagClientConversation::DiagResult::kDiagSuccess) { + std::cout << "diag_client_conversation Total size: " << diag_response.second->GetPayload().size() << std::endl; + // Print the payload + for (auto const byte: diag_response.second->GetPayload()) { + std::cout << "diag_client_conversation byte: " << std::hex << static_cast(byte) << std::endl; + } + } + + // Disconnect Tester One from ECU1 with remote ip address "172.16.25.128" + diag_client_conversation.DisconnectFromDiagServer(); + } + + } + + // shutdown the conversation + diag_client_conversation.Shutdown(); + + // important to release all the resources by calling de-initialize + diag_client->DeInitialize(); + return (0); +} diff --git a/examples/example_2/src/uds_message.h b/examples/example_2/src/uds_message.h new file mode 100644 index 00000000..d72f36c6 --- /dev/null +++ b/examples/example_2/src/uds_message.h @@ -0,0 +1,43 @@ +/* Diagnostic Client library +* Copyright (C) 2023 Avijit Dey +* +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifndef EXAMPLES_EXAMPLE_1_SRC_UDS_MESSAGE_H +#define EXAMPLES_EXAMPLE_1_SRC_UDS_MESSAGE_H + +#include +// includes from diag-client library +#include "include/create_diagnostic_client.h" +#include "include/diagnostic_client_uds_message_type.h" + +class UdsMessage final : public diag::client::uds_message::UdsMessage { +public: + // ctor + UdsMessage(std::string_view host_ip_address, diag::client::uds_message::UdsMessage::ByteVector payload) + : host_ip_address_{host_ip_address}, + uds_payload_{std::move(payload)} {} + + // dtor + ~UdsMessage() = default; + +private: + // host ip address + IpAddress host_ip_address_; + + // store only UDS payload to be sent + diag::client::uds_message::UdsMessage::ByteVector uds_payload_; + + const diag::client::uds_message::UdsMessage::ByteVector &GetPayload() const override { return uds_payload_; } + + // return the underlying buffer for write access + diag::client::uds_message::UdsMessage::ByteVector &GetPayload() override { return uds_payload_; } + + // Get Host Ip address + IpAddress GetHostIpAddress() const noexcept override { return host_ip_address_; }; +}; + +#endif // EXAMPLES_EXAMPLE_1_SRC_UDS_MESSAGE_H \ No newline at end of file