static bool ReadFlightListInner(Port &port, RecordedFlightList &flight_list, OperationEnvironment &env) { env.SetProgressRange(10); if (!Volkslogger::ConnectAndFlush(port, env, 20000)) return false; env.SetProgressPosition(3); uint8_t dirbuffer[VLAPI_LOG_MEMSIZE]; int data_length = Volkslogger::ReadFlightList(port, env, dirbuffer, sizeof(dirbuffer)); if (data_length <= 0) return data_length == 0; std::vector<DIRENTRY> directory; if (!conv_dir(directory, dirbuffer, data_length)) return false; if (directory.empty()) return true; env.SetProgressPosition(8); if (!ConvertDirectoryToRecordedFlightList(directory, flight_list)) return false; env.SetProgressPosition(10); return true; }
void CAI302WaypointUploader::Run(OperationEnvironment &env) { Waypoints waypoints; env.SetText(_("Loading Waypoints...")); if (!reader.Parse(waypoints, env)) { env.SetErrorMessage(_("Failed to load file.")); return; } if (waypoints.size() > 9999) { env.SetErrorMessage(_("Too many waypoints.")); return; } env.SetText(_("Uploading Waypoints")); env.SetProgressRange(waypoints.size() + 1); env.SetProgressPosition(0); if (!device.ClearPoints(env)) { if (!env.IsCancelled()) env.SetErrorMessage(_("Failed to erase waypoints.")); return; } if (!device.EnableBulkMode(env)) { if (!env.IsCancelled()) env.SetErrorMessage(_("Failed to switch baud rate.")); return; } unsigned id = 1; for (auto i = waypoints.begin(), end = waypoints.end(); i != end; ++i, ++id) { if (env.IsCancelled()) break; env.SetProgressPosition(id); if (!device.WriteNavpoint(id, *i, env)) { if (!env.IsCancelled()) env.SetErrorMessage(_("Failed to write waypoint.")); break; } } device.DisableBulkMode(env); }
int Net::DownloadToBuffer(Session &session, const char *url, void *_buffer, size_t max_length, OperationEnvironment &env) { Request request(session, url, 10000); if (!request.Send(10000)) return -1; int64_t total = request.GetLength(); if (total >= 0) env.SetProgressRange(total); total = 0; uint8_t *buffer = (uint8_t *)_buffer, *p = buffer, *end = buffer + max_length; while (p != end) { if (env.IsCancelled()) return -1; ssize_t nbytes = request.Read(p, end - p, 5000); if (nbytes < 0) return -1; if (nbytes == 0) break; p += nbytes; total += nbytes; env.SetProgressPosition(total); } return p - buffer; }
/** * Parses the data provided by the airfield details file handle */ static void ParseAirfieldDetails(Waypoints &way_points, TLineReader &reader, OperationEnvironment &operation) { tstring details; std::vector<tstring> files_external, files_embed; TCHAR name[201]; const TCHAR *filename; name[0] = 0; bool in_details = false; int i; const long filesize = std::max(reader.GetSize(), 1l); operation.SetProgressRange(100); TCHAR *line; while ((line = reader.ReadLine()) != NULL) { if (line[0] == _T('[')) { // Look for start if (in_details) SetAirfieldDetails(way_points, name, details, files_external, files_embed); details.clear(); files_external.clear(); files_embed.clear(); // extract name for (i = 1; i < 201; i++) { if (line[i] == _T(']')) break; name[i - 1] = line[i]; } name[i - 1] = 0; in_details = true; operation.SetProgressPosition(reader.Tell() * 100 / filesize); } else if ((filename = StringAfterPrefixCI(line, _T("image="))) != NULL) { files_embed.emplace_back(filename); } else if ((filename = StringAfterPrefixCI(line, _T("file="))) != NULL) { #ifdef ANDROID files_external.emplace_back(filename); #endif } else { // append text to details string if (!StringIsEmpty(line)) { details += line; details += _T('\n'); } } } if (in_details) SetAirfieldDetails(way_points, name, details, files_external, files_embed); }
bool Volkslogger::WriteBulk(Port &port, OperationEnvironment &env, const void *buffer, unsigned length) { const unsigned delay = 1; env.SetProgressRange(length); uint16_t crc16 = 0; const uint8_t *p = (const uint8_t *)buffer, *end = p + length; while (p < end) { unsigned n = end - p; if (n > 400) n = 400; n = port.Write(p, n); if (n == 0) return false; crc16 = UpdateCRC16CCITT(p, n, crc16); p += n; env.SetProgressPosition(p - (const uint8_t *)buffer); /* throttle sending a bit, or the Volkslogger's receive buffer will overrun */ env.Sleep(delay * 100); } return port.Write(crc16 >> 8) && port.Write(crc16 & 0xff); }
virtual void Run(OperationEnvironment &env) { env.SetText(_T("Working...")); env.SetProgressRange(30); for (unsigned i = 0; i < 30 && !env.IsCancelled(); ++i) { env.SetProgressPosition(i); env.Sleep(500); } }
bool AirspaceParser::Parse(TLineReader &reader, OperationEnvironment &operation) { bool ignore = false; // Create and init ProgressDialog operation.SetProgressRange(1024); const long file_size = reader.GetSize(); TempAirspaceType temp_area; AirspaceFileType filetype = AFT_UNKNOWN; TCHAR *line; // Iterate through the lines for (unsigned line_num = 1; (line = reader.ReadLine()) != NULL; line_num++) { // Skip empty line if (StringIsEmpty(line)) continue; if (filetype == AFT_UNKNOWN) { filetype = DetectFileType(line); if (filetype == AFT_UNKNOWN) continue; } // Parse the line if (filetype == AFT_OPENAIR) if (!ParseLine(airspaces, line, temp_area) && !ShowParseWarning(line_num, line, operation)) return false; if (filetype == AFT_TNP) if (!ParseLineTNP(airspaces, line, temp_area, ignore) && !ShowParseWarning(line_num, line, operation)) return false; // Update the ProgressDialog if ((line_num & 0xff) == 0) operation.SetProgressPosition(reader.Tell() * 1024 / file_size); } if (filetype == AFT_UNKNOWN) { operation.SetErrorMessage(_("Unknown airspace filetype")); return false; } // Process final area (if any) if (!temp_area.points.empty()) temp_area.AddPolygon(airspaces); return true; }
bool FlarmDevice::DownloadFlight(Path path, OperationEnvironment &env) { FileOutputStream fos(path); BufferedOutputStream os(fos); if (env.IsCancelled()) return false; env.SetProgressRange(100); while (true) { // Create header for getting IGC file data FLARM::FrameHeader header = PrepareFrameHeader(FLARM::MT_GETIGCDATA); // Send request if (!SendStartByte() || !SendFrameHeader(header, env, 1000) || env.IsCancelled()) return false; // Wait for an answer and save the payload for further processing AllocatedArray<uint8_t> data; uint16_t length; bool ack = WaitForACKOrNACK(header.GetSequenceNumber(), data, length, env, 10000) == FLARM::MT_ACK; // If no ACK was received if (!ack || length <= 3 || env.IsCancelled()) return false; length -= 3; // Read progress (in percent) uint8_t progress = *(data.begin() + 2); env.SetProgressPosition(std::min((unsigned)progress, 100u)); const char *last_char = (const char *)data.end() - 1; bool is_last_packet = (*last_char == 0x1A); if (is_last_packet) length--; // Read IGC data const char *igc_data = (const char *)data.begin() + 3; os.Write(igc_data, length); if (is_last_packet) break; } os.Flush(); fos.Commit(); return true; }
static bool DownloadToFile(Net::Session &session, const char *url, FILE *file, char *md5_digest, OperationEnvironment &env) { assert(url != NULL); assert(file != NULL); Net::Request request(session, url, 10000); if (!request.Send(10000)) return false; int64_t total = request.GetLength(); if (total >= 0) env.SetProgressRange(total); total = 0; MD5 md5; md5.InitKey(); uint8_t buffer[4096]; while (true) { if (env.IsCancelled()) return false; ssize_t nbytes = request.Read(buffer, sizeof(buffer), 5000); if (nbytes < 0) return false; if (nbytes == 0) break; if (md5_digest != NULL) md5.Append(buffer, nbytes); size_t written = fwrite(buffer, 1, nbytes, file); if (written != (size_t)nbytes) return false; total += nbytes; env.SetProgressPosition(total); } if (md5_digest != NULL) { md5.Finalize(); md5.GetDigest(md5_digest); } return true; }
static bool DownloadFlightInner(Port &port, const RecordedFlightInfo &flight, FILE *file, OperationEnvironment &env) { if (!LX::CommandMode(port, env)) return false; port.Flush(); LX::SeekMemory seek; seek.start_address = flight.internal.lx.start_address; seek.end_address = flight.internal.lx.end_address; if (!LX::SendPacket(port, LX::SEEK_MEMORY, &seek, sizeof(seek), env) || !LX::ExpectACK(port, env)) return false; LX::MemorySection memory_section; if (!LX::ReceivePacketRetry(port, LX::READ_MEMORY_SECTION, &memory_section, sizeof(memory_section), env, 5000, 2000, 60000, 2)) return false; unsigned lengths[LX::MemorySection::N]; unsigned total_length = 0; for (unsigned i = 0; i < LX::MemorySection::N; ++i) { lengths[i] = FromBE16(memory_section.lengths[i]); total_length += lengths[i]; } env.SetProgressRange(total_length); uint8_t *data = new uint8_t[total_length], *p = data; for (unsigned i = 0; i < LX::MemorySection::N && lengths[i] > 0; ++i) { if (!LX::ReceivePacketRetry(port, (LX::Command)(LX::READ_LOGGER_DATA + i), p, lengths[i], env, 20000, 2000, 300000, 2)) { delete [] data; return false; } p += lengths[i]; env.SetProgressPosition(p - data); } bool success = LX::ConvertLXNToIGC(data, total_length, file); delete [] data; return success; }
static bool DownloadFlightInner(Port &port, const char *filename, FILE *file, OperationEnvironment &env) { PortNMEAReader reader(port, env); unsigned row_count = 0, i = 1; while (true) { /* read up to 32 lines at a time */ unsigned nrequest = row_count == 0 ? 1 : 32; if (row_count > 0) { assert(i <= row_count); const unsigned remaining = row_count - i + 1; if (nrequest > remaining) nrequest = remaining; } const unsigned start = i; const unsigned end = start + nrequest; /* send request to Nano */ reader.Flush(); if (!RequestFlight(port, filename, start, end, env)) return false; /* read the requested lines and save to file */ TimeoutClock timeout(2000); while (i != end) { const char *line = reader.ExpectLine("PLXVC,FLIGHT,A,", timeout); if (line == nullptr || !HandleFlightLine(line, file, i, row_count)) return false; } if (i > row_count) /* finished successfully */ return true; if (start == 1) /* configure the range in the first iteration, now that we know the length of the file */ env.SetProgressRange(row_count); env.SetProgressPosition(i - 1); } }
/** * Parses the data provided by the airfield details file handle */ static void ParseAirfieldDetails(Waypoints &way_points, TLineReader &reader, OperationEnvironment &operation) { tstring Details; TCHAR Name[201]; Name[0] = 0; bool inDetails = false; int i; long filesize = std::max(reader.size(), 1l); operation.SetProgressRange(100); TCHAR *TempString; while ((TempString = reader.read()) != NULL) { if (TempString[0] == _T('[')) { // Look for start if (inDetails) SetAirfieldDetails(way_points, Name, Details); Details.clear(); // extract name for (i = 1; i < 201; i++) { if (TempString[i] == _T(']')) break; Name[i - 1] = TempString[i]; } Name[i - 1] = 0; inDetails = true; operation.SetProgressPosition(reader.tell() * 100 / filesize); } else { // append text to details string if (!string_is_empty(TempString)) { Details += TempString; Details += _T('\n'); } } } if (inDetails) SetAirfieldDetails(way_points, Name, Details); }
void WaypointReaderBase::Parse(Waypoints &way_points, TLineReader &reader, OperationEnvironment &operation) { const long filesize = std::max(reader.GetSize(), 1l); operation.SetProgressRange(100); // Read through the lines of the file TCHAR *line; for (unsigned i = 0; (line = reader.ReadLine()) != nullptr; i++) { // and parse them ParseLine(line, i, way_points); if ((i & 0x3f) == 0) operation.SetProgressPosition(reader.Tell() * 100 / filesize); } }
static bool ReadFlightListInner(Port &port, RecordedFlightList &flight_list, OperationEnvironment &env) { env.SetProgressRange(8); for (unsigned i = 0; i < 8 && !flight_list.full(); ++i) { CAI302::FileList file_list; if (!CAI302::UploadFileList(port, i, file_list, env)) break; for (unsigned j = 0; j < 8 && !flight_list.full(); ++j) { const CAI302::FileList::FileInfo &file = file_list.files[j]; if (file.start_utc.month > 0) Copy(flight_list.append(), i * 8 + j, file); } env.SetProgressPosition(i); } return !flight_list.empty() && !env.IsCancelled(); }
bool Nano::ReadFlightList(Port &port, RecordedFlightList &flight_list, OperationEnvironment &env) { port.StopRxThread(); PortNMEAReader reader(port, env); TimeoutClock timeout(2000); int nflights = GetNumberOfFlights(port, reader, env, timeout); if (nflights <= 0) return nflights == 0; env.SetProgressRange(nflights); unsigned requested_tail = 1; while (true) { const unsigned room = flight_list.max_size() - flight_list.size(); const unsigned remaining = nflights - requested_tail + 1; const unsigned nmax = std::min(room, remaining); if (nmax == 0) break; /* read 8 records at a time */ const unsigned nrequest = std::min(nmax, 8u); timeout = TimeoutClock(2000); if (!GetLogbookContents(port, reader, flight_list, requested_tail, nrequest, env, timeout)) return false; requested_tail += nrequest; env.SetProgressPosition(requested_tail - 1); } return true; }
void TopographyStore::Load(OperationEnvironment &operation, NLineReader &reader, const TCHAR *directory, struct zzip_dir *zdir) { Reset(); // Create buffer for the shape filenames // (shape_filename will be modified with the shape_filename_end pointer) char shape_filename[MAX_PATH]; if (directory != nullptr) { const WideToACPConverter narrow_directory(directory); strcpy(shape_filename, narrow_directory); strcat(shape_filename, DIR_SEPARATOR_S); } else shape_filename[0] = 0; char *shape_filename_end = shape_filename + strlen(shape_filename); // Read file size to have a rough progress estimate for the progress bar const long filesize = std::max(reader.GetSize(), 1l); // Set progress bar to 100 steps operation.SetProgressRange(100); // Iterate through shape files in the "topology.tpl" file until // end or max. file number reached char *line; while (!files.full() && (line = reader.ReadLine()) != nullptr) { // .tpl Line format: filename,range,icon,field,r,g,b,pen_width,label_range,important_range,alpha // Ignore comments (lines starting with *) and empty lines if (StringIsEmpty(line) || line[0] == '*') continue; // Find first comma to extract shape filename char *p = strchr(line, ','); if (p == nullptr || p == line) // If no comma was found -> ignore this line/shapefile continue; if (HasLittleMemory()) { /* hard-coded blacklist for huge files on PPC2000; those devices usually have very little memory */ // Null-terminate the line string after the first comma // for strcmp() calls in IsHugeTopographyFile() function *p = 0; // Skip large topography files if (IsHugeTopographyFile(line)) continue; } // Extract filename and append it to the shape_filename buffer memcpy(shape_filename_end, line, p - line); // Append ".shp" file extension to the shape_filename buffer strcpy(shape_filename_end + (p - line), ".shp"); // Parse shape range fixed shape_range = fixed(strtod(p + 1, &p)) * 1000; if (*p != _T(',')) continue; // Extract shape icon name char icon_name[23]; char *start = p + 1; p = strchr(start, ','); // Null-terminate the line string at the next comma for strncpy() call *p = 0; strncpy(icon_name, start, 22); ResourceId icon = ResourceId::Null(), big_icon = ResourceId::Null(); if (strlen(icon_name) > 0) { const LOOKUP_ICON *ip = icon_list; while (ip->name != nullptr) { if (StringIsEqual(ip->name, icon_name)) { icon = ip->resource_id; big_icon = ip->big_resource_id; break; } ip++; } } // Parse shape field for text display long shape_field = strtol(p + 1, &p, 10) - 1; if (*p != _T(',')) continue; // Parse red component of line / shading colour uint8_t red = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse green component of line / shading colour uint8_t green = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse blue component of line / shading colour uint8_t blue = (uint8_t)strtol(p + 1, &p, 10); // Parse pen width of lines unsigned pen_width = 1; if (*p == _T(',')) { pen_width = strtoul(p + 1, &p, 10); if (pen_width < 1) pen_width = 1; else if (pen_width>31) pen_width=31; } // Parse range for displaying labels fixed label_range = shape_range; if (*p == _T(',')) label_range = fixed(strtod(p + 1, &p)) * 1000; // Parse range for displaying labels with "important" rendering style fixed labelImportantRange = fixed(0); if (*p == _T(',')) labelImportantRange = fixed(strtod(p + 1, &p)) * 1000; // Handle alpha component // If not present at all (i.e. v6.6 or earlier file), default to 100% opaque uint8_t alpha = 255; if (*p == _T(',')) { // An alpha component of shading colour is present (v6.7 or later file). alpha = (uint8_t)strtol(p + 1, &p, 10); // Ignore a totally transparent file! if (alpha == 0) continue; #ifndef ENABLE_OPENGL // Without OpenGL ignore anything but 100% opaque if (alpha != 255) continue; #endif } // Create TopographyFile instance from parsed line TopographyFile *file = new TopographyFile(zdir, shape_filename, shape_range, label_range, labelImportantRange, #ifdef ENABLE_OPENGL Color(red, green, blue, alpha), #else Color(red, green, blue), #endif shape_field, icon, big_icon, pen_width); if (file->IsEmpty()) // If the shape file could not be read -> skip this line/file delete file; else // .. otherwise append it to our list of shape files files.append(file); // Update progress bar operation.SetProgressPosition((reader.Tell() * 100) / filesize); } }
bool FlytecDevice::DownloadFlight(const RecordedFlightInfo &flight, Path path, OperationEnvironment &env) { port.StopRxThread(); PeriodClock status_clock; status_clock.Update(); // Request flight record char buffer[256]; sprintf(buffer, "$PBRTR,%02d", flight.internal.flytec); AppendNMEAChecksum(buffer); strcat(buffer, "\r\n"); port.Write(buffer); if (!ExpectXOff(port, env, 1000)) return false; // Open file writer FileHandle writer(path, _T("wb")); if (!writer.IsOpen()) return false; unsigned start_sec = flight.start_time.GetSecondOfDay(); unsigned end_sec = flight.end_time.GetSecondOfDay(); if (end_sec < start_sec) end_sec += 24 * 60 * 60; unsigned range = end_sec - start_sec; env.SetProgressRange(range); while (true) { // Check if the user cancelled the operation if (env.IsCancelled()) return false; // Receive the next line if (!ReceiveLine(port, buffer, ARRAY_SIZE(buffer), 1000)) return false; // XON was received if (StringIsEmpty(buffer)) break; if (status_clock.CheckUpdate(250) && *buffer == 'B') { // Parse the fix time BrokenTime time; if (IGCParseTime(buffer + 1, time)) { unsigned time_sec = time.GetSecondOfDay(); if (time_sec < start_sec) time_sec += 24 * 60 * 60; if (time_sec > end_sec + 5 * 60) time_sec = start_sec; unsigned position = time_sec - start_sec; if (position > range) position = range; env.SetProgressPosition(position); } } // Write line to the file writer.Write(buffer); } return true; }
bool FlytecDevice::ReadFlightList(RecordedFlightList &flight_list, OperationEnvironment &env) { port.StopRxThread(); char buffer[256]; strcpy(buffer, "$PBRTL,"); AppendNMEAChecksum(buffer); strcat(buffer, "\r\n"); port.Write(buffer); if (!ExpectXOff(port, env, 1000)) return false; unsigned tracks = 0; while (true) { // Check if the user cancelled the operation if (env.IsCancelled()) return false; // Receive the next line if (!ReceiveLine(port, buffer, ARRAY_SIZE(buffer), 1000)) return false; // XON was received, last record was read already if (StringIsEmpty(buffer)) break; // $PBRTL Identifier // AA total number of stored tracks // BB actual number of track (0 indicates the most actual track) // DD.MM.YY date of recorded track (UTC)(e.g. 24.03.04) // hh:mm:ss starttime (UTC)(e.g. 08:23:15) // HH:MM:SS duration (e.g. 03:23:15) // *ZZ Checksum as defined by NMEA RecordedFlightInfo flight; NMEAInputLine line(buffer); // Skip $PBRTL line.Skip(); if (tracks == 0) { // If number of tracks not read yet // .. read and save it if (!line.ReadChecked(tracks)) continue; env.SetProgressRange(tracks); } else line.Skip(); if (!line.ReadChecked(flight.internal.flytec)) continue; if (tracks != 0 && flight.internal.flytec < tracks) env.SetProgressPosition(flight.internal.flytec); char field_buffer[16]; line.Read(field_buffer, ARRAY_SIZE(field_buffer)); if (!ParseDate(field_buffer, flight.date)) continue; line.Read(field_buffer, ARRAY_SIZE(field_buffer)); if (!ParseTime(field_buffer, flight.start_time)) continue; BrokenTime duration; line.Read(field_buffer, ARRAY_SIZE(field_buffer)); if (!ParseTime(field_buffer, duration)) continue; flight.end_time = flight.start_time + duration; flight_list.append(flight); } return true; }
static bool DownloadFlightInner(Port &port, const RecordedFlightInfo &flight, const TCHAR *path, OperationEnvironment &env) { assert(flight.internal.cai302 < 64); BinaryWriter writer(path); if (writer.HasError()) return false; CAI302::FileASCII file_ascii; if (!UploadFileASCII(port, flight.internal.cai302, file_ascii, env) || env.IsCancelled()) return false; unsigned bytes_per_block = ReadUnalignedBE16(&file_ascii.bytes_per_block); unsigned num_blocks = ReadUnalignedBE16(&file_ascii.num_blocks); env.SetProgressRange(num_blocks); unsigned allocated_size = sizeof(CAI302::FileData) + bytes_per_block; void *allocated = malloc(allocated_size); CAI302::FileData *header = (CAI302::FileData *)allocated; void *data = header + 1; unsigned current_block = 0; unsigned valid_bytes; do { int i = UploadFileData(port, true, header, allocated_size, env); if (i < (int)sizeof(*header)) { free(allocated); return false; } i -= sizeof(*header); valid_bytes = FromBE16(header->valid_bytes); if ((unsigned)i < valid_bytes) { free(allocated); return false; } if (!writer.Write(data, 1, valid_bytes)) { free(allocated); return false; } env.SetProgressPosition(current_block++); } while (valid_bytes == bytes_per_block); free(allocated); CAI302::FileSignatureASCII signature; if (!CAI302::UploadFileSignatureASCII(port, signature, env)) return false; valid_bytes = FromBE16(signature.size); if (valid_bytes > sizeof(signature.signature)) return false; if (!writer.Write(signature.signature, 1, valid_bytes)) return false; return true; }
static bool DownloadFlightInner(Port &port, const char *filename, FILE *file, OperationEnvironment &env) { PortNMEAReader reader(port, env); unsigned row_count = 0, i = 1; while (true) { /* read up to 32 lines at a time */ unsigned nrequest = row_count == 0 ? 1 : 32; if (row_count > 0) { assert(i <= row_count); const unsigned remaining = row_count - i + 1; if (nrequest > remaining) nrequest = remaining; } const unsigned start = i; const unsigned end = start + nrequest; unsigned request_retry_count = 0; /* read the requested lines and save to file */ while (i != end) { if (i == start) { /* send request range to Nano */ reader.Flush(); if (!RequestFlight(port, filename, start, end, env)) return false; request_retry_count++; } TimeoutClock timeout(2000); const char *line = reader.ExpectLine("PLXVC,FLIGHT,A,", timeout); if (line == nullptr || !HandleFlightLine(line, file, i, row_count)) { if (request_retry_count > 5) return false; /* Discard data which might still be in-transit, e.g. buffered inside a bluetooth dongle */ port.FullFlush(env, 200, 2000); /* If we already received parts of the request range correctly break out of the loop to calculate new request range */ if (i != start) break; /* No valid reply received (i==start) - request same range again */ } } if (i > row_count) /* finished successfully */ return true; if (start == 1) /* configure the range in the first iteration, now that we know the length of the file */ env.SetProgressRange(row_count); env.SetProgressPosition(i - 1); } }
int Volkslogger::ReadBulk(Port &port, OperationEnvironment &env, void *buffer, size_t max_length, unsigned timeout_firstchar_ms) { unsigned nbytes = 0; bool dle_r = false; uint16_t crc16 = 0; bool start = false, ende = false; memset(buffer, 0xff, max_length); uint8_t *p = (uint8_t *)buffer; constexpr unsigned TIMEOUT_NORMAL_MS = 2000; /** * We need to wait longer for the first char to * give the logger time to calculate security * when downloading a log-file. * Therefore timeout_firstchar is configurable. * If the timeout parameter is not specified or 0, * set standard timeout */ if (timeout_firstchar_ms == 0) timeout_firstchar_ms = TIMEOUT_NORMAL_MS; unsigned const PROGRESS_BAR_RANGE = 1000; env.SetProgressRange(PROGRESS_BAR_RANGE); while (!ende) { env.SetProgressPosition(nbytes % PROGRESS_BAR_RANGE); // Zeichen anfordern und darauf warten if (!port.Write(ACK)) return -1; // Set longer timeout on first char unsigned timeout = start ? TIMEOUT_NORMAL_MS : timeout_firstchar_ms; if (port.WaitRead(env, timeout) != Port::WaitResult::READY) return -1; int ch = port.GetChar(); if (ch < 0) return -1; // dabei ist Benutzerabbruch jederzeit möglich if (env.IsCancelled()) { env.Sleep(10); port.Write(CAN); port.Write(CAN); port.Write(CAN); return -1; } // oder aber das empfangene Zeichen wird ausgewertet switch (ch) { case DLE: if (!dle_r) { //!DLE, DLE -> Achtung! dle_r = true; } else { // DLE, DLE -> DLE-Zeichen dle_r = false; if (start) { if(nbytes < max_length) *p++ = ch; nbytes++; crc16 = UpdateCRC16CCITT(ch, crc16); } } break; case ETX: if (!dle_r) { //!DLE, ETX -> Zeichen if (start) { if(nbytes < max_length) { *p++ = ch; } nbytes++; crc16 = UpdateCRC16CCITT(ch, crc16); }; } else { if (start) { ende = true; // DLE, ETX -> Blockende dle_r = false; } } break; case STX: if (!dle_r) { //!DLE, STX -> Zeichen if (start) { if(nbytes < max_length) *p++ = ch; nbytes++; crc16 = UpdateCRC16CCITT(ch, crc16); } } else { start = true; // DLE, STX -> Blockstart dle_r = false; crc16 = 0; } break; default: if (start) { if(nbytes < max_length) *p++ = ch; nbytes++; crc16 = UpdateCRC16CCITT(ch, crc16); } break; } } env.SetProgressPosition(PROGRESS_BAR_RANGE); env.Sleep(100); if (crc16 != 0) return -1; if (nbytes < 2) return 0; // CRC am Ende abschneiden return nbytes - 2; }
bool FlarmDevice::DeclareInternal(const Declaration &declaration, OperationEnvironment &env) { unsigned size = declaration.Size(); env.SetProgressRange(6 + size); env.SetProgressPosition(0); if (!SetPilot(declaration.pilot_name.c_str(), env)) return false; env.SetProgressPosition(1); if (!SetPlaneRegistration(declaration.aircraft_registration.c_str(), env)) return false; env.SetProgressPosition(2); if (!SetPlaneType(declaration.aircraft_type.c_str(), env)) return false; env.SetProgressPosition(3); if (!SetConfig("NEWTASK", "Task", env)) return false; env.SetProgressPosition(4); if (!SetConfig("ADDWP", "0000000N,00000000E,T", env)) return false; env.SetProgressPosition(5); for (unsigned i = 0; i < size; ++i) { int DegLat, DegLon; fixed tmp, MinLat, MinLon; char NoS, EoW; tmp = declaration.GetLocation(i).latitude.Degrees(); if (negative(tmp)) { NoS = 'S'; tmp = -tmp; } else { NoS = 'N'; } DegLat = (int)tmp; MinLat = (tmp - fixed(DegLat)) * 60 * 1000; tmp = declaration.GetLocation(i).longitude.Degrees(); if (negative(tmp)) { EoW = 'W'; tmp = -tmp; } else { EoW = 'E'; } DegLon = (int)tmp; MinLon = (tmp - fixed(DegLon)) * 60 * 1000; /* * We use the waypoint index here as name to get around the 192 byte * task size limit of the FLARM devices. * * see Flarm DataPort Manual: * "The total data size entered through this command may not surpass * 192 bytes when calculated as follows: 7+(Number of Waypoints * 9) + * (sum of length of all task and waypoint descriptions)" */ NarrowString<90> buffer; buffer.Format("%02d%05.0f%c,%03d%05.0f%c,%d", DegLat, (double)MinLat, NoS, DegLon, (double)MinLon, EoW, i + 1); if (!SetConfig("ADDWP", buffer, env)) return false; env.SetProgressPosition(6 + i); } if (!SetConfig("ADDWP", "0000000N,00000000E,L", env)) return false; env.SetProgressPosition(6 + size); // PFLAC,S,KEY,VALUE // Expect // PFLAC,A,blah // PFLAC,,COPIL: // PFLAC,,COMPID: // PFLAC,,COMPCLASS: // PFLAC,,NEWTASK: // PFLAC,,ADDWP: // Reset the FLARM to activate the declaration Restart(env); return true; }
void TopographyStore::Load(OperationEnvironment &operation, NLineReader &reader, const TCHAR *directory, struct zzip_dir *zdir) { Reset(); // Create buffer for the shape filenames // (shape_filename will be modified with the shape_filename_end pointer) char shape_filename[MAX_PATH]; if (directory != NULL) { const WideToACPConverter narrow_directory(directory); strcpy(shape_filename, narrow_directory); strcat(shape_filename, DIR_SEPARATOR_S); } else shape_filename[0] = 0; char *shape_filename_end = shape_filename + strlen(shape_filename); // Read file size to have a rough progress estimate for the progress bar long filesize = std::max(reader.size(), 1l); // Set progress bar to 100 steps operation.SetProgressRange(100); // Iterate through shape files in the "topology.tpl" file until // end or max. file number reached char *line; while (!files.full() && (line = reader.read()) != NULL) { // Line format: filename,range,icon,field,r,g,b,pen_width,label_range,important_range // Ignore comments (lines starting with *) and empty lines if (StringIsEmpty(line) || line[0] == '*') continue; // Find first comma to extract shape filename char *p = strchr(line, ','); if (p == NULL || p == line) // If no comma was found -> ignore this line/shapefile continue; if (HasLittleMemory()) { /* hard-coded blacklist for huge files on PPC2000; those devices usually have very little memory */ // Null-terminate the line string after the first comma // for strcmp() calls in IsHugeTopographyFile() function *p = 0; // Skip large topography files if (IsHugeTopographyFile(line)) continue; } // Extract filename and append it to the shape_filename buffer memcpy(shape_filename_end, line, p - line); // Append ".shp" file extension to the shape_filename buffer strcpy(shape_filename_end + (p - line), ".shp"); // Parse shape range fixed shape_range = fixed(strtod(p + 1, &p)) * 1000; if (*p != _T(',')) continue; // Parse shape icon id long shape_icon = strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse shape field for text display long shape_field = strtol(p + 1, &p, 10) - 1; if (*p != _T(',')) continue; // Parse red component of line / shading colour uint8_t red = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse green component of line / shading colour uint8_t green = (uint8_t)strtol(p + 1, &p, 10); if (*p != _T(',')) continue; // Parse blue component of line / shading colour uint8_t blue = (uint8_t)strtol(p + 1, &p, 10); // Parse pen width of lines int pen_width=1; if (*p == _T(',')) { pen_width = strtol(p + 1, &p, 10); if (pen_width<0) pen_width=1; else if (pen_width>31) pen_width=31; } // Parse range for displaying labels fixed label_range = shape_range; if (*p == _T(',')) label_range = fixed(strtod(p + 1, &p)) * 1000; // Parse range for displaying labels with "important" rendering style fixed labelImportantRange = fixed_zero; if (*p == _T(',')) labelImportantRange = fixed(strtod(p + 1, &p)) * 1000; // Create TopographyFile instance from parsed line TopographyFile *file = new TopographyFile(zdir, shape_filename, shape_range, label_range, labelImportantRange, Color(red, green, blue), shape_field, shape_icon, pen_width); if (file->IsEmpty()) // If the shape file could not be read -> skip this line/file delete file; else // .. otherwise append it to our list of shape files files.append(file); // Update progress bar operation.SetProgressPosition((reader.tell() * 100) / filesize); } }