Initial import
This commit is contained in:
266
protocol/aprs/symbol.go
Normal file
266
protocol/aprs/symbol.go
Normal file
@@ -0,0 +1,266 @@
|
||||
package aprs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var emptySymbol Symbol
|
||||
|
||||
type Symbol [2]byte
|
||||
|
||||
func (s Symbol) IsPrimaryTable() bool { return s[0] != '\\' }
|
||||
|
||||
func (s Symbol) MarshalJSON() ([]byte, error) {
|
||||
if s == emptySymbol {
|
||||
return json.Marshal("")
|
||||
}
|
||||
return json.Marshal(string(s[:]))
|
||||
}
|
||||
|
||||
func (s Symbol) get(idx int) (string, error) {
|
||||
var m map[byte]map[int]string
|
||||
if s.IsPrimaryTable() {
|
||||
m = primarySymbol
|
||||
} else {
|
||||
m = alternateSymbol
|
||||
}
|
||||
n, ok := m[s[1]]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unknown symbol %x", s[1])
|
||||
}
|
||||
if i, ok := n[idx]; ok {
|
||||
return i, nil
|
||||
}
|
||||
return "", fmt.Errorf("symbol doesn't have requested index: %v", n)
|
||||
}
|
||||
|
||||
func (s Symbol) String() string {
|
||||
hr, err := s.get(1)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return hr
|
||||
}
|
||||
|
||||
func (s Symbol) SSID() (string, error) {
|
||||
return s.get(2)
|
||||
}
|
||||
|
||||
func (s Symbol) Emoji() (string, error) {
|
||||
return s.get(3)
|
||||
}
|
||||
|
||||
func IsValidCompressedSymTable(c byte) bool {
|
||||
return c == '/' ||
|
||||
c == '\\' ||
|
||||
(c >= 0x41 && c <= 0x5a) ||
|
||||
(c >= 0x61 && c <= 0x6a)
|
||||
}
|
||||
|
||||
func IsValidUncompressedSymTable(c byte) bool {
|
||||
return c == '/' ||
|
||||
c == '\\' ||
|
||||
(c >= 0x41 && c <= 0x5a) ||
|
||||
(c >= 0x30 && c <= 0x39)
|
||||
}
|
||||
|
||||
var (
|
||||
// Source: http://www.aprs.org/symbols/symbolsX.txt
|
||||
// 0: XYZ code
|
||||
// 1: Human readable
|
||||
// 2: SSID
|
||||
// 3: Emoji
|
||||
primarySymbol = map[byte]map[int]string{
|
||||
'!': {0: "BB", 1: "Police, Sheriff", 3: ":cop:"},
|
||||
'"': {0: "BC", 1: "reserved"},
|
||||
'#': {0: "BD", 1: "Digi"},
|
||||
'$': {0: "BE", 1: "Phone", 3: ":phone:"},
|
||||
'%': {0: "BF", 1: "DX Cluster"},
|
||||
'&': {0: "BG", 1: "HF Gateway"},
|
||||
'\'': {0: "BH", 1: "Small Aircraft", 2: "11", 3: ":airplane:"},
|
||||
'(': {0: "BI", 1: "Mobile Satellite Station", 3: ":satellite:"},
|
||||
')': {0: "BJ", 1: "Wheelchair", 3: ":wheelchair:"},
|
||||
'*': {0: "BK", 1: "Snowmobile"},
|
||||
'+': {0: "BL", 1: "Red Cross"},
|
||||
',': {0: "BM", 1: "Boy Scout"},
|
||||
'-': {0: "BN", 1: "House QTH (VHF)"},
|
||||
'.': {0: "BO", 1: "X"},
|
||||
'/': {0: "BP", 1: "Red Dot"},
|
||||
'0': {0: "P0", 1: "Circle (0)"},
|
||||
'1': {0: "P1", 1: "Circle (1)"},
|
||||
'2': {0: "P2", 1: "Circle (2)"},
|
||||
'3': {0: "P3", 1: "Circle (3)"},
|
||||
'4': {0: "P4", 1: "Circle (4)"},
|
||||
'5': {0: "P5", 1: "Circle (5)"},
|
||||
'6': {0: "P6", 1: "Circle (6)"},
|
||||
'7': {0: "P7", 1: "Circle (7)"},
|
||||
'8': {0: "P8", 1: "Circle (8)"},
|
||||
'9': {0: "P9", 1: "Circle (9)"},
|
||||
':': {0: "MR", 1: "Fire", 3: ":fire:"},
|
||||
';': {0: "MS", 1: "Campground", 3: ":tent:"},
|
||||
'<': {0: "MT", 1: "Motorcycle", 2: "10", 3: ":bike:"},
|
||||
'=': {0: "MU", 1: "Railroad Engine", 3: ":train:"},
|
||||
'>': {0: "MV", 1: "Car", 2: "9", 3: ":car:"},
|
||||
'?': {0: "MW", 1: "File Server"},
|
||||
'@': {0: "MX", 1: "HC Future"},
|
||||
'A': {0: "PA", 1: "Aid Station", 3: ":hospital:"},
|
||||
'B': {0: "PB", 1: "BBS or PBBS"},
|
||||
'C': {0: "PC", 1: "Canoe"},
|
||||
'D': {0: "PD"},
|
||||
'E': {0: "PE", 1: "Eyeball"},
|
||||
'F': {0: "PF", 1: "Tractor", 3: ":tractor:"},
|
||||
'G': {0: "PG", 1: "Grid Square"},
|
||||
'H': {0: "PH", 1: "Hotel", 3: ":hotel:"},
|
||||
'I': {0: "PI", 1: "TCP/IP"},
|
||||
'J': {0: "PJ"},
|
||||
'K': {0: "PK", 1: "School", 3: ":school:"},
|
||||
'L': {0: "PL", 1: "PC User", 3: ":computer:"},
|
||||
'M': {0: "PM", 1: "MacAPRS", 3: ":computer:"},
|
||||
'N': {0: "PN", 1: "NTS Station"},
|
||||
'O': {0: "PO", 1: "Balloon", 2: "11", 3: ":airplane:"},
|
||||
'P': {0: "PP", 1: "Police", 3: ":police_car:"},
|
||||
'Q': {0: "PQ"},
|
||||
'R': {0: "PR", 1: "Recreational Vehicle", 2: "13", 3: ":car:"},
|
||||
'S': {0: "PS", 1: "Shuttle"},
|
||||
'T': {0: "PT", 1: "SSTV"},
|
||||
'U': {0: "PU", 1: "Bus", 2: "2", 3: ":bus:"},
|
||||
'V': {0: "PV", 1: "ATV"},
|
||||
'W': {0: "PW", 1: "National WX Service Site"},
|
||||
'X': {0: "PX", 1: "Helo", 2: "6"},
|
||||
'Y': {0: "PY", 1: "Yacht", 2: "5", 3: ":sailboat:"},
|
||||
'Z': {0: "PZ", 1: "WinAPRS", 3: ":computer:"},
|
||||
'[': {0: "HS", 1: "Human/Person", 2: "7", 3: ":running:"},
|
||||
'\\': {0: "HT", 1: "DF Station"},
|
||||
']': {0: "HU", 1: "Post Office", 3: ":post_office:"},
|
||||
'^': {0: "HV", 1: "Large Aircraft", 3: ":airplane:"},
|
||||
'_': {0: "HW", 1: "Weather Station", 3: ":cloud:"},
|
||||
'`': {0: "HX", 1: "Dish Antenna", 3: ":satellite:"},
|
||||
'a': {0: "LA", 1: "Ambulance", 2: "1", 3: ":ambulance:"},
|
||||
'b': {0: "LB", 1: "Bike", 2: "4", 3: ":bike:"},
|
||||
'c': {0: "LC", 1: "Incident Command Post"},
|
||||
'd': {0: "LD", 1: "Fire Dept", 3: ":fire_engine:"},
|
||||
'e': {0: "LE", 1: "Horse", 3: ":racehorse:"},
|
||||
'f': {0: "LF", 1: "Fire Truck", 2: "3", 3: ":fire_engine:"},
|
||||
'g': {0: "LG", 1: "Glider", 3: ":airplane:"},
|
||||
'h': {0: "LH", 1: "Hospital", 3: ":hospital:"},
|
||||
'i': {0: "LI", 1: "IOTA"},
|
||||
'j': {0: "LJ", 1: "Jeep", 2: "12", 3: ":car:"},
|
||||
'k': {0: "LK", 1: "Truck", 2: "14", 3: ":truck:"},
|
||||
'l': {0: "LL", 1: "Laptop", 3: ":computer:"},
|
||||
'm': {0: "LM", 1: "Mic-E Repeater"},
|
||||
'n': {0: "LN", 1: "Node"},
|
||||
'o': {0: "LO", 1: "EOC"},
|
||||
'p': {0: "LP", 1: "Dog", 3: ":dog2:"},
|
||||
'q': {0: "LQ", 1: "Grid SQ"},
|
||||
'r': {0: "LR", 1: "Repeater"},
|
||||
's': {0: "LS", 1: "Ship", 2: "8", 3: ":ship:"},
|
||||
't': {0: "LT", 1: "Truck Stop"},
|
||||
'u': {0: "LU", 1: "Truck (18 Wheeler)", 3: ":truck:"},
|
||||
'v': {0: "LV", 1: "Van", 2: "15", 3: ":minibus:"},
|
||||
'w': {0: "LW", 1: "Water Station"},
|
||||
'x': {0: "LX", 1: "xAPRS", 3: ":computer:"},
|
||||
'y': {0: "LY", 1: "Yagi @ QTH"},
|
||||
'z': {0: "LZ"},
|
||||
'{': {0: "J1"},
|
||||
'|': {0: "J2", 1: "TNC Stream Switch"},
|
||||
'}': {0: "J3"},
|
||||
'~': {0: "J4", 1: "TNC Stream Switch"},
|
||||
}
|
||||
alternateSymbol = map[byte]map[int]string{
|
||||
'!': {0: "OBO", 1: "Emergency"},
|
||||
'"': {0: "OC", 1: "Reserved"},
|
||||
'#': {0: "OD#", 1: "Overlay Digi"},
|
||||
'$': {0: "OEO", 1: "Bank/ATM", 3: ":atm:"},
|
||||
'%': {0: "OFO", 1: "Power Plant", 3: ":factory:"},
|
||||
'&': {0: "OG#", 1: "I=Igte R=RX T=1hopTX 2=2hopTX"},
|
||||
'\'': {0: "OHO", 1: "Crash Site"},
|
||||
'(': {0: "OIO", 1: "Cloudy", 3: ":cloud:"},
|
||||
')': {0: "OJO", 1: "Firenet MEO"},
|
||||
'*': {0: "OK"},
|
||||
'+': {0: "OL", 1: "Church", 3: ":church:"},
|
||||
',': {0: "OM", 1: "Girl Scouts", 3: ":tent:"},
|
||||
'-': {0: "ONO", 1: "House", 3: ":house:"},
|
||||
'.': {0: "OO", 1: "Ambiguous"},
|
||||
'/': {0: "OP", 1: "Waypoint Destination"},
|
||||
'0': {0: "A0#", 1: "Circle", 3: ":red_circle:"},
|
||||
'1': {0: "A1"},
|
||||
'2': {0: "A2"},
|
||||
'3': {0: "A3"},
|
||||
'4': {0: "A4"},
|
||||
'5': {0: "A5"},
|
||||
'6': {0: "A6"},
|
||||
'7': {0: "A7"},
|
||||
'8': {0: "A8O", 1: "WiFi Network"},
|
||||
'9': {0: "A9", 1: "Gas Station", 3: ":fuelpump:"},
|
||||
':': {0: "NR"},
|
||||
';': {0: "NSO", 1: "Park/Picnic"},
|
||||
'<': {0: "NTO", 1: "Advisory"},
|
||||
'=': {0: "NUO"},
|
||||
'>': {0: "NV#", 1: "Cars & Vehicles", 3: ":car:"},
|
||||
'?': {0: "NW", 1: "Info Kiosk"},
|
||||
'@': {0: "NX", 1: "Hurricane", 3: ":cyclone:"},
|
||||
'A': {0: "AA#", 1: "Box DTMF & RFID"},
|
||||
'B': {0: "AB"},
|
||||
'C': {0: "AC", 1: "Coast Guard"},
|
||||
'D': {0: "ADO", 1: "Depots"},
|
||||
'E': {0: "AE", 1: "Smoke"},
|
||||
'F': {0: "AF"},
|
||||
'G': {0: "AG"},
|
||||
'H': {0: "AHO", 1: "Haze"},
|
||||
'I': {0: "AI", 1: "Rain Shower", 3: ":umbrella:"},
|
||||
'J': {0: "AJ"},
|
||||
'K': {0: "AK", 1: "Kenwood HT"},
|
||||
'L': {0: "AL", 1: "Lighthouse"},
|
||||
'M': {0: "AMO", 1: "MARS"},
|
||||
'N': {0: "AN", 1: "Navigation Buoy"},
|
||||
'O': {0: "AO", 1: "Rocket", 3: ":rocket:"},
|
||||
'P': {0: "AP", 1: "Parking", 3: ":parking:"},
|
||||
'Q': {0: "AQ", 1: "Quake"},
|
||||
'R': {0: "ARO", 1: "Restaurant"},
|
||||
'S': {0: "AS", 1: "Satellite/Pacsat", 3: ":rocket:"},
|
||||
'T': {0: "AT", 1: "Thunderstorm"},
|
||||
'U': {0: "AU", 1: "Sunny"},
|
||||
'V': {0: "AV", 1: "VORTAC Nav Aid"},
|
||||
'W': {0: "AW#", 1: "NWS Site"},
|
||||
'X': {0: "AX", 1: "Pharmacy"},
|
||||
'Y': {0: "AYO", 1: "Radios and devices"},
|
||||
'Z': {0: "AZ"},
|
||||
'[': {0: "DSO", 1: "W. Cloud"},
|
||||
'\\': {0: "DTO", 1: "GPS"},
|
||||
']': {0: "DU"},
|
||||
'^': {0: "DV#", 1: "Other Aircraft", 3: ":airplane:"},
|
||||
'_': {0: "DW#", 1: "WX Site"},
|
||||
'`': {0: "DX", 1: "Rain", 3: ":umbrella:"},
|
||||
'a': {0: "SA#O"},
|
||||
'b': {0: "SB"},
|
||||
'c': {0: "SC#O", 1: "CD Triangle"},
|
||||
'd': {0: "SD", 1: "DX Spot"},
|
||||
'e': {0: "SE", 1: "Sleet"},
|
||||
'f': {0: "SF", 1: "Funnel Cloud"},
|
||||
'g': {0: "SG", 1: "Gale Flags"},
|
||||
'h': {0: "SHO", 1: "Store or Hamfest"},
|
||||
'i': {0: "SI#", 1: "Box / POI"},
|
||||
'j': {0: "SJ", 1: "Work Zone"},
|
||||
'k': {0: "SKO", 1: "Special Vehicle"},
|
||||
'l': {0: "SL", 1: "Areas"},
|
||||
'm': {0: "SM", 1: "Value Sign"},
|
||||
'n': {0: "SN#", 1: "Triangle"},
|
||||
'o': {0: "SO", 1: "Small Circle"},
|
||||
'p': {0: "SP"},
|
||||
'q': {0: "SQ"},
|
||||
'r': {0: "SR", 1: "Restrooms"},
|
||||
's': {0: "SS#", 1: "Ship/Boats", 3: ":speedboat:"},
|
||||
't': {0: "ST", 1: "Tornado", 3: ":cyclone:"},
|
||||
'u': {0: "SU#", 1: "Truck", 3: ":truck:"},
|
||||
'v': {0: "SV#", 1: "Van", 3: ":minibus:"},
|
||||
'w': {0: "SWO", 1: "Flooding"},
|
||||
'x': {0: "SX", 1: "Wreck/Obstruction"},
|
||||
'y': {0: "SY", 1: "Skywarn"},
|
||||
'z': {0: "SZ#", 1: "Shelter"},
|
||||
'{': {0: "Q1"},
|
||||
'|': {0: "Q2", 1: "TNC Stream Switch"},
|
||||
'}': {0: "Q3"},
|
||||
'~': {0: "Q4", 1: "TNC Stream Switch"},
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user