J2534_WIN: ISO15765 Flow Control WAIT and ABORT support.

master
Jessy Diamond Exum 2017-10-16 02:59:26 -07:00
parent 4d02257243
commit 403aeb84eb
11 changed files with 309 additions and 74 deletions

View File

@ -44,7 +44,18 @@ std::vector<panda::PANDA_CAN_MSG> panda_recv_loop(std::unique_ptr<panda::Panda>&
}
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<unsigned long>(num_expected, ret_messages.size(), _T("Received wrong number of messages."));

View File

@ -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.

View File

@ -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<Action> 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);
}
}

View File

@ -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() {

View File

@ -28,14 +28,14 @@ std::shared_ptr<MessageTx> J2534Connection_CAN::parseMessageTx(PASSTHRU_MSG& msg
return std::dynamic_pointer_cast<MessageTx>(std::make_shared<MessageTx_CAN>(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;
}
}

View File

@ -18,7 +18,7 @@ public:
virtual std::shared_ptr<MessageTx> parseMessageTx(PASSTHRU_MSG& pMsg);
virtual long setBaud(unsigned long baud);
virtual void setBaud(unsigned long baud);
virtual unsigned long getMinMsgLen() {
return 4;

View File

@ -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);
}
}

View File

@ -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<std::shared_ptr<MessageRx>, 10> rxConversations;
unsigned int wftMax;
};

View File

@ -11,7 +11,7 @@ MessageTx_ISO15765::MessageTx_ISO15765(
PASSTHRU_MSG& to_send,
std::shared_ptr<J2534MessageFilter> 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.
}

View File

@ -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<J2534MessageFilter> filter;
@ -44,4 +44,5 @@ public:
BOOL sendAll;
unsigned int numWaitFrames;
BOOL didtimeout;
BOOL issuspended;
};

View File

@ -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;