车载信息服务软件开发包使用指南(4)
4.2. CV2X
4.2.3. 传输数据
这个示例应用程序演示了如何使用C-V2X无线电管理器API来发送C-V2X数据。
- 为ICv2xRadio和ICv2x无线电管理器方法创建回调方法
static promise<ErrorCode> gCallbackPromise;
static shared_ptr<ICv2xTxFlow> gSpsFlow;
static array<char, G_BUF_LEN> gBuf;
// Resets the global callback promise
static inline void resetCallbackPromise(void) {
gCallbackPromise = promise<ErrorCode>();
}
// Callback method for ICv2xRadioManager->requestCv2xStatus()
static void cv2xStatusCallback(Cv2xStatus status, ErrorCode error) {
if (ErrorCode::SUCCESS == error) {
gCv2xStatus = status;
}
gCallbackPromise.set_value(error);
}
// Callback method for ICv2xRadio->createTxSpsFlow()
static void createSpsFlowCallback(shared_ptr<ICv2xTxFlow> txSpsFlow,
shared_ptr<ICv2xTxFlow> unusedFlow,
ErrorCode spsError,
ErrorCode unusedError) {
if (ErrorCode::SUCCESS == spsError) {
gSpsFlow = txSpsFlow;
}
gCallbackPromise.set_value(spsError);
}
注意:我们还可以使用Lambda函数,而不是定义全局作用域回调。
- 获取对ICv2x无线电管理器实例的句柄
// Get handle to Cv2xRadioManager
auto & cv2xFactory = Cv2xFactory::getInstance();
auto cv2xRadioManager = cv2xFactory.getCv2xRadioManager()
- 请求C-V2X状态
在我们尝试发送数据之前,我们希望验证C-V2X TX状态是否处于活动状态。
assert(Status::SUCCESS == cv2xRadioManager->requestCv2xStatus(cv2xStatusCallback));
assert(ErrorCode::SUCCESS == gCallbackPromise.get_future().get());
if (Cv2xStatusType::ACTIVE == gCv2xStatus.txStatus) {
cout << "C-V2X TX status is active" << endl;
}
else {
cerr << "C-V2X TX is inactive" << endl;
return EXIT_FAILURE;
}
- 去处理C-V2X收音机
auto cv2xRadio = cv2xRadioManager->getCv2xRadio(TrafficCategory::SAFETY_TYPE);
- 等待C-V2X收音机准备就绪
if (not cv2xRadio->isReady()) {
if (Status::SUCCESS == cv2xRadio->onReady().get()) {
cout << "C-V2X Radio is ready" << endl;
}
else {
cerr << "C-V2X Radio initialization failed." << endl;
return EXIT_FAILURE;
}
}
- 创建TX SPS流,并使用TX套接字发送数据
// Set SPS parameters
SpsFlowInfo spsInfo;
spsInfo.priority = Priority::PRIORITY_2;
spsInfo.periodicity = Periodicity::PERIODICITY_100MS;
spsInfo.nbytesReserved = G_BUF_LEN;
spsInfo.autoRetransEnabledValid = true;
spsInfo.autoRetransEnabled = true;
// Create new SPS flow
resetCallbackPromise();
assert(Status::SUCCESS == cv2xRadio->createTxSpsFlow(TrafficIpType::TRAFFIC_NON_IP,
SPS_SERVICE_ID,
spsInfo,
SPS_SRC_PORT_NUM,
false,
0,
createSpsFlowCallback));
assert(ErrorCode::SUCCESS == gCallbackPromise.get_future().get());
// Send message in a loop
for (uint16_t i = 0; i < NUM_TEST_ITERATIONS; ++i) {
fillBuffer();
sampleSpsTx();
usleep(100000u);
}
- 关闭TX SPS流
// Deregister SPS flow
resetCallbackPromise();
assert(Status::SUCCESS == cv2xRadio->closeTxFlow(gSpsFlow, closeFlowCallback));
assert(ErrorCode::SUCCESS == gCallbackPromise.get_future().get());
4.2.4. 设置验证负载
这个示例应用程序演示了如何使用C-V2X无线电管理器API来设置验证负载。
- 创建验证加载回调方法
static std::promise<telux::common::ErrorCode> gCallbackPromise;
// Callback method for Cv2xThrottleManager->setVerificationLoad()
static void cv2xsetVerificationLoadCallback(telux::common::ErrorCode error) {
std::cout << "error=" << static_cast<int>(error) << std::endl;
gCallbackPromise.set_value(error);
}
- 创建一个初始化状态回调方法
telux::common::ServiceStatus cv2xTmStatus =
telux::common::ServiceStatus::SERVICE_UNAVAILABLE;
std::condition_variable cv;
std::mutex mtx;
auto statusCb = [&](telux::common::ServiceStatus status) {
std::lock_guard<std::mutex> lock(mtx);
cv2xTmStatusUpdated = true;
cv2xTmStatus = status;
cv.notify_all();
};
- 获取对ICv2x策略管理器实例的句柄
// Get handle to Cv2xThrottleManager
auto & cv2xFactory = Cv2xFactory::getInstance();
auto cv2xThrottleManager = cv2xFactory.getCv2xThrottleManager(statusCb);
- 等待油门管理器完成初始化
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck, [&] { return cv2xTmStatusUpdated; });
if (telux::common::ServiceStatus::SERVICE_AVAILABLE !=cv2xTmStatus) {
std::cout << "Error: failed to initialize Cv2xThrottleManager." << std::endl;
return EXIT_FAILURE;
}
- 设置验证负载
cv2xThrottleManager->setVerificationLoad(load, cv2xsetVerificationLoadCallback);
if (telux::common::ErrorCode::SUCCESS != gCallbackPromise.get_future().get()) {
std::cout << "Error : failed to set verification load" << std::endl;
return EXIT_FAILURE;
} else {
std::cout << "set verification load success" << std::endl;
}
gCallbackPromise = std::promise<telux::common::ErrorCode>();