#include #include #include #include #include #include #include #include #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; }