Example #1
0
TEST(Frame, FrameParsing)
{
    using uavcan::Frame;
    using uavcan::CanFrame;
    using uavcan::NodeID;
    using uavcan::TransferID;

    CanFrame can;
    Frame frame;
    ASSERT_FALSE(frame.parse(can));

    for (unsigned i = 0; i < sizeof(CanFrame::data); i++)
    {
        can.data[i] = uint8_t(i | (i << 4));
    }

    /*
     * Message CAN ID fields and offsets:
     *   24 Priority
     *   8  Message Type ID
     *   7  Service Not Message (0)
     *   0  Source Node ID
     *
     * Service CAN ID fields and offsets:
     *   24 Priority
     *   16 Service Type ID
     *   15 Request Not Response
     *   8  Destination Node ID
     *   7  Service Not Message (1)
     *   0  Source Node ID
     */

    /*
     * SFT message broadcast
     */
    can.id = CanFrame::FlagEFF |
             (2 << 24) |
             (456 << 8) |
             (0 << 7) |
             (42 << 0);

    can.data[7] = 0xcf; // SET=110, TID=0

    ASSERT_FALSE(frame.parse(can));
    can.dlc = 8;

    ASSERT_TRUE(frame.parse(can));
    EXPECT_TRUE(frame.isStartOfTransfer());
    EXPECT_TRUE(frame.isEndOfTransfer());
    EXPECT_FALSE(frame.getToggle());
    ASSERT_EQ(2, frame.getPriority().get());
    ASSERT_EQ(NodeID(42), frame.getSrcNodeID());
    ASSERT_EQ(NodeID::Broadcast, frame.getDstNodeID());
    ASSERT_EQ(456, frame.getDataTypeID().get());
    ASSERT_EQ(TransferID(15), frame.getTransferID());
    ASSERT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());

    // TODO: test service frames
    // TODO: test malformed frames
}
Example #2
0
int Dispatcher::send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline,
                     CanTxQueue::Qos qos, CanIOFlags flags, uint8_t iface_mask)
{
    if (frame.getSrcNodeID() != getNodeID())
    {
        UAVCAN_ASSERT(0);
        return -ErrLogic;
    }

    CanFrame can_frame;
    if (!frame.compile(can_frame))
    {
        UAVCAN_TRACE("Dispatcher", "Unable to send: frame is malformed: %s", frame.toString().c_str());
        UAVCAN_ASSERT(0);
        return -ErrLogic;
    }
    return canio_.send(can_frame, tx_deadline, blocking_deadline, iface_mask, qos, flags);
}
Example #3
0
TEST(Frame, ServiceParseCompile)
{
    using uavcan::Frame;
    using uavcan::CanFrame;
    using uavcan::TransferID;
    using uavcan::TransferType;

    Frame frame;

    /*
     * Priority
     * Service Type ID
     * Request Not Response
     * Destination Node ID
     * Service Not Message
     * Source Node ID
     */
    const uint32_t can_id =
        (31 << 24) |    // Priority
        (200 << 16) |   // Service Type ID
        (1 << 15) |     // Request Not Response
        (0x42 << 8) |   // Destination Node ID
        (1 << 7) |      // Service Not Message
        (42 << 0);      // Source Node ID

    const std::string payload_string = "hello\x6a"; // SET = 011, TID = 10

    /*
     * Parse
     */
    // Invalid CAN frames
    ASSERT_FALSE(frame.parse(CanFrame(can_id | CanFrame::FlagRTR, (const uint8_t*)"", 0)));
    ASSERT_FALSE(frame.parse(makeCanFrame(can_id, payload_string, STD)));

    // Valid
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    EXPECT_EQ(TransferID(10), frame.getTransferID());
    EXPECT_FALSE(frame.isStartOfTransfer());
    EXPECT_TRUE(frame.isEndOfTransfer());
    EXPECT_TRUE(frame.getToggle());
    EXPECT_EQ(uavcan::NodeID(42), frame.getSrcNodeID());
    EXPECT_EQ(uavcan::NodeID(0x42), frame.getDstNodeID());
    EXPECT_EQ(uavcan::TransferTypeServiceRequest, frame.getTransferType());
    EXPECT_EQ(200, frame.getDataTypeID().get());
    EXPECT_EQ(31, frame.getPriority().get());

    EXPECT_EQ(payload_string.length(), frame.getPayloadLen() + 1);
    EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
                           reinterpret_cast<const uint8_t*>(&payload_string[0])));

    std::cout << frame.toString() << std::endl;

    /*
     * Compile
     */
    CanFrame can_frame;
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    ASSERT_TRUE(frame.compile(can_frame));
    ASSERT_EQ(can_frame, makeCanFrame(can_id, payload_string, EXT));

    EXPECT_EQ(payload_string.length(), can_frame.dlc);
    EXPECT_TRUE(std::equal(can_frame.data, can_frame.data + can_frame.dlc,
                           reinterpret_cast<const uint8_t*>(&payload_string[0])));

    /*
     * Comparison
     */
    ASSERT_FALSE(Frame() == frame);
    ASSERT_TRUE(Frame() != frame);
    frame = Frame();
    ASSERT_TRUE(Frame() == frame);
    ASSERT_FALSE(Frame() != frame);
}
Example #4
0
TEST(Frame, AnonymousParseCompile)
{
    using uavcan::Frame;
    using uavcan::CanFrame;
    using uavcan::TransferID;
    using uavcan::TransferType;

    Frame frame;

    /*
     * Priority
     * Discriminator
     * Message Type ID
     * Service Not Message
     * Source Node ID
     */
    const uint32_t can_id =
        (16383 << 10) | // Discriminator
        (1 << 8);       // Message Type ID

    const std::string payload_string = "hello\xd4"; // SET = 110, TID = 20

    uavcan::TransferCRC payload_crc;
    payload_crc.add(reinterpret_cast<const uint8_t*>(payload_string.c_str()), unsigned(payload_string.length()));

    /*
     * Parse
     */
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    EXPECT_EQ(TransferID(20), frame.getTransferID());
    EXPECT_TRUE(frame.isStartOfTransfer());
    EXPECT_TRUE(frame.isEndOfTransfer());
    EXPECT_FALSE(frame.getToggle());
    EXPECT_TRUE(frame.getSrcNodeID().isBroadcast());
    EXPECT_TRUE(frame.getDstNodeID().isBroadcast());
    EXPECT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
    EXPECT_EQ(1, frame.getDataTypeID().get());
    EXPECT_EQ(0, frame.getPriority().get());

    EXPECT_EQ(payload_string.length() - 1, frame.getPayloadLen());
    EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
                           reinterpret_cast<const uint8_t*>(&payload_string[0])));

    std::cout << frame.toString() << std::endl;

    /*
     * Compile
     */
    const uint32_t DiscriminatorMask = 0x00FFFC00;
    const uint32_t NoDiscriminatorMask = 0xFF0003FF;

    CanFrame can_frame;
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    ASSERT_TRUE(frame.compile(can_frame));
    ASSERT_EQ(can_id & NoDiscriminatorMask & uavcan::CanFrame::MaskExtID,
              can_frame.id & NoDiscriminatorMask & uavcan::CanFrame::MaskExtID);

    EXPECT_EQ(payload_string.length(), can_frame.dlc);
    EXPECT_TRUE(std::equal(can_frame.data, can_frame.data + can_frame.dlc,
                           reinterpret_cast<const uint8_t*>(&payload_string[0])));

    EXPECT_EQ((can_frame.id & DiscriminatorMask & uavcan::CanFrame::MaskExtID) >> 10, payload_crc.get() & 16383);

    /*
     * Comparison
     */
    ASSERT_FALSE(Frame() == frame);
    ASSERT_TRUE(Frame() != frame);
    frame = Frame();
    ASSERT_TRUE(Frame() == frame);
    ASSERT_FALSE(Frame() != frame);
}
Example #5
0
TEST(Frame, MessageParseCompile)
{
    using uavcan::Frame;
    using uavcan::CanFrame;
    using uavcan::TransferID;
    using uavcan::TransferType;

    Frame frame;

    /*
     * Priority
     * Message Type ID
     * Service Not Message
     * Source Node ID
     */
    const uint32_t can_id =
        (16 << 24) |    // Priority
        (20000 << 8) |  // Message Type ID
        (0 << 7) |      // Service Not Message
        (42 << 0);      // Source Node ID

    const std::string payload_string = "hello\xD4"; // SET = 110, TID = 20

    /*
     * Parse
     */
    // Invalid CAN frames
    ASSERT_FALSE(frame.parse(CanFrame(can_id | CanFrame::FlagRTR, (const uint8_t*)"", 0)));
    ASSERT_FALSE(frame.parse(makeCanFrame(can_id, payload_string, STD)));

    // Valid
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    EXPECT_EQ(TransferID(20), frame.getTransferID());
    EXPECT_TRUE(frame.isStartOfTransfer());
    EXPECT_TRUE(frame.isEndOfTransfer());
    EXPECT_FALSE(frame.getToggle());
    EXPECT_EQ(uavcan::NodeID(42), frame.getSrcNodeID());
    EXPECT_TRUE(frame.getDstNodeID().isBroadcast());
    EXPECT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
    EXPECT_EQ(20000, frame.getDataTypeID().get());
    EXPECT_EQ(16, frame.getPriority().get());

    EXPECT_EQ(payload_string.length() - 1, frame.getPayloadLen());
    EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
                           payload_string.begin()));

    std::cout << frame.toString() << std::endl;

    /*
     * Compile
     */
    CanFrame can_frame;
    ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));

    ASSERT_TRUE(frame.compile(can_frame));
    ASSERT_EQ(can_frame, makeCanFrame(can_id, payload_string, EXT));

    EXPECT_EQ(payload_string.length(), can_frame.dlc);
    std::cout << can_frame.toString() << std::endl;
    /*
     * FUN FACT: comparison of uint8_t with char may fail on the character 0xD4 (depending on the locale),
     * because it will be considered a Unicode character. Hence, we do reinterpret_cast<>.
     */
    EXPECT_TRUE(std::equal(can_frame.data, can_frame.data + can_frame.dlc,
                           reinterpret_cast<const uint8_t*>(&payload_string[0])));

    /*
     * Comparison
     */
    ASSERT_FALSE(Frame() == frame);
    ASSERT_TRUE(Frame() != frame);
    frame = Frame();
    ASSERT_TRUE(Frame() == frame);
    ASSERT_FALSE(Frame() != frame);
}