Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions docs/development/msp/msp_messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -10371,6 +10371,106 @@
"notes": "Requires `USE_ADSB`. Only a subset of `adsbVehicle_t` is transmitted (callsign, core values, heading in whole degrees, TSLC, emitter type, TTL).",
"description": "Retrieves the list of currently tracked ADSB (Automatic Dependent Surveillance–Broadcast) vehicles. See `adsbVehicle_t` and `adsbVehicleValues_t` in `io/adsb.h` for the exact structure fields."
},
"MSP2_ADSB_VEHICLE": {
"code": 8337,
"mspv": 2,
"request": {
"payload": [
{
"name": "index",
"ctype": "uint8_t",
"desc": "Slot index to read, `0 .. (MSP2_ADSB_VEHICLE_COUNT - 1)`. WARNING: this is an iteration cursor over fixed slots, NOT a stable identifier. The same index may return a different aircraft (or an empty slot) on a later poll. Always identify the aircraft by the `icao` field in the reply; never cache or correlate data by index. Returns an error result if the index is out of range.",
"units": ""
}
]
},
"reply": {
"payload": [
{
"name": "icao",
"ctype": "uint32_t",
"desc": "ICAO 24-bit address (`vehicleValues.icao`). This is the stable per-aircraft identifier; use it to correlate replies, not the request index. An empty slot reports `icao == 0` and `ttl == 0`.",
"units": ""
},
{
"name": "lat",
"ctype": "int32_t",
"desc": "Latitude (`vehicleValues.gps.lat`).",
"units": "1e-7 deg"
},
{
"name": "lon",
"ctype": "int32_t",
"desc": "Longitude (`vehicleValues.gps.lon`).",
"units": "1e-7 deg"
},
{
"name": "alt",
"ctype": "int32_t",
"desc": "Altitude above sea level (`vehicleValues.alt`).",
"units": "cm"
},
{
"name": "heading",
"ctype": "uint16_t",
"desc": "Course over ground at full resolution (`vehicleValues.heading`). Unlike `MSP2_ADSB_VEHICLE_LIST`, this is in centidegrees, not whole degrees.",
"units": "1e-2 deg"
},
{
"name": "horVelocity",
"ctype": "uint16_t",
"desc": "Horizontal (ground) speed (`vehicleValues.horVelocity`). Not present in `MSP2_ADSB_VEHICLE_LIST`.",
"units": "cm/s"
},
{
"name": "tslc",
"ctype": "uint8_t",
"desc": "Time since last communication (`vehicleValues.tslc`).",
"units": "s"
},
{
"name": "emitterType",
"ctype": "uint8_t",
"desc": "Emitter category (`vehicleValues.emitterType`).",
"units": ""
},
{
"name": "ttl",
"ctype": "uint8_t",
"desc": "Remaining time-to-live for this slot (`adsbVehicle->ttl`). `ttl == 0` means the slot is empty/expired and its contents are stale; skip such entries.",
"units": "s"
},
{
"name": "callsign",
"desc": "Fixed-length callsign (`vehicleValues.callsign`), padded with NULs if shorter.",
"ctype": "char",
"array": true,
"array_size": 9,
"array_size_define": "ADSB_CALL_SIGN_MAX_LENGTH",
"units": ""
}
]
},
"notes": "Requires `USE_ADSB`. Reads a single ADSB vehicle slot by index. THE INDEX IS NOT A STABLE HANDLE: slots are reused, so a given index may hold a different aircraft (or be empty, `ttl == 0`) between polls. Correlate aircraft by the `icao` field in the reply, never by index. Compared with the bulk `MSP2_ADSB_VEHICLE_LIST`, this message adds horizontal velocity and reports heading at full (centidegree) resolution, and orders the callsign last. Returns an error result for an out-of-range index.",
"description": "Retrieves a single tracked ADSB (Automatic Dependent Surveillance-Broadcast) vehicle by slot index. Intended for polling one slot at a time: query `MSP2_ADSB_VEHICLE_COUNT` for the iteration bound, then request indices `0 .. count-1`, skipping slots with `ttl == 0`, and identify each aircraft by its `icao`. See `adsbVehicle_t` / `adsbVehicleValues_t` in `io/adsb.h`."
},
"MSP2_ADSB_VEHICLE_COUNT": {
"code": 8338,
"mspv": 2,
"request": null,
"reply": {
"payload": [
{
"name": "count",
"ctype": "uint8_t",
"desc": "Number of vehicle slots to iterate (`MAX_ADSB_VEHICLES`). This is the slot capacity / iteration bound, not the number of currently active aircraft - some slots may be empty (`ttl == 0`). 0 if `USE_ADSB` is disabled.",
"units": ""
}
]
},
"notes": "Requires `USE_ADSB`. Returns the iteration bound for `MSP2_ADSB_VEHICLE`: request indices `0 .. count-1` and skip any slot whose `ttl == 0`.",
"description": "Returns the number of ADSB vehicle slots available to iterate with `MSP2_ADSB_VEHICLE`."
},
"MSP2_INAV_CUSTOM_OSD_ELEMENTS": {
"code": 8448,
"mspv": 2,
Expand Down
35 changes: 35 additions & 0 deletions src/main/fc/fc_msp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,15 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU32(dst, 0);
#endif
break;

case MSP2_ADSB_VEHICLE_COUNT:
#ifdef USE_ADSB
sbufWriteU8(dst, MAX_ADSB_VEHICLES); // iteration bound for the client
#else
sbufWriteU8(dst, 0);
#endif
break;

case MSP_DEBUG:
// output some useful QA statistics
// debug[x] = ((hse_value / 1000000) * 1000) + (SystemCoreClock / 1000000); // XX0YY [crystal clock : core clock]
Expand Down Expand Up @@ -4449,6 +4458,32 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
*ret = MSP_RESULT_ACK;
break;

#ifdef USE_ADSB
case MSP2_ADSB_VEHICLE:
if (sbufBytesRemaining(src) >= 1) {
adsbVehicle_t *vehicle = findVehicle(sbufReadU8(src));
if (vehicle == NULL) { // index past MAX_ADSB_VEHICLES
*ret = MSP_RESULT_ERROR;
break;
}
sbufWriteU32(dst, vehicle->vehicleValues.icao);
sbufWriteU32(dst, vehicle->vehicleValues.gps.lat);
sbufWriteU32(dst, vehicle->vehicleValues.gps.lon);
sbufWriteU32(dst, vehicle->vehicleValues.alt);
sbufWriteU16(dst, vehicle->vehicleValues.heading); // centideg, full-res
sbufWriteU16(dst, vehicle->vehicleValues.horVelocity); // cm/s - omitted by the bulk list
sbufWriteU8(dst, vehicle->vehicleValues.tslc);
sbufWriteU8(dst, vehicle->vehicleValues.emitterType);
sbufWriteU8(dst, vehicle->ttl);
sbufWriteData(dst, vehicle->vehicleValues.callsign, ADSB_CALL_SIGN_MAX_LENGTH);
} else {
*ret = MSP_RESULT_ERROR; // no index supplied
break;
}
*ret = MSP_RESULT_ACK;
break;
#endif

#if defined(USE_FLASHFS)
case MSP_DATAFLASH_READ:
mspFcDataFlashReadCommand(dst, src);
Expand Down
2 changes: 2 additions & 0 deletions src/main/msp/msp_protocol_v2_inav.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
#define MSP2_INAV_SELECT_MIXER_PROFILE 0x2080

#define MSP2_ADSB_VEHICLE_LIST 0x2090
#define MSP2_ADSB_VEHICLE 0x2091
#define MSP2_ADSB_VEHICLE_COUNT 0x2092

#define MSP2_INAV_CUSTOM_OSD_ELEMENTS 0x2100
#define MSP2_INAV_CUSTOM_OSD_ELEMENT 0x2101
Expand Down
Loading