VNetOutQueue * v_noq_create_network_queue(void) { VNetOutQueue *queue; unsigned int i; queue = malloc(sizeof *queue); for(i = 0; i < V_NOQ_OPTIMIZATION_SLOTS; i++) { queue->unsent[i] = NULL; queue->history[i] = NULL; } queue->unsent_comands = 0; queue->unsent_size = 0; queue->sent_size = 0; queue->packet_id = 2; queue->slot = 0; queue->packed = NULL; queue->last = NULL; queue->ack_nak = NULL; queue->unsorted = NULL; queue->unsorted_end = NULL; queue->unsorted_count = 0; queue->packet_buffer_use = 0; v_n_get_current_time(&queue->seconds, &queue->fractions); return queue; }
boolean v_con_callback_update(void) { static unsigned int seconds; boolean output = FALSE; unsigned int size, connection, s; VNetInPacked *p; v_n_get_current_time(&s, NULL); connection = VConData.current_connection; for(VConData.current_connection = 0; VConData.current_connection < VConData.con_count; VConData.current_connection++) if(VConData.con[VConData.current_connection].connect_stage != V_CS_CONNECTED) v_update_connection_pending(s != seconds); seconds = s; VConData.current_connection = connection; if(VConData.pending_packets == 0) return FALSE; if(VConData.con[VConData.current_connection].connect_stage == V_CS_CONNECTED) { while((p = v_niq_get(&VConData.con[VConData.current_connection].in_queue, &size)) != NULL) { VConData.pending_packets--; v_fs_unpack(p->data, size); v_niq_release(&VConData.con[VConData.current_connection].in_queue, p); output = TRUE; } v_con_network_listen(); } return output; }
void v_con_set_time(uint32 seconds, uint32 fractions) { uint32 s, f; v_n_get_current_time(&s, &f); if(f < fractions) s--; if (s < seconds) VConData.con[VConData.current_connection].timedelta_s = -(int)(seconds - s); else VConData.con[VConData.current_connection].timedelta_s = (int)(s - seconds); VConData.con[VConData.current_connection].timedelta_f = f - fractions; }
void verse_session_get_time(uint32 *seconds, uint32 *fractions) { uint32 s, f; v_n_get_current_time(&s, &f); if((uint32)~0 - f < VConData.con[VConData.current_connection].timedelta_f) s++; if(seconds != NULL) { if(VConData.con[VConData.current_connection].timedelta_s < 0) *seconds = s - (uint32)(-VConData.con[VConData.current_connection].timedelta_s); else *seconds = s + VConData.con[VConData.current_connection].timedelta_s; } if(fractions != NULL) *fractions = f + VConData.con[VConData.current_connection].timedelta_f; }
boolean v_noq_send_queue(VNetOutQueue *queue, void *address) { static unsigned int my_counter = 0; VCMDBufHead *buf; unsigned int size; uint8 *data; uint32 seconds, fractions; double delta; data = queue->packet_buffer; v_n_get_current_time(&seconds, &fractions); delta = seconds - queue->seconds + (fractions - queue->fractions) / (double) 0xffffffff; if(queue->unsorted != NULL) v_noq_sort_unsorted(queue); if(queue->unsent_size == 0 && delta < 1.0 && (queue->ack_nak == NULL || queue->ack_nak->next == NULL)) return FALSE; if(delta > 3.0 && queue->unsent_size == 0 && queue->ack_nak == NULL && queue->packet_buffer_use != 0) { /* printf("A) re-sending last delta=%g\n", delta);*/ v_n_send_data(address, data, queue->packet_buffer_use); queue->seconds = seconds; queue->fractions = fractions; return TRUE; } size = 4; buf = queue->ack_nak; while(buf != NULL && size + buf->size < V_NOQ_MAX_PACKET_SIZE) { vnp_raw_pack_uint32(data, queue->packet_id); queue->ack_nak = buf->next; buf->next = queue->history[queue->slot]; queue->history[queue->slot] = buf; buf->packet = queue->packet_id; v_e_data_encrypt_command(data, size, ((VCMDBuffer1500 *)buf)->buf, buf->size, v_con_get_data_key()); size += buf->size; queue->sent_size += buf->size; buf = queue->ack_nak; } if(queue->unsent_size == 0 || queue->sent_size >= V_NOQ_WINDOW_SIZE) { if(size > 5) { /* printf("ACK: sending actual size=%u id=%u\n", size, queue->packet_id);*/ v_n_send_data(address, data, size); queue->packet_buffer_use = size; queue->seconds = seconds; queue->fractions = fractions; queue->packet_id++; return TRUE; } /* printf("returning FALSE from send_queue()\n");*/ return FALSE; } /* if(queue->sent_size < V_NOQ_WINDOW_SIZE && queue->unsent_size != 0)*/ { vnp_raw_pack_uint32(data, queue->packet_id); while(queue->unsent_size != 0) { queue->slot = ((1 + queue->slot) % V_NOQ_OPTIMIZATION_SLOTS); buf = queue->unsent[queue->slot]; if(buf != NULL) { if(buf->size + size > V_NOQ_MAX_PACKET_SIZE) break; queue->unsent[queue->slot] = buf->next; buf->next = queue->history[queue->slot]; queue->history[queue->slot] = buf; buf->packet = queue->packet_id; v_e_data_encrypt_command(data, size, ((VCMDBuffer1500 *)buf)->buf, buf->size, v_con_get_data_key()); size += buf->size; queue->unsent_comands--; queue->unsent_size -= buf->size; queue->sent_size += buf->size; my_counter++; } } v_n_send_data(address, data, size); queue->packet_buffer_use = size; queue->packet_id++; /* size = vnp_raw_pack_uint32(data, queue->packet_id);*/ queue->seconds = seconds; queue->fractions = fractions; } return TRUE; }