diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/ao_aprs.c | 98 | ||||
| -rw-r--r-- | src/kernel/ao_config.c | 23 | ||||
| -rw-r--r-- | src/kernel/ao_config.h | 9 | 
3 files changed, 112 insertions, 18 deletions
| diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 19beb78f..2e977612 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -707,8 +707,7 @@ static int tncPositionPacket(void)      static int32_t	latitude;      static int32_t	longitude;      static int32_t	altitude; -    int32_t		lat, lon, alt; -    uint8_t	*buf; +    uint8_t		*buf;      if (ao_gps_data.flags & AO_GPS_VALID) {  	latitude = ao_gps_data.latitude; @@ -719,28 +718,93 @@ static int tncPositionPacket(void)      }      buf = tncBuffer; -    *buf++ = '!'; -    /* Symbol table ID */ -    *buf++ = '/'; +    switch (ao_config.aprs_format) { +    case AO_APRS_FORMAT_COMPRESSED: +    default: +    { +	    int32_t		lat, lon, alt; + +	    *buf++ = '!'; + +	    /* Symbol table ID */ +	    *buf++ = '/'; + +	    lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; +	    lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; + +	    alt = ao_aprs_encode_altitude(altitude); + +	    tncCompressInt(buf, lat, 4); +	    buf += 4; +	    tncCompressInt(buf, lon, 4); +	    buf += 4; -    lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; -    lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; +	    /* Symbol code */ +	    *buf++ = '\''; -    alt = ao_aprs_encode_altitude(altitude); +	    tncCompressInt(buf, alt, 2); +	    buf += 2; -    tncCompressInt(buf, lat, 4); -    buf += 4; -    tncCompressInt(buf, lon, 4); -    buf += 4; +	    *buf++ = 33 + ((1 << 5) | (2 << 3)); -    /* Symbol code */ -    *buf++ = '\''; +	    break; +    } +    case AO_APRS_FORMAT_UNCOMPRESSED: +    { +	    char	lat_sign = 'N', lon_sign = 'E'; +	    int32_t	lat = latitude; +	    int32_t	lon = longitude; +	    int32_t	alt = altitude; +	    uint16_t	lat_deg; +	    uint16_t	lon_deg; +	    uint16_t	lat_min; +	    uint16_t	lat_frac; +	    uint16_t	lon_min; +	    uint16_t	lon_frac; + +	    if (lat < 0) { +		    lat_sign = 'S'; +		    lat = -lat; +	    } -    tncCompressInt(buf, alt, 2); -    buf += 2; +	    if (lon < 0) { +		    lon_sign = 'W'; +		    lon = -lon; +	    } -    *buf++ = 33 + ((1 << 5) | (2 << 3)); +	    /* Round latitude and longitude by 0.005 minutes */ +	    lat = lat + 833; +	    if (lat > 900000000) +		    lat = 900000000; +	    lon = lon + 833; +	    if (lon > 1800000000) +		    lon = 1800000000; + +	    lat_deg = lat / 10000000; +	    lat -= lat_deg * 10000000; +	    lat *= 60; +	    lat_min = lat / 10000000; +	    lat -= lat_min * 10000000; +	    lat_frac = lat / 100000; + +	    lon_deg = lon / 10000000; +	    lon -= lon_deg * 10000000; +	    lon *= 60; +	    lon_min = lon / 10000000; +	    lon -= lon_min * 10000000; +	    lon_frac = lon / 100000; + +	    /* Convert from meters to feet */ +	    alt = (alt * 328 + 50) / 100; + +	    buf += sprintf((char *) tncBuffer, "!%02u%02u.%02u%c/%03u%02u.%02u%c'/A=%06u ", +			   lat_deg, lat_min, lat_frac, lat_sign, +			   lon_deg, lon_min, lon_frac, lon_sign, +			   alt); +	    break; +    } +    }      buf += tncComment(buf); diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 8dab7c42..b0d3e541 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -220,6 +220,10 @@ _ao_config_get(void)  		if (minor < 21)  			ao_config.send_frequency = 434550;  #endif +#if HAS_APRS +		if (minor < 22) +			ao_config.aprs_format = AO_CONFIG_DEFAULT_APRS_FORMAT; +#endif  		ao_config.minor = AO_CONFIG_MINOR;  		ao_config_dirty = 1;  	} @@ -876,6 +880,23 @@ ao_config_aprs_ssid_set(void)  	ao_config.aprs_ssid = ao_cmd_lex_i;  	_ao_config_edit_finish();  } + +void +ao_config_aprs_format_set(void) +{ +	ao_cmd_decimal(); +	if (ao_cmd_status != ao_cmd_success) +		return; +	_ao_config_edit_start(); +	ao_config.aprs_format = ao_cmd_lex_i != 0; +	_ao_config_edit_finish(); +} + +void +ao_config_aprs_format_show(void) +{ +	printf ("APRS format: %d\n", ao_config.aprs_format); +}  #endif /* HAS_APRS */  struct ao_config_var { @@ -969,6 +990,8 @@ __code struct ao_config_var ao_config_vars[] = {  #if HAS_APRS  	{ "S <ssid>\0Set APRS SSID (0-15)",  	  ao_config_aprs_ssid_set, ao_config_aprs_ssid_show }, +	{ "C <0 compressed, 1 uncompressed>\0APRS format", +	  ao_config_aprs_format_set, ao_config_aprs_format_show },  #endif  	{ "s\0Show",  	  ao_config_show,		0 }, diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 164584a5..cfe8555c 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -57,7 +57,7 @@  #endif  #define AO_CONFIG_MAJOR	1 -#define AO_CONFIG_MINOR	21 +#define AO_CONFIG_MINOR	22  #define AO_AES_LEN 16 @@ -115,8 +115,15 @@ struct ao_config {  #if HAS_RADIO_FORWARD  	uint32_t	send_frequency;		/* minor version 21 */  #endif +#if HAS_APRS +	uint8_t		aprs_format;		/* minor version 22 */ +#endif  }; +#define AO_APRS_FORMAT_COMPRESSED	0 +#define AO_APRS_FORMAT_UNCOMPRESSED	1 +#define AO_CONFIG_DEFAULT_APRS_FORMAT	AO_APRS_FORMAT_COMPRESSED +  #if HAS_RADIO_FORWARD  extern __xdata uint32_t	ao_send_radio_setting;  #endif | 
