src/pomp_prot.c
ssize_t pomp_prot_decode_msg(struct pomp_prot *prot, const void *buf,
		size_t len, struct pomp_msg **msg)
{
	size_t off = 0;

	POMP_RETURN_ERR_IF_FAILED(prot != NULL, -EINVAL);
	POMP_RETURN_ERR_IF_FAILED(buf != NULL, -EINVAL);
	POMP_RETURN_ERR_IF_FAILED(msg != NULL, -EINVAL);

	/* If idle, start a new parsing */
	if (prot->state == POMP_PROT_STATE_IDLE)
		prot->state = POMP_PROT_STATE_HEADER_MAGIC_0;

	/* Processing loop */
	while (off < len && prot->state != POMP_PROT_STATE_IDLE) {
		switch (prot->state) {
		case POMP_PROT_STATE_IDLE: /* NO BREAK */
		case POMP_PROT_STATE_HEADER_MAGIC_0:
			pomp_prot_reset_state(prot);
			prot->state = POMP_PROT_STATE_HEADER_MAGIC_0;
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 0, POMP_PROT_HEADER_MAGIC_0,
					POMP_PROT_STATE_HEADER_MAGIC_1);
			break;

		case POMP_PROT_STATE_HEADER_MAGIC_1:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 1, POMP_PROT_HEADER_MAGIC_1,
					POMP_PROT_STATE_HEADER_MAGIC_2);
			break;

		case POMP_PROT_STATE_HEADER_MAGIC_2:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 2, POMP_PROT_HEADER_MAGIC_2,
					POMP_PROT_STATE_HEADER_MAGIC_3);
			break;

		case POMP_PROT_STATE_HEADER_MAGIC_3:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 3, POMP_PROT_HEADER_MAGIC_3,
					POMP_PROT_STATE_HEADER);
			break;

		case POMP_PROT_STATE_HEADER:
			copy_header(prot, buf, &off, len);
			if (prot->offheader == POMP_PROT_HEADER_SIZE)
				pomp_prot_decode_header(prot);
			break;

		case POMP_PROT_STATE_PAYLOAD:
			copy_payload(prot, buf, &off, len);
			break;

		default:
			POMP_LOGE("Invalid state %d", prot->state);
			break;
		}

		/* Check end of payload */
		if (prot->state == POMP_PROT_STATE_PAYLOAD
				&& prot->offpayload == prot->header.size) {
			/* Give ownership of message to caller */
			prot->msg->finished = 1;
			*msg = prot->msg;
			prot->msg = NULL;
			prot->state = POMP_PROT_STATE_IDLE;
		}
	}

	/* Return number of bytes processed */
	return (ssize_t)off;
}
/**
 * Try to decode a message with given input data.
 * @param prot : protocol decoder.
 * @param buf : input data.
 * @param len : size of input data.
 * @param msg : will receive decoded message. If more input data is required
 * to decode the message, NULL will be returned. The message needs to be
 * released either by calling 'pomp_msg_destroy' or 'pomp_prot_release_msg'.
 * Calling 'pomp_prot_release_msg' allows reuse of allocated message structure.
 * @return number of bytes processed. It can be less that input size in which
 * case caller shall call again this function with remaining bytes.
 */
