Exemple #1
0
/**
 * \brief This function handle messages in STREAM OPEN state
 *
 * \param[in] *C The pointer at cpntext
 *
 * \return This function return 1, when it ends successfuly, otherwise it
 * returns 0
 */
int v_STREAM_handle_messages(struct vContext *C)
{
	struct IO_CTX *io_ctx = CTX_io_ctx(C);
	int ret = 1, buffer_pos = 0, i;
	struct VMessage *r_message = CTX_r_message(C);
	struct VSession *vsession = CTX_current_session(C);

	/* Make sure, that buffer contains at least Verse message
	 * header. If this condition is not reached, then somebody tries
	 * to do some very bad things! .. Close this connection. */
	if(io_ctx->buf_size < VERSE_MESSAGE_HEADER_SIZE) {
		if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "received buffer too small %d\n",
				io_ctx->buf_size);
		ret = 0;
		goto end;
	}

	/* Reset content of received message */
	memset(r_message, 0, sizeof(struct VMessage));

	/* Unpack Verse message header */
	buffer_pos += v_unpack_message_header(&io_ctx->buf[buffer_pos], (io_ctx->buf_size - buffer_pos), r_message);

	/* Unpack all system commands */
	buffer_pos += v_unpack_message_system_commands(&io_ctx->buf[buffer_pos], (io_ctx->buf_size - buffer_pos), r_message);

	v_print_receive_message(C);

	/* Handle system commands */
	for(i=0;
			i<MAX_SYSTEM_COMMAND_COUNT && r_message->sys_cmd[i].cmd.id != CMD_RESERVED_ID;
			i++)
	{
		if(r_message->sys_cmd[i].cmd.id == CMD_CHANGE_L_ID &&
				r_message->sys_cmd[i].negotiate_cmd.feature == FTR_FPS &&
				r_message->sys_cmd[i].negotiate_cmd.count > 0)
		{
			vsession->fps_host = vsession->fps_peer = r_message->sys_cmd[i].negotiate_cmd.value->real32;
			vsession->tmp_flags |= SYS_CMD_NEGOTIATE_FPS;
		}

		if(r_message->sys_cmd[i].cmd.id == CMD_CONFIRM_L_ID &&
				r_message->sys_cmd[i].negotiate_cmd.feature == FTR_FPS &&
				r_message->sys_cmd[i].negotiate_cmd.count > 0)
		{
			vsession->fps_peer = r_message->sys_cmd[i].negotiate_cmd.value->real32;
		}
	}

	/* Unpack all node commands and put them to the queue of incomming commands */
	buffer_pos += v_cmd_unpack((char*)&io_ctx->buf[buffer_pos], (io_ctx->buf_size - buffer_pos), vsession->in_queue);

end:
	return ret;
}
/**
 * \brief This function handles node commands, when payload packet was received.
 *
 * This function also detects packet loss of previous not received payload
 * packets. All node commands are unpacked from the buffer and added to incoming queue.
 *
 * \param[in]	*C	The verse context.
 *
 * \return		This function returns RECEIVE_PACKET_DELAYED, when delayd packet
 * was received, otherwise it returns RECEIVE_PACKET_SUCCESS.
 */
static int handle_node_commands(struct vContext *C)
{
	struct VSession *vsession = CTX_current_session(C);
	struct VDgramConn *vconn = CTX_current_dgram_conn(C);
	struct VPacket *r_packet = CTX_r_packet(C);
	struct Ack_Nak_Cmd ack_nak_cmd;

	/* Note: when ACK and NAK command are add to the AckNak history,
	 * then this vector of commands is automatically compressed. */

	/* Was any packet lost since last receiving of packet? */
	if(r_packet->header.payload_id > vconn->last_r_pay+1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Packet(s) lost: %d - %d\n",
				vconn->last_r_pay+1, r_packet->header.payload_id-1);
		/* Add NAK command to the list of ACK NAK commands */
		ack_nak_cmd.id = CMD_NAK_ID;
		ack_nak_cmd.pay_id = vconn->last_r_pay+1;
		v_ack_nak_history_add_cmd(&vconn->ack_nak, &ack_nak_cmd);
	/* Was some delayed packet received? */
	} else if(r_packet->header.payload_id < vconn->last_r_pay+1) {
		if(is_log_level(VRS_PRINT_WARNING))
			v_print_log(VRS_PRINT_WARNING, "Received unordered packet: %d, expected: %d\n", r_packet->header.payload_id, vconn->last_r_pay+1);
		/* Drop this packet */
		return RECEIVE_PACKET_UNORDERED;
	}

	/* ADD ACK command to the list of ACK NAK commands */
	ack_nak_cmd.id = CMD_ACK_ID;
	ack_nak_cmd.pay_id = r_packet->header.payload_id;
	v_ack_nak_history_add_cmd(&vconn->ack_nak, &ack_nak_cmd);

	/* Check if there are really node commands */
	if(r_packet->data!=NULL) {
		/* Unpack node commands and put them to the queue of incoming commands */
		v_cmd_unpack((char*)r_packet->data, r_packet->data_size, vsession->in_queue);
	}

	return RECEIVE_PACKET_SUCCESS;
}