J2534_WIN: Fixed queuing a multiframe message followed by another msg.

master
Jessy Diamond Exum 2017-10-10 06:04:42 -07:00
parent 9530172d5b
commit 427e6edfa2
6 changed files with 54 additions and 8 deletions

View File

@ -19,7 +19,7 @@ std::vector<panda::PANDA_CAN_MSG> panda_recv_loop(std::unique_ptr<panda::Panda>&
Timer t = Timer();
while (t.getTimePassed() < timeout_ms) {
Sleep(100);
Sleep(10);
std::vector<panda::PANDA_CAN_MSG>msg_recv = p->can_recv();
if (msg_recv.size() > 0) {
ret_messages.insert(std::end(ret_messages), std::begin(msg_recv), std::end(msg_recv));

View File

@ -673,6 +673,37 @@ namespace pandaJ2534DLLTest
check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x05""HELLO", LINE_INFO());
}
//Check tx passes with filter multiple times. 29 bit. Good Filter. NoPadding. STD address. Multiple Single Frames.
TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD_MultipleMFSF)
{
unsigned long chanid;
Assert::AreEqual<long>(STATUS_NOERROR, open_dev(""), _T("Failed to open device."), LINE_INFO());
Assert::AreEqual<long>(STATUS_NOERROR, PassThruConnect(devid, ISO15765, CAN_29BIT_ID, 500000, &chanid), _T("Failed to open channel."), LINE_INFO());
J2534_set_flowctrl_filter(chanid, CAN_29BIT_ID, 4, "\xff\xff\xff\xff", "\x18\xda\xf1\xef", "\x18\xda\xef\xf1", LINE_INFO());
write_ioctl(chanid, LOOPBACK, TRUE, LINE_INFO());
auto p = getPanda(500);
J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 23, 0, "\x18\xda\xef\xf1""Long data because I can", LINE_INFO());
J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 9, 0, "\x18\xda\xef\xf1""HELLO", LINE_INFO());
auto panda_msg_recv = panda_recv_loop(p, 1);
check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x17""Long d", LINE_INFO());
panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x00\x00", 3, 4, LINE_INFO());
check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""ata bec", LINE_INFO());
check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x22""ause I ", LINE_INFO());
check_panda_can_msg(panda_msg_recv[2], 0, 0x18DAEFF1, TRUE, FALSE, "\x23""can", LINE_INFO());
check_panda_can_msg(panda_msg_recv[3], 0, 0x18DAEFF1, TRUE, FALSE, "\x05""HELLO", LINE_INFO());
auto j2534_msg_recv = j2534_recv_loop(chanid, 4);
check_J2534_can_msg(j2534_msg_recv[0], ISO15765, CAN_29BIT_ID | TX_INDICATION, 0, 4, 0, "\x18\xda\xef\xf1", LINE_INFO());
check_J2534_can_msg(j2534_msg_recv[1], ISO15765, CAN_29BIT_ID | TX_MSG_TYPE, 0, 4 + 23, 0, "\x18\xda\xef\xf1""Long data because I can", LINE_INFO());
check_J2534_can_msg(j2534_msg_recv[2], ISO15765, CAN_29BIT_ID | TX_INDICATION, 0, 4, 0, "\x18\xda\xef\xf1", LINE_INFO());
check_J2534_can_msg(j2534_msg_recv[3], ISO15765, CAN_29BIT_ID | TX_MSG_TYPE, 0, 4 + 5, 0, "\x18\xda\xef\xf1""HELLO", LINE_INFO());
//panda_msg_recv = panda_recv_loop(p, 1);
}
///////////////////// Tests checking things break or recover during send/receive /////////////////////

View File

@ -119,7 +119,7 @@ void J2534Connection::schedultMsgTx(std::shared_ptr<MessageTx> msgout) {
void J2534Connection::rescheduleExistingTxMsgs() {
if (auto panda_ps = this->panda_dev.lock()) {
synchronized(staged_writes_lock) {
panda_ps->registerConnectionTx(shared_from_this());
panda_ps->unstallConnectionTx(shared_from_this());
}
}
}

View File

@ -68,7 +68,7 @@ void J2534Connection_ISO15765::processMessage(const J2534Frame& msg) {
uint8_t block_size = msg.Data[addrlen + 1];
uint8_t st_min = msg.Data[addrlen + 2];
auto txConvo = std::static_pointer_cast<MessageTx_ISO15765>(this->txbuff.back());
auto txConvo = std::static_pointer_cast<MessageTx_ISO15765>(this->txbuff.front());
switch (flow_status) {
case FLOWCTRL_CONTINUE: {
if (st_min > 0xF9) break;

View File

@ -112,19 +112,21 @@ DWORD PandaJ2534Device::can_recv_thread() {
this->ConnTxSet.erase(conn);
} else {
//Add the next scheduled tx from this conn
auto fcwrite = std::make_unique<SCHEDULED_TX_MSG>(conn->txbuff.back());
auto fcwrite = std::make_unique<SCHEDULED_TX_MSG>(conn->txbuff.front());
this->insertMultiPartTxInQueue(std::move(fcwrite));
SetEvent(flow_control_wakeup_event);
SetEvent(this->flow_control_wakeup_event);
}
} else {
if (msgtx->txReady()) { //Not finished, ready to send next frame.
tx_schedule->refreshExpiration();
insertMultiPartTxInQueue(std::move(tx_schedule));
this->insertMultiPartTxInQueue(std::move(tx_schedule));
SetEvent(this->flow_control_wakeup_event);
} else {
//Not finished, but next frame not ready (maybe waiting for flow control).
//Do not schedule more messages from this connection.
this->ConnTxSet.erase(conn);
//this->ConnTxSet.erase(conn);
//Removing this means new messages queued can kickstart the queue and overstep the current message.
}
}
}
@ -203,7 +205,18 @@ void PandaJ2534Device::registerConnectionTx(std::shared_ptr<J2534Connection> con
auto ret = this->ConnTxSet.insert(conn);
if (ret.second == FALSE) return; //Conn already exists.
auto fcwrite = std::make_unique<SCHEDULED_TX_MSG>(conn->txbuff.back());
auto fcwrite = std::make_unique<SCHEDULED_TX_MSG>(conn->txbuff.front());
this->insertMultiPartTxInQueue(std::move(fcwrite));
}
SetEvent(flow_control_wakeup_event);
}
void PandaJ2534Device::unstallConnectionTx(std::shared_ptr<J2534Connection> conn) {
synchronized(ConnTxMutex) {
auto ret = this->ConnTxSet.insert(conn);
if (ret.second == TRUE) return; //Conn already exists.
auto fcwrite = std::make_unique<SCHEDULED_TX_MSG>(conn->txbuff.front());
this->insertMultiPartTxInQueue(std::move(fcwrite));
}
SetEvent(flow_control_wakeup_event);

View File

@ -41,6 +41,8 @@ public:
void registerConnectionTx(std::shared_ptr<J2534Connection> conn);
void unstallConnectionTx(std::shared_ptr<J2534Connection> conn);
private:
HANDLE thread_kill_event;