iqconn/main.c

373 lines
8.9 KiB
C

#include <errno.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <malloc.h>
#include <getopt.h>
#include <unistd.h>
#include "iqbasic.h"
#include "main.h"
#define DIE(...) error_at_line(1, errno, __FILE__, __LINE__, __VA_ARGS__)
int parameter_sizes[] = {16, 16, 16, 2, 2, 1, 4, 1, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 4, 2, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 2};
char *parameter_names[] = {"Pilot", "Glider Type", "Glider ID", "Units", "Flags", "Record Interval [s]", "Unknown 3", "Digital Vario [s]", "Climb Frequency [Hz]", "Sink Frequency [Hz]", "Climb Threshold [cm/s]", "Sink Threshold [cm/s]", "Sink Alarm [cm/s]", "Frequency Adjustment", "Pitch Adjustment", "Unknown 4", "Unknown 5", "Digital Filter", "Volume", "Time Zone [h]", "Pressure Correction [mPa]", "LT Threshold [cm/s]", "Unknown 6", NULL, NULL, NULL, "Stall Alarm [cm/s]", NULL, "Speed Correction", NULL, NULL, NULL, NULL, NULL, "Pre-Thermal Threshold [cm/s]"};
int nparameters = sizeof(parameter_sizes)/sizeof(int);
int display_parameters[] = {0, 1, 2, 5, 7, 17, 21, 10, 34, 11, 12, 26, 18, 8, 9, 13, 14, 19, 20, 28, 3, 4, 6, 15, 16, 22};
int ndisplay = sizeof(display_parameters)/sizeof(int);
void read_list(int fd, const char *action)
{
char buf[1024];
int len = 0;
int i = 0;
int done = 0;
vario_send(fd, action);
do {
len = vario_recv(fd, buf, 1024);
for(i = 0; i < terminator_count; i++)
if(memcmp(terminator[i], buf, len) == 0)
done = 1;
if(!done)
fwrite(buf, 1, len, stdout);
} while(!done);
}
int write_list(int fd, const char *action)
{
char buf[1024];
int i = 0;
int len = 0;
while((buf[i++] = getc(stdin)) != EOF) {
if(buf[i] == '\n') {
buf[i] = 0;
vario_send(fd, action);
vario_send(fd, buf);
len = vario_recv(fd, buf, 1023);
buf[len] = 0;
fprintf(stderr, "Answer: %s\n", buf);
i = 0;
}
}
}
void read_track(int fd, int trno)
{
char buf[1024];
int len = 0;
int i = 0;
int done = 0;
if(trno < 0 || trno > 99)
return;
sprintf(buf, "ACT_21_%02d", trno);
vario_send(fd, buf);
done = 0;
do {
len = vario_recv(fd, buf, 1024);
if(len >= 1 && buf[0] == 'G')
done = 1;
fwrite(buf, 1, len, stdout);
} while(!done);
}
void read_tracklist(int fd)
{
read_list(fd, "ACT_20_00");
}
void read_waypoints(int fd)
{
read_list(fd, "ACT_31_00");
}
void read_routes(int fd)
{
read_list(fd, "ACT_41_00");
}
void write_waypoints(int fd)
{
vario_send(fd, "ACT_30_00");
write_list(fd, "ACT_32_00");
}
void write_routes(int fd)
{
vario_send(fd, "ACT_40_00");
write_list(fd, "ACT_42_00");
}
void delete_tracks(int fd)
{
//vario_send(fd, "ACT_");
}
void show_parameters(int fd)
{
char cmd[10];
char buf[1024];
int len;
int param;
for(int i = 0; i < ndisplay; i++) {
param = display_parameters[i];
sprintf(cmd, "RFA_%02x", param);
vario_send(fd, cmd);
do
len = vario_recv(fd, buf, 1023);
while(len == 0);
if(len >= 2) {
buf[len-2] = 0;
if(parameter_sizes[param] == 1) {
signed char value;
unsigned int v1;
sscanf(buf+7, "%02X", &v1);
value = v1;
printf("%2d %-30s %d\n", param, parameter_names[param], value);
} else if(parameter_sizes[param] == 2) {
signed short value;
unsigned int v1, v2;
sscanf(buf+7, "%02X%02X", &v1, &v2);
value = v1 | (v2 << 8);
printf("%2d %-30s %d\n", param, parameter_names[param], value);
} else if(parameter_sizes[param] == 4) {
signed int value;
unsigned int v1, v2, v3, v4;
sscanf(buf+7, "%02X%02X%02X%02X", &v1, &v2, &v3, &v4);
value = v1 | (v2 << 8) | (v3 << 16) | (v4 << 24);
printf("%2d %-30s %d\n", param, parameter_names[param], value);
} else if(parameter_sizes[param] > 4) {
char value[1024];
unsigned int v1;
for(int j = 0; j < parameter_sizes[param]; j++) {
sscanf(buf+7+2*j, "%02X", &v1);
value[j] = v1;
}
value[parameter_sizes[param]] = 0;
printf("%2d %-30s %s\n", param, parameter_names[param], value);
}
else
printf("%2d %-30s %s\n", param, parameter_names[param], buf+7);
}
}
}
void get_parameter(int fd, int param)
{
char cmd[10];
char buf[1024];
int len;
sprintf(cmd, "RFA_%02x", param);
vario_send(fd, cmd);
do
len = vario_recv(fd, buf, 1023);
while(len == 0);
if(len >= 2) {
buf[len-2] = 0;
printf("%s\n", buf);
}
}
void set_parameter(int fd, int param, const char *value)
{
char cmd[1024];
char buf[1024];
int len;
if(param >= nparameters) {
fprintf(stderr, "Parameter %02x does not exist!\n", param);
return;
}
if(parameter_sizes[param] == 1)
sprintf(cmd, "WFA_%02x_%02X", param,
(signed char)atoi(value) & 0xff);
else if(parameter_sizes[param] == 2)
sprintf(cmd, "WFA_%02x_%02X%02X", param,
((signed short)atoi(value) >> 0) & 0xff,
((signed short)atoi(value) >> 8) & 0xff);
else if(parameter_sizes[param] == 4)
sprintf(cmd, "WFA_%02x_%02X%02X%02X%02X", param,
((signed int)atoi(value) >> 0) & 0xff,
((signed int)atoi(value) >> 8) & 0xff,
((signed int)atoi(value) >> 16) & 0xff,
((signed int)atoi(value) >> 24) & 0xff);
else if(parameter_sizes[param] > 4) {
len = strlen(value);
sprintf(cmd, "WFA_%02x_", param);
for(int i = 0; i < parameter_sizes[param]; i++)
if(i < len)
sprintf(cmd + 7 + 2*i, "%02X", value[i]);
else
sprintf(cmd + 7 + 2*i, "20");
}
fprintf(stderr, "%s\n", cmd);
vario_send(fd, "ACT_82_00");
vario_recv(fd, buf, 1023);
vario_send(fd, cmd);
vario_recv(fd, buf, 1023);
}
int main(int argc, char *argv[])
{
int fd, opt;
char mode = 0;
char *device = "/dev/ttyUSB0";
char *value = "";
int trno = -1;
int param = -1;
const char helpstr[] =
"Usage: iqconn [OPTIONS]\n"
"Read and write data from/to Bräuniger IQ Basic GPS Varios.\n"
"\n"
" -w, --read-waypoints output waypoint data to stdout\n"
" -r, --read-routes output route data to stdout\n"
" -l, --list list saved tracklogs\n"
" -d, --download download IGC file to stdout, specify track number as argument\n"
" -W, --write-waypoints upload waypoint data from stdin (does not work yet)\n"
" -R, --write-routes upload route data from stdin (does not work yet)\n"
" -D, --delete delete tracklogs (not yet implemented)\n"
" -p, --read-parameters output all configuration parameters to stdout\n"
" -P, --write-parameter set a configuration parameter, specify number as argument\n"
" -v, --value to be used with -P, specifies the desired value\n"
" -c, --connector specify serial terminal as argument (default: /dev/ttyUSB0)\n"
" -h, --help display this help page\n";
struct option long_option[] = {
{"read-waypoints", 0, 0, 'w'},
{"read-routes", 0, 0, 'r'},
{"write-waypoints", 0, 0, 'W'},
{"write-routes", 0, 0, 'R'},
{"list", 0, 0, 'l'},
{"download", 1, 0, 'd'},
{"delete", 0, 0, 'D'},
{"help", 0, 0, 'h'},
{"read-parameters", 0, 0, 'p'},
{"write-parameter", 1, 0, 'P'},
{"value", 1, 0, 'v'},
{"connector", 1, 0, 'c'},
{"test", 0, 0, 't'},
{0,0,0,0}
};
char short_option[] = "wrWRlDd:c:pP:v:ht";
while(1) {
if((opt = getopt_long(argc, argv, short_option, long_option, 0)) < 0)
break;
switch(opt) {
case '?':
return 1;
case 'c':
device = optarg;
break;
case 'v':
value = optarg;
break;
case 'd':
trno = atoi(optarg);
if(mode == 0)
mode = opt;
else
mode = 'h';
break;
case 'P':
param = atoi(optarg);
if(mode == 0)
mode = opt;
else
mode = 'h';
break;
case 'w': case 'r': case 'W': case 'R': case 'l': case 'D': case 'h': case 't': case 'p':
if(mode == 0)
mode = opt;
else
mode = 'h';
break;
default:
mode = 'h';
}
}
if(mode == 0)
mode = 'h';
switch(mode) {
case 'w':
fd = vario_open(device);
read_waypoints(fd);
vario_close(fd);
break;
case 'r':
fd = vario_open(device);
read_routes(fd);
vario_close(fd);
break;
case 'W':
fd = vario_open(device);
write_waypoints(fd);
vario_close(fd);
break;
case 'R':
fd = vario_open(device);
write_routes(fd);
vario_close(fd);
break;
case 'l':
fd = vario_open(device);
read_tracklist(fd);
vario_close(fd);
break;
case 'd':
if(trno == -1) {
fprintf(stderr, "no track number specified!\n");
return 1;
}
fd = vario_open(device);
read_track(fd, trno);
vario_close(fd);
break;
case 'D':
fd = vario_open(device);
delete_tracks(fd);
vario_close(fd);
break;
case 'h':
fprintf(stderr, helpstr);
break;
case 'p':
fd = vario_open(device);
show_parameters(fd);
vario_close(fd);
break;
case 'P':
fd = vario_open(device);
set_parameter(fd, param, value);
vario_close(fd);
break;
case 't':
break;
}
return 0;
}