2021-01-06 12:17:17 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Created on Fri Dec 25 21:25:14 2020
|
|
|
|
|
|
|
|
@author: DJ2LS
|
|
|
|
"""
|
|
|
|
|
|
|
|
import time
|
2021-03-12 13:14:36 +00:00
|
|
|
import crcengine
|
2021-01-06 12:17:17 +00:00
|
|
|
import static
|
2022-01-05 13:15:59 +00:00
|
|
|
|
2021-01-06 12:17:17 +00:00
|
|
|
|
2021-08-15 10:34:28 +00:00
|
|
|
def wait(seconds):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
seconds:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
2021-08-14 18:00:32 +00:00
|
|
|
timeout = time.time() + seconds
|
2021-09-25 13:24:25 +00:00
|
|
|
|
2021-08-14 18:00:32 +00:00
|
|
|
while time.time() < timeout:
|
|
|
|
time.sleep(0.01)
|
2021-10-05 17:59:32 +00:00
|
|
|
return True
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2021-02-10 18:43:59 +00:00
|
|
|
|
2021-01-06 12:17:17 +00:00
|
|
|
def get_crc_8(data):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""Author: DJ2LS
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
Get the CRC8 of a byte string
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
param: data = bytes()
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
data:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
"""
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_algorithm = crcengine.new("crc8-ccitt") # load crc8 library
|
2021-01-06 12:17:17 +00:00
|
|
|
crc_data = crc_algorithm(data)
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_data = crc_data.to_bytes(1, byteorder="big")
|
2021-01-06 12:17:17 +00:00
|
|
|
return crc_data
|
|
|
|
|
2021-03-12 13:14:36 +00:00
|
|
|
|
2021-01-06 12:17:17 +00:00
|
|
|
def get_crc_16(data):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""Author: DJ2LS
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
Get the CRC16 of a byte string
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
param: data = bytes()
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
data:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
2021-03-12 13:39:36 +00:00
|
|
|
"""
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_algorithm = crcengine.new("crc16-ccitt-false") # load crc16 library
|
2021-01-06 12:17:17 +00:00
|
|
|
crc_data = crc_algorithm(data)
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_data = crc_data.to_bytes(2, byteorder="big")
|
2021-03-12 13:14:36 +00:00
|
|
|
return crc_data
|
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-01-24 18:42:59 +00:00
|
|
|
def get_crc_32(data):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""Author: DJ2LS
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-01-24 18:42:59 +00:00
|
|
|
Get the CRC32 of a byte string
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-01-24 18:42:59 +00:00
|
|
|
param: data = bytes()
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
data:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
2022-01-24 18:42:59 +00:00
|
|
|
"""
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_algorithm = crcengine.new("crc32") # load crc16 library
|
2022-01-24 18:42:59 +00:00
|
|
|
crc_data = crc_algorithm(data)
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_data = crc_data.to_bytes(4, byteorder="big")
|
2022-01-24 18:42:59 +00:00
|
|
|
return crc_data
|
2021-03-12 15:18:41 +00:00
|
|
|
|
2021-09-25 13:24:25 +00:00
|
|
|
|
2021-10-24 12:44:55 +00:00
|
|
|
def add_to_heard_stations(dxcallsign, dxgrid, datatype, snr, offset, frequency):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
dxcallsign:
|
|
|
|
dxgrid:
|
|
|
|
datatype:
|
|
|
|
snr:
|
|
|
|
offset:
|
|
|
|
frequency:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
2022-02-21 11:20:36 +00:00
|
|
|
|
2021-03-16 14:21:58 +00:00
|
|
|
# check if buffer empty
|
|
|
|
if len(static.HEARD_STATIONS) == 0:
|
2022-04-11 09:03:54 +00:00
|
|
|
static.HEARD_STATIONS.append(
|
|
|
|
[dxcallsign, dxgrid, int(time.time()), datatype, snr, offset, frequency]
|
|
|
|
)
|
2021-03-16 14:21:58 +00:00
|
|
|
# if not, we search and update
|
|
|
|
else:
|
|
|
|
for i in range(0, len(static.HEARD_STATIONS)):
|
|
|
|
# update callsign with new timestamp
|
|
|
|
if static.HEARD_STATIONS[i].count(dxcallsign) > 0:
|
2022-04-11 09:03:54 +00:00
|
|
|
static.HEARD_STATIONS[i] = [
|
|
|
|
dxcallsign,
|
|
|
|
dxgrid,
|
|
|
|
int(time.time()),
|
|
|
|
datatype,
|
|
|
|
snr,
|
|
|
|
offset,
|
|
|
|
frequency,
|
|
|
|
]
|
2021-03-16 14:21:58 +00:00
|
|
|
break
|
|
|
|
# insert if nothing found
|
|
|
|
if i == len(static.HEARD_STATIONS) - 1:
|
2022-04-11 09:03:54 +00:00
|
|
|
static.HEARD_STATIONS.append(
|
|
|
|
[
|
|
|
|
dxcallsign,
|
|
|
|
dxgrid,
|
|
|
|
int(time.time()),
|
|
|
|
datatype,
|
|
|
|
snr,
|
|
|
|
offset,
|
|
|
|
frequency,
|
|
|
|
]
|
|
|
|
)
|
2021-03-16 14:21:58 +00:00
|
|
|
break
|
2021-09-25 13:24:25 +00:00
|
|
|
|
|
|
|
|
2021-03-16 14:21:58 +00:00
|
|
|
# for idx, item in enumerate(static.HEARD_STATIONS):
|
|
|
|
# if dxcallsign in item:
|
|
|
|
# item = [dxcallsign, int(time.time())]
|
2021-09-25 13:24:25 +00:00
|
|
|
# static.HEARD_STATIONS[idx] = item
|
|
|
|
|
2022-02-21 11:20:36 +00:00
|
|
|
|
|
|
|
def callsign_to_bytes(callsign):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
callsign:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
2022-02-21 11:20:36 +00:00
|
|
|
# http://www.aprs.org/aprs11/SSIDs.txt
|
2022-04-11 09:03:54 +00:00
|
|
|
# -0 Your primary station usually fixed and message capable
|
|
|
|
# -1 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -2 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -3 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -4 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -5 Other networks (Dstar, Iphones, Androids, Blackberry's etc)
|
|
|
|
# -6 Special activity, Satellite ops, camping or 6 meters, etc
|
|
|
|
# -7 walkie talkies, HT's or other human portable
|
|
|
|
# -8 boats, sailboats, RV's or second main mobile
|
|
|
|
# -9 Primary Mobile (usually message capable)
|
|
|
|
# -10 internet, Igates, echolink, winlink, AVRS, APRN, etc
|
|
|
|
# -11 balloons, aircraft, spacecraft, etc
|
|
|
|
# -12 APRStt, DTMF, RFID, devices, one-way trackers*, etc
|
|
|
|
# -13 Weather stations
|
|
|
|
# -14 Truckers or generally full time drivers
|
|
|
|
# -15 generic additional station, digi, mobile, wx, etc
|
|
|
|
|
2022-02-21 11:20:36 +00:00
|
|
|
# try converting to bytestring if possible type string
|
2022-04-11 09:03:54 +00:00
|
|
|
try:
|
|
|
|
callsign = bytes(callsign, "utf-8")
|
2022-02-21 11:20:36 +00:00
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
# we need to do this step to reduce the needed paypload by the callsign ( stripping "-" out of the callsign )
|
|
|
|
callsign = callsign.split(b"-")
|
2022-02-21 11:20:36 +00:00
|
|
|
try:
|
|
|
|
ssid = int(callsign[1])
|
|
|
|
except:
|
|
|
|
ssid = 0
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-02-21 11:20:36 +00:00
|
|
|
callsign = callsign[0]
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-02-21 11:20:36 +00:00
|
|
|
bytestring = bytearray(8)
|
2022-04-11 09:03:54 +00:00
|
|
|
bytestring[: len(callsign)] = callsign
|
2022-02-21 11:20:36 +00:00
|
|
|
bytestring[7:8] = bytes([ssid])
|
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
return bytes(bytestring)
|
|
|
|
|
|
|
|
|
2022-02-21 11:20:36 +00:00
|
|
|
def bytes_to_callsign(bytestring):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
Args:
|
2022-04-11 09:03:54 +00:00
|
|
|
bytestring:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
2022-02-21 11:20:36 +00:00
|
|
|
|
|
|
|
# http://www.aprs.org/aprs11/SSIDs.txt
|
2022-04-11 09:03:54 +00:00
|
|
|
# -0 Your primary station usually fixed and message capable
|
|
|
|
# -1 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -2 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -3 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -4 generic additional station, digi, mobile, wx, etc
|
|
|
|
# -5 Other networks (Dstar, Iphones, Androids, Blackberry's etc)
|
|
|
|
# -6 Special activity, Satellite ops, camping or 6 meters, etc
|
|
|
|
# -7 walkie talkies, HT's or other human portable
|
|
|
|
# -8 boats, sailboats, RV's or second main mobile
|
|
|
|
# -9 Primary Mobile (usually message capable)
|
|
|
|
# -10 internet, Igates, echolink, winlink, AVRS, APRN, etc
|
|
|
|
# -11 balloons, aircraft, spacecraft, etc
|
|
|
|
# -12 APRStt, DTMF, RFID, devices, one-way trackers*, etc
|
|
|
|
# -13 Weather stations
|
|
|
|
# -14 Truckers or generally full time drivers
|
|
|
|
# -15 generic additional station, digi, mobile, wx, etc
|
|
|
|
|
|
|
|
# we need to do this step to reduce the needed paypload by the callsign ( stripping "-" out of the callsign )
|
2022-02-21 11:20:36 +00:00
|
|
|
|
|
|
|
callsign = bytes(bytestring[:7])
|
2022-04-11 09:03:54 +00:00
|
|
|
callsign = callsign.rstrip(b"\x00")
|
2022-02-21 11:20:36 +00:00
|
|
|
ssid = int.from_bytes(bytes(bytestring[7:8]), "big")
|
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
callsign = callsign + b"-"
|
|
|
|
callsign = callsign.decode("utf-8")
|
2022-02-21 11:20:36 +00:00
|
|
|
callsign = callsign + str(ssid)
|
2022-04-11 09:03:54 +00:00
|
|
|
callsign = callsign.encode("utf-8")
|
2022-02-21 11:20:36 +00:00
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
return bytes(callsign)
|
2022-03-19 11:42:10 +00:00
|
|
|
|
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
def check_callsign(callsign: bytes, crc_to_check: bytes):
|
2022-03-19 11:42:10 +00:00
|
|
|
"""
|
|
|
|
Funktion to check a crc against a callsign to calculate the ssid by generating crc until we got it
|
|
|
|
|
|
|
|
Args:
|
|
|
|
callsign: Callsign which we want to check
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_to_check: The CRC which we want the callsign to check against
|
2022-03-19 11:42:10 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
[True, Callsign + SSID]
|
|
|
|
False
|
|
|
|
"""
|
2022-04-10 09:37:09 +00:00
|
|
|
|
2022-04-11 09:03:54 +00:00
|
|
|
crc_algorithm = crcengine.new("crc16-ccitt-false") # load crc16 library
|
|
|
|
|
2022-03-19 11:42:10 +00:00
|
|
|
try:
|
2022-04-11 09:03:54 +00:00
|
|
|
callsign = callsign.split(b"-")
|
|
|
|
callsign = callsign[0] # we want the callsign without SSID
|
|
|
|
|
2022-03-19 11:42:10 +00:00
|
|
|
except:
|
|
|
|
callsign = callsign
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-04-10 09:37:09 +00:00
|
|
|
print(static.SSID_LIST)
|
|
|
|
for ssid in static.SSID_LIST:
|
2022-04-11 09:03:54 +00:00
|
|
|
print(ssid)
|
2022-03-19 11:42:10 +00:00
|
|
|
for ssid in static.SSID_LIST:
|
2022-04-11 09:03:54 +00:00
|
|
|
# for ssid in range(0,254):
|
|
|
|
call_with_ssid = bytearray(callsign)
|
|
|
|
call_with_ssid.extend("-".encode("utf-8"))
|
|
|
|
call_with_ssid.extend(str(ssid).encode("utf-8"))
|
2022-03-19 11:42:10 +00:00
|
|
|
|
|
|
|
callsign_crc = get_crc_16(call_with_ssid)
|
|
|
|
|
|
|
|
if callsign_crc == crc_to_check:
|
|
|
|
print(call_with_ssid)
|
|
|
|
return [True, bytes(call_with_ssid)]
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-04-10 20:45:05 +00:00
|
|
|
return [False, ""]
|