QTH.app Changelog


  • Restored compatibility with macOS 10.14 (Mojave)
  • Added extra guards against crashes due to malformed packets


  • Embedded QTH public cert expired on 3/27/2024 and caused licenses to not load. This update pushes that expiration date 50 years into the future.


  • Fixed problem with importing license files.


  • Added support for CM108 PTTs. Tested with DINAH.
  • Reworked contact lookup that was causing extreme UI slowness #132
  • Updated to Hamlib 4.5.5
  • The GuageView should now redraw continuously while being resized
  • Changed the mechanism for determining the local station so that it will support tactical callsigns and various callsigns assigned to ports
  • Fixed error messages about volume listeners in AudioModem config panel


  • Updated for macOS Ventura


  • Fixed a mixed up localization file that caused APRS-IS filters to display in French instead of English
  • Migrated away from a reserved keyword in alert predicates


  • Fixing crash caused by malformed timestamps in packets


  • Added Italian translation. Thank you to Federico IW2MVI
  • Fixed problem importing license files with ITU T.61 encoded characters


  • Fixed AGW connection not receiving packets due to the ‘k’ packet attempting to send before the socket is connected
  • Fixed issue with config not showing Audio Modem PTT Hamlib baud correctly


  • Localized to Portuguese. Flag of Portugal Thank you to David CT1DRB/OK8RB


  • Native on Apple M1 (finally)!
  • Localized to French. Flag of France


  • Fixed issue where digipeated/igated packets were losing their ‘repeated’ flag when copied, causing QTH to think the packets were originating locally. This bug was introduced in 0.7.0.


  • Fixed Mic-E longitude encoding bug for stations in +/- 9..<10 degree range
  • Clicking on errors in notification center will now open the log file automatically


  • Added a satellite sky plot for GPS devices
  • Added support for “tactical” source callsigns on RF connections. Licensed callsign will be automatically appended to comment
  • I/O graph legend now shows active connection counts
  • Favourites that are created without an SSID will now match all stations with a matching callsign
  • The “go to my location” button has been changed to a “follow my location” toggle. Clicking it will center the map on your location and keep it centered as you move. Panning the map away will cancel it.
  • Graphs should now match the current dark/light appearance
  • Fixed CoreBluetooth auth for OS X 10.15+ for BLE GPS Connection


  • Fixed problems caused by weather station info panel failing to load on older macOS versions
  • Figured out a technique to decrease the delay between clicking a map annotation and the annotation being selected
  • Fixed a crash due to color space conversion


  • ATTENTION ALL AUDIO MODEM USERS: This version fixes an inadvertent attenuation to the TX audio amplitude. The sine wave was being multiplied by 0.25, causing the resulting audio signal to only be a quarter of full volume. If you have increased the volume on your hardware to compensate for this, you will want to test with the new, non-attenuated output
  • Added a delay to wait for Kenwood D710 to restart in KISS mode before attempting to send the first packet #115
  • The new GPU-accelerated audio level meter was crashing on Macs without the necessary video card support. Added a fallback level meter to support these machines and resolve the crash.


  • Overhauled the audio level meter for the Audio Modem
  • Removed the RX column in Connections window. Most connections don’t have a RX rate large enough to show up as more than a blip on the indicator, making it seem like the meters are broken. The RX/TX stats graph on the local info panel shows effectively the same information in a more intuitive manner.
  • Switched AudioModemConnection to using device UIDs instead of device names to more accurately identify devices that are plugged and unplugged and also devices that create separate input and output devices with the same name. Looking at you SignaLink USB 🙂
  • Major refactoring in the audio modem code


  • Fixed a problem with Signalink USB where it creates two audio devices that are named the same and QTH was wrongly selecting the output device for input
  • Commands sent to the TNC should no longer count towards the TX stats
  • Fixed error messages coming from input/output devices that don’t support volume changing
  • Added experimental Kenwood D710 KISS device type


  • Fixed Audio Modem level meter


  • Rewrote the audio capture code for the Audio Modem from Swift to C
  • Now using a lock-free ring buffer to avoid missed audio samples


  • Fixed bug where destination TOCALL field was being replaced with QTH’s default TOCALL. Not an issue for packets that originate from QTH, but could cause device misidentification for digipeated packets


  • Fixed bug calculating the DC+28 byte (speed tens) of the Mic-E payload
  • Fixed issue preventing a newly created connection from having TX turned on right away


  • Fixed crash when constructing a Mic-E packet with a negative latitude #100
  • Manual entry of coordinates now allows 3 digit longitudes
  • Set toolbar images to template rendering mode so they display correctly under dark mode #105
  • Fixed a few other color issues in dark mode
  • Added a button to jump the map back to your current location #102
  • Fixed crash due to Bluetooth permissions under Big Sur #107
  • Fixed bug where the destination field on an outgoing Mic-E packet was being overwritten by the default TOCALL


  • Fixed bug where message acks and rejs were being ignored as not addressed to the local station. Introduced in v0.3.0


  • Added timeout for PTT; if audio device fails to play audio due to sample rate mismatch, it will timeout and unkey the PTT
  • Added device removal detection. If the audio device is removed/unplugged while the Audio Modem is running, it will detect this and stop the connection
  • Audio Modem now locates devices by name instead of ID. Many USB audio devices change their ID when plugged and unplugged.
  • Fixed a bug where the search bar was expecting uppercase callsigns. It should now be case insensitive #99
  • Search bar now supports a fallback address search. If the text is not a callsign or a coordinate, it will do a regular address search


  • Fixed bug with new sample rate listener where input and output device are the same audio device


  • Audio Modem now detects when the sample rate changes for an input or output audio device and automatically reinitializes
  • Fixed coordinate field binding for the object info panel
  • Fixed a bug detecting a Yaesu device from a Mic-E packet (Yaesu uses a space to indicate device type; trimming the string was breaking that)


  • Packet sent/received graph now autoscales up and down #95
  • Restored the legacy telemetry decoding for Mic-E packets
  • Decoding frequency info now supports “tOFF”
  • Moved PTT key activation closer to audio scheduling in Audio Modem
  • Added timeline discontinuity and audio queue start/stop logging to Audio Modem


  • Added a KISS device extension to enable parsing NMEA (GPS) sentences multiplexed among KISS frames.
  • GPS devices will now wait until they have a 2D or 3D fix before beginning location events
  • Serial GPS config panel now uses the same device detection as the Serial KISS panel. Certain devices weren’t showing up before.
  • Fixed bug where hiding the main map would cause it to stop receiving station update events. #97


  • Attempting to improve the decoding of AudioModemConnection
  • Added an optional 6dB emphasis filter
  • Audio Queue handler now more quickly passes processing to a separate thread to avoid blocking queue
  • Dropped down from Double to Float audio samples – less memory to move around
  • Fixed some help button links


  • This is a refactoring release. No new features added or bugs fixed. However, I am surgically separating the core APRS engine from the macOS UI, so that the APRS engine can build and run cross platform on iOS.


  • Added PTT test button to audio modem configuration #91
  • Added a dynamic ‘favorite callsigns’ filter to the APRS-IS filter builder
  • Added a user interface for managing favorites
  • Favorites now support tactical names, symbols, and track colors
  • Support for importing and exporting favorite station list (YAAC compatible)
  • Support for sending tactical names via message
  • Support for receiving tactical names (Xastir spec)
  • Added a min height to the groups panel
  • Fixed a mixup between PHG codes and actual values #94
  • Fixed tooltip on symbol on Station Preferences


  • Removed accidental ‘transparent’ setting on the digipeater route buttons #93
  • Fixed the AX.25 SSID encoding to support a full 4-bit SSID instead of just 0-9 #92
  • Replaced the built-in MKUserLocation annotation with a custom one. The MapKit-supplied MKUserLocation only supports Location Service, whereas the custom one now supports the other locations sources such as manual and GPS
  • Fixed a bug where frequency information was not being passed from packet to entity records when the entity is first received #90
  • Removed speed/course averaging in GPS connections – it’s too slow for good corner pegging
  • Changed connection stats graph to a bar graph instead of line graph. Seems more appropriate for discrete data
  • Fixed thread safety issue when removing cleared stations
  • Added code to remove stations from station list when they have not been heard from in longer than the station clear time
  • Added time interval constraint on geocode lookup for local station; I noticed it updated too frequently when traveling at highway speeds
  • Adjusted SmartBeaconing to disregard course changes when traveling below the Slow Speed; the GPS course data tends to jump around when not moving
  • Additional error handling in NMEA sentence parsing
  • Fixed bug where the message unread badge would appear on the dock icon but viewing the messages would not clear the count
  • Printing the map now works for everything except for tile overlays like OpenStreetMap that draw asynchronously as the tiles load
  • Figured out the station fading mystery – ObjectAnnotation.update was not calling super


  • Geofence alerts are working now
  • Implemented a maximum map extents filter. By default, if the map extents span more than 20° of longitude, it will not send the filter to APRS-IS. To prevent the “firehose” effect.
  • Fixed a bug causing objects to be retained on the map far longer than the max clear time because they were incorrectly marked as ‘mine’. If you’ve ever left QTH on over night and woke up to just a bunch of digipeaters on the map, this is why
  • Major help book update


  • Added a GPSD connection type
  • Fixed bug where a manual location was not sending updates


