static int put_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; /* * Upload the file to the camera. Use gp_file_get_data_and_size etc. */ int result = -EPROTO; time_t startTime = time(NULL); enum { START, DATA, END, FINISHED } state; int src = -1; int r; int update = 0; struct stat srcStat; __u64 fileSize; __u64 byteCount = 0; const char *filename; char *path; struct tf_packet reply; if(0 != fstat(src, &srcStat)) { gp_log (GP_LOG_ERROR, "topfield", "ERROR: Can not examine source file: %s\n", strerror(errno)); result = errno; goto out; } fileSize = srcStat.st_size; if(fileSize == 0) { gp_log (GP_LOG_ERROR, "topfield", "ERROR: Source file is empty - not transfering.\n"); result = -ENODATA; goto out; } path = get_path (camera, folder, filename); r = send_cmd_hdd_file_send(camera, PUT, path, context); if(r < 0) goto out; state = START; while(0 < get_tf_packet(camera, &reply, context)) { update = (update + 1) % 16; switch (get_u32(&reply.cmd)) { case SUCCESS: switch (state) { case START: { /* Send start */ struct typefile *tf = (struct typefile *) packet.data; put_u16(&packet.length, PACKET_HEAD_SIZE + 114); put_u32(&packet.cmd, DATA_HDD_FILE_START); time_to_tfdt(srcStat.st_mtime, &tf->stamp); tf->filetype = 2; put_u64(&tf->size, srcStat.st_size); strncpy((char *) tf->name, path, 94); tf->name[94] = '\0'; tf->unused = 0; tf->attrib = 0; gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_START\n", __func__); r = send_tf_packet(camera, &packet, context); if(r < 0) { gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n"); goto out; } state = DATA; break; } case DATA: { int payloadSize = sizeof(packet.data) - 9; ssize_t w = read(src, &packet.data[8], payloadSize); /* Detect a Topfield protcol bug and prevent the sending of packets that are a multiple of 512 bytes. */ if((w > 4) && (((((PACKET_HEAD_SIZE + 8 + w) + 1) & ~1) % 0x200) == 0)) { lseek(src, -4, SEEK_CUR); w -= 4; payloadSize -= 4; } put_u16(&packet.length, PACKET_HEAD_SIZE + 8 + w); put_u32(&packet.cmd, DATA_HDD_FILE_DATA); put_u64(packet.data, byteCount); byteCount += w; /* Detect EOF and transition to END */ if((w < 0) || (byteCount >= fileSize)) { state = END; } if(w > 0) { gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_DATA\n", __func__); r = send_tf_packet(camera, &packet, context); if(r < w) { gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n"); goto out; } } if(!update && !quiet) { progressStats(fileSize, byteCount, startTime); } break; } case END: /* Send end */ put_u16(&packet.length, PACKET_HEAD_SIZE); put_u32(&packet.cmd, DATA_HDD_FILE_END); gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_END\n", __func__); r = send_tf_packet(camera, &packet, context); if(r < 0) { gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n"); goto out; } state = FINISHED; break; case FINISHED: result = 0; goto out; break; } break; case FAIL: gp_log (GP_LOG_ERROR, "topfield", "ERROR: Device reports %s\n", decode_error(&reply)); goto out; break; default: gp_log (GP_LOG_ERROR, "topfield", "ERROR: Unhandled packet (%d)\n", get_u32(&reply.cmd)); break; } } finalStats(byteCount, startTime); out: close(src); return result; }
int do_hdd_file_get(int fd, char *srcPath, char *dstPath) { int result = -EPROTO; time_t startTime = time(NULL); enum { START, DATA, ABORT } state; int dst = -1; int r; int update = 0; __u64 byteCount = 0; struct utimbuf mod_utime_buf = { 0, 0 }; dst = open64(dstPath, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(dst < 0) { fprintf(stderr, "ERROR: Can not open destination file: %s\n", strerror(errno)); return errno; } r = send_cmd_hdd_file_send(fd, GET, srcPath); if(r < 0) { goto out; } state = START; while(0 < (r = get_tf_packet(fd, &reply))) { update = (update + 1) % 16; switch (get_u32(&reply.cmd)) { case DATA_HDD_FILE_START: if(state == START) { struct typefile *tf = (struct typefile *) reply.data; byteCount = get_u64(&tf->size); mod_utime_buf.actime = mod_utime_buf.modtime = tfdt_to_time(&tf->stamp); send_success(fd); state = DATA; } else { fprintf(stderr, "ERROR: Unexpected DATA_HDD_FILE_START packet in state %d\n", state); send_cancel(fd); state = ABORT; } break; case DATA_HDD_FILE_DATA: if(state == DATA) { __u64 offset = get_u64(reply.data); __u16 dataLen = get_u16(&reply.length) - (PACKET_HEAD_SIZE + 8); ssize_t w; if(!update && !quiet) { progressStats(byteCount, offset + dataLen, startTime); } if(r < get_u16(&reply.length)) { fprintf(stderr, "ERROR: Short packet %d instead of %d\n", r, get_u16(&reply.length)); /* TODO: Fetch the rest of the packet */ } w = write(dst, &reply.data[8], dataLen); if(w < dataLen) { /* Can't write data - abort transfer */ fprintf(stderr, "ERROR: Can not write data: %s\n", strerror(errno)); send_cancel(fd); state = ABORT; } } else { fprintf(stderr, "ERROR: Unexpected DATA_HDD_FILE_DATA packet in state %d\n", state); send_cancel(fd); state = ABORT; } break; case DATA_HDD_FILE_END: send_success(fd); result = 0; goto out; break; case FAIL: fprintf(stderr, "ERROR: Device reports %s\n", decode_error(&reply)); send_cancel(fd); state = ABORT; break; case SUCCESS: goto out; break; default: fprintf(stderr, "ERROR: Unhandled packet (cmd 0x%x)\n", get_u32(&reply.cmd)); } } utime(dstPath, &mod_utime_buf); finalStats(byteCount, startTime); out: close(dst); return result; }
void Sem::ContainSim::run( void ) { // Status names const char *StatusName[] = { "Unreported", "Reported", "Attacked", "Contained", "Overrun", "Exhausted", "Sim Overflow", "Size Limit Exceeded", "Time Limit Exceeded" }; const char *TacticName[] = { "Head", "Rear" }; double at, elapsed, factor; // Log levels : 0=none, 1=major events, 2=stepwise int logLevel = 0; // Repeat simulation until [m_minSteps::m_maxSteps] steps achieved, // or if retry==TRUE, until sufficient resources are able to contain fire double area, dx, dy, suma, sumb, sumDT; double totalArea; // double maxArea = 500.0; bool rerun = true; bool MAXSTEPS_EXCEEDED=false; m_pass = 0; while ( rerun ) { m_left->containLog( ( logLevel >= 1 ), "\nPass %d Begins:\n", m_pass ); // Simulate until forces overrun, fire contained, or maxSteps reached int iLeft = 0; // First index of left half values m_u[iLeft] = m_left->m_u; m_h[iLeft] = m_left->m_h; m_x[iLeft] = m_left->m_x; m_y[iLeft] = m_left->m_y; //int iRight = m_maxSteps; // First index of right half values elapsed = m_left->m_attackTime; m_left->containLog( ( logLevel == 2 ), "%d: u=%12.10f, h=%12.10f, t=%f\n", iLeft, m_left->m_u, m_left->m_h, elapsed ); // This is the main simulation loop! m_finalSweep = m_finalLine = m_finalPerim = 0.0; totalArea=0.0; suma = sumb = sumDT = 0.0; while ( m_left->m_status != Sem::Contain::Overrun && m_left->m_status != Sem::Contain::Contained && m_left->m_step < m_maxSteps && totalArea < m_maxFireSize && m_left->m_currentTime < m_maxFireTime // MAF && m_left->m_currentTime < m_left->m_exhausted) // MAF { // Store angle and head position in the proper array element m_left->step(); // Store the new angle, head position, and coordinate values iLeft++; m_u[iLeft] = m_left->m_u; m_h[iLeft] = m_left->m_h; m_x[iLeft] = m_left->m_x; m_y[iLeft] = m_left->m_y; elapsed = m_left->m_currentTime;//m_time; // MAF // m_left->containLog( (logLevel == 2 ), // "%d: u=%12.10f, h=%12.10f, t=%12.10f\n", // iLeft, m_u[iLeft], m_h[iLeft], elapsed ); // Update the extent m_xMin = ( m_x[iLeft] < m_xMin ) ? m_x[iLeft] : m_xMin; m_xMax = ( m_x[iLeft] > m_xMax ) ? m_x[iLeft] : m_xMax; m_yMax = ( m_y[iLeft] > m_yMax ) ? m_y[iLeft] : m_yMax; // Line constructed and area swept during this simulation step dy = fabs( m_y[iLeft-1] - m_y[iLeft] ); dx = fabs( m_x[iLeft-1] - m_x[iLeft] ); m_p[iLeft-1] = sqrt( ( dy * dy ) + ( dx * dx ) ); // Accumulate line constructed for BOTH flanks (ch) m_finalLine += 2.0 * m_p[iLeft-1]; // Accumulate area of containment (apply trapazoidal rule) suma += ( m_y[iLeft-1] * m_x[iLeft] ); sumb += ( m_x[iLeft-1] * m_y[iLeft] ); area = ( suma > sumb ) ? ( 0.5 * ( suma - sumb ) ) : ( 0.5 * ( sumb - suma ) ); // Calculate the area using the trapizoidal rule sumDT = 0; for ( int i = 1; i <= iLeft; i++ ) sumDT = (m_x[i] - m_x[i-1]) * (m_y[i] + m_y[i-1]) + sumDT; if ( sumDT < 0 ) sumDT = -1.0 * sumDT; area = sumDT * .5; // Add in the area for the uncontained portion of the fire DT 1/2013 double UCarea = UncontainedArea( m_h[iLeft], fireLwRatioAtReport(), m_x[iLeft], m_y[iLeft], tactic() ); area = area + UCarea; // Accumulate area for BOTH flanks (ac) m_a[iLeft-1] = 0.2 * area; totalArea = m_a[iLeft-1]; m_left->containLog( (logLevel == 2 ), "%d: u=%12.10f, h=%12.10f, x=%12.10f, y=%12.10f, t=%12.10f, UCA=%12.10f, CA=%12.1f, TA=%12.10f, TP=%12.10f\n", iLeft, m_u[iLeft], m_h[iLeft], m_x[iLeft], m_y[iLeft], elapsed, UCarea*0.2, (area-UCarea)*0.2, totalArea, m_finalLine ); } // BEHAVEPLUS FIX: Adjust the last x-coordinate for contained head attacks if ( m_left->m_status == Sem::Contain::Contained && m_left->m_tactic == Sem::Contain::HeadAttack ) { m_x[m_left->m_step] -= 2. * m_left->m_attackDist; } suma += ( m_y[m_left->m_step] * m_x[0] ); sumb += ( m_x[m_left->m_step] * m_y[0] ); m_finalSweep = ( suma > sumb ) ? ( 0.5 * ( suma - sumb ) ) : ( 0.5 * ( sumb - suma ) ); m_finalSweep *= 0.20; // Calculate the area using the trapizoidal rule sumDT = 0; for ( int i = 1; i <= m_left->m_step; i++ ) sumDT = (m_x[i] - m_x[i-1]) * (m_y[i] + m_y[i-1]) + sumDT; if ( sumDT < 0 ) sumDT = -1.0 * sumDT; area = sumDT * .5; // Add in the area for the uncontained portion of the fire DT 1/2013 double UCarea = UncontainedArea( m_h[m_left->m_step], fireLwRatioAtReport(), m_x[m_left->m_step], m_y[m_left->m_step], tactic() ); area = area + UCarea; // Accumulate area for BOTH flanks (ac) m_finalSweep = 0.2 * area; // Cases 1-3: forces are overrun by fire... if ( m_left->m_status == Sem::Contain::Overrun ) { // Case 1: No retry allowed, simulation is complete if ( ! m_retry ) { rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 1: Overrun\n" " - resources overrun at %3.1f minutes (%d steps)\n" " - re-run is FALSE\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); } // Case 2: Try initial attack after more forces have arrived else if ( ( at = m_force->nextArrival( m_left->m_attackTime, m_left->m_exhausted, LeftFlank ) ) > 0.01 ) { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 2: Retry\n" " - resources overrun at %3.1f minutes (%d steps)\n" " - Pass %d will wait for IA until %3.1f minutes\n" " - when line building rate will be %3.2f ch/h\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_pass+1, at, m_force->productionRate( at, LeftFlank ) ); m_pass++; m_left->m_attackTime = at; m_left->reset(); rerun = true; } // Case 3: All resources exhausted else { // No more forces available, so we're done rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 3: Exhausted\n" " - resources exhausted at %3.1f minutes (%d steps)\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); m_left->m_status = Sem::Contain::Exhausted; } } // New Case 3: to set rerun to false when the outrun fires are // removed DT 7/8/10 else if (m_left->m_currentTime >= m_left->m_exhausted) { // No more forces available, so we're done rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 3: Exhausted\n" " - resources exhausted at %3.1f minutes (%d steps)\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); m_left->m_status = Sem::Contain::Exhausted; } // Case 4: maximum number of steps was exceeded // (should never happen as long as m_distStep is calculated from // m_exhausted, m_reportRate, ... ) else if ( iLeft >= m_maxSteps ) { // Make the distance step size bigger and rerun the simulation // MAF 9/29/2010, remove factor calc, just reverse previous factor and redo //factor = (double) m_maxSteps / (double) m_minSteps; factor = 2.0; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 4: Less Precision\n" " - fire uncontained at %f minutes\n" " - %d steps exceeds maximum of %d steps\n" " - increasing Eta from %f to %f chains for next Pass %d\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_maxSteps, m_left->m_distStep, (m_left->m_distStep*factor), m_pass+1 ); m_left->m_distStep *= factor; m_pass++; if(MAXSTEPS_EXCEEDED==false) { m_left->reset(); rerun = true; } else rerun=false; MAXSTEPS_EXCEEDED=true; } // Cases 5-6: fire is contained... else if ( m_left->m_status == Sem::Contain::Contained ) { // Case 5: there were insufficient simulation steps... if ( iLeft < m_minSteps && MAXSTEPS_EXCEEDED==false) // MAF 9/29/2010 added MAXSTEPS_EXCEEDED check { // Make the distance step size smaller and rerun the simulation // Need to make sure that with the new smaller step we will not // exceed the MAX steps - otherwise we end up looping // Diane 08/10 decrease the step size at a slower rate factor = 0.5 ; // (double) ( m_left->m_step + 1 ) / ((double) m_minSteps*1.25); m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 5: More Precision\n" " - fire contained at %3.1f minutes\n" " - %d steps is less than minimum of %d steps\n" " - decreasing Eta from %f to %f chains for Pass %d\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_minSteps, m_left->m_distStep, (m_left->m_distStep * factor), m_pass+1 ); m_left->m_distStep *= factor; m_pass++; // Diane 08/10 decrease the step size at a slower rate //if(m_pass<10) //{ m_left->reset(); rerun = true; //} //else // rerun=false; } // Case 6: fire contained within the simulation step range else { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 6: Contained\n" " - FIRE CONTAINED at %3.1f minutes (%d steps)\n", m_pass, elapsed, m_left->m_step ); rerun = false; } } //Add check for maximum Area else if(totalArea >= m_maxFireSize){ at = m_force->nextArrival( m_left->m_attackTime, m_left->m_exhausted, LeftFlank ); /*////////////////////////////////////////////////////////////////////////// Removed DT 6/2010 Stop when fire exceeds maximum size if (at > .01){ rerun = true; m_left->m_attackTime = at; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result max area exceeded: Retry\n" " - Maximum Area of %d exceeded at %3.1f minutes (%d steps)\n" " - Pass %d will wait for IA until %3.1f minutes\n" " - when line building rate will be %3.2f ch/h\n" " - RE-RUN\n", m_pass,m_maxFireSize, elapsed, m_left->m_step, m_pass+1, at, m_force->productionRate( at, LeftFlank ) ); m_pass++; m_left->reset(); }else{ */ // cout << m_pass << " " << totalArea << " " <<m_maxFireSize << " " << "\n"; m_left->containLog( ( logLevel >= 1 ), "Pass %d total fire size of %3.2f acres exceeds max fire size of %d acres at time %3.1f minutes\n", m_pass, totalArea, m_maxFireSize, elapsed); rerun = false; //Production rate is not longer increasing m_left->m_status = Sem::Contain::SizeLimitExceeded; // } } // time limit exceeded //------------------------------------------------------------------ // MAF 6/2010 //------------------------------------------------------------------ else if(((m_left->m_currentTime) > (m_maxFireTime-1))) { m_left->m_currentTime=m_maxFireTime; m_left->m_status = Sem::Contain::TimeLimitExceeded; rerun=false; } // Case 7: anything else (should never get here!)... else { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 7:\n" " - unknown condition at %3.1f minutes (%d steps)\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step ); rerun = true; } } // Special case for contained head tactic with non-zero offset if ( m_left->m_status == Sem::Contain::Contained && m_left->m_tactic == Sem::Contain::HeadAttack && m_left->m_attackDist > 0.01 ) { } //special case for time limit //if the time is greater than the max time, then the fire escapes //all resources that arrive prior to the max time are considered used //always subtract 1 minute from the fire time, we don't get a correct state //otherwise because the simulation forces all resources to end work before the //fire time limit is reached //if ((m_left->m_time) > (m_maxFireTime-1)) { // m_left->m_time=m_maxFireTime; // m_left->m_status = Sem::Contain::TimeLimitExceeded; //} //------------------------------------------------------------------ // MAF 6/2010 //------------------------------------------------------------------ if ((m_left->m_currentTime) > (m_maxFireTime-1)) { m_left->m_currentTime=m_maxFireTime; m_left->m_status = Sem::Contain::TimeLimitExceeded; } // Simulation complete: display results finalStats(); m_left->containLog( ( logLevel > 0 ), "\n Pass %d Step Size : %f ch\n", m_pass, m_left->m_distStep ); m_left->containLog( ( logLevel > 0 ), " Tactic : %8s\n", TacticName[m_left->m_tactic] ); m_left->containLog( ( logLevel > 0 ), " Simulation Steps : %8d\n", m_left->m_step+1 ); m_left->containLog( ( logLevel > 0 ), " Simulation Time : %8.2f min\n", m_finalTime ); m_left->containLog( ( logLevel > 0 ), " Simulation Result : %s\n", StatusName[m_left->m_status] ); m_left->containLog( ( logLevel > 0 ), " Containment Line : %8.4f ch\n", m_finalLine ); m_left->containLog( ( logLevel > 0 ), " Containment Size : %8.4f ac\n", m_finalSize ); m_left->containLog( ( logLevel > 0 ), " Resources Used : %8d\n", m_used ); m_left->containLog( ( logLevel > 0 ), " Resource Cost : %8.0f\n\n", m_finalCost ); return; }
int do_hdd_file_put(int fd, char *srcPath, char *dstPath) { int result = -EPROTO; time_t startTime = time(NULL); enum { START, DATA, END, FINISHED } state; int src = -1; int r; int update = 0; struct stat64 srcStat; __u64 fileSize; __u64 byteCount = 0; trace(4, fprintf(stderr, "%s\n", __func__)); src = open64(srcPath, O_RDONLY); if(src < 0) { fprintf(stderr, "ERROR: Can not open source file: %s\n", strerror(errno)); return errno; } if(0 != fstat64(src, &srcStat)) { fprintf(stderr, "ERROR: Can not examine source file: %s\n", strerror(errno)); result = errno; goto out; } fileSize = srcStat.st_size; if(fileSize == 0) { fprintf(stderr, "ERROR: Source file is empty - not transfering.\n"); result = -ENODATA; goto out; } r = send_cmd_hdd_file_send(fd, PUT, dstPath); if(r < 0) { goto out; } state = START; while(0 < get_tf_packet(fd, &reply)) { update = (update + 1) % 16; switch (get_u32(&reply.cmd)) { case SUCCESS: switch (state) { case START: { /* Send start */ struct typefile *tf = (struct typefile *) packet.data; put_u16(&packet.length, PACKET_HEAD_SIZE + 114); put_u32(&packet.cmd, DATA_HDD_FILE_START); time_to_tfdt(srcStat.st_mtime, &tf->stamp); tf->filetype = 2; put_u64(&tf->size, srcStat.st_size); strncpy((char *) tf->name, dstPath, 94); tf->name[94] = '\0'; tf->unused = 0; tf->attrib = 0; trace(3, fprintf(stderr, "%s: DATA_HDD_FILE_START\n", __func__)); r = send_tf_packet(fd, &packet); if(r < 0) { fprintf(stderr, "ERROR: Incomplete send.\n"); goto out; } state = DATA; break; } case DATA: { int payloadSize = sizeof(packet.data) - 9; ssize_t w = read(src, &packet.data[8], payloadSize); /* Detect a Topfield protcol bug and prevent the sending of packets that are a multiple of 512 bytes. */ if((w > 4) && (((((PACKET_HEAD_SIZE + 8 + w) + 1) & ~1) % 0x200) == 0)) { lseek64(src, -4, SEEK_CUR); w -= 4; payloadSize -= 4; } put_u16(&packet.length, PACKET_HEAD_SIZE + 8 + w); put_u32(&packet.cmd, DATA_HDD_FILE_DATA); put_u64(packet.data, byteCount); byteCount += w; /* Detect EOF and transition to END */ if((w < 0) || (byteCount >= fileSize)) { state = END; } if(w > 0) { trace(3, fprintf(stderr, "%s: DATA_HDD_FILE_DATA\n", __func__)); r = send_tf_packet(fd, &packet); if(r < w) { fprintf(stderr, "ERROR: Incomplete send.\n"); goto out; } } if(!update && !quiet) { progressStats(fileSize, byteCount, startTime); } break; } case END: /* Send end */ put_u16(&packet.length, PACKET_HEAD_SIZE); put_u32(&packet.cmd, DATA_HDD_FILE_END); trace(3, fprintf(stderr, "%s: DATA_HDD_FILE_END\n", __func__)); r = send_tf_packet(fd, &packet); if(r < 0) { fprintf(stderr, "ERROR: Incomplete send.\n"); goto out; } state = FINISHED; break; case FINISHED: result = 0; goto out; break; } break; case FAIL: fprintf(stderr, "ERROR: Device reports %s\n", decode_error(&reply)); goto out; break; default: fprintf(stderr, "ERROR: Unhandled packet\n"); break; } } finalStats(byteCount, startTime); out: close(src); return result; }