コード例 #1
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
static int coap_context_send(coap_context_t *ctx, struct net_buf *buf)
{
  int max_data_len, ret;

  max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

  PRINTF("%s: send to peer data %p len %d\n", __FUNCTION__,
	 ip_buf_appdata(buf), ip_buf_appdatalen(buf));

  if (ip_buf_appdatalen(buf) > max_data_len) {
    PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n",
	   __FUNCTION__, ip_buf_appdatalen(buf), max_data_len);
    ip_buf_unref(buf);
    ret = -EINVAL;
    goto out;
  }

  ret = net_send(buf);
  if (ret < 0) {
    PRINT("%s: sending %d bytes failed\n", __FUNCTION__,
	  ip_buf_appdatalen(buf));
    ip_buf_unref(buf);
  }

out:
  return ret;
}
コード例 #2
0
static inline bool wait_reply(const char *name,
			      struct net_context *ctx,
			      int ipsum_len,
			      int pos)
{
	struct net_buf *buf;
	bool fail = false;
	int expected_len = ipsum_len - pos;

	/* Wait for the answer */
	buf = net_receive(ctx, WAIT_TICKS);
	if (buf) {
		if (ip_buf_appdatalen(buf) != expected_len) {
			PRINT("%s: received %d bytes, expected %d\n",
			      name, ip_buf_appdatalen(buf), expected_len);
			fail = true;
			goto free_buf;
		}

		/* In this test we reverse the received bytes.
		 * We could just pass the data back as is but
		 * this way it is possible to see how the app
		 * can manipulate the received data.
		 */
		reverse(ip_buf_appdata(buf), ip_buf_appdatalen(buf));

		/* Did we get all the data back?
		 */
		if (memcmp(lorem_ipsum + pos, ip_buf_appdata(buf),
			   expected_len)) {
			PRINT("%s: received data mismatch.\n", name);
			fail = true;
			goto free_buf;
		}

		PRINT("%s: received %d bytes\n", __func__,
			      expected_len);

	free_buf:
		ip_buf_unref(buf);
	} else {
		PRINT("%s: expected data, got none\n", name);
		fail = true;
	}

	return fail;
}
コード例 #3
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
static int prepare_and_send_buf(coap_context_t *ctx, session_t *session,
				uint8_t *data, size_t len)
{
  struct net_buf *buf;
  int max_data_len;

  /* This net_buf gets sent to network, so it is not released
   * by this function unless there was an error and buf was
   * not actually sent.
   */
  buf = ip_buf_get_tx(ctx->net_ctx);
  if (!buf) {
    len = -ENOBUFS;
    goto out;
  }

  max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

  PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__, data, len);

  if (len > max_data_len) {
    PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n",
	  __FUNCTION__, len, max_data_len);
    ip_buf_unref(buf);
    len = -EINVAL;
    goto out;
  }

  /* Note that we have reversed the addresses here
   * because net_reply() will reverse them again.
   */
#ifdef CONFIG_NETWORKING_WITH_IPV6
  uip_ip6addr_copy(&NET_BUF_IP(buf)->destipaddr, (uip_ip6addr_t *)&ctx->my_addr.in6_addr);
  uip_ip6addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip6addr_t *)&session->addr.ipaddr);
#else
  uip_ip4addr_copy(&NET_BUF_IP(buf)->destipaddr,
		   (uip_ip4addr_t *)&ctx->my_addr.in_addr);
  uip_ip4addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip4addr_t *)&session->addr.ipaddr);
#endif
  NET_BUF_UDP(buf)->destport = uip_ntohs(ctx->my_port);
  NET_BUF_UDP(buf)->srcport = session->addr.port;

  uip_set_udp_conn(buf) = net_context_get_udp_connection(ctx->net_ctx);

  memcpy(net_buf_add(buf, len), data, len);
  ip_buf_appdatalen(buf) = len;
  ip_buf_appdata(buf) = buf->data + ip_buf_reserve(buf);

  if (net_reply(ctx->net_ctx, buf)) {
    ip_buf_unref(buf);
  }
out:
  return len;
}
コード例 #4
0
ファイル: ip_buf.c プロジェクト: 32bitmicro/zephyr
static struct net_buf *ip_buf_get_reserve(enum ip_buf_type type,
					  uint16_t reserve_head)