Try to decode a message with given input data.
@param prot : protocol decoder.
@param buf : input data.
@param len : size of input data.
@param msg : will receive decoded message. If more input data is required
to decode the message, NULL will be returned. The message needs to be
released either by calling 'pomp_msg_destroy' or 'pomp_prot_release_msg'.
Calling 'pomp_prot_release_msg' allows reuse of allocated message structure.
@return number of bytes processed. It can be less that input size in which
case caller shall call again this function with remaining bytes.
Try to decode a message with given input data . @param prot : protocol decoder . @param buf : input data . @param len : size of input data . @param msg : will receive decoded message . If more input data is required to decode the message NULL will be returned . The message needs to be released either by calling ' pomp_msg_destroy ' or ' pomp_prot_release_msg ' . Calling ' pomp_prot_release_msg ' allows reuse of allocated message structure . @return number of bytes processed . It can be less that input size in which case caller shall call again this function with remaining bytes .
ssize_t pomp_prot_decode_msg(struct pomp_prot *prot, const void *buf,
		size_t len, struct pomp_msg **msg)
{
	size_t off = 0;
	POMP_RETURN_ERR_IF_FAILED(prot != NULL, -EINVAL);
	POMP_RETURN_ERR_IF_FAILED(buf != NULL, -EINVAL);
	POMP_RETURN_ERR_IF_FAILED(msg != NULL, -EINVAL);
	if (prot->state == POMP_PROT_STATE_IDLE)
		prot->state = POMP_PROT_STATE_HEADER_MAGIC_0;
	while (off < len && prot->state != POMP_PROT_STATE_IDLE) {
		switch (prot->state) {
		case POMP_PROT_STATE_IDLE: 
		case POMP_PROT_STATE_HEADER_MAGIC_0:
			pomp_prot_reset_state(prot);
			prot->state = POMP_PROT_STATE_HEADER_MAGIC_0;
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 0, POMP_PROT_HEADER_MAGIC_0,
					POMP_PROT_STATE_HEADER_MAGIC_1);
			break;
		case POMP_PROT_STATE_HEADER_MAGIC_1:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 1, POMP_PROT_HEADER_MAGIC_1,
					POMP_PROT_STATE_HEADER_MAGIC_2);
			break;
		case POMP_PROT_STATE_HEADER_MAGIC_2:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 2, POMP_PROT_HEADER_MAGIC_2,
					POMP_PROT_STATE_HEADER_MAGIC_3);
			break;
		case POMP_PROT_STATE_HEADER_MAGIC_3:
			copy_header_magic(prot, buf, &off, len);
			pomp_prot_check_magic(prot, 3, POMP_PROT_HEADER_MAGIC_3,
					POMP_PROT_STATE_HEADER);
			break;
		case POMP_PROT_STATE_HEADER:
			copy_header(prot, buf, &off, len);
			if (prot->offheader == POMP_PROT_HEADER_SIZE)
				pomp_prot_decode_header(prot);
			break;
		case POMP_PROT_STATE_PAYLOAD:
			copy_payload(prot, buf, &off, len);
			break;
		default:
			POMP_LOGE("Invalid state %d", prot->state);
			break;
		}
		if (prot->state == POMP_PROT_STATE_PAYLOAD
				&& prot->offpayload == prot->header.size) {
			prot->msg->finished = 1;
			*msg = prot->msg;
			prot->msg = NULL;
			prot->state = POMP_PROT_STATE_IDLE;
		}
	}
	return (ssize_t)off;
}
ssize_t pomp_prot_decode_msg ( struct pomp_prot * prot , const void * buf , size_t len , struct pomp_msg * * msg ) { size_t off = 0 ; POMP_RETURN_ERR_IF_FAILED ( prot != NULL , - EINVAL ) ; POMP_RETURN_ERR_IF_FAILED ( buf != NULL , - EINVAL ) ; POMP_RETURN_ERR_IF_FAILED ( msg != NULL , - EINVAL ) ; if ( prot -> state == POMP_PROT_STATE_IDLE ) prot -> state = POMP_PROT_STATE_HEADER_MAGIC_0 ; while ( off < len && prot -> state != POMP_PROT_STATE_IDLE ) { switch ( prot -> state ) { case POMP_PROT_STATE_IDLE : case POMP_PROT_STATE_HEADER_MAGIC_0 : pomp_prot_reset_state ( prot ) ; prot -> state = POMP_PROT_STATE_HEADER_MAGIC_0 ; copy_header_magic ( prot , buf , & off , len ) ; pomp_prot_check_magic ( prot , 0 , POMP_PROT_HEADER_MAGIC_0 , POMP_PROT_STATE_HEADER_MAGIC_1 ) ; break ; case POMP_PROT_STATE_HEADER_MAGIC_1 : copy_header_magic ( prot , buf , & off , len ) ; pomp_prot_check_magic ( prot , 1 , POMP_PROT_HEADER_MAGIC_1 , POMP_PROT_STATE_HEADER_MAGIC_2 ) ; break ; case POMP_PROT_STATE_HEADER_MAGIC_2 : copy_header_magic ( prot , buf , & off , len ) ; pomp_prot_check_magic ( prot , 2 , POMP_PROT_HEADER_MAGIC_2 , POMP_PROT_STATE_HEADER_MAGIC_3 ) ; break ; case POMP_PROT_STATE_HEADER_MAGIC_3 : copy_header_magic ( prot , buf , & off , len ) ; pomp_prot_check_magic ( prot , 3 , POMP_PROT_HEADER_MAGIC_3 , POMP_PROT_STATE_HEADER ) ; break ; case POMP_PROT_STATE_HEADER : copy_header ( prot , buf , & off , len ) ; if ( prot -> offheader == POMP_PROT_HEADER_SIZE ) pomp_prot_decode_header ( prot ) ; break ; case POMP_PROT_STATE_PAYLOAD : copy_payload ( prot , buf , & off , len ) ; break ; default : POMP_LOGE ( " " , prot -> state ) ; break ; } if ( prot -> state == POMP_PROT_STATE_PAYLOAD && prot -> offpayload == prot -> header . size ) { prot -> msg -> finished = 1 ; * msg = prot -> msg ; prot -> msg = NULL ; prot -> state = POMP_PROT_STATE_IDLE ; } } return ( ssize_t ) off ; }
Try to decode a message with given input data.
Try to decode a message with given input data .
/* If idle, start a new parsing */ /* Processing loop */ /* NO BREAK */ /* Check end of payload */ /* Give ownership of message to caller */ /* Return number of bytes processed */