Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / Device / Driver / CAI302 / Logger.cpp
blobf0c4876b59c612bcd0964cd45fc1fcd9971f117f
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Internal.hpp"
25 #include "Protocol.hpp"
26 #include "Device/Port/Port.hpp"
27 #include "Operation/Operation.hpp"
28 #include "OS/ByteOrder.hpp"
29 #include "IO/BinaryWriter.hpp"
31 #include <stdlib.h>
33 static void
34 Copy(BrokenDate &dest, const CAI302::DateTime &src)
36 dest.year = src.year + 2000; /* Y2100 problem! */
37 dest.month = src.month;
38 dest.day = src.day;
41 static void
42 Copy(BrokenTime &dest, const CAI302::DateTime &src)
44 dest.hour = src.hour;
45 dest.minute = src.minute;
46 dest.second = src.second;
49 static void
50 Copy(RecordedFlightInfo &dest, unsigned index,
51 const CAI302::FileList::FileInfo &src)
53 Copy(dest.date, src.start_utc);
54 Copy(dest.start_time, src.start_utc);
55 Copy(dest.end_time, src.end_utc);
57 dest.internal.cai302 = index;
60 static bool
61 ReadFlightListInner(Port &port, RecordedFlightList &flight_list,
62 OperationEnvironment &env)
64 env.SetProgressRange(8);
66 for (unsigned i = 0; i < 8 && !flight_list.full(); ++i) {
67 CAI302::FileList file_list;
68 if (!CAI302::UploadFileList(port, i, file_list, env))
69 break;
71 for (unsigned j = 0; j < 8 && !flight_list.full(); ++j) {
72 const CAI302::FileList::FileInfo &file = file_list.files[j];
73 if (file.start_utc.month > 0)
74 Copy(flight_list.append(), i * 8 + j, file);
77 env.SetProgressPosition(i);
80 return !flight_list.empty() && !env.IsCancelled();
83 bool
84 CAI302Device::ReadFlightList(RecordedFlightList &flight_list,
85 OperationEnvironment &env)
87 if (!EnableBulkMode(env))
88 return false;
90 if (!UploadMode(env)) {
91 DisableBulkMode(env);
92 return false;
95 if (!ReadFlightListInner(port, flight_list, env)) {
96 mode = Mode::UNKNOWN;
97 DisableBulkMode(env);
98 return false;
101 DisableBulkMode(env);
102 return true;
105 static bool
106 DownloadFlightInner(Port &port, const RecordedFlightInfo &flight,
107 const TCHAR *path, OperationEnvironment &env)
109 assert(flight.internal.cai302 < 64);
111 BinaryWriter writer(path);
112 if (writer.HasError())
113 return false;
115 CAI302::FileASCII file_ascii;
116 if (!UploadFileASCII(port, flight.internal.cai302, file_ascii, env) ||
117 env.IsCancelled())
118 return false;
120 unsigned bytes_per_block = ReadUnalignedBE16(&file_ascii.bytes_per_block);
121 unsigned num_blocks = ReadUnalignedBE16(&file_ascii.num_blocks);
122 env.SetProgressRange(num_blocks);
124 unsigned allocated_size = sizeof(CAI302::FileData) + bytes_per_block;
125 void *allocated = malloc(allocated_size);
126 CAI302::FileData *header = (CAI302::FileData *)allocated;
127 void *data = header + 1;
129 unsigned current_block = 0;
130 unsigned valid_bytes;
131 do {
132 int i = UploadFileData(port, true, header, allocated_size, env);
133 if (i < (int)sizeof(*header)) {
134 free(allocated);
135 return false;
138 i -= sizeof(*header);
140 valid_bytes = FromBE16(header->valid_bytes);
141 if ((unsigned)i < valid_bytes) {
142 free(allocated);
143 return false;
146 if (!writer.Write(data, 1, valid_bytes)) {
147 free(allocated);
148 return false;
151 env.SetProgressPosition(current_block++);
152 } while (valid_bytes == bytes_per_block);
154 free(allocated);
156 CAI302::FileSignatureASCII signature;
157 if (!CAI302::UploadFileSignatureASCII(port, signature, env))
158 return false;
160 valid_bytes = FromBE16(signature.size);
161 if (valid_bytes > sizeof(signature.signature))
162 return false;
164 if (!writer.Write(signature.signature, 1, valid_bytes))
165 return false;
167 return true;
170 bool
171 CAI302Device::DownloadFlight(const RecordedFlightInfo &flight,
172 const TCHAR *path,
173 OperationEnvironment &env)
175 assert(flight.internal.cai302 < 64);
177 if (!EnableBulkMode(env))
178 return false;
180 if (!UploadMode(env)) {
181 DisableBulkMode(env);
182 return false;
185 if (!DownloadFlightInner(port, flight, path, env)) {
186 mode = Mode::UNKNOWN;
187 DisableBulkMode(env);
188 return false;
191 DisableBulkMode(env);
192 return true;