### Install Fedora Dependencies Source: https://github.com/everest/libiso15118/blob/main/README.md Installs necessary build tools and libraries for Fedora 41+. ```bash sudo dnf update sudo dnf install gcc gcc-c++ git make cmake openssl-devel ``` -------------------------------- ### Initialize and Run TbdController Source: https://context7.com/everest/libiso15118/llms.txt Configures SSL/TLS, network settings, and session feedback callbacks before starting the main event loop for an ISO 15118-20 charging session. ```cpp #include #include #include // Configure SSL/TLS settings iso15118::config::SSLConfig ssl_config{ iso15118::config::CertificateBackend::EVEREST_LAYOUT, {}, // config_string (for JOSEPPA_LAYOUT) "/path/to/certificate_chain.pem", "/path/to/certificate_key.pem", std::nullopt, // private_key_password "/path/to/v2g_root_ca.pem", "/path/to/mo_root_ca.pem", false, // enable_ssl_logging false, // enable_tls_key_logging false // enforce_tls_1_3 }; // Configure the controller iso15118::TbdConfig tbd_config{ ssl_config, "eth0", // network interface name iso15118::config::TlsNegotiationStrategy::ACCEPT_CLIENT_OFFER, true // enable_sdp_server }; // Define feedback callbacks for session events iso15118::session::feedback::Callbacks callbacks{ .signal = [](iso15118::session::feedback::Signal signal) { switch (signal) { case iso15118::session::feedback::Signal::REQUIRE_AUTH_EIM: std::cout << "EIM authorization required\n"; break; case iso15118::session::feedback::Signal::START_CABLE_CHECK: std::cout << "Starting cable check\n"; break; case iso15118::session::feedback::Signal::CHARGE_LOOP_STARTED: std::cout << "Charge loop started\n"; break; case iso15118::session::feedback::Signal::DC_OPEN_CONTACTOR: std::cout << "Open DC contactor\n"; break; default: break; } }, .dc_pre_charge_target_voltage = [](float voltage) { std::cout << "Pre-charge target voltage: " << voltage << " V\n"; }, .dc_charge_loop_req = [](const iso15118::session::feedback::DcChargeLoopReq& req) { // Handle DC charge loop request data }, .dc_max_limits = [](const iso15118::session::feedback::DcMaximumLimits& limits) { std::cout << "EV max limits - V: " << limits.voltage << ", A: " << limits.current << ", W: " << limits.power << "\n"; }, .evccid = [](const std::string& evcc_id) { std::cout << "EVCC ID: " << evcc_id << "\n"; }, .selected_protocol = [](const std::string& protocol) { std::cout << "Selected protocol: " << protocol << "\n"; } }; // Configure EVSE setup iso15118::d20::EvseSetupConfig evse_setup{ .evse_id = "DE*ABC*E123456", .supported_energy_services = { iso15118::message_20::datatypes::ServiceCategory::DC, iso15118::message_20::datatypes::ServiceCategory::DC_BPT }, .authorization_services = {iso15118::message_20::datatypes::Authorization::EIM}, .supported_vas_services = {}, .enable_certificate_install_service = false, .dc_limits = {}, // Set appropriate DC transfer limits .ac_limits = {}, // Set appropriate AC transfer limits .control_mobility_modes = {{ iso15118::message_20::datatypes::ControlMode::Scheduled, iso15118::message_20::datatypes::MobilityNeedsMode::ProvidedByEvcc }}, .powersupply_limits = {} }; // Create and run the controller iso15118::TbdController controller(tbd_config, callbacks, evse_setup); controller.loop(); // Blocking main event loop ``` -------------------------------- ### Install Debian Dependencies Source: https://github.com/everest/libiso15118/blob/main/README.md Installs necessary build tools and libraries for Debian GNU/Linux 12. ```bash sudo apt update sudo apt install build-essential cmake libssl-dev ``` -------------------------------- ### Install gcovr Source: https://github.com/everest/libiso15118/blob/main/README.md Installs the required gcovr tool via pip. Version 8.2 or higher is required. ```bash pip install gcovr ``` -------------------------------- ### Setup Code Coverage Targets Source: https://github.com/everest/libiso15118/blob/main/test/CMakeLists.txt Configures Gcovr coverage reporting for the project using CTest. ```cmake evc_include(CodeCoverage) append_coverage_compiler_flags_to_target(iso15118) setup_target_for_coverage_gcovr_html( NAME ${PROJECT_NAME}_gcovr_coverage EXECUTABLE ctest ) setup_target_for_coverage_gcovr_xml( NAME ${PROJECT_NAME}_gcovr_coverage_xml EXECUTABLE ctest ) ``` -------------------------------- ### Implement Service Discovery Protocol Server Source: https://context7.com/everest/libiso15118/llms.txt Handles UDP-based SECC Discovery Protocol requests from EVs for initial connection setup. This server listens on a network interface and responds to discovery requests, providing endpoint information for V2G communication. ```cpp #include #include using namespace iso15118::io; // Create SDP server on network interface SdpServer sdp_server("eth0"); // Get file descriptor for poll integration int sdp_fd = sdp_server.get_fd(); // Handle incoming SDP requests PeerRequestContext request = sdp_server.get_peer_request(); if (request) { // Check security requirements if (request.security == v2gtp::Security::TLS) { std::cout << "EV requests TLS connection\n"; } else { std::cout << "EV requests plain TCP connection\n"; } // Create appropriate connection and get endpoint Ipv6EndPoint endpoint{ .address = get_local_ipv6_address("eth0"), .port = 49152 // Dynamic port for V2G }; // Send SDP response to EV sdp_server.send_response(request, endpoint); } ``` -------------------------------- ### Create Multiple Test Targets Source: https://github.com/everest/libiso15118/blob/main/test/exi/cb/iso20/CMakeLists.txt Calls the create_exi_test_target function to define individual test executables for various ISO 15118 features, such as session setup, authorization, and power delivery. ```cmake create_exi_test_target(session_setup) ``` ```cmake create_exi_test_target(authorization_setup) ``` ```cmake create_exi_test_target(authorization) ``` ```cmake create_exi_test_target(service_discovery) ``` ```cmake create_exi_test_target(service_detail) ``` ```cmake create_exi_test_target(service_selection) ``` ```cmake create_exi_test_target(dc_charge_parameter_discovery) ``` ```cmake create_exi_test_target(schedule_exchange) ``` ```cmake create_exi_test_target(dc_cable_check) ``` ```cmake create_exi_test_target(dc_pre_charge) ``` ```cmake create_exi_test_target(power_delivery) ``` ```cmake create_exi_test_target(dc_charge_loop) ``` ```cmake create_exi_test_target(dc_welding_detection) ``` ```cmake create_exi_test_target(session_stop) ``` ```cmake create_exi_test_target(ac_charge_parameter_discovery) ``` ```cmake create_exi_test_target(ac_charge_loop) ``` -------------------------------- ### Invoke FSM Test Targets Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/fsm/CMakeLists.txt Calls the create_fsm_test_target function to generate specific test executables for session setup and service detail. ```cmake create_fsm_test_target(session_setup) create_fsm_test_target(service_detail) ``` -------------------------------- ### Manage ISO 15118 Charging Session Source: https://context7.com/everest/libiso15118/llms.txt Handles the charging session state machine, including SSL connection setup, I/O polling, and event processing. ```cpp #include #include #include using namespace iso15118; // Create poll manager for async I/O io::PollManager poll_manager; // Create SSL/TLS connection auto connection = std::make_unique( poll_manager, "eth0", // interface name ssl_config ); // Optional pause context for session resume std::optional pause_ctx = std::nullopt; // Create session Session session( std::move(connection), d20::SessionConfig(evse_config), callbacks, pause_ctx ); // Main event loop while (!session.is_finished()) { // Get next event timeout const auto& next_event = session.poll(); // Calculate poll timeout auto now = get_current_time_point(); auto timeout_ms = std::chrono::duration_cast( next_event - now ).count(); // Poll for I/O events poll_manager.poll(std::max(0L, std::min(timeout_ms, 50L))); // Push control events as needed session.push_control_event(PresentVoltageCurrent{400.0f, 100.0f}); } // Clean up session.close(); ``` -------------------------------- ### Download ISO 15118-20 Schemas with CMake Source: https://github.com/everest/libiso15118/blob/main/input/CMakeLists.txt This CMake script automatically downloads ISO 15118-20 schema files using wget. It requires wget to be installed and the OPT_AUTODOWNLOAD_ISO20_SCHEMAS option to be enabled. The script checks if schemas already exist before downloading. ```cmake if (OPT_AUTODOWNLOAD_ISO20_SCHEMAS) find_program(WGET_EXECUTABLE wget) if (NOT WGET_EXECUTABLE) message(FATAL_ERROR "Cannot find wget executable to download schema files. Please install wget.") endif () list(APPEND ISO20_SCHEMA_FILES V2G_CI_AC.xsd V2G_CI_ACDP.xsd V2G_CI_AppProtocol.xsd V2G_CI_CommonMessages.xsd V2G_CI_CommonTypes.xsd V2G_CI_DC.xsd V2G_CI_WPT.xsd xmldsig-core-schema.xsd ) set(ISO20_BASE_URL "https://standards.iso.org/iso/15118/-20/ed-1/en/") set(ISO20_SCHEMA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/schema/iso-20) if (NOT EXISTS ${ISO20_SCHEMA_DIR}) file(MAKE_DIRECTORY ${ISO20_SCHEMA_DIR}) endif () foreach (ISO20_SCHEMA_FILE ${ISO20_SCHEMA_FILES}) if (EXISTS "${ISO20_SCHEMA_DIR}/${ISO20_SCHEMA_FILE}") continue() endif () message(STATUS "Downloading ${ISO20_SCHEMA_FILE}") execute_process( COMMAND ${WGET_EXECUTABLE} -P ${ISO20_SCHEMA_DIR} ${ISO20_BASE_URL}${ISO20_SCHEMA_FILE} RESULT_VARIABLE DOWNLOAD_FAILED ERROR_VARIABLE DOWNLOAD_ERROR_MSG ) if (DOWNLOAD_FAILED) message(FATAL_ERROR "Download of ${ISO20_BASE_URL}${ISO20_SCHEMA_FILE} failed. Reason:\n${DOWNLOAD_ERROR_MSG}") endif () endforeach() endif() # OPT_AUTODOWNLOAD_ISO20_SCHEMAS ``` -------------------------------- ### Build Project with Ninja Source: https://github.com/everest/libiso15118/blob/main/README.md Builds the project using the Ninja build system. ```bash ninja -C build ``` -------------------------------- ### Configure and Initialize ConnectionSSL Source: https://context7.com/everest/libiso15118/llms.txt Sets up a TLS-encrypted connection for ISO 15118 sessions using certificate-based authentication. Requires a PollManager and a populated SSLConfig structure. ```cpp #include #include using namespace iso15118; // Configure SSL for Plug & Charge config::SSLConfig ssl_config{ .backend = config::CertificateBackend::EVEREST_LAYOUT, .config_string = {}, .path_certificate_chain = "/etc/everest/certs/secc_chain.pem", .path_certificate_key = "/etc/everest/certs/secc_key.pem", .private_key_password = "secure_password", .path_certificate_v2g_root = "/etc/everest/certs/v2g_root_ca.pem", .path_certificate_mo_root = "/etc/everest/certs/mo_root_ca.pem", .enable_ssl_logging = false, .enable_tls_key_logging = false, // Enable for Wireshark debugging .enforce_tls_1_3 = true, .tls_key_logging_path = "/tmp/tls_keys.log" }; // Create connection io::PollManager poll_manager; auto connection = std::make_unique( poll_manager, "eth0", ssl_config ); // Set event callback connection->set_event_callback([](io::ConnectionEvent event) { switch (event) { case io::ConnectionEvent::ACCEPTED: std::cout << "Connection accepted\n"; break; case io::ConnectionEvent::OPEN: std::cout << "TLS handshake complete\n"; break; case io::ConnectionEvent::NEW_DATA: std::cout << "Data available\n"; break; case io::ConnectionEvent::CLOSED: std::cout << "Connection closed\n"; break; } }); // Get vehicle certificate hash (for session resume) auto cert_hash = connection->get_vehicle_cert_hash(); if (cert_hash) { std::cout << "Vehicle certificate available for session binding\n"; } // Get connection endpoint io::Ipv6EndPoint endpoint = connection->get_public_endpoint(); std::cout << "Listening on port: " << endpoint.port << "\n"; ``` -------------------------------- ### Configure I/O and Session Logging Callbacks Source: https://context7.com/everest/libiso15118/llms.txt Set global I/O logging callbacks to capture library-level messages and session logging callbacks for detailed EXI message tracing. Ensure necessary headers are included. ```cpp #include #include using namespace iso15118; // Set global I/O logging callback io::set_logging_callback([](LogLevel level, std::string message) { const char* level_str; switch (level) { case LogLevel::Error: level_str = "ERROR"; break; case LogLevel::Warning: level_str = "WARN"; break; case LogLevel::Info: level_str = "INFO"; break; case LogLevel::Debug: level_str = "DEBUG"; break; case LogLevel::Trace: level_str = "TRACE"; break; } std::cout << "[" << level_str << "] " << message << "\n"; }); // Set session logging callback for EXI message tracing session::logging::set_session_log_callback( [](std::size_t session_id, const session::logging::Event& event) { if (const auto* simple = std::get_if(&event)) { std::cout << "Session " << session_id << ": " << simple->info << "\n"; } else if (const auto* exi = std::get_if(&event)) { const char* direction = (exi->direction == session::logging::ExiMessageDirection::FROM_EV) ? "RX" : "TX"; std::cout << "Session " << session_id << " " << direction << " payload_type=0x" << std::hex << exi->payload_type << " len=" << std::dec << exi->len << "\n"; } } ); ``` -------------------------------- ### Configure D20 Transitions Test Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/fsm/CMakeLists.txt Manual configuration for the d20_transitions test executable, linking it with necessary dependencies. ```cmake add_executable(test_d20_transitions d20_transitions.cpp) target_sources(test_d20_transitions PRIVATE helper.cpp ) target_link_libraries(test_d20_transitions PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_d20_transitions) ``` -------------------------------- ### Configure Project with CMake (No Warnings) Source: https://github.com/everest/libiso15118/blob/main/README.md Configures the build system with CMake, disabling compiler warnings. ```bash cmake -S . -B build -G Ninja -DBUILD_TESTING=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DISO15118_COMPILE_OPTIONS_WARNING="" ``` -------------------------------- ### Configure Project with CMake Source: https://github.com/everest/libiso15118/blob/main/README.md Configures the build system using CMake, enabling unit tests and generating compile commands. ```bash cmake -S . -B build -G Ninja -DBUILD_TESTING=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ``` -------------------------------- ### Configure OpenSSL Connection Test Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/CMakeLists.txt Sets up the connection_openssl_test executable, including a custom command to prepare the PKI directory structure. ```cmake add_executable(connection_openssl_test) add_custom_command( TARGET connection_openssl_test POST_BUILD COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/pki COMMAND cd pki && cp pki.sh ${CMAKE_CURRENT_BINARY_DIR}/pki && cp -r configs ${CMAKE_CURRENT_BINARY_DIR}/pki WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) target_sources(connection_openssl_test PRIVATE connection_openssl.cpp ) target_link_libraries(connection_openssl_test PRIVATE iso15118::iso15118 ) ``` -------------------------------- ### Configure EVSE Parameters Source: https://context7.com/everest/libiso15118/llms.txt Initializes the EvseSetupConfig structure with supported services, authorization methods, and power limits for a DC fast charger. ```cpp #include using namespace iso15118::d20; using namespace iso15118::message_20::datatypes; // Complete EVSE configuration for a DC fast charger with BPT EvseSetupConfig evse_config{ .evse_id = "DE*ABC*E000001*1", .supported_energy_services = { ServiceCategory::DC, // Standard DC charging ServiceCategory::DC_BPT, // Bidirectional DC (V2G) ServiceCategory::AC, // Standard AC charging ServiceCategory::AC_BPT // Bidirectional AC }, .authorization_services = { Authorization::EIM, // External Identification Means Authorization::PnC // Plug & Charge }, .supported_vas_services = {65, 66}, // Internet, ParkingStatus .enable_certificate_install_service = true, // Allow certificate installation .dc_limits = dc_limits, // From previous example .ac_limits = ac_limits, // From previous example .control_mobility_modes = { {ControlMode::Scheduled, MobilityNeedsMode::ProvidedByEvcc}, {ControlMode::Dynamic, MobilityNeedsMode::ProvidedByEvcc}, {ControlMode::Dynamic, MobilityNeedsMode::ProvidedBySecc} }, .custom_protocol = std::nullopt, .ac_setup_config = AcSetupConfig{ .voltage = 230, // Nominal voltage .connectors = {AcConnector::ThreePhase} }, .bpt_setup_config = BptSetupConfig{ .bpt_channel = BptChannel::Unified, .generator_mode = GeneratorMode::GridFollowing, .grid_code_detection_method = GridCodeIslandingDetectionMethod::Passive }, .powersupply_limits = dc_limits }; // Create session configuration from EVSE setup SessionConfig session_config(evse_config); ``` -------------------------------- ### Run Tests with Ninja Source: https://github.com/everest/libiso15118/blob/main/README.md Executes the unit tests for the project using Ninja. ```bash ninja -C build test ``` -------------------------------- ### Add Executable and Link Libraries Source: https://github.com/everest/libiso15118/blob/main/test/v2gtp/CMakeLists.txt Defines an executable target named 'test_v2gtp' and links it with the 'cbv2g::tp' and 'Catch2::Catch2WithMain' libraries. ```cmake add_executable(test_v2gtp v2gtp.cpp) target_link_libraries(test_v2gtp PRIVATE cbv2g::tp Catch2::Catch2WithMain ) ``` -------------------------------- ### Configure CMake Build Environment Source: https://github.com/everest/libiso15118/blob/main/test/CMakeLists.txt Sets compiler warnings, module paths, and includes project subdirectories. ```cmake add_compile_options(${ISO15118_COMPILE_OPTIONS_WARNING}) list(APPEND CMAKE_MODULE_PATH ${CPM_PACKAGE_catch2_SOURCE_DIR}/extras) add_subdirectory(exi) add_subdirectory(iso15118) add_subdirectory(v2gtp) ``` -------------------------------- ### openssl s_client for TLS 1.2 and TLS 1.3 Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/README.md Connect to a server using `openssl s_client` with support for both TLS 1.2 and TLS 1.3. Ensure all certificate and key paths are correctly specified. ```bash openssl s_client -connect [ipv6%iface]:port -verify 2 -debug -msg -verifyCAfile ./pki/certs/ca/v2g/V2G_ROOT_CA.pem -verify_return_error -cert ./pki/certs/client/vehicle/VEHICLE_LEAF.pem -cert_chain ./pki/certs/ca/vehicle/VEHICLE_CERT_CHAIN.pem -certform PEM -key ./pki/certs/client/vehicle/VEHICLE_LEAF.key -keyform PEM -pass file:./pki/certs/client/vehicle/VEHICLE_LEAF_PASSWORD.txt -ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" -cipher "ECDHE-ECDSA-AES128-SHA256" -requestCAfile ./pki/certs/ca/v2g/V2G_ROOT_CA.pem ``` -------------------------------- ### Discover Catch2 Tests Source: https://github.com/everest/libiso15118/blob/main/test/v2gtp/CMakeLists.txt Includes the Catch2 testing framework and discovers tests for the 'test_v2gtp' executable. ```cmake include(Catch) catch_discover_tests(test_v2gtp) ``` -------------------------------- ### Configure Logging Test Executable Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/CMakeLists.txt Defines the test_logging executable and links it against the iso15118 library and Catch2 framework. ```cmake include(Catch) add_executable(test_logging logging.cpp) target_link_libraries(test_logging PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_logging) ``` -------------------------------- ### Handle Session Event Notifications with Callbacks Source: https://context7.com/everest/libiso15118/llms.txt Defines callback functions for session state changes, DC pre-charge voltage, charge loop requests, maximum limits, EVCC ID, selected protocol, charging needs, service parameters, and EV information. Use this structure to integrate session event handling into your application. ```cpp #include using namespace iso15118::session::feedback; using namespace iso15118::d20; using namespace iso15118::message_20::datatypes; Callbacks callbacks{ // Signal events for session state changes .signal = [](Signal sig) { switch (sig) { case Signal::REQUIRE_AUTH_EIM: // Trigger RFID reader or other auth method break; case Signal::START_CABLE_CHECK: // Begin isolation monitoring break; case Signal::SETUP_FINISHED: // Service selection complete break; case Signal::PRE_CHARGE_STARTED: // Begin pre-charge sequence break; case Signal::CHARGE_LOOP_STARTED: // Main charging started break; case Signal::CHARGE_LOOP_FINISHED: // Charging complete break; case Signal::DC_OPEN_CONTACTOR: // Open DC contactors safely break; case Signal::AC_CLOSE_CONTACTOR: // Close AC contactor break; case Signal::AC_OPEN_CONTACTOR: // Open AC contactor break; case Signal::DLINK_TERMINATE: // Session terminated break; case Signal::DLINK_PAUSE: // Session paused for resume break; } }, // DC pre-charge target voltage .dc_pre_charge_target_voltage = [](float voltage) { // Set power supply to target voltage power_supply.set_voltage(voltage); }, // DC charge loop data from EV .dc_charge_loop_req = [](const DcChargeLoopReq& req) { // Process charge loop request variants std::visit([](auto&& arg) { using T = std::decay_t if constexpr (std::is_same_v) { // Handle control mode data } else if constexpr (std::is_same_v) { // Handle display parameters (SoC, etc.) } }, req); }, // EV maximum limits .dc_max_limits = [](const DcMaximumLimits& limits) { std::cout << "EV max voltage: " << limits.voltage << " V\n"; std::cout << "EV max current: " << limits.current << " A\n"; std::cout << "EV max power: " << limits.power << " W\n"; }, // EVCC identifier .evccid = [](const std::string& id) { std::cout << "Vehicle ID: " << id << "\n"; }, // Selected application protocol .selected_protocol = [](const std::string& protocol) { std::cout << "Using protocol: " << protocol << "\n"; }, // EV charging needs notification .notify_ev_charging_needs = ( const ServiceCategory& service, const std::optional& ac_connector, const ControlMode& control_mode, const MobilityNeedsMode& mobility_mode, const EvseTransferLimits& evse_limits, const EvTransferLimits& ev_limits, const EvSEControlMode& se_control, const std::vector& vas ) { // Process EV charging requirements }, // Selected service parameters .selected_service_parameters = [](const SelectedServiceParameters& params) { std::cout << "Selected control mode: " << from_control_mode(params.selected_control_mode) << "\n"; }, // Complete EV information .ev_information = [](const EVInformation& info) { std::cout << "EVCC ID: " << info.evcc_id << "\n"; } }; ``` -------------------------------- ### Generate Code Coverage Report Source: https://github.com/everest/libiso15118/blob/main/README.md Executes the coverage report generation using ninja. Requires BUILD_TESTING to be enabled. ```bash ninja -C build iso15118_gcovr_coverage ``` -------------------------------- ### openssl s_client for TLS 1.2 Only Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/README.md Connect to a server using `openssl s_client` specifically for TLS 1.2. This command is useful for testing compatibility with older TLS versions. ```bash openssl s_client -connect [ipv6%iface]:port -verify 2 -debug -msg -verifyCAfile ./pki/certs/ca/v2g/V2G_ROOT_CA.pem -verify_return_error -tls1_2 -cipher "ECDHE-ECDSA-AES128-SHA256" ``` -------------------------------- ### Standalone TLS Server Execution Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/README.md Execute the standalone TLS server for testing. This server gracefully terminates after 30 seconds and requires a client certificate. It supports TCP, TLS1.2, and TLS1.3. ```bash ./connection_openssl -i ``` -------------------------------- ### Configure CMake for ISO15118 Test Application Source: https://github.com/everest/libiso15118/blob/main/test/exi/cb/app_hand/CMakeLists.txt Defines the test executable, links the iso15118 library and Catch2, and enables test discovery. ```cmake add_executable(test_app_hand app_hand.cpp) target_link_libraries(test_app_hand PRIVATE iso15118 Catch2::Catch2WithMain ) include(Catch) catch_discover_tests(test_app_hand) ``` -------------------------------- ### openssl s_client for TLS 1.3 Only Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/io/README.md Connect to a server using `openssl s_client` exclusively for TLS 1.3. This command is used to test the latest TLS protocol version and requires specific cipher suites. ```bash openssl s_client -connect [ipv6%iface]:port -verify 2 -debug -msg -verifyCAfile ./pki/certs/ca/v2g/V2G_ROOT_CA.pem -verify_return_error -tls1_3 -cert ./pki/certs/client/vehicle/VEHICLE_LEAF.pem -cert_chain ./pki/certs/ca/vehicle/VEHICLE_CERT_CHAIN.pem -certform PEM -key ./pki/certs/client/vehicle/VEHICLE_LEAF.key -keyform PEM -pass file:./pki/certs/client/vehicle/VEHICLE_LEAF_PASSWORD.txt -ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" -requestCAfile ./pki/certs/ca/v2g/V2G_ROOT_CA.pem ``` -------------------------------- ### Define and Register State Test Targets Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/states/CMakeLists.txt Uses a CMake function to create executables for specific state tests, linking them against the iso15118 library and Catch2. ```cmake include(Catch) function(create_states_test_target NAME) add_executable(test_${NAME} ${NAME}.cpp) target_link_libraries(test_${NAME} PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_${NAME}) endfunction() create_states_test_target(ac_charge_loop) create_states_test_target(ac_charge_parameter_discovery) create_states_test_target(authorization_setup) create_states_test_target(authorization) create_states_test_target(service_discovery) create_states_test_target(service_detail) create_states_test_target(service_selection) create_states_test_target(dc_charge_parameter_discovery) create_states_test_target(schedule_exchange) create_states_test_target(dc_cable_check) create_states_test_target(dc_pre_charge) create_states_test_target(power_delivery) create_states_test_target(dc_charge_loop) create_states_test_target(dc_welding_detection) create_states_test_target(session_stop) ``` -------------------------------- ### Configure CMake for Debugging Source: https://github.com/everest/libiso15118/blob/main/README.md Configures the build directory with debug symbols and testing enabled. ```bash cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON ``` -------------------------------- ### VS Code GDB Debugger Configuration Source: https://github.com/everest/libiso15118/blob/main/README.md JSON configuration for launching GDB in VS Code. Update the program path to target specific test executables. ```json { "name": "(gdb) Launch LIBISO TESTS", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/libiso15118/build/test/iso15118/fsm/test_d20_transitions", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}/libiso15118/build/test/iso15118/fsm/", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] }, ``` -------------------------------- ### Configure DC Transfer Limits Source: https://context7.com/everest/libiso15118/llms.txt Defines power, current, and voltage limits for DC charging, supporting bidirectional power transfer. Ensure correct RationalNumber values for power, current, and voltage. ```cpp #include #include using namespace iso15118::d20; using namespace iso15118::message_20::datatypes; // Helper function to create RationalNumber (value * 10^exponent) RationalNumber make_rational(int16_t value, int8_t exponent) { return RationalNumber{value, exponent}; } // Configure DC transfer limits for a 150kW charger DcTransferLimits dc_limits{ .charge_limits = { .power = { .max = make_rational(150, 3), // 150 kW max .min = make_rational(0, 0) // 0 W min }, .current = { .max = make_rational(400, 0), // 400 A max .min = make_rational(0, 0) // 0 A min } }, .discharge_limits = Limits{ // For BPT (bidirectional) support .power = { .max = make_rational(50, 3), // 50 kW max discharge .min = make_rational(0, 0) }, .current = { .max = make_rational(100, 0), // 100 A max discharge .min = make_rational(0, 0) } }, .voltage = { .max = make_rational(920, 0), // 920 V max .min = make_rational(150, 0) // 150 V min }, .power_ramp_limit = make_rational(10, 3) // 10 kW/s ramp rate }; // Update limits during a session controller.update_dc_limits(dc_limits); controller.update_powersupply_limits(dc_limits); ``` -------------------------------- ### Configure CMake for ISO15118 Timeout Tests Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/d20/CMakeLists.txt Defines the test executable and links required dependencies for the ISO15118 timeout test suite. ```cmake include(Catch) add_executable(test_timeouts timeouts.cpp) target_link_libraries(test_timeouts PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_timeouts) ``` -------------------------------- ### Manage ISO 15118-20 States with FSM Source: https://context7.com/everest/libiso15118/llms.txt Implements a hierarchical finite state machine to manage charging session states. Events are fed into the FSM to trigger transitions and state-specific logic. ```cpp #include #include #include using namespace iso15118::d20; using namespace fsm::v2; // State IDs for the charging session // StateID::SupportedAppProtocol -> StateID::SessionSetup -> // StateID::AuthorizationSetup -> StateID::Authorization -> // StateID::ServiceDiscovery -> StateID::ServiceDetail -> // StateID::ServiceSelection -> StateID::DC_ChargeParameterDiscovery -> // StateID::DC_CableCheck -> StateID::DC_PreCharge -> StateID::DC_ChargeLoop -> // StateID::PowerDelivery -> StateID::DC_WeldingDetection -> StateID::SessionStop // Create FSM with initial state FSM fsm{ctx.create_state()}; // Feed events to the FSM auto result = fsm.feed(Event::V2GTP_MESSAGE); if (result.transitioned()) { std::cout << "State transition occurred\n"; } // Get current state ID StateID current = fsm.get_current_state_id(); switch (current) { case StateID::DC_ChargeLoop: std::cout << "In DC charge loop state\n"; break; case StateID::SessionStop: std::cout << "Session stopping\n"; break; default: break; } // Feed control events fsm.feed(Event::CONTROL_MESSAGE); // Feed timeout events fsm.feed(Event::TIMEOUT); ``` -------------------------------- ### Send Control Events for Session Management Source: https://context7.com/everest/libiso15118/llms.txt Utilizes the `ControlEvent` type to send various signals during a charging session, such as authorization, status updates, and commands. ```cpp #include using namespace iso15118::d20; // Send authorization response controller.send_control_event(AuthorizationResponse(true)); // Authorized // Send cable check completion controller.send_control_event(CableCheckFinished(true)); // Cable check passed // Send present voltage and current during DC charging controller.send_control_event(PresentVoltageCurrent{ .voltage = 400.5f, // Present voltage in V .current = 125.3f // Present current in A }); // Send contactor closed status controller.send_control_event(ClosedContactor(true)); // Request to stop charging controller.send_control_event(StopCharging(true)); // Request to pause charging (for session resume support) controller.send_control_event(PauseCharging(true)); // Update dynamic mode parameters during session controller.send_control_event(UpdateDynamicModeParameters{ .departure_time = std::time(nullptr) + 3600, // 1 hour from now .target_soc = 80, // Target 80% SoC .min_soc = 20 // Minimum 20% SoC }); // Update AC target power controller.send_control_event(AcTargetPower{ .target_active_power = message_20::datatypes::RationalNumber{11, 3}, // 11 kW .target_reactive_power = std::nullopt }); // Update AC present power controller.send_control_event(AcPresentPower{ .present_active_power = message_20::datatypes::RationalNumber{10500, 0} // 10.5 kW }); ``` -------------------------------- ### Configure AC Transfer Limits Source: https://context7.com/everest/libiso15118/llms.txt Defines power limits for AC charging, supporting single-phase and three-phase configurations. Includes per-phase limits and BPT discharge limits. ```cpp #include using namespace iso15118::d20; using namespace iso15118::message_20::datatypes; // Configure AC transfer limits for a 22kW three-phase charger AcTransferLimits ac_limits{ .charge_power = { .max = RationalNumber{22, 3}, // 22 kW max L1 .min = RationalNumber{0, 0} }, .charge_power_L2 = Limit{ .max = RationalNumber{22, 3}, // 22 kW max L2 .min = RationalNumber{0, 0} }, .charge_power_L3 = Limit{ .max = RationalNumber{22, 3}, // 22 kW max L3 .min = RationalNumber{0, 0} }, .nominal_frequency = RationalNumber{50, 0}, // 50 Hz .max_power_asymmetry = RationalNumber{4600, 0}, // 4.6 kW asymmetry allowed .power_ramp_limitation = RationalNumber{5, 3}, // 5 kW/s ramp // BPT discharge limits (optional) .discharge_power = Limit{ .max = RationalNumber{11, 3}, // 11 kW discharge .min = RationalNumber{0, 0} } }; controller.update_ac_limits(ac_limits); ``` -------------------------------- ### Define FSM Test Target Function Source: https://github.com/everest/libiso15118/blob/main/test/iso15118/fsm/CMakeLists.txt A CMake function to automate the creation, source linking, and test discovery for FSM-related test executables. ```cmake function(create_fsm_test_target NAME) add_executable(test_fsm_${NAME} ${NAME}.cpp) target_sources(test_fsm_${NAME} PRIVATE helper.cpp ) target_link_libraries(test_fsm_${NAME} PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_fsm_${NAME}) endfunction() ``` -------------------------------- ### Define CMake Test Target Function Source: https://github.com/everest/libiso15118/blob/main/test/exi/cb/iso20/CMakeLists.txt Defines a CMake function to create an executable test target. It links against the iso15118 library and Catch2, and discovers tests using Catch2's test discovery mechanism. ```cmake function(create_exi_test_target NAME) add_executable(test_exi_${NAME} ${NAME}.cpp) target_link_libraries(test_exi_${NAME} PRIVATE iso15118 Catch2::Catch2WithMain ) catch_discover_tests(test_exi_${NAME}) endfunction() ``` -------------------------------- ### ISO 15118-20 Common Data Types Usage Source: https://context7.com/everest/libiso15118/llms.txt Demonstrates the usage of common data types for ISO 15118-20 messages, including rational numbers, service categories, authorization methods, control modes, response codes, connector types, display parameters, and meter information. Ensure the 'common_types.hpp' header is included. ```cpp #include using namespace iso15118::message_20::datatypes; // RationalNumber: value * 10^exponent RationalNumber power{150, 3}; // 150 * 10^3 = 150,000 W = 150 kW float power_watts = from_RationalNumber(power); // Convert to float RationalNumber converted = from_float(11500.0f); // Convert from float // Service categories ServiceCategory dc_service = ServiceCategory::DC; ServiceCategory dc_bpt = ServiceCategory::DC_BPT; ServiceCategory mcs = ServiceCategory::MCS; // Megawatt Charging // Authorization methods Authorization auth_eim = Authorization::EIM; // RFID, app, etc. Authorization auth_pnc = Authorization::PnC; // Plug & Charge // Control modes ControlMode scheduled = ControlMode::Scheduled; // Grid operator schedules ControlMode dynamic = ControlMode::Dynamic; // EV controls charging // Response codes ResponseCode ok = ResponseCode::OK; ResponseCode new_session = ResponseCode::OK_NewSessionEstablished; ResponseCode old_session = ResponseCode::OK_OldSessionJoined; ResponseCode failed = ResponseCode::FAILED; ResponseCode sequence_error = ResponseCode::FAILED_SequenceError; // Connector types DcConnector dc_connector = DcConnector::Extended; // CCS2 extended AcConnector ac_connector = AcConnector::ThreePhase; McsConnector mcs_connector = McsConnector::Mcs; // Display parameters from EV DisplayParameters display{ .present_soc = 45, // 45% current SoC .min_soc = 20, // 20% minimum SoC .target_soc = 80, // 80% target SoC .max_soc = 100, // 100% max SoC .remaining_time_to_target_soc = 1800, // 30 minutes .charging_complete = false, .battery_energy_capacity = RationalNumber{75, 3}, // 75 kWh .inlet_hot = false }; // Meter information MeterInfo meter{ .meter_id = "METER001", .charged_energy_reading_wh = 15000, // 15 kWh charged .bpt_discharged_energy_reading_wh = 0, .meter_timestamp = std::time(nullptr) }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.