コード例 #1
0
ファイル: main.c プロジェクト: rsalveti/zephyr
static void test_ipv6_multi_frags(void)
{
	struct net_pkt *pkt;
	struct net_buf *frag;
	struct ipv6_hdr *ipv6;
	struct udp_hdr *udp;
	int bytes, remaining = strlen(example_data), pos = 0;

	/* Example of multi fragment scenario with IPv6 */
	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 byte count");
	}

	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(example_data));
		zassert_true(false, "Still space");
	}

	while (remaining > 0) {
		int copy;

		bytes = net_buf_tailroom(frag);
		copy = remaining > bytes ? bytes : remaining;
		memcpy(net_buf_add(frag, copy), &example_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, "There is 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(example_data)) {
		printk("Invalid number of bytes in message, %zd vs %d\n",
		       strlen(example_data), bytes);
		zassert_true(false, "Invalid number of bytes");
	}

	/* Normally one should not unref the fragment list like this
	 * because it will leave the pkt->frags pointing to already
	 * freed fragment.
	 */
	net_pkt_frag_unref(pkt->frags);

	zassert_not_null(pkt->frags, "Frag list empty");

	pkt->frags = NULL; /* to prevent double free */

	net_pkt_unref(pkt);
}
コード例 #2
0
ファイル: http_server.c プロジェクト: bboozzoo/zephyr
void http_rx_tx(struct net_context *net_ctx, struct net_pkt *rx, int status,
		void *user_data)
{
	struct http_server_ctx *http_ctx = NULL;
	struct net_buf *data = NULL;
	u16_t rcv_len;
	u16_t offset;
	int parsed_len;
	int rc;

	if (status) {
		printf("[%s:%d] Status code: %d, <%s>\n",
			__func__, __LINE__, status, RC_STR(status));
		goto lb_exit;
	}

	if (!user_data) {
		printf("[%s:%d] User data is null\n", __func__, __LINE__);
		goto lb_exit;
	}

	http_ctx = (struct http_server_ctx *)user_data;
	if (http_ctx->net_ctx != net_ctx) {
		printf("[%s:%d] Wrong network context received\n",
		       __func__, __LINE__);
		goto lb_exit;
	}

	if (!rx) {
		printf("[%s:%d] Connection closed by peer\n",
		       __func__, __LINE__);
		goto lb_exit;
	}

	rcv_len = net_pkt_appdatalen(rx);
	if (rcv_len == 0) {
		/* don't print info about zero-length app data buffers */
		goto lb_exit;
	}

	data = net_buf_alloc(&http_msg_pool, APP_SLEEP_MSECS);
	if (data == NULL) {
		printf("[%s:%d] Data buffer alloc error\n", __func__, __LINE__);
		goto lb_exit;
	}

	offset = net_pkt_get_len(rx) - rcv_len;
	rc = net_frag_linear_copy(data, rx->frags, offset, rcv_len);
	if (rc != 0) {
		printf("[%s:%d] Linear copy error\n", __func__, __LINE__);
		goto lb_exit;
	}

	data->data[min(data->size - 1, rcv_len)] = 0;

	parser_init(http_ctx);
	parsed_len = parser_parse_request(http_ctx, data);
	if (parsed_len <= 0) {
		printf("[%s:%d] Received: %u bytes, only parsed: %d bytes\n",
		       __func__, __LINE__, rcv_len, parsed_len);
	}

	if (http_ctx->parser.http_errno != HPE_OK) {
		http_response_400(http_ctx, NULL);
	} else {
		http_tx(http_ctx);
	}

lb_exit:
	net_pkt_frag_unref(data);
	net_pkt_unref(rx);

	http_ctx_release(http_ctx);
}