Universe 0 and values >63999 are reserved per E1.31 spec and must be rejected. Priority is deliberately not validated (compared relatively in later tasks only). Test coverage: - test_universe_zero_rejected: rejects universe 0 - test_universe_too_high_rejected: rejects universe 64000 - test_universe_is_read: continues to accept universe 63999
218 lines
6.1 KiB
C
218 lines
6.1 KiB
C
#include <string.h>
|
|
#include "unity.h"
|
|
#include "net/nl_e131.h"
|
|
|
|
static uint8_t pkt[NL_E131_MAX_PACKET];
|
|
static size_t pkt_len;
|
|
|
|
static void be16(size_t off, uint16_t v) { pkt[off] = (uint8_t)(v >> 8); pkt[off + 1] = (uint8_t)v; }
|
|
static void be32(size_t off, uint32_t v)
|
|
{
|
|
pkt[off] = (uint8_t)(v >> 24); pkt[off + 1] = (uint8_t)(v >> 16);
|
|
pkt[off + 2] = (uint8_t)(v >> 8); pkt[off + 3] = (uint8_t)v;
|
|
}
|
|
|
|
/* Baut ein gueltiges Paket mit `slots` Slots, aufsteigend gefuellt (1, 2, 3, ...). */
|
|
static void build(uint16_t universe, uint8_t prio, uint8_t seq, uint8_t options, uint16_t slots)
|
|
{
|
|
pkt_len = 126u + slots;
|
|
memset(pkt, 0, sizeof pkt);
|
|
be16(0, 0x0010);
|
|
be16(2, 0x0000);
|
|
memcpy(pkt + 4, "ASC-E1.17\0\0\0", 12);
|
|
be16(16, (uint16_t)(0x7000u | (pkt_len - 16u)));
|
|
be32(18, 0x00000004u);
|
|
be16(38, (uint16_t)(0x7000u | (pkt_len - 38u)));
|
|
be32(40, 0x00000002u);
|
|
memcpy(pkt + 44, "ninlight test", 13);
|
|
pkt[108] = prio;
|
|
pkt[111] = seq;
|
|
pkt[112] = options;
|
|
be16(113, universe);
|
|
be16(115, (uint16_t)(0x7000u | (pkt_len - 115u)));
|
|
pkt[117] = 0x02;
|
|
pkt[118] = 0xa1;
|
|
be16(119, 0x0000);
|
|
be16(121, 0x0001);
|
|
be16(123, (uint16_t)(slots + 1u));
|
|
pkt[125] = 0x00; /* Start-Code */
|
|
for (uint16_t i = 0; i < slots; i++)
|
|
pkt[126 + i] = (uint8_t)(i + 1u);
|
|
}
|
|
|
|
void setUp(void) { build(1, 100, 0, 0, 6); }
|
|
void tearDown(void) {}
|
|
|
|
static void test_valid_packet(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
TEST_ASSERT_TRUE(nl_e131_parse(pkt, pkt_len, &p));
|
|
TEST_ASSERT_EQUAL_UINT16(1, p.universe);
|
|
TEST_ASSERT_EQUAL_UINT8(100, p.priority);
|
|
TEST_ASSERT_EQUAL_UINT8(0, p.sequence);
|
|
TEST_ASSERT_FALSE(p.terminated);
|
|
TEST_ASSERT_EQUAL_UINT16(6, p.slot_count);
|
|
TEST_ASSERT_EQUAL_UINT8(1, p.slots[0]);
|
|
TEST_ASSERT_EQUAL_UINT8(6, p.slots[5]);
|
|
}
|
|
|
|
static void test_full_universe(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(1, 100, 0, 0, 512);
|
|
TEST_ASSERT_EQUAL_size_t(638, pkt_len);
|
|
TEST_ASSERT_TRUE(nl_e131_parse(pkt, pkt_len, &p));
|
|
TEST_ASSERT_EQUAL_UINT16(512, p.slot_count);
|
|
}
|
|
|
|
static void test_empty_slot_set(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(1, 100, 0, 0, 0);
|
|
TEST_ASSERT_EQUAL_size_t(126, pkt_len);
|
|
TEST_ASSERT_TRUE(nl_e131_parse(pkt, pkt_len, &p));
|
|
TEST_ASSERT_EQUAL_UINT16(0, p.slot_count);
|
|
}
|
|
|
|
static void test_terminated_bit(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(1, 100, 0, 0x40, 6);
|
|
TEST_ASSERT_TRUE(nl_e131_parse(pkt, pkt_len, &p));
|
|
TEST_ASSERT_TRUE(p.terminated);
|
|
}
|
|
|
|
static void test_preview_bit_rejected(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(1, 100, 0, 0x80, 6);
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_preamble(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
pkt[1] = 0x11;
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_package_identifier(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
pkt[4] = 'X';
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_root_vector(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
be32(18, 0x00000008u);
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_framing_vector(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
be32(40, 0x00000001u); /* VECTOR_E131_EXTENDED_SYNCHRONIZATION */
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_dmp_vector(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
pkt[117] = 0x03;
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_bad_address_type(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
pkt[118] = 0xa2;
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_per_channel_priority_start_code_rejected(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
pkt[125] = 0xdd;
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_truncated_length_fields(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
/* Root-Laenge behauptet mehr, als das Datagramm hergibt. */
|
|
be16(16, (uint16_t)(0x7000u | (pkt_len - 16u + 4u)));
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
build(1, 100, 0, 0, 6);
|
|
be16(38, (uint16_t)(0x7000u | (pkt_len - 38u - 2u)));
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
build(1, 100, 0, 0, 6);
|
|
be16(115, (uint16_t)(0x7000u | (pkt_len - 115u + 1u)));
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_property_value_count_mismatch(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
be16(123, 9); /* behauptet 8 Slots, das Paket traegt 6 */
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_too_short_and_too_long(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, 125, &p));
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, 0, &p));
|
|
build(1, 100, 0, 0, 512);
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, 639, &p)); /* laenger als jedes gueltige Paket */
|
|
}
|
|
|
|
static void test_universe_is_read(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(63999, 200, 7, 0, 6);
|
|
TEST_ASSERT_TRUE(nl_e131_parse(pkt, pkt_len, &p));
|
|
TEST_ASSERT_EQUAL_UINT16(63999, p.universe);
|
|
TEST_ASSERT_EQUAL_UINT8(200, p.priority);
|
|
TEST_ASSERT_EQUAL_UINT8(7, p.sequence);
|
|
}
|
|
|
|
static void test_universe_zero_rejected(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(0, 100, 0, 0, 6);
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
static void test_universe_too_high_rejected(void)
|
|
{
|
|
nl_e131_packet_t p;
|
|
build(64000, 100, 0, 0, 6);
|
|
TEST_ASSERT_FALSE(nl_e131_parse(pkt, pkt_len, &p));
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_valid_packet);
|
|
RUN_TEST(test_full_universe);
|
|
RUN_TEST(test_empty_slot_set);
|
|
RUN_TEST(test_terminated_bit);
|
|
RUN_TEST(test_preview_bit_rejected);
|
|
RUN_TEST(test_bad_preamble);
|
|
RUN_TEST(test_bad_package_identifier);
|
|
RUN_TEST(test_bad_root_vector);
|
|
RUN_TEST(test_bad_framing_vector);
|
|
RUN_TEST(test_bad_dmp_vector);
|
|
RUN_TEST(test_bad_address_type);
|
|
RUN_TEST(test_per_channel_priority_start_code_rejected);
|
|
RUN_TEST(test_truncated_length_fields);
|
|
RUN_TEST(test_property_value_count_mismatch);
|
|
RUN_TEST(test_too_short_and_too_long);
|
|
RUN_TEST(test_universe_is_read);
|
|
RUN_TEST(test_universe_zero_rejected);
|
|
RUN_TEST(test_universe_too_high_rejected);
|
|
return UNITY_END();
|
|
}
|