/** * Process an KEY_REQ message */ void handle_key_req(const union sockaddr_u *src, const unsigned char *packet, unsigned packetlen) { const struct key_req_h *keyreq; struct timeval current_timestamp; char destname[INET6_ADDRSTRLEN]; int rval; keyreq = (const struct key_req_h *)(packet + sizeof(struct uftp_h)); if ((rval = getnameinfo((const struct sockaddr *)src, family_len(*src), destname, sizeof(destname), NULL, 0, NI_NUMERICHOST)) != 0) { log1(0, 0, 0, "getnameinfo failed: %s", gai_strerror(rval)); } if ((packetlen < sizeof(struct uftp_h) + (keyreq->hlen * 4U)) || ((keyreq->hlen * 4U) < sizeof(struct key_req_h))) { log1(0,0,0,"Rejecting KEY_REQ from %s: invalid message size", destname); return; } log2(0, 0, 0, "Received KEY_REQ from %s", destname); gettimeofday(¤t_timestamp, NULL); if (diff_sec(current_timestamp, last_key_req) > KEY_REQ_LIMIT) { send_proxy_key(); } }
void refresh_stat() { long long this_tick = gettime(); if(diff_sec(last_refresh, this_tick) >= 1) { time_in_section[0] = this_tick - last_start[0]; sprintf(txtbuffer, "gfx=%f%%", 100.0f * (float)time_in_section[GFX_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_GFX); sprintf(txtbuffer, "audio=%f%%", 100.0f * (float)time_in_section[AUDIO_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_AUDIO); sprintf(txtbuffer, "tlb=%f%%", 100.0f * (float)time_in_section[TLB_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_TLB); sprintf(txtbuffer, "fp=%f%%", 100.0f * (float)time_in_section[FP_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_FP); sprintf(txtbuffer, "comp=%f%%", 100.0f * (float)time_in_section[COMPILER_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_COMP); sprintf(txtbuffer, "interp=%f%%", 100.0f * (float)time_in_section[INTERP_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_INTERP); sprintf(txtbuffer, "tramp=%f%%", 100.0f * (float)time_in_section[TRAMP_SECTION] / (float)time_in_section[0]); DEBUG_print(txtbuffer, DBG_PROFILE_TRAMP); int i; for(i=1; i<=NUM_SECTIONS; ++i) time_in_section[i] = 0; last_start[0] = this_tick; last_refresh = this_tick; } }
void UpdatePads() { #ifdef HW_RVL WPAD_ScanPads(); #endif now = gettime(); if(!padsConnected && diff_sec(prev, now) < 2) return; prev = now; padsConnected = PAD_ScanPads(); if(!padsConnected) return; for(int i=3; i >= 0; i--) { userInput[i].pad.btns_d = PAD_ButtonsDown(i); userInput[i].pad.btns_u = PAD_ButtonsUp(i); userInput[i].pad.btns_h = PAD_ButtonsHeld(i); userInput[i].pad.stickX = PAD_StickX(i); userInput[i].pad.stickY = PAD_StickY(i); userInput[i].pad.substickX = PAD_SubStickX(i); userInput[i].pad.substickY = PAD_SubStickY(i); userInput[i].pad.triggerL = PAD_TriggerL(i); userInput[i].pad.triggerR = PAD_TriggerR(i); } }
long CTimerCpu::get_time_sec(){ #ifndef USE_CUSTOM_TIMER return get_time_ms() / 1000; #else if( isRunning == true ){ clock_gettime(CLOCK_MONOTONIC, &t_stop); } return diff_sec( t_start, t_stop ); #endif }
void DEBUG_update() { #ifdef SHOW_DEBUG int i; long long nowTick = gettime(); for(i=0; i<DEBUG_TEXT_HEIGHT; i++){ if(diff_sec(texttimes[i],nowTick)>=DEBUG_STRING_LIFE) { memset(text[i],0,DEBUG_TEXT_WIDTH); } } check_heap_space(); #endif }
bool InitializeNetwork(bool silent) { #ifdef HW_RVL StopNetworkThread(); if(networkInit && net_gethostip() > 0) return true; networkInit = false; #else if(networkInit) return true; #endif int retry = 1; while(retry) { ShowAction("Initializing network..."); #ifdef HW_RVL u64 start = gettime(); StartNetworkThread(); while (!LWP_ThreadIsSuspended(networkthread)) { usleep(50 * 1000); if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init break; } #else networkInit = !(if_config(wiiIP, NULL, NULL, true) < 0); #endif CancelAction(); if(networkInit || silent) break; retry = ErrorPromptRetry("Unable to initialize network!"); #ifdef HW_RVL if(networkInit && net_gethostip() > 0) #else if(networkInit) #endif return true; } return networkInit; }
/** * Process an KEY_REQ message */ void handle_key_req(const struct sockaddr_in *src, const unsigned char *packet) { struct hostent *hp; struct timeval current_timestamp; if (!noname && (hp = gethostbyaddr((char *)&src->sin_addr, sizeof(struct in_addr), AF_INET))) { log(0, 0, "Received KEY_REQ from %s (%s)", hp->h_name, inet_ntoa(src->sin_addr)); } else { log(0, 0, "Received KEY_REQ from %s", inet_ntoa(src->sin_addr)); } gettimeofday(¤t_timestamp, NULL); if (diff_sec(current_timestamp, last_key_req) > KEY_REQ_LIMIT) { send_proxy_key(); } }
/**************************************************************************** * InitializeNetwork * Initializes the Wii/GameCube network interface ***************************************************************************/ bool InitializeNetwork(bool silent) { StopNetworkThread(); if(networkInit && net_gethostip() > 0) return true; networkInit = false; int retry = 1; while(retry) { ShowAction("Initializing network..."); u64 start = gettime(); StartNetworkThread(); while (!LWP_ThreadIsSuspended(networkthread)) { usleep(50 * 1000); if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init break; } CancelAction(); if(networkInit || silent) break; retry = ErrorPromptRetry("Unable to initialize network!"); if(networkInit && net_gethostip() > 0) return true; } return networkInit; }
/** * Performs the Transfer phase for a particular file * Returns 1 if at least one client finished, 0 if all are dropped or aborted */ int transfer_phase(struct finfo_t *finfo) { unsigned char *packet, *encpacket, *data; char path[MAXPATHNAME]; struct uftp_h *header; struct fileseg_h *fileseg; int max_time, alldone, numbytes, sent_blocks, current_naks; unsigned int pass, section, numnaks, block; struct timeval start_time, last_sent, current_sent; int64_t avgwait, waitcnt, overage, tdiff; f_offset_t offset, curr_offset; int file, i; if (finfo->file_id != 0) { // First check to see if all clients are already done for this file. // This can happen on a restart when the file finished on the // last attempt and responded to the FILEINFO with a COMPLETE for (i = 0, alldone = 1; (i < destcount) && alldone; i++) { alldone = alldone && ((destlist[i].status == DEST_DONE) || (client_error(i)) || (destlist[i].clientcnt != -1)); } if (alldone) { gettimeofday(&start_time, NULL); print_status(finfo, start_time); return 1; } } // If rate is -1, use 100Mbps for purpose of calculating max time max_time = (int)floor(((double)weight / 100) * ((double)finfo->size / (((rate == -1) ? 100000 : rate) / 8) / 1024)); if (max_time < min_time) { max_time = min_time; } if ((finfo->file_id != 0) && (finfo->ftype == FTYPE_REG)) { log(0, 0, "Maximum file transfer time: %d seconds", max_time); snprintf(path, sizeof(path), "%s%c%s", finfo->basedir, PATH_SEP, finfo->filename); if ((file = open(path, OPENREAD, 0)) == -1) { syserror(0, 0, "Error opening file"); return 1; } } else { // At end of group, all non-errored client are DEST_DONE from the // last file, so reset them to DEST_ACTIVE to get the final COMPLETE. for (i = 0; i < destcount; i++) { if (!client_error(i)) { destlist[i].status = DEST_ACTIVE; } } } packet = calloc(mtu, 1); encpacket = calloc(mtu, 1); if ((packet == NULL) || (encpacket == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)packet; fileseg = (struct fileseg_h *)(packet + sizeof(struct uftp_h)); data = (unsigned char *)fileseg + sizeof(struct fileseg_h); set_uftp_header(header, FILESEG, finfo, &receive_dest); pass = 1; alldone = 0; gettimeofday(&start_time, NULL); do { avgwait = 0; waitcnt = 0; numnaks = 0; overage = 0; section = 1; curr_offset = 0; sent_blocks = 0; gettimeofday(&last_sent, NULL); if (finfo->file_id != 0) { log(0, 0, "Sending file...pass %d", pass); lseek_func(file, 0, SEEK_SET); } else { log(0, 0, "Finishing group"); } fileseg->func = FILESEG; fileseg->file_id = htons(finfo->file_id); fileseg->pass = pass; fileseg->section = htons(section); for (block = 0; block < finfo->blocks; block++) { // If all clients received this file partially on a prior attempt // and it's the first pass, request NAKs for all sections // right away and don't send any data packets. if (((pass == 1) || finfo->naklist[block]) && !((pass == 1) && finfo->partial)) { if (diff_sec(last_sent, start_time) > max_time) { log0(0, 0, "Max file transfer time exceeded"); send_abort(finfo, "Max file transfer time exceeded", &receive_dest, NULL, (keytype != KEY_NONE), !quit_on_error); alldone = 1; for (i = 0; i < destcount; i++) { if (quit_on_error || ((destlist[i].status == DEST_ACTIVE) && destlist[i].clientcnt == -1 )) { destlist[i].status = DEST_ABORT; } } break; } // On the first pass, go straight through the file. // On later passes, seek to the next packet. if (pass != 1) { log4(0, 0, "Resending %d", block); if (!seek_block(file, block, &offset, curr_offset)) { continue; } } if ((numbytes = read(file, data, blocksize)) == -1) { syserror(0, 0, "read failed"); continue; } if (pass != 1) { curr_offset = offset + numbytes; } // Keep track of how long we really slept compared to how // long we expected to sleep. If we went over, subtract the // time over from the next sleep time. This way we maintain // the proper average sleep time. This can result in multiple // packets going out at once, potentially losing packets. if (packet_wait > overage) { usleep(packet_wait - (int32_t)overage); } gettimeofday(¤t_sent, NULL); tdiff = diff_usec(current_sent, last_sent); avgwait += tdiff; waitcnt++; if (packet_wait) overage += tdiff - packet_wait; last_sent = current_sent; fileseg->seq_num = htonl(block); send_data(finfo, packet, numbytes, encpacket); sent_blocks++; } if ((block % (blocksize * 8) == (blocksize * 8) - 1) || (block == finfo->blocks - 1)) { if ((pass == 1) || sent_blocks) { current_naks = get_naks(finfo, pass, section, &alldone); numnaks += current_naks; if ((rate != -1) && (cc_count > 0)) { if (!read_cc_config(cc_config)) { log1(0, 0, "Error rereading congestion control " "config, using prior values"); } adjust_rate(current_naks, sent_blocks); } overage = 0; if (alldone) break; } sent_blocks = 0; gettimeofday(&last_sent, NULL); fileseg->section = htons(++section); } } if ((finfo->size == 0) && !alldone) { // If it's the end of the group, or an empty file, a DONE was // never sent, so send it now numnaks += get_naks(finfo, pass, section, &alldone); } if (finfo->file_id != 0) { log(0, 0, "Average wait time = %.2f us", (waitcnt == 0) ? 0 : (float)avgwait / waitcnt); log(0, 0, "Received %d distinct NAKs for pass %d", numnaks, pass); } pass++; } while (!alldone); if ((finfo->file_id != 0) && (finfo->ftype == FTYPE_REG)) { close(file); } print_status(finfo, start_time); free(packet); free(encpacket); for (i = 0; i < destcount; i++) { if (quit_on_error) { // Check to see that all finished if ((destlist[i].status != DEST_DONE) && (destlist[i].clientcnt == -1)) { return 0; } } else { // Check to see if at least one finished if (destlist[i].status == DEST_DONE) { return 1; } } } if (quit_on_error) { return 1; } else { return 0; } }