Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
114
tools/EVerest-main/lib/everest/io/examples/CMakeLists.txt
Normal file
114
tools/EVerest-main/lib/everest/io/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,114 @@
|
||||
add_executable(mosquitto_client test_mosquitto_client.cpp)
|
||||
|
||||
target_link_libraries(mosquitto_client
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(mosquitto_client PUBLIC cxx_std_17)
|
||||
target_compile_options(mosquitto_client PRIVATE -fsanitize=address -g)
|
||||
target_link_options(mosquitto_client PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
|
||||
add_executable(test_serial test_serial.cpp)
|
||||
|
||||
target_link_libraries(test_serial
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_serial PUBLIC cxx_std_17)
|
||||
target_compile_options(test_serial PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_serial PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_socket_can test_socket_can.cpp)
|
||||
|
||||
target_link_libraries(test_socket_can
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_socket_can PUBLIC cxx_std_17)
|
||||
target_compile_options(test_socket_can PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_socket_can PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_tcp_client test_tcp_client.cpp)
|
||||
|
||||
target_link_libraries(test_tcp_client
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_tcp_client PUBLIC cxx_std_17)
|
||||
target_compile_options(test_tcp_client PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_tcp_client PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_tun_tap test_tun_tap.cpp)
|
||||
|
||||
target_link_libraries(test_tun_tap
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_tun_tap PUBLIC cxx_std_17)
|
||||
target_compile_options(test_tun_tap PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_tun_tap PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_udp_client test_udp_client.cpp)
|
||||
|
||||
target_link_libraries(test_udp_client
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_udp_client PUBLIC cxx_std_17)
|
||||
target_compile_options(test_udp_client PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_udp_client PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_udp_server test_udp_server.cpp)
|
||||
|
||||
target_link_libraries(test_udp_server
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_udp_server PUBLIC cxx_std_17)
|
||||
target_compile_options(test_udp_server PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_udp_server PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
###
|
||||
|
||||
add_executable(test_udp_unconnected_client test_udp_unconnected_client.cpp)
|
||||
|
||||
target_link_libraries(test_udp_unconnected_client
|
||||
PRIVATE
|
||||
everest::io
|
||||
)
|
||||
|
||||
target_compile_features(test_udp_unconnected_client PUBLIC cxx_std_17)
|
||||
target_compile_options(test_udp_unconnected_client PRIVATE -fsanitize=address -g)
|
||||
target_link_options(test_udp_unconnected_client PRIVATE -static-libasan -fsanitize=address)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
/**
|
||||
* @example test_mqtt_client.cpp Creates two MQTT clients that ping/pong messages to each other
|
||||
*/
|
||||
|
||||
#include "everest/io/mqtt/mosquitto_cpp.hpp"
|
||||
#include <cstdio>
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/mqtt/mqtt_client.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace everest::lib::io;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
constexpr auto HOST = "localhost";
|
||||
constexpr std::uint16_t PORT = 1883;
|
||||
|
||||
using payloadT = mqtt::mosquitto_cpp::message;
|
||||
using generic_client = typename mqtt::mosquitto_cpp;
|
||||
|
||||
// Creates the error handler for the clients
|
||||
mqtt::mqtt_client::cb_error make_error_cb(mqtt::mqtt_client& client) {
|
||||
return [&](int error, std::string const& msg) {
|
||||
std::cerr << "ERROR ( " << error << " ): " << msg << std::endl;
|
||||
if (error) {
|
||||
std::cout << "What to do?" << std::endl;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Creates the RX handler for the client
|
||||
mqtt::mqtt_client::subscribe_message_callback make_rx_callback(mqtt::mosquitto_cpp&, std::string tar) {
|
||||
return [&, tar](generic_client& client, payloadT const& data) {
|
||||
std::cout << &client << "\n"
|
||||
<< "topic: " << data.topic << "\n"
|
||||
<< "msg: " << data.payload << std::endl;
|
||||
payloadT dataset;
|
||||
auto c = std::stoi(data.payload) + 1;
|
||||
dataset.payload = std::to_string(c);
|
||||
dataset.topic = tar;
|
||||
client.publish(dataset);
|
||||
};
|
||||
}
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "mqtt_client ping/pong demonstration" << std::endl;
|
||||
bool server_connected = false;
|
||||
bool client_connected = false;
|
||||
|
||||
// Create first mqtt_client
|
||||
mqtt::mqtt_client client(2000);
|
||||
// Create and assign error handler
|
||||
client.set_error_handler(make_error_cb(client));
|
||||
// Create and assign rx handler
|
||||
client.set_callback_connect([&](auto& mqtt, auto, auto, auto const&) {
|
||||
client_connected = true;
|
||||
mqtt.subscribe("test/client/recv/#", make_rx_callback(mqtt, "test/server/recv"),
|
||||
mqtt::mosquitto_cpp::QoS::at_most_once);
|
||||
if (server_connected) {
|
||||
mqtt.publish("test/server/recv", "1");
|
||||
}
|
||||
});
|
||||
client.connect(HOST, PORT, 1000);
|
||||
|
||||
// Create second mqtt_client
|
||||
mqtt::mqtt_client server(2000);
|
||||
server.set_callback_connect([&](auto& mqtt, auto, auto, auto const&) {
|
||||
server_connected = true;
|
||||
mqtt.subscribe("test/server/recv/#", make_rx_callback(mqtt, "test/client/recv"),
|
||||
mqtt::mosquitto_cpp::QoS::at_most_once);
|
||||
if (client_connected) {
|
||||
mqtt.publish("test/client/recv", "1");
|
||||
}
|
||||
});
|
||||
server.set_error_handler(make_error_cb(server));
|
||||
|
||||
server.connect(HOST, PORT, 1000);
|
||||
|
||||
// Create event handler and register clients
|
||||
fd_event_handler ev_handler;
|
||||
ev_handler.register_event_handler(&client);
|
||||
ev_handler.register_event_handler(&server);
|
||||
|
||||
std::atomic_bool running = true;
|
||||
ev_handler.run(running);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
/**
|
||||
* @example test_mqtt_client.cpp Creates two MQTT clients that ping/pong messages to each other
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/mqtt/mqtt_client.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace everest::lib::io;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
constexpr auto HOST = "localhost";
|
||||
constexpr std::uint16_t PORT = 1883;
|
||||
|
||||
using payloadT = mqtt::mqtt_client::ClientPayloadT;
|
||||
using generic_client = typename mqtt::mqtt_client::interface;
|
||||
|
||||
// Creates the error handler for the clients
|
||||
mqtt::mqtt_client::cb_error make_error_cb(mqtt::mqtt_client& client) {
|
||||
return [&](int error, std::string const& msg) {
|
||||
std::cerr << "ERROR ( " << error << " ): " << msg << std::endl;
|
||||
if (error) {
|
||||
std::this_thread::sleep_for(1s);
|
||||
client.reset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Creates the RX handler for the client
|
||||
mqtt::mqtt_client::cb_rx make_rx_callback(mqtt::mqtt_client& client, std::string tar) {
|
||||
return [&, tar](payloadT const& data, generic_client& tx) {
|
||||
std::cout << &client << "\n"
|
||||
<< "topic: " << data.topic << "\n"
|
||||
<< "msg: " << data.message << std::endl;
|
||||
payloadT dataset;
|
||||
auto c = std::stoi(data.message) + 1;
|
||||
dataset.message = std::to_string(c);
|
||||
dataset.topic = tar;
|
||||
tx.tx(dataset);
|
||||
};
|
||||
}
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "mqtt_client ping/pong demonstration" << std::endl;
|
||||
|
||||
// Create first mqtt_client
|
||||
mqtt::mqtt_client client(HOST, PORT);
|
||||
// Create and assign error handler
|
||||
client.set_error_handler(make_error_cb(client));
|
||||
// Create and assign rx handler
|
||||
client.set_message_handler(make_rx_callback(client, "test/server/recv"));
|
||||
// Subscribe to topic
|
||||
client.subscribe("test/client/recv/#");
|
||||
|
||||
// Create second mqtt_client
|
||||
mqtt::mqtt_client server(HOST, PORT);
|
||||
server.set_error_handler(make_error_cb(server));
|
||||
server.set_message_handler(make_rx_callback(server, "test/client/recv"));
|
||||
server.subscribe("test/server/recv/#");
|
||||
|
||||
// Create event handler and register clients
|
||||
fd_event_handler ev_handler;
|
||||
ev_handler.register_event_handler(&client);
|
||||
ev_handler.register_event_handler(&server);
|
||||
|
||||
// Send first message to trigger ping/pong
|
||||
client.tx({"test/server/recv", "1"});
|
||||
// event loop
|
||||
while (true) {
|
||||
// Handles all the work and blocks if there is nothing to do.
|
||||
ev_handler.poll();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
64
tools/EVerest-main/lib/everest/io/examples/test_serial.cpp
Normal file
64
tools/EVerest-main/lib/everest/io/examples/test_serial.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
/**
|
||||
* @example test_serial.cpp Event based PTY handling for data and status updates.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/serial/event_pty.hpp>
|
||||
#include <everest/io/serial/serial.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace everest::lib::io;
|
||||
using namespace everest::lib::io::utilities;
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
int main() {
|
||||
std::cout << "This is serial test" << std::endl;
|
||||
|
||||
// Create PTY
|
||||
serial::event_pty handler;
|
||||
// Register callback for data events
|
||||
handler.set_data_handler([](auto const& pl, auto& dev) {
|
||||
auto msg = std::string(pl.begin(), pl.end());
|
||||
std::cout << " ##data update: " << msg << std::endl;
|
||||
|
||||
// generate reply and send it to the PTY
|
||||
static auto counter = 0;
|
||||
auto str = std::to_string(++counter) + "\n";
|
||||
auto ptr = reinterpret_cast<uint8_t*>(str.data());
|
||||
serial::event_pty::ClientPayloadT repl(ptr, ptr + str.size());
|
||||
dev.tx(repl);
|
||||
});
|
||||
|
||||
handler.set_status_handler([](auto const& status) {
|
||||
std::cout << " ##status update" << std::endl;
|
||||
// clang-format off
|
||||
std::cout << " - ixon -> " << status.ixon << "\n"
|
||||
<< " - ixoff -> " << status.ixoff << "\n"
|
||||
<< " - cstopb -> " << status.cstopb << "\n"
|
||||
<< " - baud -> " << status.cbaud
|
||||
<< std::endl;
|
||||
// clang-format on
|
||||
});
|
||||
|
||||
handler.set_error_handler([](int error, std::string const& err_msg) {
|
||||
std::cout << "ERRORHANDLER: " << err_msg << "(" << error << ")" << std::endl;
|
||||
});
|
||||
|
||||
// register the client with the event handler
|
||||
fd_event_handler ev_handler;
|
||||
ev_handler.register_event_handler(&handler);
|
||||
|
||||
while (true) {
|
||||
ev_handler.poll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <everest/io/can/socket_can.hpp>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io;
|
||||
using namespace std::chrono_literals;
|
||||
using generic_socket_can = typename can::socket_can::interface;
|
||||
|
||||
const std::string current_date_time() {
|
||||
time_t now = time(0);
|
||||
struct tm tstruct;
|
||||
char buf[80];
|
||||
tstruct = *localtime(&now);
|
||||
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::atomic_bool on_error{false};
|
||||
|
||||
void rx(can::can_dataset const& data, generic_socket_can& dev) {
|
||||
auto can_id = data.get_can_id();
|
||||
auto& payload = data.payload;
|
||||
|
||||
std::cout << "[ " << std::hex << can_id << " ] -> ";
|
||||
for (auto elem : payload) {
|
||||
std::cout << std::setw(2) << std::setfill('0') << (uint)elem << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
can::can_dataset msg;
|
||||
msg.set_can_id(002);
|
||||
msg.payload = {01, 02, 03, 04};
|
||||
dev.tx(msg);
|
||||
}
|
||||
|
||||
void error_fn(int err, std::string const& message, std::ostream& logger) {
|
||||
if (err == 0) {
|
||||
std::cerr << "ERROR: ( " << err << " ): " << message << std::endl;
|
||||
on_error.store(false);
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << "ERROR: ( " << err << " ): " << message << std::endl;
|
||||
|
||||
on_error.store(true);
|
||||
std::cerr << ss.str() << std::endl;
|
||||
logger << current_date_time() << " " << ss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::ofstream logfile("logfile.txt", std::ofstream::out);
|
||||
std::cout << "hello socket_can test" << std::endl;
|
||||
can::socket_can can_dev("can0");
|
||||
can_dev.set_rx_handler(&rx);
|
||||
can_dev.set_error_handler([&](auto err, auto msg) {
|
||||
error_fn(err, msg, logfile);
|
||||
if (err != 0) {
|
||||
can_dev.reset();
|
||||
on_error.store(can_dev.on_error());
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
});
|
||||
while (true) {
|
||||
can_dev.sync();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
110
tools/EVerest-main/lib/everest/io/examples/test_tcp_client.cpp
Normal file
110
tools/EVerest-main/lib/everest/io/examples/test_tcp_client.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/tcp/tcp_client.hpp>
|
||||
#include <everest/io/tcp/tcp_socket.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io::tcp;
|
||||
using namespace everest::lib::io::utilities;
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using payload_type = everest::lib::io::event::fd_event_client<tcp_socket>::payload;
|
||||
using generic_tcp = typename tcp_client::interface;
|
||||
|
||||
auto to_string_data(const payload_type& d) {
|
||||
return std::string(d.begin(), d.end());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, payload_type const& p) {
|
||||
os << "[TCP ( " << p.size() << " )]: " << to_string_data(p) << " ";
|
||||
return os;
|
||||
}
|
||||
|
||||
void rx_handler(payload_type const& payload, generic_tcp& client) {
|
||||
std::cout << "MSG: " << payload << std::endl;
|
||||
client.tx(payload);
|
||||
}
|
||||
|
||||
payload_type make_message(int val) {
|
||||
std::stringstream ss;
|
||||
ss << "message #" << std::to_string(val) << std::flush;
|
||||
auto tmp = ss.str();
|
||||
return {tmp.begin(), tmp.end()};
|
||||
}
|
||||
|
||||
tcp_client::cb_error make_error_cb(tcp_client& client) {
|
||||
return [&](int error, std::string const& msg) {
|
||||
std::cerr << "ERROR ( " << error << " ): " << msg << std::endl;
|
||||
if (error) {
|
||||
client.reset();
|
||||
} else {
|
||||
client.tx(make_message(1));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tcp_client::cb_rx make_rx_callback(tcp_client& client) {
|
||||
return [&](payload_type const& payload, generic_tcp& repl) { rx_handler(payload, repl); };
|
||||
}
|
||||
|
||||
bool parse_args(int argc, char* argv[], std::string& remote, uint16_t& port) {
|
||||
if (argc != 3) {
|
||||
std::cout << "\nUSAGE: test_tcp_client {remote} {port}" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
remote = argv[1];
|
||||
std::string port_str = argv[2];
|
||||
|
||||
port = 0;
|
||||
|
||||
try {
|
||||
auto tmp = std::stoul(port_str);
|
||||
if (tmp > std::numeric_limits<uint16_t>::max()) {
|
||||
throw "";
|
||||
}
|
||||
port = tmp;
|
||||
} catch (...) {
|
||||
std::cout << "\nERROR '" << port_str << "' is not a valid port" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::cout << "tcp echo test client" << std::endl;
|
||||
uint16_t port;
|
||||
std::string remote;
|
||||
|
||||
if (not parse_args(argc, argv, remote, port)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Connecting to -> " << remote << ":" << port << std::endl;
|
||||
tcp_client client(remote, port, 1000);
|
||||
timer_fd timer;
|
||||
timer.set_timeout_ms(100);
|
||||
|
||||
client.set_error_handler(make_error_cb(client));
|
||||
client.set_rx_handler(make_rx_callback(client));
|
||||
|
||||
std::cout << "TCP socket ok? -> " << not client.on_error() << std::endl;
|
||||
|
||||
fd_event_handler ev_handler;
|
||||
|
||||
ev_handler.register_event_handler(&timer, [&client](auto const&) {
|
||||
std::cout << "timer" << std::endl;
|
||||
// client.tx(make_message(12));
|
||||
});
|
||||
|
||||
ev_handler.register_event_handler(&client);
|
||||
std::atomic_bool running = true;
|
||||
ev_handler.run(running);
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
tools/EVerest-main/lib/everest/io/examples/test_tun_tap.cpp
Normal file
71
tools/EVerest-main/lib/everest/io/examples/test_tun_tap.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <everest/io/tun_tap/tap_client.hpp>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io;
|
||||
using namespace std::chrono_literals;
|
||||
using generic_tun_tap = typename tun_tap::tap_client::interface;
|
||||
|
||||
const std::string current_date_time() {
|
||||
time_t now = time(0);
|
||||
struct tm tstruct;
|
||||
char buf[80];
|
||||
tstruct = *localtime(&now);
|
||||
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::atomic_bool on_error{false};
|
||||
|
||||
void rx(std::vector<uint8_t> const& data, generic_tun_tap& dev) {
|
||||
std::cout << "[ tap ] -> ";
|
||||
for (auto elem : data) {
|
||||
std::cout << std::setw(2) << std::setfill('0') << (uint)elem << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void error_fn(int err, std::string const& message, std::ostream& logger) {
|
||||
if (err == 0) {
|
||||
std::cerr << "ERROR: ( " << err << " ): " << message << std::endl;
|
||||
on_error.store(false);
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << "ERROR: ( " << err << " ): " << message << std::endl;
|
||||
|
||||
on_error.store(true);
|
||||
std::cerr << ss.str() << std::endl;
|
||||
logger << current_date_time() << " " << ss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::ofstream logfile("logfile.txt", std::ofstream::out);
|
||||
std::cout << "hello socket_can test" << std::endl;
|
||||
tun_tap::tap_client tap("test_tap", "172.1.1.1", "255.255.255.0", 1518);
|
||||
tap.set_rx_handler(&rx);
|
||||
tap.set_error_handler([&](auto err, auto msg) {
|
||||
error_fn(err, msg, logfile);
|
||||
if (err != 0) {
|
||||
tap.reset();
|
||||
on_error.store(tap.on_error());
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
});
|
||||
while (true) {
|
||||
tap.sync();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
124
tools/EVerest-main/lib/everest/io/examples/test_udp_client.cpp
Normal file
124
tools/EVerest-main/lib/everest/io/examples/test_udp_client.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/udp/udp_client.hpp>
|
||||
#include <everest/io/udp/udp_payload.hpp>
|
||||
#include <everest/io/udp/udp_socket.hpp>
|
||||
#include <everest/io/utilities/stop_watch.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io::udp;
|
||||
using namespace everest::lib::io::utilities;
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
udp_payload current_message;
|
||||
stop_watch message_timer;
|
||||
using generic_udp = typename udp_client::interface;
|
||||
|
||||
auto to_string_data(const udp_payload& d) {
|
||||
return std::string(d.buffer.begin(), d.buffer.end());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, udp_payload const& p) {
|
||||
os << "[UDP ( " << p.size() << " )]: " << to_string_data(p) << " ";
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, stop_watch const& sw) {
|
||||
os << sw.lap().count() << " us";
|
||||
return os;
|
||||
}
|
||||
|
||||
void rx_handler(udp_payload const& payload, generic_udp&) {
|
||||
if (payload == current_message) {
|
||||
std::cout << "REPLY: " << payload << message_timer << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
udp_payload make_message(int val) {
|
||||
std::stringstream ss;
|
||||
ss << "message #" << std::to_string(val) << std::flush;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
udp_client::cb_error make_error_cb(udp_client& client) {
|
||||
return [&](int error, std::string const& msg) {
|
||||
std::cerr << "ERROR ( " << error << " ): " << msg << std::endl;
|
||||
if (error) {
|
||||
std::this_thread::sleep_for(1s);
|
||||
client.reset();
|
||||
client.tx(make_message(-1));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
udp_client::cb_rx make_rx_callback(udp_client& client) {
|
||||
return [&](udp_payload const& payload, generic_udp& repl) { rx_handler(payload, repl); };
|
||||
}
|
||||
|
||||
fd_event_handler::event_handler_type make_timer_cb(udp_client& client) {
|
||||
return [&](fd_event_handler::event_list const& events) {
|
||||
static int counter = 0;
|
||||
current_message = make_message(++counter);
|
||||
message_timer.reset();
|
||||
client.tx(current_message);
|
||||
};
|
||||
}
|
||||
|
||||
bool parse_args(int argc, char* argv[], std::string& remote, uint16_t& port) {
|
||||
if (argc != 3) {
|
||||
std::cout << "\nUSAGE: test_udp_client {remote} {port}" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
remote = argv[1];
|
||||
std::string port_str = argv[2];
|
||||
|
||||
port = 0;
|
||||
|
||||
try {
|
||||
auto tmp = std::stoul(port_str);
|
||||
if (tmp > std::numeric_limits<uint16_t>::max()) {
|
||||
throw "";
|
||||
}
|
||||
port = tmp;
|
||||
} catch (...) {
|
||||
std::cout << "\nERROR '" << port_str << "' is not a valid port" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::cout << "udp echo test client" << std::endl;
|
||||
uint16_t port;
|
||||
std::string remote;
|
||||
|
||||
if (not parse_args(argc, argv, remote, port)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Connecting to -> " << remote << ":" << port << std::endl;
|
||||
udp_client client(remote, port, 1000);
|
||||
client.set_error_handler(make_error_cb(client));
|
||||
client.set_rx_handler(make_rx_callback(client));
|
||||
|
||||
std::cout << "UDP socket ok? -> " << not client.on_error() << std::endl;
|
||||
|
||||
fd_event_handler ev_handler;
|
||||
timer_fd msg_timer;
|
||||
msg_timer.set_timeout(100ms);
|
||||
|
||||
ev_handler.register_event_handler(client.get_poll_fd(), [&](auto&) { client.sync(); }, {poll_events::read});
|
||||
ev_handler.register_event_handler(&msg_timer, make_timer_cb(client));
|
||||
|
||||
while (true) {
|
||||
ev_handler.poll();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
#include <everest/io/udp/udp_socket.hpp>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
using namespace everest::lib::io::udp;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
auto to_string_data(const udp_payload& d) {
|
||||
return std::string(d.buffer.begin(), d.buffer.end());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, udp_payload const& p) {
|
||||
os << "[UDP ( " << p.size() << " )]: " << to_string_data(p) << " ";
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "udp server" << std::endl;
|
||||
udp_client_socket socket;
|
||||
|
||||
socket.open_as_server(7766);
|
||||
|
||||
std::cout << "UDP socket open? -> " << socket.is_open() << std::endl;
|
||||
|
||||
while (socket.is_open()) {
|
||||
udp_payload payload;
|
||||
auto source = socket.rx(payload);
|
||||
|
||||
if (source) {
|
||||
std::cout << payload << std::endl;
|
||||
socket.tx(payload);
|
||||
} else {
|
||||
std::cout << "no value" << std::endl;
|
||||
}
|
||||
std::this_thread::sleep_for(500ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
//
|
||||
// Example: how to use udp_unconnected_client (an unconnected UDP datagram
|
||||
// client, IPv4 or IPv6 auto-selected from the target). Sends a text message
|
||||
// once per second to <dest>:<port> and prints any datagram received back,
|
||||
// together with its source endpoint.
|
||||
//
|
||||
// test_udp_unconnected_client <dest> <port> [iface]
|
||||
//
|
||||
// <dest> may be an IPv4 address, an IPv6 address, or a hostname. For IPv6
|
||||
// link-local / multicast destinations pass the optional <iface> (used as the
|
||||
// scope id and as a best-effort SO_BINDTODEVICE hint).
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/udp/endpoint.hpp>
|
||||
#include <everest/io/udp/udp_payload.hpp>
|
||||
#include <everest/io/udp/udp_unconnected_client.hpp>
|
||||
|
||||
using namespace everest::lib::io::udp;
|
||||
using namespace everest::lib::io::event;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using generic_udp = typename udp_unconnected_client::interface;
|
||||
|
||||
namespace {
|
||||
|
||||
std::string to_text(udp_payload const& payload) {
|
||||
return std::string(payload.buffer.begin(), payload.buffer.end());
|
||||
}
|
||||
|
||||
bool parse_args(int argc, char* argv[], std::string& dest, uint16_t& port, std::string& iface) {
|
||||
if (argc != 3 && argc != 4) {
|
||||
std::cout << "USAGE: test_udp_unconnected_client <dest> <port> [iface]\n";
|
||||
return false;
|
||||
}
|
||||
dest = argv[1];
|
||||
try {
|
||||
auto tmp = std::stoul(argv[2]);
|
||||
if (tmp > std::numeric_limits<uint16_t>::max()) {
|
||||
throw std::out_of_range("port");
|
||||
}
|
||||
port = static_cast<uint16_t>(tmp);
|
||||
} catch (...) {
|
||||
std::cout << "ERROR: '" << argv[2] << "' is not a valid port\n";
|
||||
return false;
|
||||
}
|
||||
iface = argc == 4 ? argv[3] : "";
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string dest;
|
||||
std::string iface;
|
||||
uint16_t port = 0;
|
||||
if (not parse_args(argc, argv, dest, port, iface)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
endpoint target;
|
||||
try {
|
||||
target = endpoint(dest, port, iface);
|
||||
} catch (std::exception const& e) {
|
||||
std::cerr << "ERROR: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
udp_unconnected_client client(target, iface);
|
||||
|
||||
client.set_error_handler([](int err, std::string const& msg) {
|
||||
if (err) {
|
||||
std::cerr << "ERROR (" << err << "): " << msg << "\n";
|
||||
}
|
||||
});
|
||||
client.set_rx_handler([&](udp_payload const& payload, generic_udp&) {
|
||||
std::cout << "RX (" << payload.size() << "): " << to_text(payload);
|
||||
if (const auto src = client.get_raw_handler()->last_source()) {
|
||||
std::cout << " from [" << src->addr_str() << "]:" << src->port();
|
||||
}
|
||||
std::cout << "\n";
|
||||
});
|
||||
|
||||
fd_event_handler ev;
|
||||
ev.register_event_handler(client.get_poll_fd(), [&](auto&) { client.sync(); }, {poll_events::read});
|
||||
|
||||
timer_fd ticker;
|
||||
ticker.set_timeout(1s);
|
||||
int counter = 0;
|
||||
fd_event_handler::event_handler_type on_tick = [&](fd_event_handler::event_list const&) {
|
||||
ticker.set_timeout(1s); // re-arm
|
||||
std::ostringstream msg;
|
||||
msg << "ping #" << ++counter;
|
||||
udp_payload payload;
|
||||
payload.set_message(msg.str());
|
||||
std::cout << "TX: " << msg.str() << " -> [" << target.addr_str() << "]:" << target.port() << "\n";
|
||||
client.tx(payload);
|
||||
};
|
||||
ev.register_event_handler(&ticker, on_tick);
|
||||
|
||||
std::cout << "udp unconnected client: sending to [" << target.addr_str() << "]:" << target.port()
|
||||
<< (iface.empty() ? "" : (" via " + iface)) << " every 1s\n";
|
||||
while (true) {
|
||||
ev.poll();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user