#endif
{
	struct net_buf *buf = NULL;

	/* Note that we do not reserve any space in front of the
	 * buffer so buf->data points to first byte of the IP header.
	 * This is done like this so that IP stack works the same
	 * way as BT and 802.15.4 stacks.
	 *
	 * The reserve_head variable in the function will tell
	 * the size of the IP + other headers if there are any.
	 * That variable is only used to calculate the pointer
	 * where the application data starts.
	 */
	switch (type) {
	case IP_BUF_RX:
		buf = net_buf_get(&free_rx_bufs, 0);
		dec_free_rx_bufs(buf);
		break;
	case IP_BUF_TX:
		buf = net_buf_get(&free_tx_bufs, 0);
		dec_free_tx_bufs(buf);
		break;
	}

	if (!buf) {
#ifdef DEBUG_IP_BUFS
		NET_ERR("Failed to get free %s buffer (%s():%d)\n",
			type2str(type), caller, line);
#else
		NET_ERR("Failed to get free %s buffer\n", type2str(type));
#endif
		return NULL;
	}

	ip_buf_type(buf) = type;
	ip_buf_appdata(buf) = buf->data + reserve_head;
	ip_buf_appdatalen(buf) = 0;
	ip_buf_reserve(buf) = reserve_head;
	net_buf_add(buf, reserve_head);

	NET_BUF_CHECK_IF_NOT_IN_USE(buf);

#ifdef DEBUG_IP_BUFS
	NET_DBG("%s [%d] buf %p reserve %u ref %d (%s():%d)\n",
		type2str(type), get_frees(type),
		buf, reserve_head, buf->ref, caller, line);
#else
	NET_DBG("%s buf %p reserve %u ref %d\n", type2str(type), buf,
		reserve_head, buf->ref);
#endif
	return buf;
}
コード例 #5
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks)
{
  struct net_buf *buf;

  buf = net_receive(coap_ctx->net_ctx, ticks);
  if (buf) {
    session_t session;
    int ret;

    uip_ipaddr_copy(&session.addr.ipaddr, &UIP_IP_BUF(buf)->srcipaddr);
    session.addr.port = UIP_UDP_BUF(buf)->srcport;
    session.size = sizeof(session.addr);
    session.ifindex = 1;

    PRINTF("coap-context: got dtls message from ");
    PRINT6ADDR(&session.addr.ipaddr);
    PRINTF(":%d %u bytes\n", uip_ntohs(session.addr.port), uip_appdatalen(buf));

    PRINTF("Received appdata %p appdatalen %d\n",
	   ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    coap_ctx->buf = buf;

    ret = dtls_handle_message(coap_ctx->dtls_context, &session,
			      ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    /* We always release the buffer here as this buffer is never sent
     * to network anyway.
     */
    if (coap_ctx->buf) {
      ip_buf_unref(coap_ctx->buf);
      coap_ctx->buf = NULL;
    }

    return ret;
  }

  return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: CurieBSP/zephyr
static inline struct net_buf *prepare_reply(const char *type,
					    struct net_buf *buf)
{
	printk("%s: received %d bytes\n", type, ip_buf_appdatalen(buf));

	/* In this test we reverse the received bytes.
	 * We could just pass the data back as is but
	 * this way it is possible to see how the app
	 * can manipulate the received data.
	 */
	reverse(ip_buf_appdata(buf), ip_buf_appdatalen(buf));

	return buf;
}
コード例 #7
0
ファイル: tcp.c プロジェクト: hudkmr/zephyr
int tcp_rx(struct net_context *ctx, uint8_t *buf, size_t *read_bytes, size_t size)
{
	struct net_buf *nbuf;
	int rc;

	nbuf = net_receive(ctx, TCP_RX_TIMEOUT);
	rc = -EIO;
	if (nbuf != NULL) {
		*read_bytes = ip_buf_appdatalen(nbuf);
		if (*read_bytes > size) {
			rc = -ENOMEM;
		} else {
			memcpy(buf, ip_buf_appdata(nbuf), *read_bytes);
			rc = 0;
		}
		ip_buf_unref(nbuf);
	}
	return rc;
}
コード例 #8
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks)
{
  struct net_buf *buf;

  buf = net_receive(coap_ctx->net_ctx, ticks);
  if (buf) {
    PRINTF("coap-context: got message from ");
    PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
    PRINTF(":%d %u bytes\n", uip_ntohs(UIP_UDP_BUF(buf)->srcport),
	   uip_appdatalen(buf));

    PRINTF("Received data appdata %p appdatalen %d\n",
	   ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    coap_ctx->buf = buf;

    coap_engine_receive(coap_ctx);

    return 1;
  }

  return 0;
}
コード例 #9
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
int coap_context_reply(coap_context_t *ctx, struct net_buf *buf)
{
  int max_data_len, ret;

  max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

  PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__,
	 ip_buf_appdata(buf), ip_buf_appdatalen(buf));

  if (ip_buf_appdatalen(buf) > max_data_len) {
    PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n",
	  __FUNCTION__, ip_buf_appdatalen(buf), max_data_len);
    ip_buf_unref(buf);
    ret = -EINVAL;
    goto out;
  }

  if (net_reply(ctx->net_ctx, buf)) {
    ip_buf_unref(buf);
  }
out:
  return ret;
}
コード例 #10
0
ファイル: er-coap-context.c プロジェクト: CurieBSP/zephyr
/*---------------------------------------------------------------------------*/
int
coap_context_send_message(coap_context_t *coap_ctx,
                          uip_ipaddr_t *addr, uint16_t port,
                          const uint8_t *data, uint16_t length)
{
  int ret;

  if(coap_ctx == NULL || coap_ctx->is_used == 0) {
    PRINTF("coap-context: can not send on non-used context\n");
    return 0;
  }

  ip_buf_appdatalen(coap_ctx->buf) = length;

  if (!uip_udp_conn(coap_ctx->buf)) {
    /* Normal send, not a reply */
    ret = coap_context_send(coap_ctx, coap_ctx->buf);

  } else {

    /* We need to set the uIP buffer lengths in net_buf properly as
     * otherwise the final buffer length in
     * net_init.c:udp_prepare_and_send() will be usually incorrect
     * (uip_len() will be length of the received packet). So by setting
     * uip_len() to 0 here, we let the sending in net_init.c to
     * set the send buffer length correctly.
     */
    uip_len(coap_ctx->buf) = 0;
    memcpy(ip_buf_appdata(coap_ctx->buf), data, length);

    ret = coap_context_reply(coap_ctx, coap_ctx->buf);
  }

  coap_ctx->buf = NULL;
  return ret;
}
コード例 #11
0
ファイル: network.c プロジェクト: 32bitmicro/zephyr
static void receive_data(const char *taskname, struct net_context *ctx)
{
	struct net_buf *buf;
#ifdef CONFIG_NET_SANITY_TEST
	int rp;
#endif

	buf = net_receive(ctx, TICKS_NONE);
	if (buf) {
		PRINT("%s: %s(): received %d bytes\n", taskname,
		      __func__, ip_buf_appdatalen(buf));
		if (memcmp(ip_buf_appdata(buf),
			   lorem_ipsum, sizeof(lorem_ipsum))) {
			PRINT("ERROR: data does not match\n");

#ifdef CONFIG_NET_SANITY_TEST
			rp = TC_FAIL;
		} else {
			rp = TC_PASS;
#endif
		}

		ip_buf_unref(buf);

#ifdef CONFIG_NET_SANITY_TEST
		loopback++;
		test_rp = test_rp && rp;
		TC_END_RESULT(rp);

		if (loopback == CONFIG_NET_15_4_LOOPBACK_NUM) {
			loopback = 0;
			TC_END_REPORT(test_rp);
		}
#endif
	}
}
コード例 #12
0
ファイル: net_context.c プロジェクト: 32bitmicro/zephyr
/* This is called by contiki/ip/tcpip.c:tcpip_uipcall() when packet
 * is processed.
 */
PROCESS_THREAD(tcp, ev, data, buf, user_data)
{
	PROCESS_BEGIN();

	while(1) {
		PROCESS_YIELD_UNTIL(ev == tcpip_event);

		if (POINTER_TO_INT(data) == TCP_WRITE_EVENT) {
			/* We want to send data to peer. */
			struct net_context *context = user_data;

			if (!context) {
				continue;
			}

			do {
				context = user_data;
				if (!context || !buf) {
					break;
				}

				if (!context->ps.net_buf ||
				    context->ps.net_buf != buf) {
					NET_DBG("psock init %p buf %p\n",
						&context->ps, buf);
					PSOCK_INIT(&context->ps, buf);
				}

				handle_tcp_connection(&context->ps,
						      POINTER_TO_INT(data),
						      buf);

				PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);

				if (POINTER_TO_INT(data) != TCP_WRITE_EVENT) {
					goto read_data;
				}
			} while(!(uip_closed(buf)  ||
				  uip_aborted(buf) ||
				  uip_timedout(buf)));

			context = user_data;

			if (context &&
			    context->tcp_type == NET_TCP_TYPE_CLIENT) {
				NET_DBG("\nConnection closed.\n");
				ip_buf_sent_status(buf) = -ECONNRESET;
			}

			continue;
		}

	read_data:
		/* We are receiving data from peer. */
		if (buf && uip_newdata(buf)) {
			struct net_buf *clone;

			if (!uip_len(buf)) {
				continue;
			}

			/* Note that uIP stack will reuse the buffer when
			 * sending ACK to peer host. The sending will happen
			 * right after this function returns. Because of this
			 * we cannot use the same buffer to pass data to
			 * application.
			 */
			clone = net_buf_clone(buf);
			if (!clone) {
				NET_ERR("No enough RX buffers, "
					"packet %p discarded\n", buf);
				continue;
			}

			ip_buf_appdata(clone) = uip_buf(clone) +
				(ip_buf_appdata(buf) - (void *)uip_buf(buf));
			ip_buf_appdatalen(clone) = uip_len(buf);
			ip_buf_len(clone) = ip_buf_len(buf);
			ip_buf_context(clone) = user_data;
			uip_set_conn(clone) = uip_conn(buf);
			uip_flags(clone) = uip_flags(buf);
			uip_flags(clone) |= UIP_CONNECTED;

			NET_DBG("packet received context %p buf %p len %d "
				"appdata %p appdatalen %d\n",
				ip_buf_context(clone),
				clone,
				ip_buf_len(clone),
				ip_buf_appdata(clone),
				ip_buf_appdatalen(clone));

			nano_fifo_put(net_context_get_queue(user_data), clone);

			/* We let the application to read the data now */
			fiber_yield();
		}
	}

	PROCESS_END();
}