Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_ADSB/sagetech-sdk/sgDecodeMSR.c
Views: 1799
/**1* @copyright Copyright (c) 2020 Sagetech, Inc. All rights reserved.2*3* @file sgDecodeMSR.c4* @author jim.billmeyer5*6* @date Mar 17, 20217*/89#include "sg.h"10#include <stdbool.h>11#include <stdint.h>12#include <string.h>13#include "sgUtil.h"1415#define MS_PARAM_TOA (1 << 3)16#define MS_PARAM_ADSBVER (1 << 2)17#define MS_PARAM_CALLSIGN (1 << 1)18#define MS_PARAM_CATEMITTER (1 << 0)1920#define MS_PARAM_AVLEN (1 << 7)21#define MS_PARAM_PRIORITY (1 << 6)22#define MS_PARAM_CAPCODES (1 << 5)23#define MS_PARAM_OPMODE (1 << 4)24#define MS_PARAM_NACP (1 << 3)25#define MS_PARAM_NACV (1 << 2)26#define MS_PARAM_SDA (1 << 1)27#define MS_PARAM_GVA (1 << 0)2829#define MS_PARAM_NIC (1 << 7)30#define MS_PARAM_HEADING (1 << 6)31#define MS_PARAM_VRATE (1 << 5)3233#define MS_CAP_B2LOW (1 << 3)34#define MS_CAP_UAT (1 << 1)35#define MS_CAP_TCR ((1 << 2) | (1 << 3))36#define MS_CAP_TSR (1 << 4)37#define MS_CAP_ARV (1 << 5)38#define MS_CAP_ADSB (1 << 6)39#define MS_CAP_TCAS (1 << 7)4041#define MS_OP_GPS_LATFMT (1 << 7)42#define MS_OP_GPS_LONFMT (1 << 6)43#define MS_OP_TCAS_RA (1 << 5)44#define MS_OP_IDENT (1 << 4)45#define MS_OP_SINGLE_ANT (1 << 2)4647/// the payload offset.48#define PBASE 44950/*51* Documented in the header file.52*/53bool sgDecodeMSR(uint8_t *buffer, sg_msr_t *msr)54{55memset(msr, 0, sizeof(sg_msr_t));5657uint8_t fields[3];58memcpy(fields, &buffer[PBASE + 0], 3);5960if (buffer[PBASE + 1] == 0x6E && buffer[PBASE + 2] == 0x60)61{62msr->type = msrTypeV0;63}64else if (buffer[PBASE + 1] == 0x7E && buffer[PBASE + 2] == 0xE0)65{66msr->type = msrTypeV1Airborne;67}68else if (buffer[PBASE + 1] == 0xFE && buffer[PBASE + 2] == 0xE0)69{70msr->type = msrTypeV1Surface;71}72else if (buffer[PBASE + 1] == 0x7F && buffer[PBASE + 2] == 0xE0)73{74msr->type = msrTypeV2Airborne;75}76else if (buffer[PBASE + 1] == 0xFF && buffer[PBASE + 2] == 0xE0)77{78msr->type = msrTypeV2Surface;79}8081msr->flags = buffer[PBASE + 3];82msr->addr = toInt32(&buffer[PBASE + 4]) & 0xFFFFFF;83msr->addrType = buffer[PBASE + 7] & 0xFF;8485uint8_t ofs = 8;8687if (fields[0] & MS_PARAM_TOA)88{89msr->toa = toTOA(&buffer[PBASE + ofs]);90ofs += 2;91}9293if (fields[0] & MS_PARAM_ADSBVER)94{95msr->version = buffer[PBASE + ofs];96ofs++;97}9899if (fields[0] & MS_PARAM_CALLSIGN)100{101memset(msr->callsign, 0, 9);102memcpy(msr->callsign, &buffer[PBASE + ofs], 8);103ofs += 8;104}105106if (fields[0] & MS_PARAM_CATEMITTER)107{108msr->emitter = buffer[PBASE + ofs];109ofs++;110}111112if (fields[1] & MS_PARAM_AVLEN)113{114msr->size = buffer[PBASE + ofs];115ofs++;116}117118if (fields[1] & MS_PARAM_PRIORITY)119{120msr->priority = buffer[PBASE + ofs];121ofs++;122}123124if (fields[1] & MS_PARAM_CAPCODES)125{126uint8_t cap = buffer[PBASE + ofs + 0];127msr->capability.b2low = cap & MS_CAP_B2LOW;128129cap = buffer[PBASE + ofs + 1];130msr->capability.uat = cap & MS_CAP_UAT;131msr->capability.tcr = (cap & MS_CAP_TCR) >> 2;132msr->capability.tsr = cap & MS_CAP_TSR;133msr->capability.arv = cap & MS_CAP_ARV;134msr->capability.adsb = cap & MS_CAP_ADSB;135msr->capability.tcas = cap & MS_CAP_TCAS;136137ofs += 3;138}139140if (fields[1] & MS_PARAM_OPMODE)141{142uint8_t op = buffer[PBASE + ofs + 0];143msr->opMode.gpsLatFmt = (op & MS_OP_GPS_LATFMT) == 0;144msr->opMode.gpsLonFmt = (op & MS_OP_GPS_LONFMT) == 0;145msr->opMode.tcasRA = op & MS_OP_TCAS_RA;146msr->opMode.ident = op & MS_OP_IDENT;147msr->opMode.singleAnt = op & MS_OP_SINGLE_ANT;148149op = buffer[PBASE + ofs + 1];150msr->opMode.gpsLatOfs = op >> 5;151msr->opMode.gpsLonOfs = op & 0x17;152153ofs += 2;154}155156if (fields[1] & MS_PARAM_NACP)157{158msr->svQuality.nacp = buffer[PBASE + ofs];159ofs++;160}161162if (fields[1] & MS_PARAM_NACV)163{164msr->svQuality.nacv = buffer[PBASE + ofs];165ofs++;166}167168if (fields[1] & MS_PARAM_SDA)169{170uint8_t sda = buffer[PBASE + ofs];171msr->svQuality.sda = (sda & 0x18) >> 3;172msr->svQuality.silSupp = (sda & 0x04);173msr->svQuality.sil = (sda & 0x03);174ofs++;175}176177if (fields[1] & MS_PARAM_GVA)178{179msr->svQuality.gva = buffer[PBASE + ofs];180ofs++;181}182183if (fields[2] & MS_PARAM_NIC)184{185msr->svQuality.nicBaro = buffer[PBASE + ofs];186ofs++;187}188189if (fields[2] & MS_PARAM_HEADING)190{191msr->trackHeading = buffer[PBASE + ofs];192ofs++;193}194195if (fields[2] & MS_PARAM_VRATE)196{197msr->vrateType = buffer[PBASE + ofs];198ofs++;199}200201return true;202}203204205