diff --git a/drivers/windows/pandaJ2534DLL Test/TestHelpers.cpp b/drivers/windows/pandaJ2534DLL Test/TestHelpers.cpp index affea86..62096d1 100644 --- a/drivers/windows/pandaJ2534DLL Test/TestHelpers.cpp +++ b/drivers/windows/pandaJ2534DLL Test/TestHelpers.cpp @@ -44,7 +44,18 @@ std::vector panda_recv_loop(std::unique_ptr& } std::ostringstream stringStream; - stringStream << "j2534_recv_loop Broke at " << t.getTimePassed() << " ms size is " << ret_messages.size(); + + stringStream << "j2534_recv_loop Broke at " << t.getTimePassed() << " ms size is " << ret_messages.size() << std::endl; + + if (num_expected != ret_messages.size()) { + stringStream << "Incorrect number of messages received. Displaying the messages:" << std::endl; + for (auto msg : ret_messages) { + stringStream << " TS: " << msg.recv_time << "; Dat: "; + for (int i = 0; i < msg.len; i++) stringStream << std::hex << std::setw(2) << std::setfill('0') << int(msg.dat[i] & 0xFF) << " "; + stringStream << std::endl; + } + } + Logger::WriteMessage(stringStream.str().c_str()); Assert::AreEqual(num_expected, ret_messages.size(), _T("Received wrong number of messages.")); diff --git a/drivers/windows/pandaJ2534DLL Test/j2534_tests.cpp b/drivers/windows/pandaJ2534DLL Test/j2534_tests.cpp index 0568a4d..774b8ed 100644 --- a/drivers/windows/pandaJ2534DLL Test/j2534_tests.cpp +++ b/drivers/windows/pandaJ2534DLL Test/j2534_tests.cpp @@ -1322,6 +1322,177 @@ namespace pandaJ2534DLLTest j2534_recv_loop(chanid, 0); } + //Check MF tx will stop upon receiving a flow control ABORT. 29 bit. Good Filter. NoPadding. STD address. Large STmin, then abort, then send SF. + TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD__MF_FCAbort_SF) + { + auto chanid = J2534_open_and_connect("", ISO15765, CAN_29BIT_ID, 500000, 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 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + + auto panda_msg_recv = panda_recv_loop(p, 1); + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x30""AABBCC", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x02\x20", 3, 2, LINE_INFO());//Start a conversation. FC timeout is 32 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""DDEEFFG", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x22""GHHIIJJ", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x32\x0\x0", 3, 0, LINE_INFO());//Abort the conversation + + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + + auto j2534_msg_recv = j2534_recv_loop(chanid, 2); + 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 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + } + + //Check MF tx will stop upon receiving a flow control ABORT during valid blocksize. 29 bit. Good Filter. NoPadding. STD address. Large STmin, then mid tx abort, then send SF. + TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD__MF_FCMixTXAbort_SF) + { + auto chanid = J2534_open_and_connect("", ISO15765, CAN_29BIT_ID, 500000, 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 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + + auto panda_msg_recv = panda_recv_loop(p, 1); + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x30""AABBCC", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x06\x7F", 3, 1, LINE_INFO(), 200);//Start a conversation. FC timeout is 127 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""DDEEFFG", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x32\x0\x0", 3, 0, LINE_INFO());//Abort the conversation + panda_recv_loop(p, 0, 200); + + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + + auto j2534_msg_recv = j2534_recv_loop(chanid, 2); + 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 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + } + + //Check slow tx can be stalled past timeout with CF WAIT frames. 29 bit. Good Filter. NoPadding. STD address. MF tx that would timeout without WAIT frames. + TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD_MFWithWaitFrames) + { + auto chanid = J2534_open_and_connect("", ISO15765, CAN_29BIT_ID, 500000, 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()); + write_ioctl(chanid, ISO15765_WFT_MAX, 10, LINE_INFO()); + auto p = getPanda(500); + + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + + auto panda_msg_recv = panda_recv_loop(p, 1); + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x30""AABBCC", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x02\x40", 3, 2, LINE_INFO(), 3000);//Start a conversation. FC timeout is 250 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""DDEEFFG", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x22""GHHIIJJ", LINE_INFO()); + + checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x0\x0", 3, 4, LINE_INFO(), 3000);//Start a conversation. FC timeout is 250 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x23""KKLLMMN", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x24""NOOPPQQ", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[2], 0, 0x18DAEFF1, TRUE, FALSE, "\x25""RRSSTTU", LINE_INFO());//Some of these should fail to recv if there is an issue. + check_panda_can_msg(panda_msg_recv[3], 0, 0x18DAEFF1, TRUE, FALSE, "\x26""UVVWWXX", LINE_INFO()); + + auto j2534_msg_recv = j2534_recv_loop(chanid, 2); + 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 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + } + + //Check slow tx can be stalled past timeout with CF WAIT frames during normal TX. 29 bit. Good Filter. NoPadding. STD address. Stalling working MF tx. + TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD_MFWithMidTXWaitFrames) + { + auto chanid = J2534_open_and_connect("", ISO15765, CAN_29BIT_ID, 500000, 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()); + write_ioctl(chanid, ISO15765_WFT_MAX, 10, LINE_INFO()); + auto p = getPanda(500); + + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + + auto panda_msg_recv = panda_recv_loop(p, 1); + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x30""AABBCC", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x06\x64", 3, 2, LINE_INFO(), 120);//Start a conversation. STmin 100. FC timeout is 250 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""DDEEFFG", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x22""GHHIIJJ", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x0\x0", 3, 4, LINE_INFO(), 3000);//Start a conversation. FC timeout is 250 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x23""KKLLMMN", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x24""NOOPPQQ", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[2], 0, 0x18DAEFF1, TRUE, FALSE, "\x25""RRSSTTU", LINE_INFO());//Some of these should fail to recv if there is an issue. + check_panda_can_msg(panda_msg_recv[3], 0, 0x18DAEFF1, TRUE, FALSE, "\x26""UVVWWXX", LINE_INFO()); + + auto j2534_msg_recv = j2534_recv_loop(chanid, 2); + 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 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + } + + //Check that too many WAIT frames will abort the transfer. 29 bit. Good Filter. NoPadding. STD address. Too much stalling causes abort. + TEST_METHOD(J2534_ISO15765_SuccessTx_29b_Filter_NoPad_STD_MFTooManyWaitFrames) + { + auto chanid = J2534_open_and_connect("", ISO15765, CAN_29BIT_ID, 500000, 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()); + write_ioctl(chanid, ISO15765_WFT_MAX, 2, LINE_INFO()); + auto p = getPanda(500); + + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 48, 0, "\x18\xda\xef\xf1""AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXX", LINE_INFO()); + + auto panda_msg_recv = panda_recv_loop(p, 1); + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x10\x30""AABBCC", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x02\x64", 3, 2, LINE_INFO(), 120);//Start a conversation. STmin 100. FC timeout is 250 ms. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x21""DDEEFFG", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x22""GHHIIJJ", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x02\x64", 3, 2, LINE_INFO(), 120);//Resume the conversation. + check_panda_can_msg(panda_msg_recv[0], 0, 0x18DAEFF1, TRUE, FALSE, "\x23""KKLLMMN", LINE_INFO()); + check_panda_can_msg(panda_msg_recv[1], 0, 0x18DAEFF1, TRUE, FALSE, "\x24""NOOPPQQ", LINE_INFO()); + + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x31\x0\x0", 3, 0, LINE_INFO(), 100);//Delay the conversation. + Sleep(100); + + //Should not resume because the conversation has been delayed too long. + panda_msg_recv = checked_panda_send(p, 0x18DAF1EF, TRUE, "\x30\x0\x0", 3, 0, LINE_INFO(), 300); + + //Send a SF message to check the tubes are not clogged. + J2534_send_msg_checked(chanid, ISO15765, 0, CAN_29BIT_ID, 0, 4 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + + auto j2534_msg_recv = j2534_recv_loop(chanid, 2); + 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 + 4, 0, "\x18\xda\xef\xf1""SUP!", LINE_INFO()); + } + ///////////////////// Tests checking things actually send/receive. Ext 5 byte Addressing ///////////////////// //Check rx passes with filter. 29 bit. Good Filter. NoPadding. EXT address. Single Frame. diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection.cpp b/drivers/windows/pandaJ2534DLL/J2534Connection.cpp index a6bc5b3..358158b 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection.cpp +++ b/drivers/windows/pandaJ2534DLL/J2534Connection.cpp @@ -161,9 +161,8 @@ long J2534Connection::clearMsgFilters() { return STATUS_NOERROR; } -long J2534Connection::setBaud(unsigned long baud) { +void J2534Connection::setBaud(unsigned long baud) { this->BaudRate = baud; - return STATUS_NOERROR; } void J2534Connection::schedultMsgTx(std::shared_ptr msgout) { @@ -198,3 +197,61 @@ void J2534Connection::processMessage(const J2534Frame& msg) { addMsgToRxQueue(msg); } } + +void J2534Connection::processIOCTLSetConfig(unsigned long Parameter, unsigned long Value) { + switch (Parameter) { + case DATA_RATE: // 5-500000 + this->setBaud(Value); + case LOOPBACK: // 0 (OFF), 1 (ON) [0] + this->loopback = (Value != 0); + break; + case ISO15765_WFT_MAX: + break; + case NODE_ADDRESS: // J1850PWM Related (Not supported by panda). HDS requires these to 'work'. + case NETWORK_LINE: + case P1_MIN: // A bunch of stuff relating to ISO9141 and ISO14230 that the panda + case P1_MAX: // currently doesn't support. Don't let HDS know we can't use these. + case P2_MIN: + case P2_MAX: + case P3_MIN: + case P3_MAX: + case P4_MIN: + case P4_MAX: + case W0: + case W1: + case W2: + case W3: + case W4: + case W5: + case TIDLE: + case TINIL: + case TWUP: + case PARITY: + case T1_MAX: // SCI related options. The panda does not appear to support this + case T2_MAX: + case T3_MAX: + case T4_MAX: + case T5_MAX: + break; // Just smile and nod. + default: + printf("Got unknown SET code %X\n", Parameter); + } +} + +unsigned long J2534Connection::processIOCTLGetConfig(unsigned long Parameter) { + switch (Parameter) { + case DATA_RATE: + return this->getBaud(); + case LOOPBACK: + return this->loopback; + break; + case BIT_SAMPLE_POINT: + return 80; + case SYNC_JUMP_WIDTH: + return 15; + default: + // HDS rarely reads off values through ioctl GET_CONFIG, but it often + // just wants the call to pass without erroring, so just don't do anything. + printf("Got unknown code %X\n", Parameter); + } +} diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection.h b/drivers/windows/pandaJ2534DLL/J2534Connection.h index 25ca595..399c347 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection.h +++ b/drivers/windows/pandaJ2534DLL/J2534Connection.h @@ -47,7 +47,7 @@ public: long clearPeriodicMsgs(); long clearMsgFilters(); - virtual long setBaud(unsigned long baud); + virtual void setBaud(unsigned long baud); unsigned long getBaud() { return this->BaudRate; @@ -65,6 +65,10 @@ public: return this->port; } + virtual void processIOCTLSetConfig(unsigned long Parameter, unsigned long Value); + + virtual unsigned long processIOCTLGetConfig(unsigned long Parameter); + virtual void processMessage(const J2534Frame& msg); virtual unsigned long getMinMsgLen() { diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.cpp b/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.cpp index 05cf522..3426169 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.cpp +++ b/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.cpp @@ -28,14 +28,14 @@ std::shared_ptr J2534Connection_CAN::parseMessageTx(PASSTHRU_MSG& msg return std::dynamic_pointer_cast(std::make_shared(shared_from_this(), msg)); } -long J2534Connection_CAN::setBaud(unsigned long BaudRate) { +void J2534Connection_CAN::setBaud(unsigned long BaudRate) { if (auto panda_dev = this->getPandaDev()) { if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000) - return ERR_NOT_SUPPORTED; + throw ERR_NOT_SUPPORTED; panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, (uint16_t)(BaudRate / 100)); return J2534Connection::setBaud(BaudRate); } else { - return ERR_DEVICE_NOT_CONNECTED; + throw ERR_DEVICE_NOT_CONNECTED; } } diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.h b/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.h index 054084e..4dd950b 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.h +++ b/drivers/windows/pandaJ2534DLL/J2534Connection_CAN.h @@ -18,7 +18,7 @@ public: virtual std::shared_ptr parseMessageTx(PASSTHRU_MSG& pMsg); - virtual long setBaud(unsigned long baud); + virtual void setBaud(unsigned long baud); virtual unsigned long getMinMsgLen() { return 4; diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.cpp b/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.cpp index 109a2fe..2b9d97c 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.cpp +++ b/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.cpp @@ -9,7 +9,7 @@ J2534Connection_ISO15765::J2534Connection_ISO15765( unsigned long ProtocolID, unsigned long Flags, unsigned long BaudRate -) : J2534Connection(panda_dev, ProtocolID, Flags, BaudRate) { +) : J2534Connection(panda_dev, ProtocolID, Flags, BaudRate), wftMax(0) { this->port = 0; if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000) @@ -76,11 +76,10 @@ void J2534Connection_ISO15765::processMessage(const J2534Frame& msg) { break; } case FLOWCTRL_WAIT: - txConvo->flowControlWait(); + txConvo->flowControlWait(this->wftMax); break; case FLOWCTRL_ABORT: txConvo->flowControlAbort(); - this->rxConversations[fid] = nullptr; break; } break; @@ -170,15 +169,15 @@ void J2534Connection_ISO15765::processMessage(const J2534Frame& msg) { } } -long J2534Connection_ISO15765::setBaud(unsigned long BaudRate) { +void J2534Connection_ISO15765::setBaud(unsigned long BaudRate) { if (auto panda_dev = this->getPandaDev()) { if (BaudRate % 100 || BaudRate < 10000 || BaudRate > 5000000) - return ERR_NOT_SUPPORTED; + throw ERR_NOT_SUPPORTED; panda_dev->panda->set_can_speed_cbps(panda::PANDA_CAN1, (uint16_t)(BaudRate / 100)); return J2534Connection::setBaud(BaudRate); } else { - return ERR_DEVICE_NOT_CONNECTED; + throw ERR_DEVICE_NOT_CONNECTED; } } @@ -209,3 +208,22 @@ int J2534Connection_ISO15765::get_matching_in_fc_filter_id(const J2534Frame& msg } return -1; } + +void J2534Connection_ISO15765::processIOCTLSetConfig(unsigned long Parameter, unsigned long Value) { + switch (Parameter) { + case ISO15765_WFT_MAX: + this->wftMax = Value; + break; + default: + J2534Connection::processIOCTLSetConfig(Parameter, Value); + } +} + +unsigned long J2534Connection_ISO15765::processIOCTLGetConfig(unsigned long Parameter) { + switch (Parameter) { + case ISO15765_WFT_MAX: + return this->wftMax; + default: + return J2534Connection::processIOCTLGetConfig(Parameter); + } +} diff --git a/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.h b/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.h index 7b21443..ddbf2dc 100644 --- a/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.h +++ b/drivers/windows/pandaJ2534DLL/J2534Connection_ISO15765.h @@ -33,7 +33,11 @@ public: virtual void processMessage(const J2534Frame& msg); - virtual long setBaud(unsigned long baud); + virtual void setBaud(unsigned long baud); + + virtual void processIOCTLSetConfig(unsigned long Parameter, unsigned long Value); + + virtual unsigned long processIOCTLGetConfig(unsigned long Parameter); virtual unsigned long getMinMsgLen() { return 4; @@ -57,4 +61,5 @@ public: private: std::array, 10> rxConversations; + unsigned int wftMax; }; diff --git a/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.cpp b/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.cpp index 887cfe8..abcf3f6 100644 --- a/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.cpp +++ b/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.cpp @@ -11,7 +11,7 @@ MessageTx_ISO15765::MessageTx_ISO15765( PASSTHRU_MSG& to_send, std::shared_ptr filter ) : MessageTxTimeoutable(connection_in, to_send), filter(filter), frames_sent(0), -consumed_count(0), txInFlight(FALSE), sendAll(FALSE), block_size(0), numWaitFrames(0), didtimeout(FALSE) { +consumed_count(0), txInFlight(FALSE), sendAll(FALSE), block_size(0), numWaitFrames(0), didtimeout(FALSE), issuspended(FALSE){ CANid = ((uint8_t)fullmsg.Data[0]) << 24 | ((uint8_t)fullmsg.Data[1]) << 16 | ((uint8_t)fullmsg.Data[2]) << 8 | ((uint8_t)fullmsg.Data[3]); @@ -57,7 +57,7 @@ unsigned int MessageTx_ISO15765::addressLength() { } void MessageTx_ISO15765::execute() { - if (didtimeout) return; + if (didtimeout || issuspended) return; if (this->frames_sent >= this->framePayloads.size()) return; if (block_size == 0 && !sendAll && this->frames_sent > 0) return; if (block_size > 0 && !sendAll) block_size--; @@ -86,7 +86,7 @@ BOOL MessageTx_ISO15765::checkTxReceipt(J2534Frame frame) { ((this->fullmsg.TxFlags & CAN_29BIT_ID) == (frame.RxStatus & CAN_29BIT_ID))) { //Check receipt is expected txInFlight = FALSE; //Received the expected receipt. Allow another msg to be sent. - if(this->recvCount == 0 && this->framePayloads.size() > 1) + if (this->recvCount == 0 && this->framePayloads.size() > 1) scheduleTimeout(TIMEOUT_FC); if (frames_sent == framePayloads.size()) { //Check message done @@ -115,7 +115,7 @@ BOOL MessageTx_ISO15765::checkTxReceipt(J2534Frame frame) { //already been received (differentiating from first frame), the //message is not finished, and there is more than one frame in //the message. - if(block_size == 0 && recvCount != 0 && !sendAll && !this->isFinished() && this->framePayloads.size() > 1) + if (block_size == 0 && recvCount != 0 && !sendAll && !this->isFinished() && this->framePayloads.size() > 1) scheduleTimeout(TIMEOUT_CF); } return TRUE; @@ -151,19 +151,30 @@ void MessageTx_ISO15765::onTimeout() { } void MessageTx_ISO15765::flowControlContinue(uint8_t block_size, std::chrono::microseconds separation_time) { + this->issuspended = FALSE; this->block_size = block_size; this->delay = separation_time; this->sendAll = block_size == 0; this->recvCount++; } -void MessageTx_ISO15765::flowControlWait() { +void MessageTx_ISO15765::flowControlWait(unsigned long N_WFTmax) { + this->issuspended = TRUE; this->recvCount++; this->numWaitFrames++; this->sendAll = FALSE; - scheduleTimeout(TIMEOUT_FC); + this->block_size = block_size; + this->delay = std::chrono::microseconds(0); + //Docs are vague on if 0 means NO WAITS ALLOWED or NO LIMIT TO WAITS. + //It is less likely to cause issue if NO LIMIT is assumed. + if (N_WFTmax > 0 && this->numWaitFrames > N_WFTmax) { + this->onTimeout(); //Trigger self destruction of message. + } else { + scheduleTimeout(TIMEOUT_FC); + } } void MessageTx_ISO15765::flowControlAbort() { - this->recvCount++; + this->recvCount++; //Invalidate future timeout actions. + this->onTimeout(); //Trigger self destruction of message. } diff --git a/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.h b/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.h index 8db56b3..2844351 100644 --- a/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.h +++ b/drivers/windows/pandaJ2534DLL/MessageTx_ISO15765.h @@ -28,7 +28,7 @@ public: virtual void onTimeout(); void MessageTx_ISO15765::flowControlContinue(uint8_t block_size, std::chrono::microseconds separation_time); - void MessageTx_ISO15765::flowControlWait(); + void MessageTx_ISO15765::flowControlWait(unsigned long N_WFTmax); void MessageTx_ISO15765::flowControlAbort(); std::shared_ptr filter; @@ -44,4 +44,5 @@ public: BOOL sendAll; unsigned int numWaitFrames; BOOL didtimeout; + BOOL issuspended; }; diff --git a/drivers/windows/pandaJ2534DLL/pandaJ2534DLL.cpp b/drivers/windows/pandaJ2534DLL/pandaJ2534DLL.cpp index 4f389c4..2e706f5 100644 --- a/drivers/windows/pandaJ2534DLL/pandaJ2534DLL.cpp +++ b/drivers/windows/pandaJ2534DLL/pandaJ2534DLL.cpp @@ -374,23 +374,10 @@ PANDAJ2534DLL_API long PTAPI PassThruIoctl(unsigned long ChannelID, unsigned lon if (inconfig == NULL) return ret_code(ERR_NULL_PARAMETER); for (unsigned int i = 0; i < inconfig->NumOfParams; i++) { - switch (inconfig->ConfigPtr[i].Parameter) { - case DATA_RATE: - inconfig->ConfigPtr[i].Value = get_channel(ChannelID)->getBaud(); - break; - case LOOPBACK: - inconfig->ConfigPtr[i].Value = get_channel(ChannelID)->loopback; - break; - case BIT_SAMPLE_POINT: - inconfig->ConfigPtr[i].Value = 80; - break; - case SYNC_JUMP_WIDTH: - inconfig->ConfigPtr[i].Value = 15; - break; - default: - // HDS rarely reads off values through ioctl GET_CONFIG, but it often - // just wants the call to pass without erroring, so just don't do anything. - printf("Got unknown code %X\n", inconfig->ConfigPtr[i].Parameter); + try { + inconfig->ConfigPtr[i].Value = get_channel(ChannelID)->processIOCTLGetConfig(inconfig->ConfigPtr[i].Parameter); + } catch (int e) { + return ret_code(e); } } break; @@ -401,40 +388,10 @@ PANDAJ2534DLL_API long PTAPI PassThruIoctl(unsigned long ChannelID, unsigned lon if (inconfig == NULL) return ret_code(ERR_NULL_PARAMETER); for (unsigned int i = 0; i < inconfig->NumOfParams; i++) { - switch (inconfig->ConfigPtr[i].Parameter) { - case DATA_RATE: // 5-500000 - return ret_code(get_channel(ChannelID)->setBaud(inconfig->ConfigPtr[i].Value)); - case LOOPBACK: // 0 (OFF), 1 (ON) [0] - get_channel(ChannelID)->loopback = (inconfig->ConfigPtr[i].Value != 0); - break; - case NODE_ADDRESS: // J1850PWM Related (Not supported by panda). HDS requires these to 'work'. - case NETWORK_LINE: - case P1_MIN: // A bunch of stuff relating to ISO9141 and ISO14230 that the panda - case P1_MAX: // currently doesn't support. Don't let HDS know we can't use these. - case P2_MIN: - case P2_MAX: - case P3_MIN: - case P3_MAX: - case P4_MIN: - case P4_MAX: - case W0: - case W1: - case W2: - case W3: - case W4: - case W5: - case TIDLE: - case TINIL: - case TWUP: - case PARITY: - case T1_MAX: // SCI related options. The panda does not appear to support this - case T2_MAX: - case T3_MAX: - case T4_MAX: - case T5_MAX: - break; // Just smile and nod. - default: - printf("Got unknown SET code %X\n", inconfig->ConfigPtr[i].Parameter); + try { + get_channel(ChannelID)->processIOCTLSetConfig(inconfig->ConfigPtr[i].Parameter, inconfig->ConfigPtr[i].Value); + } catch (int e) { + return ret_code(e); } } break;