Programming/Etc
PCAN ISOTP 송신 시 루프백 이용해서 처리
_SYPark
2024. 3. 22. 11:46
728x90
PCAN ISOTP API Write 호출 시 비동기 처리가 되기 때문에 loop back을 이용해서 제대로 모든 데이터가 처리가 되었는지 확인할 수 있습니다.
void PCANISOTP::Write(const char *pData, int nSize)
{
cantp_msg message = {};
cantp_can_msgtype msgtype = PCANTP_CAN_MSGTYPE_EXTENDED | PCANTP_CAN_MSGTYPE_FD | PCANTP_CAN_MSGTYPE_BRS;
cantp_netaddrinfo isotp_nai = {};
isotp_nai.source_addr = N_SA;
isotp_nai.target_addr = N_TA_PHYS;
isotp_nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
isotp_nai.msgtype = PCANTP_ISOTP_MSGTYPE_DIAGNOSTIC;
isotp_nai.format = PCANTP_ISOTP_FORMAT_NORMAL;
status = CANTP_MsgDataAlloc_2016(&message, PCANTP_MSGTYPE_ISOTP);
if (CANTP_StatusIsOk_2016(status)) {
// initialize ISOTP message
status = CANTP_MsgDataInit_2016(&message, PCANTP_MAPPING_FLOW_CTRL_NONE, msgtype, nSize, pData, &isotp_nai);
if (CANTP_StatusIsOk_2016(status)) {
// write message
do {
status = CANTP_Write_2016(channel, &message);
if (CANTP_StatusIsOk_2016(status)) {
debug(QString::asprintf("Successfully queued ISOTP message: Length %i (sts=0x%04X).", nSize, (int)status));
}
else {
debug(QString::asprintf("Failed to write ISOTP message: Length %i (sts=0x%04X).", nSize, (int)status));
return;
}
} while ( !checkWriteState(message) );
emit emit_sendISOTPPacketData(enTx, message);
}
else {
debug(QString::asprintf("Failed to initialize ISOTP message: Length %i (sts=0x%04X).", nSize, (int)status));
return;
}
// release message
if (!CANTP_StatusIsOk_2016(status)) {
debug(QString::asprintf("Failed to deallocate message (sts=0x%04X).", status));
return;
}
}
else {
debug(QString::asprintf("Failed to allocate message (sts=0x%04X).", status));
return;
}
}
bool PCANISOTP::checkWriteState(cantp_msg& rx_msg)
{
cantp_msg loopback_msg;
bool bRes = false;
cantp_msgprogress progress;
cantp_status result;
memset(&loopback_msg, 0, sizeof(loopback_msg));
memset(&progress, 0, sizeof(progress));
HANDLE receive_event = NULL;
status = CANTP_GetValue_2016(channel, PCANTP_PARAMETER_RECEIVE_EVENT, &receive_event, sizeof(receive_event));
if (!CANTP_StatusIsOk_2016(status) || receive_event == NULL) {
debug(QString("Failed to make loop back receive event"));
return false;
}
do {
int nResult = WaitForSingleObject(receive_event, 10);
if (nResult == WAIT_OBJECT_0) {
status = CANTP_MsgDataAlloc_2016(&loopback_msg, PCANTP_MSGTYPE_NONE);
// Read transmission confirmation.
result = CANTP_Read_2016(channel, &loopback_msg, 0, PCANTP_MSGTYPE_ANY);
if (CANTP_StatusIsOk_2016(result, PCANTP_STATUS_OK, false)) {
if (((PCANTP_MSGTYPE_ISOTP & loopback_msg.type) == PCANTP_MSGTYPE_ISOTP) && (loopback_msg.msgdata.isotp->flags == PCANTP_MSGFLAG_LOOPBACK)
&& ((loopback_msg.msgdata.isotp->netaddrinfo.msgtype & PCANTP_ISOTP_MSGTYPE_FLAG_INDICATION_TX) == PCANTP_ISOTP_MSGTYPE_FLAG_INDICATION_TX)) {
// The message is being received, wait and show progress
do {
result = CANTP_GetMsgProgress_2016(channel, &loopback_msg, PCANTP_MSGDIRECTION_RX, &progress);
} while (progress.state == PCANTP_MSGPROGRESS_STATE_PROCESSING);
if ( CANTP_MsgEqual_2016(&rx_msg, &loopback_msg, true) ) {
qDebug() << "Equal";
bRes = true;
}
}
}
}
} while ( !bRes );
CANTP_MsgDataFree_2016(&loopback_msg);
return bRes;
}
checkWriteState 함수를 통해 loop back read를 진행 후 전송한 cantp_msg를 CANTP_MsgEqual_2016 호출로 비교해서 같다면 전송이 성공했다는 방식으로 처리를 할 수 있습니다.
728x90