static inline void telnet_handle_input(struct net_pkt *pkt) { struct console_input *input; u16_t len, offset, pos; len = net_pkt_appdatalen(pkt); if (len > CONSOLE_MAX_LINE_LEN || len < TELNET_MIN_MSG) { return; } if (telnet_handle_command(pkt)) { return; } if (!avail_queue || !input_queue) { return; } input = k_fifo_get(avail_queue, K_NO_WAIT); if (!input) { return; } offset = net_pkt_get_len(pkt) - len; net_frag_read(pkt->frags, offset, &pos, len, input->line); /* LF/CR will be removed if only the line is not NUL terminated */ if (input->line[len-1] != NVT_NUL) { if (input->line[len-1] == NVT_LF) { input->line[len-1] = NVT_NUL; } if (input->line[len-2] == NVT_CR) { input->line[len-2] = NVT_NUL; } } k_fifo_put(input_queue, input); }
static void test_pkt_read_write_insert(void) { struct net_buf *read_frag; struct net_buf *temp_frag; struct net_pkt *pkt; struct net_buf *frag; u8_t read_data[100]; u16_t read_pos; u16_t len; u16_t pos; /* Example of multi fragment read, append and skip APS's */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); /* 1) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). */ frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 1: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 1: Read failed"); zassert_false(memcmp(read_data, sample_data, 10), "Usecase 1: Read data mismatch"); /* 2) Write IPv6 and UDP header at offset 0. (Empty space is created * already in Usecase 1, just need to fill the header, at this point * there shouldn't be any length change). */ frag = net_pkt_write(pkt, frag, 0, &pos, NET_IPV6UDPH_LEN, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag || pos != 48, "Usecase 2: Write failed"); read_frag = net_frag_read(frag, 0, &read_pos, NET_IPV6UDPH_LEN, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 2: Read failed"); zassert_false(memcmp(read_data, sample_data, NET_IPV6UDPH_LEN), "Usecase 2: Read data mismatch"); net_pkt_unref(pkt); pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* 3) Offset is in next to next fragment. * Write app data after 2 fragments. (If the offset far away, api will * create empty fragments(space) till offset and write data). */ frag = net_pkt_write(pkt, pkt->frags, 200, &pos, 10, (u8_t *)sample_data + 10, K_FOREVER); zassert_not_null(frag, "Usecase 3: Write failed"); read_frag = net_frag_read(frag, pos - 10, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 3: Read failed"); zassert_false(memcmp(read_data, sample_data + 10, 10), "Usecase 3: Read data mismatch"); /* 4) Offset is in next to next fragment (overwrite). * Write app data after 2 fragments. (Space is already available from * Usecase 3, this scenatio doesn't create any space, it just overwrites * the existing data. */ frag = net_pkt_write(pkt, pkt->frags, 190, &pos, 10, (u8_t *)sample_data, K_FOREVER); zassert_not_null(frag, "Usecase 4: Write failed"); read_frag = net_frag_read(frag, pos - 10, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 4: Read failed"); zassert_false(memcmp(read_data, sample_data, 20), "Usecase 4: Read data mismatch"); net_pkt_unref(pkt); /* 5) Write 20 bytes in fragment which has only 10 bytes space. * API should overwrite on first 10 bytes and create extra 10 bytes * and write there. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); /* Create 10 bytes space. */ net_buf_add(frag, 10); frag = net_pkt_write(pkt, frag, 0, &pos, 20, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag && pos != 20, "Usecase 5: Write failed"); read_frag = net_frag_read(frag, 0, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 5: Read failed"); zassert_false(memcmp(read_data, sample_data, 20), "USecase 5: Read data mismatch"); net_pkt_unref(pkt); /* 6) First fragment is full, second fragment has 10 bytes tail room, * third fragment has 5 bytes. * Write data (30 bytes) in second fragment where offset is 10 bytes * before the tailroom. * So it should overwrite 10 bytes and create space for another 10 * bytes and write data. Third fragment 5 bytes overwritten and space * for 5 bytes created. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); len = net_buf_tailroom(frag); net_buf_add(frag, len); /* 2nd fragment last 10 bytes tailroom, rest occupied */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); len = net_buf_tailroom(frag); net_buf_add(frag, len - 10); read_frag = temp_frag = frag; read_pos = frag->len - 10; /* 3rd fragment, only 5 bytes occupied */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); net_buf_add(frag, 5); temp_frag = net_pkt_write(pkt, temp_frag, temp_frag->len - 10, &pos, 30, (u8_t *) sample_data, K_FOREVER); zassert_not_null(temp_frag, "Use case 6: Write failed"); read_frag = net_frag_read(read_frag, read_pos, &read_pos, 30, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 6: Read failed"); zassert_false(memcmp(read_data, sample_data, 30), "Usecase 6: Read data mismatch"); net_pkt_unref(pkt); /* 7) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). Insert some app data after IPv6 + UDP header * before first set of app data. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data + 10, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 7: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 7: Read failed"); zassert_false(memcmp(read_data, sample_data + 10, 10), "Usecase 7: Read data mismatch"); zassert_true(net_pkt_insert(pkt, frag, NET_IPV6UDPH_LEN, 10, (u8_t *)sample_data, K_FOREVER), "Usecase 7: Insert failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 7: Read after failed"); zassert_false(memcmp(read_data, sample_data, 20), "Usecase 7: Read data mismatch after insertion"); /* Insert data outside input fragment length, error case. */ zassert_false(net_pkt_insert(pkt, frag, 70, 10, (u8_t *)sample_data, K_FOREVER), "Usecase 7: False insert failed"); net_pkt_unref(pkt); /* 8) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). Insert some app data after IPv6 + UDP header * before first set of app data. Insertion data is long which will * take two fragments. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data + 60, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 8: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 8: Read failed"); zassert_false(memcmp(read_data, sample_data + 60, 10), "Usecase 8: Read data mismatch"); zassert_true(net_pkt_insert(pkt, frag, NET_IPV6UDPH_LEN, 60, (u8_t *)sample_data, K_FOREVER), "Usecase 8: Insert failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 70, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 8: Read after failed"); zassert_false(memcmp(read_data, sample_data, 70), "Usecase 8: Read data mismatch after insertion"); net_pkt_unref(pkt); DBG("test_pkt_read_write_insert passed\n"); }
static void test_pkt_read_append(void) { int remaining = strlen(sample_data); u8_t verify_rw_short[sizeof(test_rw_short)]; u8_t verify_rw_long[sizeof(test_rw_long)]; struct net_pkt *pkt; struct net_buf *frag; struct net_buf *tfrag; struct ipv6_hdr *ipv6; struct udp_hdr *udp; u8_t data[10]; int pos = 0; int bytes; u16_t off; u16_t tpos; u16_t fail_pos; /* Example of multi fragment read, append and skip APS's */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); frag = net_pkt_get_reserve_rx_data(LL_RESERVE, K_FOREVER); /* Place the IP + UDP header in the first fragment */ if (!net_buf_tailroom(frag)) { ipv6 = (struct ipv6_hdr *)(frag->data); udp = (struct udp_hdr *)((void *)ipv6 + sizeof(*ipv6)); if (net_buf_tailroom(frag) < sizeof(ipv6)) { printk("Not enough space for IPv6 header, " "needed %zd bytes, has %zd bytes\n", sizeof(ipv6), net_buf_tailroom(frag)); zassert_true(false, "No space for IPv6 header"); } net_buf_add(frag, sizeof(ipv6)); if (net_buf_tailroom(frag) < sizeof(udp)) { printk("Not enough space for UDP header, " "needed %zd bytes, has %zd bytes\n", sizeof(udp), net_buf_tailroom(frag)); zassert_true(false, "No space for UDP header"); } net_pkt_set_appdata(pkt, (void *)udp + sizeof(*udp)); net_pkt_set_appdatalen(pkt, 0); } net_pkt_frag_add(pkt, frag); /* Put some data to rest of the fragments */ frag = net_pkt_get_reserve_rx_data(LL_RESERVE, K_FOREVER); if (net_buf_tailroom(frag) - (CONFIG_NET_BUF_DATA_SIZE - LL_RESERVE)) { printk("Invalid number of bytes available in the buf, " "should be 0 but was %zd - %d\n", net_buf_tailroom(frag), CONFIG_NET_BUF_DATA_SIZE - LL_RESERVE); zassert_true(false, "Invalid number of bytes avail"); } if (((int)net_buf_tailroom(frag) - remaining) > 0) { printk("We should have been out of space now, " "tailroom %zd user data len %zd\n", net_buf_tailroom(frag), strlen(sample_data)); zassert_true(false, "Not out of space"); } while (remaining > 0) { int copy; bytes = net_buf_tailroom(frag); copy = remaining > bytes ? bytes : remaining; memcpy(net_buf_add(frag, copy), &sample_data[pos], copy); DBG("Remaining %d left %d copy %d\n", remaining, bytes, copy); pos += bytes; remaining -= bytes; if (net_buf_tailroom(frag) - (bytes - copy)) { printk("There should have not been any tailroom left, " "tailroom %zd\n", net_buf_tailroom(frag) - (bytes - copy)); zassert_true(false, "Still tailroom left"); } net_pkt_frag_add(pkt, frag); if (remaining > 0) { frag = net_pkt_get_reserve_rx_data(LL_RESERVE, K_FOREVER); } } bytes = net_pkt_get_len(pkt); if (bytes != strlen(sample_data)) { printk("Invalid number of bytes in message, %zd vs %d\n", strlen(sample_data), bytes); zassert_true(false, "Message size wrong"); } /* Failure cases */ /* Invalid buffer */ tfrag = net_frag_skip(NULL, 10, &fail_pos, 10); zassert_true(!tfrag && fail_pos == 0xffff, "Invalid case NULL buffer"); /* Invalid: Skip more than a buffer length.*/ tfrag = net_buf_frag_last(pkt->frags); tfrag = net_frag_skip(tfrag, tfrag->len - 1, &fail_pos, tfrag->len + 2); if (!(!tfrag && fail_pos == 0xffff)) { printk("Invalid case offset %d length to skip %d," "frag length %d\n", tfrag->len - 1, tfrag->len + 2, tfrag->len); zassert_true(false, "Invalid offset"); } /* Invalid offset */ tfrag = net_buf_frag_last(pkt->frags); tfrag = net_frag_skip(tfrag, tfrag->len + 10, &fail_pos, 10); if (!(!tfrag && fail_pos == 0xffff)) { printk("Invalid case offset %d length to skip %d," "frag length %d\n", tfrag->len + 10, 10, tfrag->len); zassert_true(false, "Invalid offset"); } /* Valid cases */ /* Offset is more than single fragment length */ /* Get the first data fragment */ tfrag = pkt->frags; tfrag = tfrag->frags; off = tfrag->len; tfrag = net_frag_read(tfrag, off + 10, &tpos, 10, data); if (!tfrag || memcmp(sample_data + off + 10, data, 10)) { printk("Failed to read from offset %d, frag length %d " "read length %d\n", tfrag->len + 10, tfrag->len, 10); zassert_true(false, "Fail offset read"); } /* Skip till end of all fragments */ /* Get the first data fragment */ tfrag = pkt->frags; tfrag = tfrag->frags; tfrag = net_frag_skip(tfrag, 0, &tpos, strlen(sample_data)); zassert_true(!tfrag && tpos == 0, "Invalid skip till end of all fragments"); /* Short data test case */ /* Test case scenario: * 1) Cache the current fragment and offset * 2) Append short data * 3) Append short data again * 4) Skip first short data from cached frag or offset * 5) Read short data and compare */ tfrag = net_buf_frag_last(pkt->frags); off = tfrag->len; zassert_true(net_pkt_append_all(pkt, (u16_t)sizeof(test_rw_short), test_rw_short, K_FOREVER), "net_pkt_append failed"); zassert_true(net_pkt_append_all(pkt, (u16_t)sizeof(test_rw_short), test_rw_short, K_FOREVER), "net_pkt_append failed"); tfrag = net_frag_skip(tfrag, off, &tpos, (u16_t)sizeof(test_rw_short)); zassert_not_null(tfrag, "net_frag_skip failed"); tfrag = net_frag_read(tfrag, tpos, &tpos, (u16_t)sizeof(test_rw_short), verify_rw_short); zassert_true(!tfrag && tpos == 0, "net_frag_read failed"); zassert_false(memcmp(test_rw_short, verify_rw_short, sizeof(test_rw_short)), "net_frag_read failed with mismatch data"); /* Long data test case */ /* Test case scenario: * 1) Cache the current fragment and offset * 2) Append long data * 3) Append long data again * 4) Skip first long data from cached frag or offset * 5) Read long data and compare */ tfrag = net_buf_frag_last(pkt->frags); off = tfrag->len; zassert_true(net_pkt_append_all(pkt, (u16_t)sizeof(test_rw_long), test_rw_long, K_FOREVER), "net_pkt_append failed"); zassert_true(net_pkt_append_all(pkt, (u16_t)sizeof(test_rw_long), test_rw_long, K_FOREVER), "net_pkt_append failed"); tfrag = net_frag_skip(tfrag, off, &tpos, (u16_t)sizeof(test_rw_long)); zassert_not_null(tfrag, "net_frag_skip failed"); tfrag = net_frag_read(tfrag, tpos, &tpos, (u16_t)sizeof(test_rw_long), verify_rw_long); zassert_true(!tfrag && tpos == 0, "net_frag_read failed"); zassert_false(memcmp(test_rw_long, verify_rw_long, sizeof(test_rw_long)), "net_frag_read failed with mismatch data"); net_pkt_unref(pkt); DBG("test_pkt_read_append passed\n"); }