int udp_tx(void *context, const unsigned char *buf, size_t size) { struct udp_context *ctx = context; struct net_context *net_ctx; struct net_pkt *send_pkt; int rc, len; net_ctx = ctx->net_ctx; send_pkt = net_pkt_get_tx(net_ctx, K_FOREVER); if (!send_pkt) { printk("cannot create pkt\n"); return -EIO; } rc = net_pkt_append_all(send_pkt, size, (u8_t *) buf, K_FOREVER); if (!rc) { printk("cannot write buf\n"); return -EIO; } len = net_pkt_get_len(send_pkt); rc = net_context_sendto(send_pkt, &net_ctx->remote, addrlen, NULL, K_FOREVER, NULL, NULL); if (rc < 0) { printk("Cannot send data to peer (%d)\n", rc); net_pkt_unref(send_pkt); return -EIO; } else { return len; } }
/* Send encrypted data */ static int ssl_tx(void *context, const unsigned char *buf, size_t size) { struct http_client_ctx *ctx = context; struct net_pkt *send_pkt; int ret, len; send_pkt = net_pkt_get_tx(ctx->tcp.ctx, BUF_ALLOC_TIMEOUT); if (!send_pkt) { return MBEDTLS_ERR_SSL_ALLOC_FAILED; } ret = net_pkt_append_all(send_pkt, size, (u8_t *)buf, BUF_ALLOC_TIMEOUT); if (!ret) { /* Cannot append data */ net_pkt_unref(send_pkt); return MBEDTLS_ERR_SSL_ALLOC_FAILED; } len = size; ret = net_context_send(send_pkt, ssl_sent, K_NO_WAIT, NULL, ctx); if (ret < 0) { net_pkt_unref(send_pkt); return ret; } k_sem_take(&ctx->https.mbedtls.ssl_ctx.tx_sem, K_FOREVER); return len; }
static inline void telnet_command_send_reply(u8_t *msg, u16_t len) { net_pkt_append_all(out_pkt, len, msg, K_FOREVER); net_context_send(out_pkt, telnet_sent_cb, K_NO_WAIT, NULL, NULL); telnet_setup_out_pkt(client_cnx); }
static inline bool telnet_send(void) { struct line_buf *lb = telnet_rb_get_line_out(); if (lb) { net_pkt_append_all(out_pkt, lb->len, lb->buf, K_FOREVER); /* We reinitialize the line buffer */ lb->len = 0; if (net_context_send(out_pkt, telnet_sent_cb, K_NO_WAIT, NULL, NULL) || telnet_setup_out_pkt(client_cnx)) { return false; } } return true; }
static int transmitv(struct net_context *conn, int iovcnt, struct io_vec *iov) { struct net_pkt *pkt; int i; pkt = net_pkt_get_tx(conn, K_FOREVER); if (!pkt) { return -ENOMEM; } for (i = 0; i < iovcnt; i++) { if (!net_pkt_append_all(pkt, iov[i].len, iov[i].base, K_FOREVER)) { net_pkt_unref(pkt); return -ENOMEM; } } return net_context_send(pkt, NULL, K_NO_WAIT, NULL, NULL); }
static bool send_iface(struct net_if *iface, int val, bool expect_fail) { static u8_t data[] = { 't', 'e', 's', 't', '\0' }; struct net_pkt *pkt; int ret; pkt = net_pkt_get_reserve_tx(0, K_FOREVER); net_pkt_set_iface(pkt, iface); net_pkt_append_all(pkt, sizeof(data), data, K_FOREVER); ret = net_send_data(pkt); if (!expect_fail && ret < 0) { DBG("Cannot send test packet (%d)\n", ret); return false; } if (!expect_fail && k_sem_take(&wait_data, WAIT_TIME)) { DBG("Timeout while waiting interface %d data\n", val); return false; } return true; }
int http_request(struct http_client_ctx *ctx, struct http_client_request *req, s32_t timeout) { const char *method = http_method_str(req->method); struct net_pkt *pkt; int ret = -ENOMEM; pkt = net_pkt_get_tx(ctx->tcp.ctx, timeout); if (!pkt) { return -ENOMEM; } if (!net_pkt_append_all(pkt, strlen(method), (u8_t *)method, timeout)) { goto out; } /* Space after method string. */ if (!net_pkt_append_all(pkt, 1, (u8_t *)" ", timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->url), (u8_t *)req->url, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->protocol), (u8_t *)req->protocol, timeout)) { goto out; } if (req->host) { if (!net_pkt_append_all(pkt, strlen(HTTP_HOST), (u8_t *)HTTP_HOST, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->host), (u8_t *)req->host, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(HTTP_CRLF), (u8_t *)HTTP_CRLF, timeout)) { goto out; } } if (req->header_fields) { if (!net_pkt_append_all(pkt, strlen(req->header_fields), (u8_t *)req->header_fields, timeout)) { goto out; } } if (req->content_type_value) { if (!net_pkt_append_all(pkt, strlen(HTTP_CONTENT_TYPE), (u8_t *)HTTP_CONTENT_TYPE, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->content_type_value), (u8_t *)req->content_type_value, timeout)) { goto out; } } if (req->payload && req->payload_size) { char content_len_str[HTTP_CONT_LEN_SIZE]; ret = snprintk(content_len_str, HTTP_CONT_LEN_SIZE, HTTP_CRLF "Content-Length: %u" HTTP_CRLF HTTP_CRLF, req->payload_size); if (ret <= 0 || ret >= HTTP_CONT_LEN_SIZE) { ret = -ENOMEM; goto out; } if (!net_pkt_append_all(pkt, ret, (u8_t *)content_len_str, timeout)) { ret = -ENOMEM; goto out; } if (!net_pkt_append_all(pkt, req->payload_size, (u8_t *)req->payload, timeout)) { ret = -ENOMEM; goto out; } } else { if (!net_pkt_append_all(pkt, strlen(HTTP_EOF), (u8_t *)HTTP_EOF, timeout)) { goto out; } } #if defined(CONFIG_NET_IPV6) if (net_pkt_family(pkt) == AF_INET6) { net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) - net_pkt_ipv6_ext_opt_len(pkt)); } else #endif { net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt)); } ret = ctx->tcp.send_data(pkt, NULL, timeout, NULL, ctx); if (ret == 0) { return 0; } out: net_pkt_unref(pkt); return ret; }
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"); }
static void setup_ipv6_udp_long(struct net_pkt *pkt, struct in6_addr *remote_addr, struct in6_addr *local_addr, u16_t remote_port, u16_t local_port) { struct net_udp_hdr hdr, *udp_hdr; struct net_ipv6_hdr ipv6; ipv6.vtc = 0x60; ipv6.tcflow = 0; ipv6.flow = 0; ipv6.len[0] = 0; ipv6.len[1] = NET_UDPH_LEN + strlen(payload) + sizeof(ipv6_hop_by_hop_ext_hdr); ipv6.nexthdr = 0; /* HBHO */ ipv6.hop_limit = 255; net_ipaddr_copy(&ipv6.src, remote_addr); net_ipaddr_copy(&ipv6.dst, local_addr); net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr)); hdr.src_port = htons(remote_port); hdr.dst_port = htons(local_port); net_pkt_append_all(pkt, sizeof(ipv6), (u8_t *)&ipv6, K_FOREVER); net_pkt_append_all(pkt, sizeof(ipv6_hop_by_hop_ext_hdr), ipv6_hop_by_hop_ext_hdr, K_FOREVER); net_pkt_append_all(pkt, sizeof(hdr), (u8_t *)&hdr, K_FOREVER); net_pkt_append_all(pkt, strlen(payload), (u8_t *)payload, K_FOREVER); net_pkt_set_ipv6_ext_len(pkt, sizeof(ipv6_hop_by_hop_ext_hdr)); udp_hdr = net_udp_get_hdr(pkt, &hdr); /**TESTPOINT: Check if pointer is valid*/ zassert_equal_ptr(udp_hdr, &hdr, "Invalid UDP header pointer"); udp_hdr->src_port = htons(remote_port); udp_hdr->dst_port = htons(local_port); net_udp_set_hdr(pkt, &hdr); udp_hdr = net_udp_get_hdr(pkt, &hdr); if (udp_hdr != &hdr) { TC_ERROR("Invalid UDP header pointer %p\n", udp_hdr); zassert_true(0, "exiting"); } if (udp_hdr->src_port != htons(remote_port)) { TC_ERROR("Invalid remote port, should have been %d was %d\n", remote_port, ntohs(udp_hdr->src_port)); zassert_true(0, "exiting"); } if (udp_hdr->dst_port != htons(local_port)) { TC_ERROR("Invalid local port, should have been %d was %d\n", local_port, ntohs(udp_hdr->dst_port)); zassert_true(0, "exiting"); } net_hexdump_frags("frag", pkt); }