#include "test_channel.hpp" #if CONFIG_MICROBU_TEST_CHANNEL #include namespace microbu { link::Bytes test_channel_execute(Station& station, const link::Bytes& request) { using link::Code; Code result = Code::malformed; std::deque records; link::Bytes extra; if (!request.empty()) { link::Reader r(request, 1); switch (request[0]) { case 0x01: { // MIRROR mode const auto mode = r.u8(); if (r.done() && mode <= 2) { station.test_mirror(static_cast(mode)); result = Code::accepted; } break; } case 0x02: { // INJECT source destination gnpdu vanetza::MacAddress source, destination; r.bytes(source.octets.data(), 6); r.bytes(destination.octets.data(), 6); auto gnpdu = r.rest(); if (r.ok() && !gnpdu.empty()) result = station.test_inject(source, destination, std::move(gnpdu)); break; } case 0x03: { // GN_REQUEST traffic class payload const auto tc = r.u8(); auto payload = r.rest(); if (r.ok() && !payload.empty()) result = station.test_gn_request(tc, std::move(payload)); break; } case 0x04: { // DRAIN bool overflow = false; records = station.test_drain(overflow, 1536 - 2); result = overflow ? Code::resource_limit : Code::accepted; break; } case 0x05: // RESET station.test_reset(); result = Code::accepted; break; case 0x06: { // RADIO_BURST [channel u16 LE][power_quarter_db u8][mcs u8][count u16 LE][interval_ms u16 LE][payload_len u16 LE] const auto channel = r.u16(); const auto power_quarter_db = r.u8(); const auto mcs = r.u8(); const auto count = r.u16(); const auto interval_ms = r.u16(); const auto payload_len = r.u16(); if (r.done()) { const double power_dbm = power_quarter_db / 4.0; result = station.test_radio_burst(channel, power_dbm, mcs, count, interval_ms, payload_len); } break; } case 0x07: { // CCA_SAMPLE [duration_ms u16 LE] -- CCA polling feasibility probe const auto duration_ms = r.u16(); if (r.done()) result = station.test_cca_sample(duration_ms, extra); break; } default: result = Code::unknown_opcode; } } link::Writer w; w.u8(static_cast(result)); w.u8(static_cast(std::min(records.size(), 255))); for (const auto& record : records) { w.u8(record.kind); w.u16(static_cast(record.bytes.size())); w.bytes(record.bytes); } w.bytes(extra); return w.out; } } // namespace microbu #endif // CONFIG_MICROBU_TEST_CHANNEL