// ============================================================================================ void contribute_log_entry(uint32_t temperature_set, uint32_t onproportion_set, uint32_t setpoint_set, uint32_t time_tick) // Add part of an entry for logging - we don't log as often as we refresh the sample, so // the purpose of this routine is to average the readings and write them at the logging interval. { static uint32_t acc_temp = 0, acc_onprop = 0, acc_time = 0, acc_setpoint = 0; static uint32_t old_onprop = 0, old_setpoint = 0; uint32_t time_part; // Only work in integer seconds, to keep sizes under control time_tick/=mS; acc_time += time_tick; // Time is in integer seconds if (acc_time >= sysConfig.recordInterval) { // It's time to write some data time_part = (sysConfig.recordInterval) - (acc_time - time_tick); } else time_part = time_tick; // Accumulate variables .... acc_temp += temperature_set * time_part; acc_onprop += onproportion_set * time_part; acc_setpoint += setpoint_set * time_part; if (acc_time >= sysConfig.recordInterval) { acc_onprop/=acc_time; acc_temp/=acc_time; acc_setpoint/=acc_time; // Write the average for this period of time if (old_onprop != acc_onprop) { logWrite(LOG_ON_PERCENTAGE, acc_onprop); old_onprop = acc_onprop; } if (old_setpoint != acc_setpoint) { logWrite(LOG_SETPOINT_SET, acc_setpoint); old_setpoint = acc_setpoint; } // We make sure temperature is written last as it simplifies reconstruction logWrite(LOG_TEMPERATURE, acc_temp); // Zero the variables acc_temp = 0; acc_onprop = 0; acc_time = 0; acc_setpoint = 0; // .. and store whatever is left over for the next minute if (time_tick-time_part) contribute_log_entry(temperature_set, onproportion_set, setpoint_set, time_tick - time_part); } }
void GLContext::scale(float scale) { logWrite("scale: %.02f", scale); //Matrix::scaleM(modelMatrix, 0.0f, 0.0f, 0.8f); //transform_->scale(scale); }
void GLContext::translate(float x, float y) { logWrite("translate: (%.02f, %.02f)", x, y); Matrix::translateM(modelMatrix, x/10., -y/10., 0.0f); //transform_->translate(x, y); }
void CTestMonitor::monitorQueueTimesBeforeReturnToFreeQueue(CVideoFrame* pFrame, CFrameGrinder* pFrameGrinder) { std::string sLine; static struct timespec timeAtStartOfInterval = {0}; std::string sMsg; unsigned int i = 0; double timeIntervalSeconds = 0.0; getTicks(&pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_FREE]); if (m_nTasksDone[TASK_DONE_CAMERA] >= NUMBER_OF_SAMPLES_PER_TEST_INTERVAL) { timeIntervalSeconds = getDeltaTimeSeconds( timeAtStartOfInterval, pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_FREE]); timeAtStartOfInterval = pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_FREE]; if (m_nIntervalisUpperGoalFound == 0) { sLine += "Upper goal not found\n"; } else { m_avgUpperGoalRectangle.center.x /= m_nIntervalisUpperGoalFound; m_avgUpperGoalRectangle.center.y /= m_nIntervalisUpperGoalFound; m_avgUpperGoalRectangle.angle /= m_nIntervalisUpperGoalFound; sLine += "Upper goal ("; sLine += numberToText(m_nIntervalisUpperGoalFound); sLine += " in this interval) avg "; sLine += m_avgUpperGoalRectangle.displayText(); sLine += "\n"; } for (i = 0; i < NUMBER_OF_TIME_IN_TASK; i++) { m_avgElapsedSeconds[i] /= NUMBER_OF_SAMPLES_PER_TEST_INTERVAL; } m_avgTimeBetweenCameraFramesMilliseconds /= NUMBER_OF_SAMPLES_PER_TEST_INTERVAL; m_avgLatencyForProcessingFrameMilliseconds /= NUMBER_OF_SAMPLES_PER_TEST_INTERVAL; memcpy(&m_savedElapsedSeconds, &m_avgElapsedSeconds, sizeof (double)*NUMBER_OF_TIME_IN_TASK); sLine += displayQueueTimes(timeIntervalSeconds, pFrameGrinder); logWrite(sLine); sLine = ""; for (i = 0; i < NUMBER_OF_TASK_DONE_TYPES; i++) { m_nTasksDone[i] = 0; } m_nIntervalisUpperGoalFound = 0; m_avgUpperGoalRectangle.init(); m_nCountTestInterval = 0; memset(&m_avgElapsedSeconds, 0, sizeof (unsigned int)*NUMBER_OF_TIME_IN_TASK); m_avgTimeBetweenCameraFramesMilliseconds = 0; m_avgLatencyForProcessingFrameMilliseconds = 0; // 'true' is returned when the end of the interval is reached for (i = 0; i < CVideoFrame::NUMBER_OF_FRAME_QUEUES; i++) { pFrameGrinder->m_frameQueueList[i].m_droppedFrames = 0; } } if (pFrame->m_targetInfo.isUpperGoalFound()) { m_nIntervalisUpperGoalFound++; m_avgUpperGoalRectangle.center.x += pFrame->m_upperGoalRectangle.center.x; m_avgUpperGoalRectangle.center.y += pFrame->m_upperGoalRectangle.center.y; m_avgUpperGoalRectangle.angle += pFrame->m_upperGoalRectangle.angle; } m_avgElapsedSeconds[TIME_IN_TASK_CAMERA] += getDeltaTimeSeconds( pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_FREE], // earlier time pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BLOB_DETECT]); // later time m_avgElapsedSeconds[TIME_IN_TASK_WAIT_FOR_BLOB_DETECT] += getDeltaTimeSeconds( pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BLOB_DETECT], pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BLOB_DETECT]); m_avgElapsedSeconds[TIME_IN_TASK_BLOB_DETECT] += getDeltaTimeSeconds( pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BLOB_DETECT], pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_TEXT_CLIENT]); m_avgElapsedSeconds[TIME_IN_TASK_WAIT_FOR_TEXT_CLIENT] += getDeltaTimeSeconds( pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_TEXT_CLIENT], pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_TEXT_CLIENT]); m_avgElapsedSeconds[TIME_IN_TASK_TEXT_CLIENT] += getDeltaTimeSeconds( pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_TEXT_CLIENT], pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BROWSER_CLIENT]); m_avgElapsedSeconds[TIME_IN_TASK_WAIT_FOR_BROWSER_CLIENT] += getDeltaTimeSeconds( pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BROWSER_CLIENT], pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BROWSER_CLIENT]); m_avgElapsedSeconds[TIME_IN_TASK_BROWSER_CLIENT] += getDeltaTimeSeconds( pFrame->m_timeRemovedFromQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BROWSER_CLIENT], pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_FREE]); m_avgElapsedSeconds[TIME_TOTAL_CAMDONE_TO_TEXTDONE] += getDeltaTimeSeconds( pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BLOB_DETECT], pFrame->m_timeAddedToQueue[(int) CVideoFrame::FRAME_QUEUE_WAIT_FOR_BROWSER_CLIENT]); m_avgTimeBetweenCameraFramesMilliseconds += pFrame->m_targetInfo.getTimeSinceLastCameraFrameMilliseconds(); m_avgLatencyForProcessingFrameMilliseconds += pFrame->m_targetInfo.getTimeLatencyThisCameraFrameMilliseconds(); }
void GLContext::rotate(float rotateX, float rotateY, float rotateZ) { logWrite("rotate: (%.02f, %.02f, %.02f)", rotateX, rotateY, rotateZ); //Matrix::setRotateM(modelMatrix, 30.0f, 0.0f, 1.0f, 0.0f); //transform_->rotate(rotateX, rotateY, rotateZ); }
void handle_packet_buffer(struct timeval * deadline, fd_set * write_fds_copy) { struct timeval now; packet_info packet; gettimeofday(&now, NULL); int index = 0; int error = 0; #ifdef USE_PACKET_BUFFER if (packet_buffer_more()) { packet = packet_buffer_front(); } while (packet_buffer_more() && (deadline->tv_sec < now.tv_sec || (deadline->tv_sec == now.tv_sec && deadline->tv_usec < now.tv_usec))) { // struct in_addr debug_temp; // debug_temp.s_addr = packet.ip; // printf("Sending packet to %s of size %ld\n", inet_ntoa(debug_temp), // packet.size); process_control_packet(packet, *deadline); packet_buffer_advance(); if (packet_buffer_more()) { packet = packet_buffer_front(); deadline->tv_usec += packet.delta * 1000; if (deadline->tv_usec > 1000000) { deadline->tv_sec += deadline->tv_usec / 1000000; deadline->tv_usec = deadline->tv_usec % 1000000; } } } #else if (write_buffer != NULL) { packet = write_buffer[write_buffer_index]; while (deadline->tv_sec < now.tv_sec || (deadline->tv_sec == now.tv_sec && deadline->tv_usec < now.tv_usec)) { int delta = 0; index = insert_by_address(packet.ip, packet.source_port, packet.dest_port); if (index == -1) { printf("No more connection slots.\n"); clean_exit(1); } logWrite(CONTROL_RECEIVE, NULL, "Told to write %d bytes", packet.value); error = send_with_reconnect(index, packet.value); if (error > 0) { // There are bytes that were unwritten. buffer_full[index] = 1; logWrite(DELAY_DETAIL, NULL, "Buffer Full"); } ++write_buffer_index; if (write_buffer_index == write_buffer_size) { // If we are going to wraparound, then we need to add the // delay of the remaining quanta time. This is to prevent a // single write from causing link saturation, for instance. write_buffer_index = 0; delta = QUANTA - write_delta_total; if (delta < 0) { delta = 0; } } while (write_buffer[write_buffer_index].type != PACKET_WRITE) { ++write_buffer_index; if (write_buffer_index == write_buffer_size) { // If we are going to wraparound, then we need to add the // delay of the remaining quanta time. This is to prevent a // single write from causing link saturation, for instance. write_buffer_index = 0; delta = QUANTA - write_delta_total; if (delta < 0) { delta = 0; } } } if (packet.delta == 0) { ++delta; } else { delta += packet.delta; } if (delta <= 0) { fprintf(stderr, "Delta is below 0! delta: %d, packet.delta %ld" ", write_delta_total: %d\n", delta, packet.delta, write_delta_total); clean_exit(1); } deadline->tv_usec += delta * 1000; if (deadline->tv_usec > 1000000) { deadline->tv_sec += deadline->tv_usec / 1000000; deadline->tv_usec = deadline->tv_usec % 1000000; } } } #endif }
void init_pcap(int to_ms, unsigned short port, char * device) { char errbuf[PCAP_ERRBUF_SIZE]; if (flag_debug) { printf("The sniff_interface: %s \n", device); } if (is_live) { logWrite(MAIN_LOOP, NULL, "Initializing pcap live interface with device %s, and port %d", device, port); // We are running using live data. device refers to the network // device. struct bpf_program fp; /* hold compiled program */ bpf_u_int32 maskp; /* subnet mask */ bpf_u_int32 netp; /* ip */ char string_filter[128]; /* ask pcap for the network address and mask of the device */ pcap_lookupnet(device, &netp, &maskp, errbuf); //For an unknown reason, netp has the wrong 4th number //addr.s_addr = netp; sprintf(string_filter, "port %d and tcp", port); /* open device for reading. * NOTE: We use non-promiscuous */ descr = pcap_open_live(device, BUFSIZ, 0, to_ms, errbuf); if(descr == NULL) { printf("Error: pcap_open_live(): %s\n",errbuf); exit(1); } // Lets try and compile the program, optimized if(pcap_compile(descr, &fp, string_filter, 1, maskp) == -1) { fprintf(stderr,"Error: calling pcap_compile\n"); exit(1); } // set the compiled program as the filter if(pcap_setfilter(descr,&fp) == -1) { fprintf(stderr,"Error: setting filter\n"); exit(1); } /* if (pcap_setnonblock(descr, 1, errbuf) == -1){ printf("Error: pcap_setnonblock(): %s\n",errbuf); exit(1); } */ } else { logWrite(MAIN_LOOP, NULL, "Initializing pcap replay interface"); // We are running offline using data recorded by tcpdump // earlier. device is the filename. If device == '-', then we // read from stdin. descr = pcap_open_offline(device, errbuf); if(descr == NULL) { printf("Error: pcap_open_offline(): %s\n", errbuf); exit(1); } } // pcapfd = pcap_fileno(descr); pcapfd = pcap_get_selectable_fd(descr); if (pcapfd == -1) { fprintf(stderr, "Error: pcap file descriptor is not selectable\n"); exit(1); } init_sniff_rcvdb(); loss_log = fopen("loss.log", "w"); //loss log }
void debugTestConsoleVars() { logWrite("Testing convars..."); ConvarID cvar1 = Convar.Create("cvar1"); ConvarID cvar2 = Convar.Create("cvar2",123.0f); ConvarID cvar3 = Convar.Create("cvar3",456); ConvarID cvar4 = Convar.Create("cvar4",cvar_read,cvar_write); logWrite("Initial cvar contents:"); PRINT_CVAR(cvar1,"Var1") PRINT_CVAR(cvar2,"Var2") PRINT_CVAR(cvar3,"Var3") PRINT_CVAR(cvar4,"Var4") logWrite("Contents after setting stuff:"); Convar[cvar1]->SetInt(Random.Int(111,999)); PRINT_CVAR(cvar1,"Var1") Convar[cvar1]->SetFloat(Random.Float(111,999)); PRINT_CVAR(cvar1,"Var1") Convar[cvar2]->SetInt(Random.Int(111,999)); PRINT_CVAR(cvar2,"Var2") Convar[cvar2]->SetFloat(Random.Float(111,999)); PRINT_CVAR(cvar2,"Var2") Convar[cvar3]->SetInt(Random.Int(111,999)); PRINT_CVAR(cvar3,"Var3") Convar[cvar3]->SetFloat(Random.Float(111,999)); PRINT_CVAR(cvar3,"Var3") Convar[cvar4]->SetInt(Random.Int(111,999)); PRINT_CVAR(cvar4,"Var4") Convar[cvar4]->SetFloat(Random.Float(111,999)); PRINT_CVAR(cvar4,"Var4") Convar.Create("cvar5"); logWrite("Get CVAR1: %.5f",Convar.GetFloat("cvar1")); logWrite("Get CVAR5 with def 123: %.5f",Convar.GetFloat("cvar5",123)); logWrite("Set CVAR1"); Convar.SetFloat("cvar1",345); logWrite("Get CVAR1: %.5f",Convar.GetFloat("cvar1")); logWrite("Set CVAR6"); logWrite("Get CVAR6 with def 123: %.5f",Convar.GetFloat("cvar6",123)); Convar.SetFloat("cvar6",456456); logWrite("Get CVAR6: %.5f",Convar.GetFloat("cvar6")); logWrite("(cvar5 was created uninitialized, cvar6 was created implictly)"); logWrite("Convar test passed!\n"); }
void GLFWCALL debugThread_InfLoop(void* t) { logWrite("Infinite loop thread %d starts, thread ID 0x%X",(int)t,Thread.GetCurrentThreadID()); while (1) Thread.Sleep(); }
void Thread_Manager::Kill(ThreadID threadID) { logWrite("Killed thread (ThreadID[0x%x])",threadID); glfwDestroyThread(threadID); }
void debugTestMalloc() { logWrite("Testing memory allocation"); float startTime; logDisableDebugOutput = true; void* ptrs[TEST_ALLOCATIONS_IN_CYCLE]; for (int j = 0; j < TEST_ALLOCATION_CYCLES; j++) { logWrite("Memory alloc/free cycle %d, peak usage %d bytes",j,mem.malloc_max); startTime = curtime(); for (int i = 0; i < TEST_ALLOCATIONS_IN_CYCLE; i++) { ptrs[i] = mem.alloc(TEST_ALLOCATION_CYCLE_SIZE); if (!ptrs[i]) { logError("Memory test failed: null block returned"); return; } } for (int i = 0; i < TEST_ALLOCATIONS_IN_CYCLE; i++) mem.free(ptrs[i]); logWrite("Cycle time %.5f seconds",curtime() - startTime); } logWrite("Allocating large memory chunk (%d mb)",TEST_ALLOC_LARGE_CHUNK_MB); startTime = curtime(); void* largePtr = mem.alloc(TEST_ALLOC_LARGE_CHUNK_MB*1024*1024); logWrite("Done, %.5f seconds",curtime() - startTime); if (!largePtr) { logError("Could not allocate large memory chunk"); } logWrite("Filling with pattern..."); startTime = curtime(); for (int i = 0; i < TEST_ALLOC_LARGE_CHUNK_MB*1024*1024; i++) { ((char*)largePtr)[i] = (i ^ 0xFF) & 0xFF; } logWrite("Done, %.5f seconds",curtime() - startTime); mem.free(largePtr); logWrite("Testing string pool..."); for (int i = 0; i < TEST_ALLOCATE_NUM_STRINGS; i++) { int strSize = Random.Int(1,TEST_ALLOCATE_MAX_STR_SIZE); char* strPtr = mem.alloc_string(strSize); if (mem.malloc_memory > 256*1024*1024) { logWrite("Too much memory used, terminating earlier with %d strings",i+1); break; } for (int j = 0; j < strSize; j++) strPtr[j] = (i ^ j) & 0xFF; } int stringpool_size = 0; int stringpool_used = 0; int stringpool_lost = 0; for (int i = 0; i <= mem.malloc_curstringpool; i++) { stringpool_size += mem.malloc_stringpoolsz[i]; stringpool_used += mem.malloc_curstringpoolsz[i]; stringpool_lost += mem.malloc_stringpoolsz[i] - mem.malloc_curstringpoolsz[i]; if ((mem.malloc_stringpoolsz[i] <= 0) || (mem.malloc_stringpoolsz[i] > 16384) || (mem.malloc_curstringpoolsz[i] <= 0) || (mem.malloc_curstringpoolsz[i] > 16384)) { logError("Memory test failed: corrupted string pool block %d",i); return; } } logWrite("String pool usage: %d out of %d bytes (%.2f percent, lost %d bytes, %d entries used)", stringpool_used,stringpool_size,(100.0f*stringpool_used) / stringpool_size,stringpool_lost,mem.malloc_curstringpool+1); logWrite("Testing boundary overflow detection"); char* testPtr = (char*)mem.alloc(512); testPtr[600] = 0x10; mem.free(testPtr); logWrite("Reinitializing memory (and console variables, they are in mem too)..."); logWrite("You should see warning about memory leak"); Convar.Deinitialize(); Memory.Deinitialize(); logDisableDebugOutput = false; Memory.Initialize(); Convar.Initialize(); logWrite("Memory allocation test passed!\n"); }
ThreadID Thread_Manager::Create(ThreadFunction* funcptr, void* param) { ThreadID th = glfwCreateThread(funcptr,param); logWrite("Spawned thread [%p] (ThreadID[0x%x])",funcptr,th); return th; }
void Graphics_Manager::LoadGraphics(GraphicsID graphicsEntry) { logWrite("STUB CALL TO LOADGRAPHICS!!! FIXME"); }
void Graphics_Manager::Initialize(bool PreloadTextures) { //Update maps info logWrite("Initializing graphics manager (updating texture file entries)"); int TexSize = 0; DIR *directory; struct dirent *direntry; globalIDCounter = 0; graphicsEntries.Create(); graphicsEntries.Preallocate(MAX_TEXTURE_FILE_ENTRIES); Animations.Initialize(); directory = opendir("./data"); while ((directory) && ((direntry = readdir(directory)) != 0)) { int len = strlen(direntry->d_name); switch (len) { case 1: if (direntry->d_name[0] == '.') continue; case 2: if (direntry->d_name[0] == '.' && direntry->d_name[1] == '.') continue; default: break; } //Check file format Chunk_Loader TEX; //Read map header char Filename[256]; snprintf(Filename,256,"./data/%s",direntry->d_name); TEX.Open(Filename); if (TEX.IsFileFormat("ZTEX",TEX_VERSION) == false) { continue; } logWrite("Loading graphics from %s...",Filename); //Read all chunks from file int lastRead = 0; while (TEX.ReadChunk()) { LockID lockID = Thread.EnterLock(MUTEX_CRESOURCE_LOAD); Graphics.texReadGTA2Graphics(&TEX, false); Graphics.texReadFonts(&TEX, false); Animations.LoadFromChunk(&TEX); Thread.LeaveLock(lockID); } TexSize += TEX.fileSize; TEX.Close(); } if (directory) closedir(directory); totalTextures = globalIDCounter + 1; logWrite("Found %d KB worth of texture files (%d textures)",TexSize/1024,totalTextures); logWritem("shrinking graphicsEntries, animationEntries, fontEntries..."); LockID lockID = Thread.EnterLock(MUTEX_CRESOURCE_LOAD); graphicsEntries.Shrink(); Thread.LeaveLock(lockID); Animations.Entries.Shrink(); //FIXME: should be shrink call directly Fonts.shrinkFontEntries(); //FIXME: ??? this should shrink font entries, call only after all fonts have been loaded }
void on_new_component(MX *mx, int fd, const char *name, void *udata) { logWrite(logger, "New component %s on fd %d.\n", name, fd); }
//FIXME: a lot less map requests (therefore a lot higher map rendering speed) can be made //if you draw volumes of cells separately. transparency may break void Map_Render_Debug::drawPlane(int bx1, int by1, int bx2, int by2, int bz) { int tx = (int)floor(bx1 / 64.0f); int ty = (int)floor(by1 / 64.0f); rmp_cityscape* cityscape = Map.cellCityscape(tx,ty); //cityscape to gather data from for (int x = bx1; x <= bx2; x++) for (int y = by1; y <= by2; y++) { int cx = (int)floor(x / 64.0f); //current cityscape int cy = (int)floor(y / 64.0f); if ((tx != cx) || (ty != cy)) { tx = cx; ty = cy; //precache new one cityscape = Map.cellCityscape(tx,ty); } int kx = x - 64*(x / 64);//abs(x % 64);//x-abs(cx*64); int ky = y - 64*(y / 64);//abs(y % 64);//y-abs(cy*64); //int texID = if ((cityscape->rmp_city_scape) && (bz < cityscape->maxHeight)) { Vertex_Buffer* vBuffer = 0; TexID texBase = 0; for (uint i = 0; i < VBOEntry.Count; i++) { if (strcmp(VBOEntry[i]->GraphicsName,cityscape->GraphicsName[0]) == 0) { vBuffer = &VBOEntry[i]->VBO; texBase = VBOEntry[i]->SpriteBase; break; } } if (vBuffer == 0) { //debugrender_vboentry* vboEntry = VBOEntry.Add(); VBOEntry.Count++; //Add(); if (VBOEntry.Count >= VBOEntry.AllocCount) { logWrite("BAD ERROR: attempting to draw more different VBO's than allocated entries"); return; } VBOEntry[VBOEntry.Count-1]->GraphicsName = cityscape->GraphicsName[0]; VBOEntry[VBOEntry.Count-1]->VBO.Clear(); vBuffer = &VBOEntry[VBOEntry.Count-1]->VBO; //Get sprite base TexID to use later to bind texture atlas (also this is offset for blockgeometry) char texName[256]; snprintf(texName,256,"%s_0",VBOEntry[VBOEntry.Count-1]->GraphicsName); VBOEntry[VBOEntry.Count-1]->SpriteBase = Graphics.GetTextureID(texName); texBase = VBOEntry[VBOEntry.Count-1]->SpriteBase; } //Block fetched from map: rmp_block_info* block = &cityscape->rmp_city_scape[bz*64*64+ky*64+kx]; //Block with (possibly) animated textures: rmp_block_info _block; memcpy(&_block,block,sizeof(rmp_block_info)); TexID tex_left = texBase+block->tex_left; TexID tex_right = texBase+block->tex_right; TexID tex_top = texBase+block->tex_top; TexID tex_bottom = texBase+block->tex_bottom; TexID tex_lid = texBase+block->tex_lid; AnimSeqID anim_left = Animations.GetAnimationSeq(tex_left); AnimSeqID anim_right = Animations.GetAnimationSeq(tex_right); AnimSeqID anim_top = Animations.GetAnimationSeq(tex_top); AnimSeqID anim_bottom = Animations.GetAnimationSeq(tex_bottom); AnimSeqID anim_lid = Animations.GetAnimationSeq(tex_lid); //Animate faces float tgtAnimationTime = 0.0f; if (anim_left != BAD_ID) { //HAX Animation anim = Animations.GetAnimation(anim_left); anim.startTime = 0.0f; _block.tex_left = anim.GetTexID()-texBase; tgtAnimationTime = Timer.Time() + anim.RemainingTime(); } if (anim_right != BAD_ID) { Animation anim = Animations.GetAnimation(anim_right); anim.startTime = 0.0f; _block.tex_right = anim.GetTexID()-texBase; tgtAnimationTime = Timer.Time() + anim.RemainingTime(); } if (anim_top != BAD_ID) { Animation anim = Animations.GetAnimation(anim_top); anim.startTime = 0.0f; _block.tex_top = anim.GetTexID()-texBase; tgtAnimationTime = Timer.Time() + anim.RemainingTime(); } if (anim_bottom != BAD_ID) { Animation anim = Animations.GetAnimation(anim_bottom); anim.startTime = 0.0f; _block.tex_bottom = anim.GetTexID()-texBase; tgtAnimationTime = Timer.Time() + anim.RemainingTime(); } if (anim_lid != BAD_ID) { Animation anim = Animations.GetAnimation(anim_lid); anim.startTime = 0.0f; _block.tex_lid = anim.GetTexID()-texBase; tgtAnimationTime = Timer.Time() + anim.RemainingTime(); } if (tgtAnimationTime > 0.0f) { if (nextAnimationTime > 0.0f) { nextAnimationTime = min(tgtAnimationTime,nextAnimationTime); } else { nextAnimationTime = tgtAnimationTime; } } //if ((block->block_type & 0xF) > 0) Map_Vertex_Geometry.blockGeometry(vBuffer, &_block, texBase, Vector3f(x*1.0f,y*1.0f,bz*1.0f-1.0f)); } } }
void on_end_component(MX *mx, int fd, const char *name, void *udata) { logWrite(logger, "End of component %s on fd %d.\n", name, fd); }
void Map_Manager::Initialize() { logWrite("Initializing map manager (scanning for maps)"); DIR *directory; struct dirent *direntry; int MapSize = 0; //Total size of maps loaded (for stats) mapsInfo.Preallocate(1024); cacheCityscape.Preallocate(1024); directory = opendir("./data"); while ((directory) && ((direntry = readdir(directory)) != 0)) { int len = strlen(direntry->d_name); switch (len) { case 1: if (direntry->d_name[0] == '.') continue; case 2: if (direntry->d_name[0] == '.' && direntry->d_name[1] == '.') continue; default: break; } Chunk_Loader RMP; //Read the map char Filename[256]; snprintf(Filename,256,"./data/%s",direntry->d_name); RMP.Open(Filename); if (RMP.IsFileFormat("ZRMP",RMP_VERSION) == false) { continue; } //Read all chunks from file while (RMP.ReadChunk()) { if (RMP.IsChunk("RMAP")) { //Scan the chunk for district name, and cell coordinates int CX,CY; char districtName[5] = " "; RMP.Read(&CX,4); RMP.Read(&CY,4); RMP.Read(districtName,4); //Check if the map entry was already there int idx = cellEntryIndex(CX,CY); if (idx == BAD_ID) { logWritem("Found cell [%d;%d belongs to %s]: %s",CX,CY,districtName,direntry->d_name); rmp_entry* entry = mapsInfo.Add(); entry->CX = CX; entry->CY = CY; strncpy(entry->Filename,Filename,256); } else { logWritem("Duplicate map cell! No place for [%d;%d] from %s",CX,CY,direntry->d_name); } } } MapSize += RMP.fileSize; RMP.Close(); } if (directory) closedir(directory); logWrite("Found %d KB worth of maps",MapSize/1024); //Shrink entry table mapsInfo.Shrink(); }
int main(int argc, char *argv[]) { int sockfd_snd, sockfd_rcv_sender, sockfd_rcv_monitor, sockfd_monitor=-1; struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information fd_set read_fds_copy, write_fds_copy; socklen_t sin_size; struct timeval start_tv, left_tv; int yes=1;//, flag_send_monitor=0; struct timeval packet_deadline; struct in_addr addr; int flag_measure=0; char ch; unsigned short standalone_port = SENDER_PORT; // Do we use live data? Or previously recorded data? FILE * logfile = NULL; unsigned long quantum_no=0; int logflags = LOG_NOTHING; int select_count = 0; gettimeofday(&packet_deadline, NULL); init(); //set up debug flag if (getenv("Debug")!=NULL) flag_debug=1; else flag_debug=0; flag_standalone = 0; /* * Process command-line arguments */ while ((ch = getopt(argc,argv,"df:l:b:rst")) != -1) { switch (ch) { case 'd': flag_debug = 1; break; case 'f': if (logfile == NULL) { logfile = fopen(optarg, "a"); if (logfile == NULL) { perror("Log fopen()"); exit(1); } } break; case 'b': if (strcmp(optarg, "average") == 0) { bandwidth_method = BANDWIDTH_AVERAGE; } else if (strcmp(optarg, "max") == 0) { bandwidth_method = BANDWIDTH_MAX; } else if (strcmp(optarg, "vegas") == 0) { bandwidth_method = BANDWIDTH_VEGAS; } else if (strcmp(optarg, "buffer") == 0) { bandwidth_method = BANDWIDTH_BUFFER; } else { fprintf(stderr, "Unknown bandwidth method\n"); usage(); exit(1); } break; case 'l': if (strcmp(optarg, "everything") == 0) { logflags = LOG_EVERYTHING; } else if (strcmp(optarg, "nothing") == 0) { logflags = LOG_NOTHING; } else if (strcmp(optarg, "control-send") == 0) { logflags = logflags | CONTROL_SEND; } else if (strcmp(optarg, "control-receive") == 0) { logflags = logflags | CONTROL_RECEIVE; } else if (strcmp(optarg, "tcptrace-send") == 0) { logflags = logflags | TCPTRACE_SEND; } else if (strcmp(optarg, "tcptrace-receive") == 0) { logflags = logflags | TCPTRACE_RECEIVE; } else if (strcmp(optarg, "sniff-send") == 0) { logflags = logflags | SNIFF_SEND; } else if (strcmp(optarg, "sniff-receive") == 0) { logflags = logflags | SNIFF_RECEIVE; } else if (strcmp(optarg, "peer-write") == 0) { logflags = logflags | PEER_WRITE; } else if (strcmp(optarg, "peer-read") == 0) { logflags = logflags | PEER_READ; } else if (strcmp(optarg, "main-loop") == 0) { logflags = logflags | MAIN_LOOP; } else if (strcmp(optarg, "lookup-db") == 0) { logflags = logflags | LOOKUP_DB; } else if (strcmp(optarg, "delay-detail") == 0) { logflags = logflags | DELAY_DETAIL; } else if (strcmp(optarg, "packet-buffer-detail") == 0) { logflags = logflags | PACKET_BUFFER_DETAIL; } else { fprintf(stderr, "Unknown logging option %s\n", optarg); usage(); exit(1); } break; case 's': flag_standalone = 1; break; case 'r': flag_standalone = 1; is_live = 0; break; case 't': flag_testmode = 1; break; default: fprintf(stderr,"Unknown option %c\n",ch); usage(); exit(1); } } argc -= optind; argv += optind; if (logfile == NULL) { logfile = stderr; } logInit(logfile, logflags, 1); if (flag_standalone) { if (argc != 3) { fprintf(stderr,"Wrong number of options for standalone: %i\n",argc); usage(); exit(1); } else { flag_measure = 1; // rcvdb[0].valid = 1; standalone_port = atoi(argv[2]); inet_aton(argv[1], &addr); insert_fake(addr.s_addr, standalone_port); // rcvdb[0].ip = addr.s_addr; // rcvdb[0].sockfd= -1; //show error if used // rcvdb[0].last_usetime = time(NULL); } printf("Running in standalone mode\n"); } else { if (argc != 1) { fprintf(stderr,"Wrong number of options: %i\n",argc); usage(); exit(1); } } if (flag_testmode) { printf("Running in testmode\n"); test_state = TEST_NOTSTARTED; } if (strlen(argv[0]) > 127) { fprintf(stderr,"Error: the <sniff-interface> name must be less than 127 characters \n"); exit(1); } // strcpy(sniff_interface, argv[0]); //set up the sender connection listener if ((sockfd_rcv_sender = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(sockfd_rcv_sender, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(SENDER_PORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP // memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr)); if (bind(sockfd_rcv_sender, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(sockfd_rcv_sender, PENDING_CONNECTIONS) == -1) { perror("listen"); exit(1); } //set up the monitor connection listener if ((sockfd_rcv_monitor = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(sockfd_rcv_monitor, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MONITOR_PORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP // memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr)); if (bind(sockfd_rcv_monitor, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(sockfd_rcv_monitor, 1) == -1) { perror("listen"); exit(1); } //initialization packet_buffer_init(); init_random_buffer(); init_pcap(SNIFF_TIMEOUT, standalone_port, argv[0]); FD_ZERO(&read_fds); FD_ZERO(&read_fds_copy); FD_ZERO(&write_fds); FD_ZERO(&write_fds_copy); FD_SET(pcapfd, &read_fds); FD_SET(sockfd_rcv_sender, &read_fds); FD_SET(sockfd_rcv_monitor, &read_fds); maxfd = pcapfd; //socket order sin_size = sizeof(struct sockaddr_in); //main loop - the stubd runs forever while (1) { // flag_send_monitor=0; //reset flag for each quanta gettimeofday(&start_tv, NULL); //reset start time for each quanta // printf("Total: %d\n", total_size); // printf("========== Quantum %lu ==========\n", quantum_no); logWrite(MAIN_LOOP, NULL, "Quantum %lu", quantum_no); if (is_live) { update_stats(); logWrite(MAIN_LOOP, NULL, "PCAP Received: %u Dropped: %u", received_stat(), dropped_stat()); } quantum_no++; //while in a quanta while(have_time(&start_tv, &left_tv)) { read_fds_copy = read_fds; write_fds_copy = write_fds; select_count = select(maxfd+1, &read_fds_copy, &write_fds_copy, NULL, &left_tv); if (select_count == -1) { perror("select"); clean_exit(1); } // fprintf(stderr, "Select count: %d\n", select_count); // Send out packets to our peers if the deadline has passed. // logWrite(MAIN_LOOP, NULL, "Send normal packets to peers"); handle_packet_buffer(&packet_deadline, &write_fds_copy); // send to destinations which are writeable and are behind. // logWrite(MAIN_LOOP, NULL, "Send pending packets to peers"); #ifdef USE_PACKET_BUFFER for_each_pending(try_pending, &write_fds_copy); #endif // receive from existing senders // logWrite(MAIN_LOOP, NULL, "Receive packets from peers"); for_each_readable_sender(receive_sender, &read_fds_copy); /* //receive from existent senders for (i=0; i<CONCURRENT_SENDERS; i++){ // Send pending data if it exists. if (snddb[i].valid==1 && FD_ISSET(snddb[i].sockfd, &read_fds_copy)) { receive_sender(i); } } */ //handle new senders if (FD_ISSET(sockfd_rcv_sender, &read_fds_copy)) { if ((sockfd_snd = accept(sockfd_rcv_sender, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } else { logWrite(MAIN_LOOP, NULL, "Accept new peer (%s)", inet_ntoa(their_addr.sin_addr)); replace_sender_by_stub_port(their_addr.sin_addr.s_addr, ntohs(their_addr.sin_port), sockfd_snd, &read_fds); // insert_db(their_addr.sin_addr.s_addr, their_addr.sin_port, // SENDER_PORT, sockfd_snd, 1); //insert snddb // FD_SET(sockfd_snd, &read_fds); // add to master set // if (sockfd_snd > maxfd) { // keep track of the maximum // maxfd = sockfd_snd; // } if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr)); } } //handle the new monitor if (FD_ISSET(sockfd_rcv_monitor, &read_fds_copy)) { if ((sockfd_monitor = accept(sockfd_rcv_monitor, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } else { int nodelay = 1; int nodelay_error = setsockopt(sockfd_monitor, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); if (nodelay_error == -1) { perror("setsockopt (TCP_NODELAY)"); clean_exit(1); } logWrite(MAIN_LOOP, NULL, "Accept new monitor (%s)", inet_ntoa(their_addr.sin_addr)); FD_CLR(sockfd_rcv_monitor, &read_fds); //allow only one monitor connection FD_SET(sockfd_monitor, &read_fds); //check the monitor connection for read // FD_SET(sockfd_monitor, &write_fds); //check the monitor connection for write if (sockfd_monitor > maxfd) { //keep track of the maximum maxfd = sockfd_monitor; } if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr)); } } //receive from the monitor if (sockfd_monitor!=-1 && FD_ISSET(sockfd_monitor, &read_fds_copy)) { logWrite(MAIN_LOOP, NULL, "Receive control message from monitor"); if (receive_monitor(sockfd_monitor, &packet_deadline) == 0) { //socket_monitor closed by peer FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket // FD_CLR(sockfd_monitor, &write_fds); sockfd_monitor = -1; FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum maxfd = sockfd_rcv_monitor; } } } //sniff packets if (FD_ISSET(pcapfd, &read_fds_copy)) { logWrite(MAIN_LOOP, NULL, "Sniff packet stream"); sniff(); } } //while in quanta //send measurements to the monitor once in each quanta if (sockfd_monitor!=-1) // && FD_ISSET(sockfd_monitor, &write_fds_copy)) { { logWrite(MAIN_LOOP, NULL, "Send control message to monitor"); if (send_monitor(sockfd_monitor) == 0) { //socket_monitor closed by peer logWrite(MAIN_LOOP, NULL, "Message to monitor failed"); FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket // FD_CLR(sockfd_monitor, &write_fds); sockfd_monitor = -1; FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum maxfd = sockfd_rcv_monitor; } } else { logWrite(MAIN_LOOP, NULL, "Message to monitor succeeded"); // flag_send_monitor=1; } } // In testmode, we only start printing in the quanta we first see a packet if (flag_standalone) { print_measurements(); } // If running in testmode, and the test is over, exit! if (flag_testmode && test_state == TEST_DONE) { printf("Test done - total bytes transmitted: %llu\n",total_bytes); break; } } //while forever packet_buffer_cleanup(); return 0; }
u_int16_t handle_IP(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet){ const struct my_ip* ip; const struct tcphdr *tp; const struct udphdr *up; u_char *cp; u_int length = pkthdr->len; u_int caplen = pkthdr->caplen; u_short len, hlen, version, tcp_hlen, ack_bit; u_long seq_start, seq_end, ack_seq, ip_src, ip_dst; unsigned short source_port = 0; unsigned short dest_port = 0; int path_id, record_id, msecs, end; sniff_path *path; unsigned int acked_size, tmpuint; // struct in_addr debug_addr; /* jump pass the ethernet header */ ip = (struct my_ip*)(packet + sizeof(struct ether_header)); length -= sizeof(struct ether_header); caplen -= sizeof(struct ether_header); /* check if we have captured enough to continue parse */ if (caplen < sizeof(struct my_ip)) { printf("Error: truncated ip header - %d bytes missing \n",sizeof(struct my_ip)-caplen); return -1; } len = ntohs(ip->ip_len); hlen = IP_HL(ip); /* header length */ version = IP_V(ip); /* ip version */ /* check version, we will take care of ipv6 later */ if(version != 4){ fprintf(stdout,"Error: unknown version %d\n",version); return -1; } /* check header length */ if(hlen < 5 ){ fprintf(stdout,"Error: bad ip header length: %d \n",hlen); return -1; } /* see if we have as much packet as we should */ if(length < len) { printf("Error: truncated ip - %d bytes missing\n",len - length); return -1; } /* Check only the unfragmented datagram or the last fragment */ /* Note: assume all fregments have the same header fields except the segmentation offset and flag */ if((ntohs(ip->ip_off) & IP_MF) != 1 ) { /* aka the 14 bit != 1 */ ip_src = ip->ip_src.s_addr; ip_dst = ip->ip_dst.s_addr; if (flag_debug){ //Note:inet_ntoa returns the same string if called twice in one line due to static string buffer fprintf(stdout,"IP src:%s ", inet_ntoa(ip->ip_src)); fprintf(stdout,"dst:%s hlen:%d version:%d len:%d\n",inet_ntoa(ip->ip_dst),hlen,version,len); } /*jump pass the ip header */ cp = (u_char *)ip + (hlen * 4); caplen -= (hlen * 4); length -= (hlen * 4); switch (ip->ip_p) { case IPPROTO_TCP: if (caplen < sizeof(struct tcphdr)) { printf("Error: truncated tcp header - %d bytes missing\n", sizeof(struct tcphdr)-caplen); return -1; } tp = (struct tcphdr *)cp; tcp_hlen = ((tp)->doff & 0x000f); length -= (tcp_hlen * 4); //jump pass the tcp header caplen -= (tcp_hlen * 4); //jump pass the tcp header seq_start = ntohl(tp->seq); seq_end = ((unsigned long)(seq_start+length)); ack_bit= ((tp)->ack & 0x0001); source_port = htons(tp->source); dest_port = htons(tp->dest); if (flag_standalone) { // If this is standalone mode, the stub_port entry will be the // destination port requested by the command line. path_id = find_by_stub_port(ip_dst, dest_port); } else { // I contacted the receiver. Therefore, my port is unique and // the receiver's port is fixed. The destination is the // receiver, therefore my port is the one that is of interest. path_id = find_by_stub_port(ip_dst, source_port); } if (path_id != -1) { //a monitored outgoing packet //ignore the pure outgoing ack if ((ack_bit==1) && (seq_end==seq_start)) { return 0; } path = &(sniff_rcvdb[path_id]); loss_records[path_id].total_counter++; if (path->end == path->start){ //no previous packet throughputInit(&throughput[path_id], seq_start, &(pkthdr->ts)); throughputProcessSend(&throughput[path_id], seq_start, length); return push_sniff_rcvdb(path_id, seq_start, seq_end, &(pkthdr->ts), pkthdr->len); //new packet } else { throughputProcessSend(&throughput[path_id], seq_start, length); //find the real received end index end = nnmod(path->end-1, SNIFF_WINSIZE); //if the packet has no payload if (seq_end == seq_start) { if ((path->records[end].seq_end==path->records[end].seq_start) && (path->records[end].seq_end==seq_end)) { //the last packet also has no payload and has the same seqnum, pure resent loss_records[path_id].loss_counter++; fprintf(loss_log, "Resent: %lu\n",seq_end); //loss log fflush(loss_log); //loss log } else { return push_sniff_rcvdb(path_id, seq_start, seq_end, &(pkthdr->ts), pkthdr->len); //new packet } } else if (seq_start >= path->records[end].seq_end) { //new packet return push_sniff_rcvdb(path_id, seq_start, seq_end, &(pkthdr->ts), pkthdr->len); } else { //resend loss_records[path_id].loss_counter++; if (seq_end > path->records[end].seq_end){ //partial resend fprintf(loss_log, "Resent: %lu to %lu\n",seq_start, path->records[end].seq_end-1); //loss log fflush(loss_log); //loss log tmpuint = pkthdr->len - (path->records[end].seq_end-seq_start); return push_sniff_rcvdb(path_id, path->records[end].seq_end, seq_end, &(pkthdr->ts), tmpuint); } fprintf(loss_log, "Resent: %lu to %lu\n",seq_start, seq_end-1); //loss log fflush(loss_log); //loss log } // if has payload and resent } } else { if (flag_standalone) { // If this is standalone mode, and the packet is incoming, // then the source_port will be the remote port requested on // the command line. path_id = find_by_stub_port(ip_src, source_port); } else { // I contacted the receiver, so my port is unique and their // port is the same every time. This means that if a packet is // coming from them, the destination port is the one of // interest. path_id = find_by_stub_port(ip_src, dest_port); } if (path_id != -1) { //a monitored incoming packet if (ack_bit == 1) { //has an acknowledgement ack_seq = ntohl(tp->ack_seq); acked_size = 0; record_id = search_sniff_rcvdb(path_id, (unsigned long)(ack_seq-1)); /* Note: we use the in-flight widnow to igore the duplicate Acks in the delay estimation * because TCP don't use them to calculate the sample RTT in the RTT estimation */ if (record_id != -1) { //new ack received int delay = 0; struct tcp_info info; int info_size = sizeof(info); int error = 0; if (is_live) { error = getsockopt(rcvdb[path_id].sockfd, SOL_TCP, TCP_INFO, &info, &info_size); if (error == -1) { perror("getsockopt() TCP_INFO"); clean_exit(1); } if ((info.tcpi_snd_cwnd < info.tcpi_snd_ssthresh || ((unsigned int)(tp->window) << info.tcpi_rcv_wscale) <= (info.tcpi_unacked * 1448)) && bandwidth_method == BANDWIDTH_BUFFER) { // We are in slow start. This means that even if the // socket buffer is full, we are still not sending // at the ABW rate. buffer_full[path_id] = 0; last_through[path_id] = INT_MAX; logWrite(DELAY_DETAIL, NULL, "Buffer Clear"); } logWrite(DELAY_DETAIL, NULL, "receive_window: %u, unacked: %u", (unsigned int)(tp->window) << info.tcpi_rcv_wscale, info.tcpi_unacked * 1448); } msecs = floor((pkthdr->ts.tv_usec-sniff_rcvdb[path_id].records[record_id].captime.tv_usec)/1000.0+0.5); delay = (pkthdr->ts.tv_sec-sniff_rcvdb[path_id].records[record_id].captime.tv_sec)*1000 + msecs; if (delay != 0) { delays[path_id] += delay; (delay_count[path_id])++; if (delay < base_rtt[path_id]) { base_rtt[path_id] = delay; } logWrite(DELAY_DETAIL, NULL, "delay: %d, max_delay: %d", delay, max_delay[path_id]); if (delay > max_delay[path_id]) { max_delay[path_id] = delay + delay/10 + 1; } if (is_live && delay_count[path_id] > 0 && bandwidth_method == BANDWIDTH_VEGAS) { int bandwidth = 0; bandwidth = (info.tcpi_unacked/*tcpi_snd_cwnd*/ * info.tcpi_snd_mss * 8) / base_rtt[path_id]; if (bandwidth > max_throughput[path_id]) { max_throughput[path_id] = bandwidth; } logWrite(DELAY_DETAIL, NULL, "Kernel RTT: %lu, Kernel Losses: %lu, " "Receive Window: %lu, Kernel packets out: %lu", info.tcpi_rtt, info.tcpi_lost, tp->window, info.tcpi_unacked); logWrite(DELAY_DETAIL, NULL, "Tput: %lu, cwnd: %lu, snd_MSS: %lu bytes, " "Base RTT: %lu", bandwidth, info.tcpi_snd_cwnd, info.tcpi_snd_mss, base_rtt[path_id]); } else if (bandwidth_method == BANDWIDTH_MAX) { int goodput = 0; goodput = throughputTick(&throughput[path_id]); logWrite(DELAY_DETAIL, NULL, "Goodput: %d", goodput); if (goodput > max_throughput[path_id]) { max_throughput[path_id] = goodput; } } // append_delay_sample(path_id, delay, &(pkthdr->ts)); logWrite(DELAY_DETAIL, &(pkthdr->ts), "Delay: %lu, Sum: %lu, Count: %lu", delay, delays[path_id], delay_count[path_id]); } acked_size = pop_sniff_rcvdb(path_id, (unsigned long)(ack_seq-1)); //advance the sniff window base } //ack in rcvdb throughputProcessAck(&throughput[path_id], ack_seq, &(pkthdr->ts), acked_size); } //has ack } //if incoming } //if outgoing if (flag_debug) { printf("TCP start_seq:%lu end_seq:%lu length:%d\n", seq_start, seq_end, length); printf("TCP ack_seq:%lu ack_flag:%d hlen:%d\n", ack_seq, ack_bit, tcp_hlen); } break; case IPPROTO_UDP: up = (struct udphdr *)cp; //sport = ntohs(up->source); //uh_sport in BSD //dport = ntohs(up->dest); //uh_dport in BSD //printf("UDP source port: %d dest port: %d \n", sport, dport); if (flag_debug) printf("A UDP packet captured.\n"); break; case IPPROTO_ICMP: if (flag_debug) printf("A ICMP packet captured.\n"); break; default: if (flag_debug) printf("An unknow packet captured: %d \n", ip->ip_p); break; } //switch } else { //if unfragmented or last fragment printf("Got an incomplete fragment\n"); } return 0; }