Ejemplo n.º 1
0
bool ieee802154_create_data_frame(struct net_if *iface,
				  struct in6_addr *dst,
				  uint8_t *p_buf,
				  uint8_t len)
{
	struct ieee802154_context *ctx = net_if_l2_data(iface);
	struct ieee802154_frame_params params;
	struct ieee802154_fcf_seq *fs;
	uint8_t *frag_start = p_buf;

	fs = generate_fcf_grounds(&p_buf, ctx->ack_requested);

	fs->fc.frame_type = IEEE802154_FRAME_TYPE_DATA;
	fs->sequence = ctx->sequence++;

	params.dst.pan_id = ctx->pan_id;
	params.pan_id = ctx->pan_id;
	data_addr_to_fs_settings(iface, dst, fs, &params);

	p_buf = generate_addressing_fields(iface, fs, &params, p_buf);

	if ((p_buf - frag_start) != len) {
		/* ll reserve was too small? We probably overwrote
		 * payload bytes
		 */
		return false;
	}

	/* Todo: handle security aux header */

	dbg_print_fs(fs);

	return true;
}
Ejemplo n.º 2
0
struct net_buf *
ieee802154_create_mac_cmd_frame(struct net_if *iface,
				enum ieee802154_cfi type,
				struct ieee802154_frame_params *params)
{
	struct ieee802154_context *ctx = net_if_l2_data(iface);
	struct ieee802154_fcf_seq *fs;
	struct net_buf *buf, *frag;
	uint8_t *p_buf;

	buf = net_nbuf_get_reserve_tx(0);
	if (!buf) {
		return NULL;
	}

	frag = net_nbuf_get_reserve_data(0);
	if (!frag) {
		goto error;
	}

	net_buf_frag_add(buf, frag);
	p_buf = net_nbuf_ll(buf);

	fs = generate_fcf_grounds(&p_buf, false);

	fs->fc.frame_type = IEEE802154_FRAME_TYPE_MAC_COMMAND;
	fs->sequence = ctx->sequence;

	if (!cfi_to_fs_settings(type, fs, params)) {
		goto error;
	}

	p_buf = generate_addressing_fields(iface, fs, params, p_buf);

	/* Let's insert the cfi */
	((struct ieee802154_command *)p_buf)->cfi = type;

	/* In MAC command, we consider ll header being the mhr.
	 * Rest will be the MAC command itself. This will proove
	 * to be easy to handle afterwards to point directly to MAC
	 * command space, in order to fill-in its content.
	 */
	net_nbuf_set_ll_reserve(buf, p_buf - net_nbuf_ll(buf));
	net_buf_pull(frag, net_nbuf_ll_reserve(buf));

	/* Thus setting the right MAC command length
	 * Now up to the caller to fill-in this space relevantly.
	 * See ieee802154_mac_command() helper.
	 */
	net_nbuf_set_len(frag, mac_command_length(type));

	dbg_print_fs(fs);

	return buf;
error:
	net_nbuf_unref(buf);

	return NULL;
}
Ejemplo n.º 3
0
struct net_pkt *
ieee802154_create_mac_cmd_frame(struct ieee802154_context *ctx,
				enum ieee802154_cfi type,
				struct ieee802154_frame_params *params)
{
	struct ieee802154_fcf_seq *fs;
	struct net_pkt *pkt;
	struct net_buf *frag;
	u8_t *p_buf;

	pkt = net_pkt_get_reserve_tx(0, K_FOREVER);
	if (!pkt) {
		return NULL;
	}

	frag = net_pkt_get_frag(pkt, K_FOREVER);
	if (!frag) {
		goto error;
	}

	net_pkt_frag_add(pkt, frag);
	p_buf = net_pkt_ll(pkt);

	fs = generate_fcf_grounds(&p_buf,
				  type == IEEE802154_CFI_BEACON_REQUEST ?
				  false : ctx->ack_requested);

	fs->fc.frame_type = IEEE802154_FRAME_TYPE_MAC_COMMAND;
	fs->sequence = ctx->sequence;

	if (!cfi_to_fs_settings(type, fs, params)) {
		goto error;
	}

	p_buf = generate_addressing_fields(ctx, fs, params, p_buf);

	/* Let's insert the cfi */
	((struct ieee802154_command *)p_buf)->cfi = type;

	/* In MAC command, we consider ll header being the mhr.
	 * Rest will be the MAC command itself. This will proove
	 * to be easy to handle afterwards to point directly to MAC
	 * command space, in order to fill-in its content.
	 */
	net_pkt_set_ll_reserve(pkt, p_buf - net_pkt_ll(pkt));
	net_buf_pull(frag, net_pkt_ll_reserve(pkt));

	/* Thus setting the right MAC command length
	 * Now up to the caller to fill-in this space relevantly.
	 * See ieee802154_mac_command() helper.
	 */
	frag->len = mac_command_length(type);

	dbg_print_fs(fs);

	return pkt;
error:
	net_pkt_unref(pkt);

	return NULL;
}
Ejemplo n.º 4
0
bool ieee802154_create_data_frame(struct ieee802154_context *ctx,
				  struct net_linkaddr *dst,
				  struct net_buf *frag,
				  u8_t reserved_len)
{
	struct ieee802154_frame_params params;
	struct ieee802154_fcf_seq *fs;
	u8_t *p_buf = frag->data - reserved_len;
	u8_t *frag_start = p_buf;
	bool broadcast;

	fs = generate_fcf_grounds(&p_buf, ctx->ack_requested);

	fs->fc.frame_type = IEEE802154_FRAME_TYPE_DATA;
	fs->sequence = ctx->sequence++;

	params.dst.pan_id = ctx->pan_id;
	params.pan_id = ctx->pan_id;

	broadcast = data_addr_to_fs_settings(dst, fs, &params);

	p_buf = generate_addressing_fields(ctx, fs, &params, p_buf);

#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
	if (broadcast) {
		NET_DBG("No security hdr needed: broadcasting");

		goto no_security_hdr;
	}

	fs->fc.security_enabled = 1;

	p_buf = generate_aux_security_hdr(&ctx->sec_ctx, p_buf);

	/* If tagged, let's retrieve tag space from ll reserved space.
	 * See comment in ieee802154_compute_header_size()
	 */
	if (ctx->sec_ctx.level != IEEE802154_SECURITY_LEVEL_NONE &&
	    ctx->sec_ctx.level != IEEE802154_SECURITY_LEVEL_ENC) {
		u8_t level;

		level = ctx->sec_ctx.level;
		if (level >= IEEE802154_SECURITY_LEVEL_ENC) {
			level -= 4;
		}

		/* p_buf should point to the right place */
		memmove(p_buf, frag->data, frag->len);
		reserved_len -= level_2_tag_size[level];
	}

no_security_hdr:
#endif /* CONFIG_NET_L2_IEEE802154_SECURITY */

	if ((p_buf - frag_start) != reserved_len) {
		/* ll reserve was too small? We probably overwrote
		 * payload bytes
		 */
		NET_ERR("Could not generate data frame %zu vs %u",
			(p_buf - frag_start), reserved_len);
		return false;
	}

	dbg_print_fs(fs);

	/* Let's encrypt/auth only in the end, is needed */
	return ieee802154_encrypt_auth(broadcast ? NULL : &ctx->sec_ctx,
				       frag_start, reserved_len, frag->len,
				       ctx->ext_addr);
}