int xbee_ipv4_envelope_send(const xbee_ipv4_envelope_t FAR *envelope)
{
	xbee_dev_t *xbee;
	xbee_header_transmit_ipv4_t header;
	int retval;
	
	if (envelope == NULL || envelope->xbee == NULL) {
		return -EINVAL;
	}
	
	if (envelope->length > XBEE_IPV4_MAX_PAYLOAD) {
		return -E2BIG;
	}
	
	xbee = (xbee_dev_t *) envelope->xbee;
	
	header.frame_type = XBEE_FRAME_TRANSMIT_IPV4;
	header.frame_id = xbee_next_frame_id(xbee);
	header.remote_addr_be = envelope->remote_addr_be;
	header.remote_port_be = htobe16(envelope->remote_port);
	header.local_port_be = htobe16(envelope->local_port);
	header.protocol = envelope->protocol;
	header.options = envelope->options;
	

	#ifdef XBEE_IPV4_VERBOSE
		char protocol_string[8];
		char buf_addr[16];
		xbee_ipv4_protocol_str(protocol_string, envelope->protocol)
		printf( "%s: %u bytes to %s "	\
			"(src_port=0x%04x dest_port=0x%04x prot=%s opt=%02x)\n",
			__FUNCTION__, envelope->length, 
			xbee_ipv4_ntoa(buf_addr, envelope->remote_addr_be),
			envelope->remote_port, envelope->local_port,
			protocol_string, envelope->options);
	#endif
	
	retval = xbee_frame_write( xbee, &header, sizeof(header), 
				envelope->payload, envelope->length, 0);
	
	#ifdef XBEE_IPV4_VERBOSE
		printf( "%s: %s returned %d\n", __FUNCTION__, "xbee_frame_write", retval);
	#endif
	return retval;
}
/**
	@internal

	Sends data to an endpoint/profile/cluster on a remote WPAN
	node.  See wpan_endpoint_send_fn() for parameters and return values.

	User code should use wpan_envelope_send() instead of calling this
	function directly.
*/
xbee_wpan_debug
int _xbee_endpoint_send( const wpan_envelope_t FAR *envelope, uint16_t flags)
{
	xbee_dev_t *xbee;
	xbee_header_transmit_explicit_t	header;
	int error;

	// note that wpan_envelope_send() verifies that envelope is not NULL

	xbee = (xbee_dev_t *) envelope->dev;

	// Convert envelope to the necessary frame type and call xbee_frame_send
	header.frame_type = (uint8_t) XBEE_FRAME_TRANSMIT_EXPLICIT;
	header.frame_id = xbee_next_frame_id( xbee);
	header.ieee_address = envelope->ieee_address;
	header.network_address_be = htobe16( envelope->network_address);
	header.source_endpoint = envelope->source_endpoint;
	header.dest_endpoint = envelope->dest_endpoint;
	header.cluster_id_be = htobe16( envelope->cluster_id);
	header.profile_id_be = htobe16( envelope->profile_id);
	header.broadcast_radius = 0;
	header.options = (flags & WPAN_SEND_FLAG_ENCRYPTED)
														? XBEE_TX_OPT_APS_ENCRYPT : 0;

	#ifdef XBEE_WPAN_VERBOSE
		printf( "%s: %u bytes to 0x%04x "	\
			"(ep=%02x->%02x clust=%04x prof=%04x opt=%02x)\n",
			__FUNCTION__, envelope->length, envelope->network_address,
			envelope->source_endpoint, envelope->dest_endpoint,
			envelope->cluster_id, envelope->profile_id, header.options);
	#endif

	error = xbee_frame_write( xbee,
		&header, sizeof(header), envelope->payload, envelope->length, 0);

	#ifdef XBEE_WPAN_VERBOSE
		printf( "%s: %s returned %d\n", __FUNCTION__, "xbee_frame_write", error);
	#endif

	return error;
}