diff --git a/isobus/include/isobus/isobus/can_control_function.hpp b/isobus/include/isobus/isobus/can_control_function.hpp index 5e5e45a6..2bb973f5 100644 --- a/isobus/include/isobus/isobus/can_control_function.hpp +++ b/isobus/include/isobus/isobus/can_control_function.hpp @@ -76,6 +76,7 @@ namespace isobus /// @param[in] NAMEValue The NAME of the control function /// @param[in] addressValue The current address of the control function /// @param[in] CANPort The CAN channel index that the control function communicates on + /// @param[in] type The 'Type' of control function to create ControlFunction(NAME NAMEValue, std::uint8_t addressValue, std::uint8_t CANPort, Type type = Type::External); friend class CANNetworkManager; diff --git a/isobus/src/isobus_diagnostic_protocol.cpp b/isobus/src/isobus_diagnostic_protocol.cpp index 13693b07..a44893ba 100644 --- a/isobus/src/isobus_diagnostic_protocol.cpp +++ b/isobus/src/isobus_diagnostic_protocol.cpp @@ -1093,7 +1093,7 @@ namespace isobus { const auto &messageData = message.get_data(); - auto command = static_cast(messageData[0] & (DM13_NETWORK_BITMASK << (DM13_BITS_PER_NETWORK * static_cast(networkType)))); + auto command = static_cast((messageData[0] & (DM13_NETWORK_BITMASK << (DM13_BITS_PER_NETWORK * static_cast(networkType)))) >> (DM13_BITS_PER_NETWORK * static_cast(networkType))); switch (command) { case StopStartCommand::StopBroadcast: @@ -1140,7 +1140,7 @@ namespace isobus } // Check current data link - command = static_cast(messageData[0] & (DM13_NETWORK_BITMASK << (DM13_BITS_PER_NETWORK * static_cast(NetworkType::CurrentDataLink)))); + command = static_cast((messageData[0] & (DM13_NETWORK_BITMASK << (DM13_BITS_PER_NETWORK * static_cast(NetworkType::CurrentDataLink)))) >> (DM13_BITS_PER_NETWORK * static_cast(NetworkType::CurrentDataLink))); switch (command) { case StopStartCommand::StopBroadcast: @@ -1179,8 +1179,11 @@ namespace isobus break; case StopStartCommand::StartBroadcast: + { broadcastState = true; - break; + customDM13SuspensionTime = 0; + } + break; default: break; diff --git a/test/diagnostic_protocol_tests.cpp b/test/diagnostic_protocol_tests.cpp index 387b7b67..bb009e76 100644 --- a/test/diagnostic_protocol_tests.cpp +++ b/test/diagnostic_protocol_tests.cpp @@ -908,6 +908,36 @@ TEST(DIAGNOSTIC_PROTOCOL_TESTS, MessageEncoding) EXPECT_EQ(0x00, testFrame.data[5]); // Occurrence Count + Conversion Method EXPECT_EQ(0xFF, testFrame.data[6]); // Padding EXPECT_EQ(0xFF, testFrame.data[7]); // Padding + + // Try in J1939 Mode, make sure lamps are not reserved values + protocolUnderTest.set_j1939_mode(true); + protocolUnderTest.set_diagnostic_trouble_code_active(testDTC1, true); + protocolUnderTest.set_diagnostic_trouble_code_active(testDTC1, false); + + testFrame.dataLength = 3; + testFrame.identifier = 0x18EAAAAB; + testFrame.data[0] = 0xCB; + testFrame.data[1] = 0xFE; + testFrame.data[2] = 0x00; + CANNetworkManager::process_receive_can_message_frame(testFrame); + CANNetworkManager::CANNetwork.update(); + protocolUnderTest.update(); + + EXPECT_TRUE(testPlugin.read_frame(testFrame)); + + EXPECT_EQ(CAN_DATA_LENGTH, testFrame.dataLength); + EXPECT_EQ(0x18FECBAA, testFrame.identifier); // BAM from address AA + EXPECT_NE(0xFF, testFrame.data[0]); // Lamp + EXPECT_EQ(0xFF, testFrame.data[1]); // Solid Lamp + EXPECT_EQ(0xD2, testFrame.data[2]); // SPN LSB + EXPECT_EQ(0x04, testFrame.data[3]); // SPN + EXPECT_EQ(31, testFrame.data[4]); // SPN + FMI + EXPECT_EQ(0x01, testFrame.data[5]); // Occurrence Count + Conversion Method + EXPECT_EQ(0xFF, testFrame.data[6]); // Padding + EXPECT_EQ(0xFF, testFrame.data[7]); // Padding + + protocolUnderTest.set_j1939_mode(false); + protocolUnderTest.clear_inactive_diagnostic_trouble_codes(); } { @@ -942,7 +972,7 @@ TEST(DIAGNOSTIC_PROTOCOL_TESTS, MessageEncoding) testFrame.data[0] = 0xFC; testFrame.data[1] = 0xFF; testFrame.data[2] = 0xFF; - testFrame.data[3] = 0x00; + testFrame.data[3] = 0x03; testFrame.data[4] = 0x0A; testFrame.data[5] = 0x00; testFrame.data[6] = 0xFF; @@ -966,6 +996,36 @@ TEST(DIAGNOSTIC_PROTOCOL_TESTS, MessageEncoding) CANNetworkManager::CANNetwork.update(); protocolUnderTest.update(); EXPECT_TRUE(protocolUnderTest.get_broadcast_state()); + + // Test suspending the current data link + testFrame.dataLength = 8; + testFrame.data[0] = 0x3F; + testFrame.data[1] = 0xFF; + testFrame.data[2] = 0xFF; + testFrame.data[3] = 0x00; + testFrame.data[4] = 0x0A; + testFrame.data[5] = 0x00; + testFrame.data[6] = 0xFF; + testFrame.data[7] = 0xFF; + CANNetworkManager::process_receive_can_message_frame(testFrame); + CANNetworkManager::CANNetwork.update(); + protocolUnderTest.update(); + EXPECT_FALSE(protocolUnderTest.get_broadcast_state()); + + // Restart broadcasts + testFrame.dataLength = 8; + testFrame.data[0] = 0x7F; + testFrame.data[1] = 0xFF; + testFrame.data[2] = 0xFF; + testFrame.data[3] = 0x00; + testFrame.data[4] = 0xFF; + testFrame.data[5] = 0xFF; + testFrame.data[6] = 0xFF; + testFrame.data[7] = 0xFF; + CANNetworkManager::process_receive_can_message_frame(testFrame); + CANNetworkManager::CANNetwork.update(); + protocolUnderTest.update(); + EXPECT_TRUE(protocolUnderTest.get_broadcast_state()); } { @@ -1087,6 +1147,35 @@ TEST(DIAGNOSTIC_PROTOCOL_TESTS, MessageEncoding) EXPECT_EQ(0x04, testFrame.data[6]); // SPN EXPECT_EQ(31, testFrame.data[7]); // 5 bits of FMI + protocolUnderTest.set_diagnostic_trouble_code_active(testDTC1, true); + + // Try clearing an inactive DTC that is in the active list to check the error code + testFrame.dataLength = 8; + testFrame.identifier = 0x18C3AAAB; + testFrame.data[0] = 1; // Request to clear/reset a specific previously active DTC 5.7.22.1 + testFrame.data[1] = 0xFF; // Control Byte Specific Indicator for Individual DTC Clear (N/A) + testFrame.data[2] = 0xFF; // Reserved + testFrame.data[3] = 0xFF; // Reserved + testFrame.data[4] = 0xFF; // Reserved + testFrame.data[5] = 0xD2; // SPN + testFrame.data[6] = 0x04; // SPN + testFrame.data[7] = 31; // FMI (5 bits) + CANNetworkManager::process_receive_can_message_frame(testFrame); + CANNetworkManager::CANNetwork.update(); + protocolUnderTest.update(); + + EXPECT_TRUE(testPlugin.read_frame(testFrame)); + EXPECT_EQ(CAN_DATA_LENGTH, testFrame.dataLength); + EXPECT_EQ(0x18C3ABAA, testFrame.identifier); + EXPECT_EQ(3, testFrame.data[0]); // Positive acknowledge of clear/reset of a specific active DTC + EXPECT_EQ(0x03, testFrame.data[1]); // DTC is not inactive (because it's in the active list) + EXPECT_EQ(0xFF, testFrame.data[2]); // Reserved + EXPECT_EQ(0xFF, testFrame.data[3]); // Reserved + EXPECT_EQ(0xFF, testFrame.data[4]); // Reserved + EXPECT_EQ(0xD2, testFrame.data[5]); // SPN + EXPECT_EQ(0x04, testFrame.data[6]); // SPN + EXPECT_EQ(31, testFrame.data[7]); // 5 bits of FMI + // Reset back to a known state protocolUnderTest.clear_active_diagnostic_trouble_codes(); protocolUnderTest.clear_inactive_diagnostic_trouble_codes();