Telemetry code was mis-computing RSSI
[fw/altos] / ao-tools / lib / cc-telem.c
index a6ac0313b03f173c49cf75859e0b05c9f3740f1b..aa52b7c5b14ce863b4c663679072107fc8c0a0a2 100644 (file)
@@ -62,7 +62,9 @@ int
 cc_telem_parse(const char *input_line, struct cc_telem *telem)
 {
        char *saveptr;
-       char *words[PARSE_MAX_WORDS];
+       char *raw_words[PARSE_MAX_WORDS];
+       char **words;
+       int version = 0;
        int nword;
        char line_buf[8192], *line;
        int     tracking_pos;
@@ -72,19 +74,37 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem)
        line_buf[sizeof(line_buf) - 1] = '\0';
        line = line_buf;
        for (nword = 0; nword < PARSE_MAX_WORDS; nword++) {
-               words[nword] = strtok_r(line, " \t\n", &saveptr);
+               raw_words[nword] = strtok_r(line, " \t\n", &saveptr);
                line = NULL;
-               if (words[nword] == NULL)
+               if (raw_words[nword] == NULL)
                        break;
        }
        if (nword < 36)
                return FALSE;
+       words = raw_words;
+       if (strcmp(words[0], "VERSION") == 0) {
+               cc_parse_int(&version, words[1]);
+               words += 2;
+               nword -= 2;
+       }
+
        if (strcmp(words[0], "CALL") != 0)
                return FALSE;
        cc_parse_string(telem->callsign, sizeof (telem->callsign), words[1]);
        cc_parse_int(&telem->serial, words[3]);
 
+       if (version >= 2) {
+               cc_parse_int(&telem->flight, words[5]);
+               words += 2;
+               nword -= 2;
+       } else
+               telem->flight = 0;
+
        cc_parse_int(&telem->rssi, words[5]);
+       if (version <= 2) {
+               /* Older telemetry versions mis-computed the rssi value */
+               telem->rssi = (telem->rssi + 74) / 2 - 74;
+       }
        cc_parse_string(telem->state, sizeof (telem->state), words[9]);
        cc_parse_int(&telem->tick, words[10]);
        cc_parse_int(&telem->accel, words[12]);
@@ -98,10 +118,20 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem)
        cc_parse_int(&telem->flight_vel, words[28]);
        cc_parse_int(&telem->flight_pres, words[30]);
        cc_parse_int(&telem->ground_pres, words[32]);
+       if (version >= 1) {
+               cc_parse_int(&telem->accel_plus_g, words[34]);
+               cc_parse_int(&telem->accel_minus_g, words[36]);
+               words += 4;
+               nword -= 4;
+       } else {
+               telem->accel_plus_g = telem->ground_accel;
+               telem->accel_minus_g = telem->ground_accel + 530;
+       }
        cc_parse_int(&telem->gps.nsat, words[34]);
        if (strcmp (words[36], "unlocked") == 0) {
                telem->gps.gps_connected = 1;
                telem->gps.gps_locked = 0;
+               telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0;
                telem->gps.gps_time.hour = telem->gps.gps_time.minute = telem->gps.gps_time.second = 0;
                telem->gps.lat = telem->gps.lon = 0;
                telem->gps.alt = 0;
@@ -109,6 +139,16 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem)
        } else if (nword >= 40) {
                telem->gps.gps_locked = 1;
                telem->gps.gps_connected = 1;
+               if (version >= 2) {
+                       sscanf(words[36], "%d-%d-%d",
+                              &telem->gps.gps_time.year,
+                              &telem->gps.gps_time.month,
+                              &telem->gps.gps_time.day);
+                       words += 1;
+                       nword -= 1;
+               } else {
+                       telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0;
+               }
                sscanf(words[36], "%d:%d:%d", &telem->gps.gps_time.hour, &telem->gps.gps_time.minute, &telem->gps.gps_time.second);
                cc_parse_pos(&telem->gps.lat, words[37]);
                cc_parse_pos(&telem->gps.lon, words[38]);
@@ -117,6 +157,7 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem)
        } else {
                telem->gps.gps_connected = 0;
                telem->gps.gps_locked = 0;
+               telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0;
                telem->gps.gps_time.hour = telem->gps.gps_time.minute = telem->gps.gps_time.second = 0;
                telem->gps.lat = telem->gps.lon = 0;
                telem->gps.alt = 0;
@@ -141,18 +182,25 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem)
        }
        if (tracking_pos >= 0 && nword >= tracking_pos + 2 && strcmp(words[tracking_pos], "SAT") == 0) {
                int     c, n, pos;
+               int     per_sat;
+               int     state;
+
+               if (version >= 2)
+                       per_sat = 2;
+               else
+                       per_sat = 3;
                cc_parse_int(&n, words[tracking_pos + 1]);
                pos = tracking_pos + 2;
-               if (nword >= pos + n * 3) {
+               if (nword >= pos + n * per_sat) {
                        telem->gps_tracking.channels = n;
                        for (c = 0; c < n; c++) {
                                cc_parse_int(&telem->gps_tracking.sats[c].svid,
                                                 words[pos + 0]);
-                               cc_parse_hex(&telem->gps_tracking.sats[c].state,
-                                                words[pos + 1]);
+                               if (version < 2)
+                                       cc_parse_hex(&state, words[pos + 1]);
                                cc_parse_int(&telem->gps_tracking.sats[c].c_n0,
-                                                words[pos + 2]);
-                               pos += 3;
+                                                words[pos + per_sat - 1]);
+                               pos += per_sat;
                        }
                } else {
                        telem->gps_tracking.channels = 0;