/** * \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; }