From 2f9c3fe0e180ddd2286c224331d939e790d9895a Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 28 Mar 2020 15:23:30 -0400 Subject: [PATCH] clean up --- net_io.c | 283 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 150 insertions(+), 133 deletions(-) diff --git a/net_io.c b/net_io.c index 73ecff8..d4ca0ff 100644 --- a/net_io.c +++ b/net_io.c @@ -780,16 +780,10 @@ static void send_sbs_heartbeat(struct net_service *service) completeWrite(service->writer, data + len); } -////////////////////////////////////////// Start Stratux block - // //========================================================================= // // Write Stratux output to TCP clients -// The message structure mm->bFlags tells us what has been updated by this message -// -// Output format is a JSON representation of a subset of the fields used in the -// Stratux traffic structure. // static void modesSendStratuxOutput(struct modesMessage *mm, struct aircraft *a) { char *p; @@ -813,11 +807,17 @@ static void modesSendStratuxOutput(struct modesMessage *mm, struct aircraft *a) if (!mm->reliable && !a->reliable) return; + //// For now, suppress non-ICAO addresses + //if (mm->addr & MODES_NON_ICAO_ADDRESS) + // return; + p = prepareWrite(&Modes.stratux_out, 1000); // larger buffer size needed vs SBS if (!p) return; - + // NOTE: not sure about message types, so keep the original code from + // stratux/dump1090 as-is. + // // Decide on the basic SBS Message Type if ((mm->msgtype == 4) || (mm->msgtype == 20)) { msgType = 5; @@ -842,7 +842,7 @@ static void modesSendStratuxOutput(struct modesMessage *mm, struct aircraft *a) else {msgType = 7;} } else if ((mm->metype == 29) || (mm->metype == 31)) { - msgType = 9; // new message type for target state and operational status messages + msgType = 9; // new message type for target state and operational status messages } else if (mm->metype != 19) { return; } else if ((mm->mesub == 1) || (mm->mesub == 2)) { @@ -852,146 +852,163 @@ static void modesSendStratuxOutput(struct modesMessage *mm, struct aircraft *a) } // Begin populating the traffic.go fields. - // ICAO address, Mode S message types, and signal level - + // ICAO address, Mode S message types, and signal level + int cacf = 0; // overload the JSON "CA" field to report CA (DF11 or DF17), CF (DF18), or zero (all other DF types) if ((mm->msgtype == 11) || (mm->msgtype == 17)) { cacf = mm->CA; } else if (mm->msgtype == 18) { cacf = mm->CF; } - - p += sprintf(p, "{\"Icao_addr\":%d,\"DF\":%d,\"CA\":%d,\"TypeCode\":%d,\"SubtypeCode\":%d,\"SBS_MsgType\":%d,\"SignalLevel\":%f,",mm->addr, mm->msgtype, cacf, mm->metype, mm->mesub, msgType, mm->signalLevel); // what precision and range is needed for RSSI? - - // Callsign - if (mm->callsign_valid) { - p += sprintf(p, "\"Tail\":\"%s\",", mm->callsign); - } else { - p += sprintf(p, "\"Tail\":null,"); - } - - //Squawk - if (mm->squawk_valid) { - p += sprintf(p, "\"Squawk\":%x,", mm->squawk); - } - else { - p += sprintf(p, "\"Squawk\":null,"); - } - - // Emitter type - int emitter = 0; - int setEmitter = 0; - if ((mm->msgtype == 17) || (mm->msgtype == 18)) { - switch (mm->metype) { - case 1: - emitter = ((mm->mesub) | 0x18); - setEmitter = 1; - break; - case 2: - emitter = ((mm->mesub) | 0x10); - setEmitter = 1; - break; - case 3: - emitter = ((mm->mesub) | 0x08); - setEmitter = 1; - break; - case 4: - emitter = (mm->mesub); - setEmitter = 1; - break; - } - } - - if (setEmitter) { - p += sprintf(p, "\"Emitter_category\":%d,", emitter); - } else { - p += sprintf(p, "\"Emitter_category\":null,"); - } - - // OnGround - if (mm->airground == AG_GROUND) { - p += sprintf(p, "\"OnGround\":true,"); - } else if (mm->airground == AG_AIRBORNE) { - p += sprintf(p, "\"OnGround\":false,"); - } else { - p += sprintf(p, "\"OnGround\":null,"); - } - - // Position and position valid flag - if (mm->cpr_decoded) { - p += sprintf(p, "\"Lat\":%.6f,\"Lng\":%.6f,\"Position_valid\":true,", mm->decoded_lat, mm->decoded_lon); - } else { - p += sprintf(p, "\"Lat\":null,\"Lng\":null,\"Position_valid\":false,"); - } - - // Navigation Accuracy Category - Position - if (mm->accuracy.nac_p_valid) { - p += sprintf(p, "\"NACp\":%d,", mm->accuracy.nac_p); - } else { - p += sprintf(p, "\"NACp\":null,"); - } - - bool alt_is_geom = false; - // Altitude - if (Modes.use_gnss && mm->altitude_geom_valid) { - p += sprintf(p, "\"Alt\":%d,",mm->altitude_geom); - alt_is_geom = true; - } else if (mm->altitude_baro_valid) { - p += sprintf(p, "\"Alt\":%d,",mm->altitude_baro); - } else { - p += sprintf(p, "\"Alt\":null,"); - } - - // Altitude Source. True if altitude source is GNSS, false if pressure altitude. - if (alt_is_geom) { - p += sprintf(p, "\"AltIsGNSS\":true,"); - } else { - p += sprintf(p, "\"AltIsGNSS\":false,"); - } - // GNSS Alt Diff From Baro Alt - if (trackDataValid(&a->geom_delta_valid)) { - p += sprintf(p, "\"GnssDiffFromBaroAlt\":%d,",a->geom_delta); // Verify that this is part of a and not mm - } else { - p += sprintf(p, "\"GnssDiffFromBaroAlt\":null,"); - } - - //Vertical velocity - if (alt_is_geom) { - if (mm->geom_rate_valid) - p += sprintf(p, "\"Vvel\":%d,", mm->geom_rate); - else - p += sprintf(p, "\"Vvel\":null,"); - } else { - if (mm->baro_rate_valid) - p += sprintf(p, "\"Vvel\":%d,", mm->baro_rate); - else - p += sprintf(p, "\"Vvel\":null,"); - } - // Ground speed and track - if (mm->gs_valid) { - p += sprintf(p, "\"Speed_valid\":true,\"Speed\":%.0f,", mm->gs.selected); - } else { - p += sprintf(p, "\"Speed_valid\":false,\"Speed\":null,"); - } - - if (mm->heading_valid && mm->heading_type == HEADING_GROUND_TRACK) { - p += sprintf(p, "\"Track\":%.0f,", mm->heading); - } else { - p += sprintf(p, "\"Track\":null,"); - } + p += sprintf(p, + "{\"Icao_addr\":%d," + "\"DF\":%d,\"CA\":%d," + "\"TypeCode\":%d," + "\"SubtypeCode\":%d," + "\"SBS_MsgType\":%d," + "\"SignalLevel\":%f,", + mm->addr, + mm->msgtype, cacf, + mm->metype, + mm->mesub, + msgType, + mm->signalLevel); // what precision and range is needed for RSSI? // Find current system time clock_gettime(CLOCK_REALTIME, &now); - gmtime_r(&now.tv_sec, &stTime_now); // we expect UTC + gmtime_r(&now.tv_sec, &stTime_now); // we expect UTC // Find message reception time time_t received = (time_t) (mm->sysTimestampMsg / 1000); localtime_r(&received, &stTime_receive); - //Time message received (based on system clock). Format is 2016-02-20T06:35:43.155Z - p += sprintf(p, "\"Timestamp\":\"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ\"", (stTime_receive.tm_year+1900),(stTime_receive.tm_mon+1), stTime_receive.tm_mday, stTime_receive.tm_hour, stTime_receive.tm_min, stTime_receive.tm_sec, (unsigned) (mm->sysTimestampMsg % 1000)); - + // Time message received (based on system clock). Format is 2016-02-20T06:35:43.155Z + p += sprintf(p, "\"Timestamp\":\"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ\"", (stTime_receive.tm_year+1900),(stTime_receive.tm_mon+1), stTime_receive.tm_mday, stTime_receive.tm_hour, stTime_receive.tm_min, stTime_receive.tm_sec, (unsigned) (mm->sysTimestampMsg % 1000)); + + //// callsign + if (mm->callsign_valid) + p += sprintf(p, "\"Tail\":\"%s\",", mm->callsign); + else + p += sprintf(p, "\"Tail\":null,"); + + //// altitude & gnss + bool alt_is_geom = false; + if (Modes.use_gnss && mm->altitude_geom_valid) { + p += sprintf(p, "\"Alt\":%d,",mm->altitude_geom); + alt_is_geom = true; + } else if (mm->altitude_baro_valid) + p += sprintf(p, "\"Alt\":%d,",mm->altitude_baro); + else + p += sprintf(p, "\"Alt\":null,"); + + // altitude source + if (alt_is_geom) + p += sprintf(p, "\"AltIsGNSS\":true,"); + else + p += sprintf(p, "\"AltIsGNSS\":false,"); + + // GNSS alt. delta From baro alt. + if (trackDataValid(&a->geom_delta_valid)) + p += sprintf(p, "\"GnssDiffFromBaroAlt\":%d,",a->geom_delta); + else + p += sprintf(p, "\"GnssDiffFromBaroAlt\":null,"); + //// + + //// ground speed and track + if (mm->gs_valid) + p += sprintf(p, "\"Speed_valid\":true,\"Speed\":%.0f,", mm->gs.selected); + else + p += sprintf(p, "\"Speed_valid\":false,\"Speed\":null,"); + + //// ground heading + if (mm->heading_valid && mm->heading_type == HEADING_GROUND_TRACK) + p += sprintf(p, "\"Track\":%.0f,", mm->heading); + else + p += sprintf(p, "\"Track\":null,"); + + //// position + if (mm->cpr_decoded) + p += sprintf(p, "\"Lat\":%.6f,\"Lng\":%.6f,\"Position_valid\":true,", + mm->decoded_lat, mm->decoded_lon); + else + p += sprintf(p, "\"Lat\":null,\"Lng\":null,\"Position_valid\":false,"); + + //// vrate + if (Modes.use_gnss) { + if (mm->geom_rate_valid) + p += sprintf(p, "\"Vvel\":%d,", mm->geom_rate); + else if (mm->baro_rate_valid) + p += sprintf(p, "\"Vvel\":%d,", mm->baro_rate); + else + p += sprintf(p, "\"Vvel\":null,"); + } else { + if (mm->baro_rate_valid) + p += sprintf(p, "\"Vvel\":%d,", mm->baro_rate); + else if (mm->geom_rate_valid) + p += sprintf(p, "\"Vvel\":%d,", mm->geom_rate); + else + p += sprintf(p, "\"Vvel\":null,"); + } + + //// squawk + if (mm->squawk_valid) + p += sprintf(p, "\"Squawk\":%x,", mm->squawk); + else + p += sprintf(p, "\"Squawk\":null,"); + + // TODO: squawk changing alert support in stratux? + // TODO: squawk emergency flag? + // TODO: squawk ident flag? + + // airground + switch (mm->airground) { + case AG_GROUND: + p += sprintf(p, "\"OnGround\":true,"); + break; + case AG_AIRBORNE: + p += sprintf(p, "\"OnGround\":false,"); + break; + default: + p += sprintf(p, "\"OnGround\":null,"); + } + + // navigation accuracy category - position + if (mm->accuracy.nac_p_valid) { + p += sprintf(p, "\"NACp\":%d,", mm->accuracy.nac_p); + } else { + p += sprintf(p, "\"NACp\":null,"); + } + + // emitter type + int emitter = 0; + int setEmitter = 0; + if ((mm->msgtype == 17) || (mm->msgtype == 18)) { + switch (mm->metype) { + case 1: + emitter = ((mm->mesub) | 0x18); + setEmitter = 1; + break; + case 2: + emitter = ((mm->mesub) | 0x10); + setEmitter = 1; + break; + case 3: + emitter = ((mm->mesub) | 0x08); + setEmitter = 1; + break; + case 4: + emitter = (mm->mesub); + setEmitter = 1; + break; + } + } + + if (setEmitter) + p += sprintf(p, "\"Emitter_category\":%d,", emitter); + else + p += sprintf(p, "\"Emitter_category\":null,"); + p += sprintf(p, "}\r\n"); completeWrite(&Modes.stratux_out, p);