obu-firmware builds against the vanetza-idf C-ITS library, which until now came from the colleague's microbu-esp32c5 tree beside the repository and was not tracked here, so a clone of this repository could not build the firmware it ships. The library alone is now part of obu-firmware, as obu-firmware/external/vanetza-idf: their external/vanetza-idf at commit cf4b99f, unchanged (9775 files; see its PROVENANCE.md). CMake takes it from there by default; -DVANETZA_IDF_DIR still points the build elsewhere. The rest of the colleague's tree (their own VAM firmware, PKI tooling, station-link Python tools, the V2X2MAP bridge) stays out of this repository and gitignored; nothing is pushed to their repository. NOTES.md, docs/06, TODO.md and the pcap verifier's usage line point at the new location.
138 lines
4.4 KiB
C++
138 lines
4.4 KiB
C++
#include "cam_application.hpp"
|
|
#include <vanetza/btp/ports.hpp>
|
|
#include <vanetza/asn1/cam.hpp>
|
|
#include <vanetza/asn1/packet_visitor.hpp>
|
|
#include <vanetza/facilities/cam_functions.hpp>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
// This is a very simple CA application sending CAMs at a fixed rate.
|
|
|
|
using namespace vanetza;
|
|
using namespace vanetza::facilities;
|
|
using namespace std::chrono;
|
|
|
|
CamApplication::CamApplication(PositionProvider& positioning, Runtime& rt) :
|
|
positioning_(positioning), runtime_(rt), cam_interval_(seconds(1))
|
|
{
|
|
schedule_timer();
|
|
}
|
|
|
|
void CamApplication::set_interval(Clock::duration interval)
|
|
{
|
|
cam_interval_ = interval;
|
|
runtime_.cancel(this);
|
|
schedule_timer();
|
|
}
|
|
|
|
void CamApplication::set_station_id(std::uint32_t station_id)
|
|
{
|
|
station_id_ = station_id;
|
|
}
|
|
|
|
void CamApplication::print_generated_message(bool flag)
|
|
{
|
|
print_tx_msg_ = flag;
|
|
}
|
|
|
|
void CamApplication::print_received_message(bool flag)
|
|
{
|
|
print_rx_msg_ = flag;
|
|
}
|
|
|
|
CamApplication::PortType CamApplication::port()
|
|
{
|
|
return btp::ports::CAM;
|
|
}
|
|
|
|
void CamApplication::indicate(const DataIndication&, UpPacketPtr packet)
|
|
{
|
|
asn1::PacketVisitor<asn1::Cam> visitor;
|
|
std::shared_ptr<const asn1::Cam> cam = boost::apply_visitor(visitor, *packet);
|
|
|
|
std::cout << "CAM application received a packet with " << (cam ? "decodable" : "broken") << " content" << std::endl;
|
|
if (cam && print_rx_msg_) {
|
|
std::cout << "Received CAM contains\n";
|
|
print_indented(std::cout, *cam, " ", 1);
|
|
}
|
|
}
|
|
|
|
void CamApplication::schedule_timer()
|
|
{
|
|
runtime_.schedule(cam_interval_, std::bind(&CamApplication::on_timer, this, std::placeholders::_1), this);
|
|
}
|
|
|
|
void CamApplication::on_timer(Clock::time_point)
|
|
{
|
|
schedule_timer();
|
|
vanetza::asn1::Cam message;
|
|
|
|
ItsPduHeader_t& header = message->header;
|
|
header.protocolVersion = 2;
|
|
header.messageID = ItsPduHeader__messageID_cam;
|
|
header.stationID = station_id_;
|
|
|
|
const auto time_now = duration_cast<milliseconds>(runtime_.now().time_since_epoch());
|
|
uint16_t gen_delta_time = time_now.count();
|
|
|
|
CoopAwareness_t& cam = message->cam;
|
|
cam.generationDeltaTime = gen_delta_time * GenerationDeltaTime_oneMilliSec;
|
|
|
|
auto position = positioning_.position_fix();
|
|
if (!has_horizontal_position(position)) {
|
|
std::cerr << "Skip CAM generation without position fix" << std::endl;
|
|
return;
|
|
}
|
|
|
|
BasicContainer_t& basic = cam.camParameters.basicContainer;
|
|
basic.stationType = StationType_passengerCar;
|
|
copy(position, basic.referencePosition);
|
|
|
|
cam.camParameters.highFrequencyContainer.present = HighFrequencyContainer_PR_basicVehicleContainerHighFrequency;
|
|
|
|
BasicVehicleContainerHighFrequency& bvc = cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency;
|
|
bvc.heading.headingValue = 0;
|
|
bvc.heading.headingConfidence = HeadingConfidence_equalOrWithinOneDegree;
|
|
|
|
bvc.speed.speedValue = 0;
|
|
bvc.speed.speedConfidence = SpeedConfidence_equalOrWithinOneCentimeterPerSec;
|
|
|
|
bvc.driveDirection = DriveDirection_forward;
|
|
bvc.longitudinalAcceleration.longitudinalAccelerationValue = LongitudinalAccelerationValue_unavailable;
|
|
|
|
bvc.vehicleLength.vehicleLengthValue = VehicleLengthValue_unavailable;
|
|
bvc.vehicleLength.vehicleLengthConfidenceIndication = VehicleLengthConfidenceIndication_noTrailerPresent;
|
|
bvc.vehicleWidth = VehicleWidth_unavailable;
|
|
|
|
bvc.curvature.curvatureValue = 0;
|
|
bvc.curvature.curvatureConfidence = CurvatureConfidence_unavailable;
|
|
bvc.curvatureCalculationMode = CurvatureCalculationMode_yawRateUsed;
|
|
|
|
bvc.yawRate.yawRateValue = YawRateValue_unavailable;
|
|
|
|
std::string error;
|
|
if (!message.validate(error)) {
|
|
throw std::runtime_error("Invalid high frequency CAM: %s" + error);
|
|
}
|
|
|
|
if (print_tx_msg_) {
|
|
std::cout << "Generated CAM contains\n";
|
|
print_indented(std::cout, message, " ", 1);
|
|
}
|
|
|
|
DownPacketPtr packet { new DownPacket() };
|
|
packet->layer(OsiLayer::Application) = std::move(message);
|
|
|
|
DataRequest request;
|
|
request.its_aid = aid::CA;
|
|
request.transport_type = geonet::TransportType::SHB;
|
|
request.communication_profile = geonet::CommunicationProfile::ITS_G5;
|
|
|
|
auto confirm = Application::request(request, std::move(packet));
|
|
if (!confirm.accepted()) {
|
|
throw std::runtime_error("CAM application data request failed");
|
|
}
|
|
}
|