47 int main(
int argc,
char *argv[]) {
51 char *outFileName = NULL;
52 bool clobberOutput =
false;
58 "Usage: %1$s [-v] [-q] [-f] [-r] [-o outfile] -S source [-C channel [-C channel ...]] DATFILE\n"
59 "\t-v\tIncrease verbosity\n"
60 "\t-q\tDecrease verbosity\n"
61 "\t-f\tOverwrite existing output files\n"
62 "\t-r\tWrite raw data (No message formatting)\n"
63 "\t-S\tSource number to extract\n"
64 "\t-T\tMessage type(s) to extract\n"
65 "\t-o\tWrite output to named file\n"
67 "\nOutput file name will be generated based on input file name, unless set by -o option\n";
73 uint8_t typeCount = 0;
74 while ((go = getopt(argc, argv,
"vqfro:S:C:")) != -1) {
89 source = strtol(optarg, NULL, 0);
90 if (source < 2 || source > 128) {
91 log_error(&state,
"Invalid source requested (%s)", optarg);
96 tmp = strtol(optarg, NULL, 0);
97 if (tmp < 1 || tmp >= 128) {
98 log_error(&state,
"Invalid message type requested (%s)",
110 "Only a single output file name can be provided");
113 outFileName = strdup(optarg);
117 log_error(&state,
"Unknown option `-%c'", optopt);
123 if (argc - optind != 1) {
129 fprintf(stderr, usage, argv[0]);
135 char *inFileName = strdup(argv[optind]);
136 FILE *inFile = fopen(inFileName,
"rb");
137 if (inFile == NULL) {
138 log_error(&state,
"Unable to open input file");
145 if (raw && typeCount != 1) {
146 log_warning(&state,
"Raw mode requested without a message type filter");
148 "Different message types will not be distinguished in output file");
151 if (outFileName == NULL) {
155 char *inF1 = strdup(inFileName);
156 char *inF2 = strdup(inFileName);
157 char *dn = dirname(inF1);
158 char *bn = basename(inF2);
161 char *ep = strrchr(bn,
'.');
171 char *nbn = calloc(bnl + 1,
sizeof(
char));
172 strncpy(nbn, bn, bnl);
173 if (asprintf(&outFileName,
"%s/%s.s%02x.dat", dn, nbn, source) <= 0) {
179 if (outFileName == NULL) {
180 log_error(&state,
"Unable to generate output file name");
187 char fmode[4] = {
'w',
'b', 0};
189 if (!clobberOutput) {
194 FILE *outFile = fopen(outFileName, fmode);
195 if (outFile == NULL) {
196 log_error(&state,
"Unable to open output file");
197 log_error(&state,
"%s", strerror(errno));
204 log_info(&state, 1,
"Writing messages from source 0x%02x to %s", source, outFileName);
205 log_info(&state, 1,
"Raw mode %s", raw ?
"enabled" :
"disabled");
207 log_info(&state, 2,
"Filtering for %d message types", typeCount);
208 for (
int i = 0; i < 128; i++) {
209 if (type[i]) {
log_info(&state, 3,
"Message type 0x%02x enabled", i); }
217 struct stat inStat = {0};
218 if (fstat(fileno(inFile), &inStat) != 0) {
219 log_error(&state,
"Unable to get input file status: %s", strerror(errno));
226 long inSize = inStat.st_size;
230 log_info(&state, 1,
"Reading %.2fGB of data from %s", inSize / 1.0E9, inFileName);
231 }
else if (inSize >= 1E6) {
232 log_info(&state, 1,
"Reading %.2fMB of data from %s", inSize / 1.0E6, inFileName);
233 }
else if (inSize >= 1E3) {
234 log_info(&state, 1,
"Reading %.2fkB of data from %s", inSize / 1.0E3, inFileName);
236 log_info(&state, 1,
"Reading %ld bytes of data from %s", inSize, inFileName);
241 while (!(feof(inFile))) {
247 "Error reading messages from file (Code: 0x%52x)\n",
252 log_info(&state, 1,
"End of file reached");
256 if (mtmp.
source == source) {
257 bool writeMsg =
true;
258 if (typeCount > 0) { writeMsg = type[mtmp.
type]; }
263 log_error(&state,
"Unable to write output: %s",
272 log_error(&state,
"Unable to write output: %s",
284 inPos = ftell(inFile);
285 if (((((1.0 * inPos) / inSize) * 100) - progress) >= 5) {
286 progress = (((1.0 * inPos) / inSize) * 100);
287 log_info(&state, 2,
"Progress: %d%% (%ld / %ld)", progress, inPos, inSize);
void msg_destroy(msg_t *msg)
Destroy a message.
bool mp_readMessage(int handle, msg_t *out)
Static wrapper around mp_readMessage_buf.
bool mp_writeData(int handle, const msg_t *out)
Send message data (only!) to attached device.
bool mp_writeMessage(int handle, const msg_t *out)
Send message to attached device.
void destroy_program_state(program_state *s)
Cleanly destroy program state.
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
void log_warning(const program_state *s, const char *format,...)
Output formatted warning message.
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
msg_data_t data
Embedded data.
uint8_t type
Message type. Common types to be documented.
uint8_t source
Maps to a specific sensor unit or data source.
Program state and logging information.
int verbose
Current log verbosity (console output)
bool started
Indicates startup completed.
float value
Generic numerical data.
#define GIT_VERSION_STRING
Git version description.