Major changes and features:
  • Implemented Digipeater functionality
  • Implemented IGate functionality
  • Now unwraps and attempts to process third party traffic packets
  • Fixed a race condition bug with canBeacon missing a location update and not enabling the button
  • Fixed the layer rotation for a few mobile symbols that do not point right
  • Fixed bug were last heard time was incorrectly showing the last updated time when packets are replayed from history #88


  • Filter changes on the APRS-IS config window will now automatically be sent to the server if the connection is active
  • Implemented message authentication
  • Fixed a bug with parsing patterns in the tocall database
  • Now detects OS sleep and wake, disconnecting and reconnecting connections respectively
  • Last path for stations is now stored in the entity table and displayed on the info panels
  • Refreshing canSend whenever the message to: address changes #87
  • Fixed bug where MeasurementFormatter was not behaving as expected and temperatures were displayed in the wrong units #86


  • Objects can now be assigned a QRU group
  • Implemented TOCALL device detection
  • New field in aprs_entity stores device
  • Updated tocall file and changed to JSONDecoder
  • Reworked the weather report view to bind fields differently
  • Fixed a bug in the object transmission code that kept restarting the decay timer
  • Now responds to most queries described in APRS 1.0.1 spec
  • Now responds to QRU queries for local objects
  • Fixed a bug preventing the re-use of object names that have been killed
  • Fixed a crash that could result from updating an object’s symbol
  • The H bit in the repeater path is now decoded properly and converted to TNC2 format in the database
  • Re-enabled the reverse geocode address display on the local station panel


  • Sorting favorite stations to the top of the station list
  • Fixed a bug with selecting a station on the map not selecting it elsewhere
  • Enabled contact-related menu items on the Station menu in the Messages center window
  • Viewing a contact now opens it in Contacts.app, rather than a popup. Apple’s popup is buggy


  • Added a USNG / MGRS grid layer
  • Added a Maidenhead grid layer
  • Added USNG / MGRS as a coordinate display format option (in Preferences)
  • The search box will now accept USNG coordinates, in addition to the other format types, with the exclusion of Maidenhead. The standard Maidenhead spec specifies a grid area, rather than a specific lat/lon point.
  • Added a pin tool to the drawing tool palette. Up to this point, you could drop pins by typing a coordinate into the search box. The pin tool simply lets you choose the coordinates with the mouse.


