1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
//! # Automatic Position Reporting System protocol //! //! ## What's APRS? //! Automatic Packet Reporting System (APRS) is a system for real time digital communication //! over HAM radio. It is a packet communications protocol for disseminating live data to //! everyone on a network enabling radio amateurs to automatically display the positions of radio //! stations and other objects on maps. There are also other features such as weather reporting and //! messaging. //! //! # What's in this crate? //! This crate defines Rust data types, traits and symbols per //! [APRS v1.01 specification](http://www.aprs.org/doc/APRS101.PDF). //! //! It does not provide any parsing or encoding behavior, there are //! separate crates for this. The intent here is to enable interoperability //! between different implementations and let client code use them as drop-in //! replacements for each other. //! //! If you're looking for a compartible parser check out the //! [`fap`](https://docs.rs/fap) crate, which is a //! Rust wrapper around Tapio Aaltonen's //! [`libfap`](http://www.pakettiradio.net/libfap/) library. //! use std::borrow::Cow; use std::time::SystemTime; mod units; pub use units::{Feet, Meters, Knots, MetersPerSecond, MilesPerHour, KilometersPerHour, Degrees, Fahrenheits, Celsius, Radians}; // Latitude and logitude are technically also degrees, // but in APRS packets latlng degrees and course degrees // use different ranges pub struct Position{ pub latitude: f32, pub longitude: f32, pub precision: Option<Feet>, } impl Position { pub fn from_latlng(lat: f32, lng: f32) -> Position { Position{ latitude: lat, longitude: lng, precision: None, } } pub fn from_latlng_precise(lat: f32, lng: f32, precision: Feet) -> Position { Position{ latitude: lat, longitude: lng, precision: Some(precision), } } pub fn set_precision(&mut self, precision : Feet) -> &mut Self { self.precision = Some(precision); self } } #[derive(Debug, Clone, Eq, PartialEq)] pub enum Symbol { Sheriff, // /! BB Police, Sheriff Emergency, // \! OBO EMERGENCY (and overlays) Phone, // /$ BE PHONE BankOrAtm, // \$ OEO Bank or ATM (green box) PowerPlant, // \% OFO Power Plant with overlay HfGateway, // /& BG HF GATEway SmallAircraft, // /' BH Small AIRCRAFT (SSID-11) IncidentSite, // \' OHO Crash (& now Incident sites) MobileSatelliteStation, // /( BI Mobile Satellite Station Cloudy, // \( OIO CLOUDY (other clouds w ovrly) Handicapped, // /) BJ Wheelchair (handicapped) Firenet, // \) OJO Firenet MEO, MODIS Earth Obs. Snowmobile, // /* BK SnowMobile RedCross, // /+ BL Red Cross Church, // \+ OL Church BoyScouts, // /, BM Boy Scouts GirlScouts, // \, OM Girl Scouts HouseQth, // /- BN House QTH (VHF) HouseHhf, // \- ONO House (H=HF) (O = Op Present) Cross, // /. BO X BigQuestionMark, // \. OO Ambiguous (Big Question mark) RedDot, // // BP Red Dot Waypoint, // \/ OP Waypoint Destination Circle, // \0 A0# CIRCLE (IRLP/Echolink/WIRES) WiFi, // \8 A8O 802.11 or other network node GasStation, // \9 A9 Gas Station (blue pump) Fire, // /: MR FIRE Campground, // /; MS Campground (Portable ops) Park, // \; NSO Park/Picnic + overlay events Motorcycle, // /< MT Motorcycle (SSID-10) Advisory, // \< NTO ADVISORY (one WX flag) RailroadEngine, // /= MU RAILROAD ENGINE Car, // /> MV CAR (SSID-9) OverlayedVehicles, // \> NV# OVERLAYED CARs & Vehicles Server, // /? MW SERVER for Files InfoKiosk, // \? NW INFO Kiosk (Blue box with ?) Dot, // /@ MX HC FUTURE predict (dot) Huricane, // \@ NX HURICANE/Trop-Storm AidStation, // /A PA Aid Station BoxOverlay, // \A AA# overlayBOX DTMF & RFID & XO Bbs, // /B PB BBS or PBBS Canoe, // /C PC Canoe CoastGuard, // \C AC Coast Guard Depots, // \D ADO DEPOTS (Drizzle ==> ' ovly D) Eyeball, // /E PE EYEBALL (Events, etc!) Smoke, // \E AE Smoke (& other vis codes) Tractor, // /F PF Farm Vehicle (tractor) GridSquare, // /G PG Grid Square (6 digit) SnowShower, // \G AG AVAIL (Snow Shwr ==> I ovly S) Hotel, // /H PH HOTEL (blue bed symbol) Haze, // \H AHO \Haze (& Overlay Hazards) NetworkStation, // /I PI TcpIp on air network stn RainShower, // \I AI Rain Shower Lightening, // \J AJ AVAIL (Lightening ==> I ovly L) School, // /K PK School KenwoodHt, // \K AK Kenwood HT (W) PcUser, // /L PL PC user (Jan 03) Lighthouse, // \L AL Lighthouse MacAprs, // /M PM MacAPRS Military, // \M AMO MARS (A=Army,N=Navy,F=AF) NtsStation, // /N PN NTS Station NavigationBuoy, // \N AN Navigation Buoy Balloon, // /O PO BALLOON (SSID-11) Rocket, // \O AO Overlay Balloon (Rocket = \O) Police, // /P PP Police Parking, // \P AP Parking Quake, // \Q AQ QUAKE RecVehicle, // /R PR REC. VEHICLE (SSID-13) Restaurant, // \R ARO Restaurant Shuttle, // /S PS SHUTTLE Satellite, // \S AS Satellite/Pacsat Sstv, // /T PT SSTV Thunderstorm, // \T AT Thunderstorm Bus, // /U PU BUS (SSID-2) Sunny, // \U AU SUNNY Atv, // /V PV ATV VortacNavAid, // \V AV VORTAC Nav Aid NationalWxServiceSite, // /W PW National WX Service Site NwsSite, // \W AW# # NWS site (NWS options) Helo, // /X PX HELO (SSID-6) Pharmacy, // \X AX Pharmacy Rx (Apothicary) Yacht, // /Y PY YACHT (sail) (SSID-5) RadiosAndDevices, // \Y AYO Radios and devices WinAprs, // /Z PZ WinAPRS Person, // /[ HS Human/Person (SSID-7) CloudOrHumansWOvrly, // \[ DSO W.Cloud (& humans w Ovrly) Triangle, // /\ HT TRIANGLE(DF station) GpsSymbol, // \\ DTO New overlayable GPS symbol PostOffice, // /] HU MAIL/PostOffice(was PBBS) LargeAircraft, // /^ HV LARGE AIRCRAFT OtherAircraft, // \^ DV# other Aircraft ovrlys (2014) WeatherStation, // /_ HW WEATHER Station (blue) WxSite, // \_ DW# # WX site (green digi) DishAntenna, // /` HX Dish Antenna Rain, // \` DX Rain (all types w ovrly) Ambulance, // /a LA AMBULANCE (SSID-1) Bike, // /b LB BIKE (SSID-4) IncidentCommandPost, // /c LC Incident Command Post FireDept, // /d LD Fire dept Horse, // /e LE HORSE (equestrian) Sleet, // \e SE Sleet (& future ovrly codes) FireTruck, // /f LF FIRE TRUCK (SSID-3) FunnelCloud, // \f SF Funnel Cloud Glider, // /g LG Glider Gale, // \g SG Gale Flags Hospital, // /h LH HOSPITAL Store, // \h SHO Store. or HAMFST Hh=HAM store PointOfInterest, // \i SI# BOX or points of Interest Jeep, // /j LJ JEEP (SSID-12) Workzone, // \j SJ WorkZone (Steam Shovel) Truck, // /k LK TRUCK (SSID-14) SpecialVehicle, // \k SKO Special Vehicle SUV,ATV,4x4 Laptop, // /l LL Laptop (Jan 03) (Feb 07) Areas, // \l SL Areas (box,circles,etc) MicERepeater, // /m LM Mic-E Repeater ValueSign, // \m SM Value Sign (3 digit display) Node, // /n LN Node (black bulls-eye) OverlayTriangle, // \n SN# OVERLAY TRIANGLE SmallCircle, // \o SO small circle Dog, // /p LP ROVER (puppy, or dog) Restroom, // \r SR Restrooms Boat, // /s LS SHIP (pwr boat) (SSID-8) OverlayBoat, // \s SS# OVERLAY SHIP/boats TruckStop, // /t LT TRUCK STOP Tornado, // \t ST Tornado Truck18Wheeler, // /u LU TRUCK (18 wheeler) OverlayedTruck, // \u SU# OVERLAYED TRUCK Van, // /v LV VAN (SSID-15) OverlayedVan, // \v SV# OVERLAYED Van WaterStation, // /w LW WATER station Flooding, // \w SWO Flooding (Avalanches/Slides) Wreck, // \x SX Wreck or Obstruction ->X<- Skywarn, // \y SY Skywarn OverlayedShelter, // \z SZ# OVERLAYED Shelter Other, } pub const PRIMARY_SYMBOL_TABLE : u8 = 0x2f; pub const ALT_SYMBOL_TABLE : u8 = 0x5c; mod symbol; impl Symbol { pub fn from_table(table: u8, code: u8) -> Symbol { symbol::from_table(table, code) } } pub trait Packet { fn source(&self) -> Cow<str>; fn symbol(&self) -> Symbol; fn timestamp(&self) -> Option<SystemTime>; fn destination(&self) -> Option<Cow<str>>; fn comment(&self) -> Option<Cow<str>>; fn position(&self) -> Option<Position>; fn speed(&self) -> Option<Knots>; fn course(&self) -> Option<Degrees>; fn altitude(&self) -> Option<Feet>; fn temperature(&self) -> Option<Fahrenheits>; fn wind_direction(&self) -> Option<Degrees>; fn wind_speed(&self) -> Option<Knots>; // fn message_id(&self) -> Option<&str>; // fn message_addressee(&self) -> Option<&str>; // fn message_text(&self) -> Option<&str>; // fn message_ack(&self) -> Option<bool>; // fn message_rjc(&self) -> Option<bool>; fn latitude(&self) -> Option<f32> { self.position().map(|v| v.latitude) } fn longitude(&self) -> Option<f32> { self.position().map(|v| v.longitude) } fn precision(&self) -> Option<Feet> { self.position().and_then(|v| v.precision) } } // Floating point asserts for tests #[cfg(test)] #[macro_use] extern crate approx;