Files
MicrOBU/obu-firmware/external/vanetza-idf/tools/socktap/cam_application.cpp
T

138 lines
4.4 KiB
C++
Raw Normal View History

#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");
}
}