Major changes and features:
  • Major UI code refactoring to support multiple map windows. (As requested by Steve K4HG)
  • Map windows should now retain their view settings and map extents through restarts
  • New Layers! Layers for OpenStreetMap, OpenTopoMap, CyclOSM, and, a huge goal of mine, a Local Tile Server for offline maps. Look for an article coming soon on how to set this up. More layer types to follow.
  • It is now possible to import and export GPX files and export KML. (Import for KML is coming, but it’s a much more complicated format)
  • Moved the station menu from a popup button on the station panel to the main application menu. This feels more Mac-like to me and more discoverable.
  • SmartBeaconing is now implemented, with permission from Steve Bragg, KA9MVA
  • Implemented proportional pathing for interval beacons #80
  • Custom AX.25 paths are now supported, with “Path Profiles” renamed to “Path Presets” #79
  • Added reconnect for KISS-over-TCP connections #85
  • Added DNS-SD (Bonjour) support for locating KISS-over-TCP servers, like Direwolf
  • Tracks can now be cleared for stations
  • Tracks now shorten as old locations expire
  • The history purging process is now working as intended and preserves stations you’ve marked as favorites and packets that have originated from your station.
  • Fixed bug where loaded tracks were disappearing during maintenance because of an ID mismatch due to the ID cache
  • Tracks are now loaded as one event instead of a sequence of packet events
  • Fixed bug where symbol was not displaying on local object list
  • Fixed bug where a renamed object could appear multiple times on the entity list
  • Fixed bug where timeline timestamp was showing up even when not scrolling the timeline
  • Enhanced About page to include an EULA and Acknowledgements
  • APRSManager no longer has a single map region
  • Fixed bug with entity update notifications not being sent when initially saved to the database (not dirty)
  • Fixed retain cycles so that MainMapViewController is deallocated when the map window is closed
  • Fixed bug where the display point being used by CrosshairsButton was not in the correct coordinate system
  • Moved map layer toggles away from UserDefaults to properties of QTHMapView. This is so that multiple map windows can have separate settings
  • Fixed crash when failing to detect any usable string from an unknown character set #83
  • Fixed telemetry unique constraint error message #84
  • SmartBeaconing settings are now locale unit aware
  • Implemented a debug mode
  • Debug mode now includes a function for simulating a track with GPS coordinates. Used for testing SmartBeaconing
  • Starting a GPS connection now automatically and temporarily sets the beacon source to GPS
  • Fixed course change calculations
  • Fixed date handling in NMEA sentences – it was picking up the date in the current timezone when parsing times, instead of UTC


  • Fixed bug when parsing SSIDs received over an AX.25 connection with a 2 digit SSID
  • Weather stations that send Peet reports should now properly show up as a weather station in the info panel
  • Increased font size on info panels from “System Small” to “System Regular”
  • Stations that beacon non-position packets, like telemetry, are now visible in the station list even if they cannot be placed on the map #78
  • Fixed issue where message ack processing was using the recipient instead of the sender to find the correct message to ack
  • Fixed issue where duplicate messages were being sent due to reply-ack processing #82
  • Provided a different default value for the QRU distance preference for metric users #81
  • Mobilinkd connections will now turn off the verbose setting when starting the connection. According to the Rob, having verbose logging on “will reduce the TNC’s ability to decode”


  • Fixed bug in decoding longitude in certain Mic-E packets
  • Implemented a Setup Assistant to help new users set up QTH for the first time. It will be shown on startup when no connections have been configured. It can also be found on the Help menu
  • Set the default symbol to /M – The Apple logo originally created for MacAPRS
  • An attempt to send a beacon without a symbol selected will now fail
  • Decreased the logging level for errors that occur when loading packets from the database


  • Fixed a crash on macOS 10.14 when displaying a user notification. A new API was introduced in 10.14, but one of the notification properties was not introduced until 10.15 #76
  • Fixed negative speed coming in from core location
  • Fixed the map extents filter; the filter commands were missing the EOL characters
  • Added a crosshair location picker to both the APRS-IS range filter and the manual beacon location in Preferences. Instead of entering the coordinates manually, you can click the crosshairs button and choose the location using the map.


  • Fixed APRS-IS filter field sizes in Big Sur #65 #73
  • Silenced warnings about accessing CLLocationManager.location before it is ready in Big Sur
  • Changed toolbar items to automatic width to silence Big Sur warnings
  • Fixed malformed compressed packets when the last byte in the base91 sequence happened to be zero
  • APRS-IS connections should now react properly to toggling on the transmit flag
  • Reduced BeaconManager debug logging
  • Coordinate parsing is now even more lenient. Hopefully it will recognize anything that even remotely looks like a latitude/longitude pair. A comma separator is accepted, but no longer required. Commas as decimal separators are now accepted. The cardinal directions are not localized yet, so continue to use NSEW, rather than NSOW (de), NSEO (fr) #69 #66
  • Add a numbers-only formatter to the SSID field(s) to prevent someone from entering “-9”
  • Added a Map Type to the View menu to switch the map view type


  • When autostarting an APRS-IS connection with a map extents filter, it will now wait until the map is initialized before connecting so that the filter is set correctly
  • Setting SO_KEEPALIVE on sockets to hopefully speed up the detection of servers that have closed the connection
  • Auto-reconnect is now implemented for APRS-IS connections. It will retry exponential backoff. i.e. 1s, 2s, 4s, 8.. up to 32s before failing
  • Now detects network reachability. Will immediately disconnect if the network disappears and reconnect when it comes back, if auto reconnect is enabled
  • Default filter for new APRS-IS connections is now map extents, instead of a “my range filter”, since unlicensed users can’t send their position
  • Added callsign and ssid to APRS-IS config to accommodate unlicensed users and licensed users that want to use a different callsign for the connection
  • Added T2 server list to APRS-IS connection config
  • Fixed timeline date label in dark mode #75
  • The main map now remembers the map region when you shut down and restores it when you start back up


  • Callsign on main window changes when changed in preferences #71
  • Password field in license file chooser has a much larger margin and now will not let you choose a file without entering a password #70
  • Removed broken link on help file welcome page #72
  • Added a # before the filter update; still servers seem to be ignoring it
  • Attempting to get the distance filter box to stay at the proper width. Big Sur sometimes ignores all sizing information I provide
  • Hardcoded the decimal separator to “.” until I figure the right way to parse commas as decimal separators


  • Changed default alert to look for “!EMERGENCY!” rather than “EMERGENCY” in comments
  • Increased the size of the add/remove buttons on the connections window
  • Added code to guard against malformed messages
  • Attempting to fix a High Sierra crash
  • More help file contents
  • Fixed description on symbols in symbol picker
  • Invalid symbols are now hidden in symbol picker