/**
	@file		msg.c
	@brief 		File containing the source code of the messaging functions passed between the nodes
	@author		Adrían Antoñana Gómez
	@author		Carlos Díaz Cánovas
	@version	rc-2008/12/07

*/
#include "msg.h"


/**
	Makes a message array according to the protocol.Allows a void payload
	and just a length, so the payload will be filled with 0.

	@verbatim
	Protocol description:
	p[0] 		= route length	(N bytes)
	p[1] 		= jump		(points to next byte/node to jump, 0 for the first...)
	p[2]		= payload len	(X bytes)
	p[3..n+3]	= route		(the route itself, in order, 1 byte per node)
	p[n+4..n+x]	= payload
	@endverbatim
	@note		The first byte of the payload will contain the message ID


	@param[out]	*data		The array where the message will be stored, with already reserved memory
	@param[in]	*route		The route to send through
	@param[in]	routeLen	Length of the route
	@param[in]	*payload	The payload to include, could be NULL so the payload will be 0
	@param[in]	payloadLen	The length of the payload
	@param[in]	msgId		The message ID to include
	@return		void
*/
void msg_make(uint8_t *data, uint8_t *route, uint8_t routeLen, uint8_t *payload, uint8_t payloadLen, uint8_t msgId) {
int i = 0;

	if (!route || !data) return NULL;

	data[0] = routeLen;
	data[1] = 0;
	data[2] = payloadLen;

	for (i=0; i<routeLen; i++)	data[3+i] = route[i];

	data[3+routeLen] = msgId;

	for (i=1; i<payloadLen; i++) {
		if (payload)	data[3+routeLen+i] = payload[i-1];
		else		data[3+routeLen+i] = 0;
	}

}


/**
	Takes a message packet and sends it to the next node in the list or
	returns the payload if the final node has been reached.

	@brief		Processes a message
	@param[in]	*d		The message containing the packet
	@param[in]	thisNode	The actual node ID
	@return		uint8_t*	The payload if the message has reached its destination or NULL		
*/
uint8_t *msg_process(uint8_t *d, uint8_t thisNode) {
netpacket_send_args_t npsargs;
uint8_t to = 0, routeLen = 0, payloadLen = 0, jump = 0;

	if (!d) return NULL;

	/*Get the length of the route and the payload and the jump value*/
	routeLen = d[MSG_ROUTELEN];
	payloadLen = d[MSG_PAYLOADLEN];
	jump = d[MSG_JUMP] + 1;

	/*Send to...*/
	to = d[3+jump];

	/*Next node !*/
	d[MSG_JUMP] = jump;

	/*If the message is for us, return it*/
	if (d[3+jump-1] == thisNode && jump == routeLen) return d+(3+routeLen);

	/*If not, we send it*/
	else {

		DEBUGM("message to : %d\n", to);

		Net_sendArgsInit(&npsargs);
		npsargs.netheader.to = to;
		npsargs.netheader.type = USERDEFINED_PACKET+MESSAGE;
		npsargs.netheader.flags = 0;
		npsargs.payload[0].buffer = (uint8_t*) d;
		npsargs.payload[0].size = 3 + routeLen + payloadLen;
		Net_send(&npsargs);


	}

return NULL;
}


/**
	Returns the payload length of a message

	@brief		Returns the payload length of a message
	@param[in]	*d		The packet containing the message
	@return		uint8_t		The message length
*/
uint8_t msg_len(uint8_t *d) {
	
	if (!d) return 0;

	return d[MSG_PAYLOADLEN];

}


/**
	Returns the payload of a message
	
	@brief		Returns the payload of a message
	@param[in]	*d		The packet containing the message
	@return		uint8_t*	Message payload or NULL if the packet is void
*/
uint8_t *msg_get_message(uint8_t *d) {
uint8_t routeLen = 0;

	if (!d) return NULL;

	routeLen = d[MSG_ROUTELEN];

return d+(3+routeLen);
}

