Skip to content

Commit 2a32741

Browse files
committed
update examples
1 parent c1e472f commit 2a32741

File tree

4 files changed

+246
-2
lines changed

4 files changed

+246
-2
lines changed

examples/pyais-to-tak-with-cert.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import socket
2+
import pyais
3+
import CoT
4+
import datetime
5+
import ssl
6+
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
7+
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
8+
9+
UDP_IP = "0.0.0.0" # Listen on all interfaces
10+
UDP_PORT = 9009
11+
12+
TAK_HOSTNAME = 'x.x.x.x'
13+
TAK_PORT = 8089
14+
15+
# Load the .p12 file
16+
p12_file_path = '/admin.p12'
17+
p12_password = b'atakatak'
18+
19+
with open(p12_file_path, 'rb') as f:
20+
p12_data = f.read()
21+
22+
private_key, certificate, additional_certificates = load_key_and_certificates(p12_data, p12_password)
23+
24+
# Save cert and key to temp files
25+
with open('client_cert.pem', 'wb') as cert_file:
26+
cert_file.write(certificate.public_bytes(Encoding.PEM))
27+
28+
with open('client_key.pem', 'wb') as key_file:
29+
key_file.write(private_key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption()))
30+
31+
# Insecure context
32+
context = ssl._create_unverified_context()
33+
context.load_cert_chain(certfile='client_cert.pem', keyfile='client_key.pem')
34+
35+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
36+
sock.bind((UDP_IP, UDP_PORT))
37+
38+
print(f"Listening on {UDP_IP}:{UDP_PORT}")
39+
40+
while True:
41+
try:
42+
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
43+
44+
decoded = pyais.decode(data)
45+
46+
47+
ais_dict = decoded.asdict()
48+
49+
50+
# {'msg_type': 1, 'repeat': 0, 'mmsi': 368088610, 'status': <NavigationStatus.UnderWayUsingEngine: 0>, 'turn': 0.0, 'speed': 28.0, 'accuracy': False, 'lon': -122.383025, 'lat': 37.806888, 'course': 159.7, 'heading': 156, 'second': 54, 'maneuver': <ManeuverIndicator.NotAvailable: 0>, 'spare_1': b'\x00', 'raim': False, 'radio': 100365}
51+
52+
now = datetime.datetime.now(datetime.timezone.utc)
53+
stale = now + datetime.timedelta(minutes=2)
54+
55+
event = CoT.Event(
56+
version="2.0",
57+
type="a-u-S-X-M",
58+
access="Undefined",
59+
uid="MMSI-{}".format(ais_dict['mmsi']),
60+
time=now,
61+
start=now,
62+
stale=stale,
63+
how="m-f",
64+
qos="2-i-c",
65+
point=CoT.Point(lat=float(ais_dict['lat']), lon=float(ais_dict['lon']), hae=9999999, ce=9999999, le=9999999),
66+
detail={"contact": {"callsign": "MMSI-{}".format(ais_dict['mmsi'])}},
67+
)
68+
69+
data = event.xml()
70+
b = bytes(data, encoding="utf-8")
71+
72+
73+
with socket.create_connection((TAK_HOSTNAME, TAK_PORT)) as tcp_sock:
74+
with context.wrap_socket(tcp_sock, server_hostname=TAK_HOSTNAME) as send_sock:
75+
send_sock.sendall(b)
76+
data = send_sock.recv(1024)
77+
except:
78+
print("Failed to parse ship.")
79+
continue

examples/pycot-aisstrem.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import socket
2+
import ssl
3+
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
4+
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
5+
import asyncio
6+
import websockets
7+
import json
8+
import datetime
9+
import CoT
10+
11+
12+
# Load the .p12 file
13+
p12_file_path = 'examples/admin.p12'
14+
p12_password = b'atakatak'
15+
16+
with open(p12_file_path, 'rb') as f:
17+
p12_data = f.read()
18+
19+
private_key, certificate, additional_certificates = load_key_and_certificates(p12_data, p12_password)
20+
21+
# Save cert and key to temp files
22+
with open('client_cert.pem', 'wb') as cert_file:
23+
cert_file.write(certificate.public_bytes(Encoding.PEM))
24+
25+
with open('client_key.pem', 'wb') as key_file:
26+
key_file.write(private_key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption()))
27+
28+
# Insecure context
29+
context = ssl._create_unverified_context()
30+
context.load_cert_chain(certfile='client_cert.pem', keyfile='client_key.pem')
31+
32+
# Connect to server
33+
hostname = 'x.x.x.x'
34+
port = 8089
35+
36+
def get_sar(mmsi: str) -> bool:
37+
"""Get the AIS Search-And-Rescue (SAR) status of a given MMSI.
38+
39+
Search and Rescue Aircraft:
40+
AIS and DSC equipment used on search and rescue aircraft use the format
41+
111213M4I5D6X7X8X9 where the digits 4, 5 and 6 represent the MID and X
42+
is any figure from 0 to 9. In the United States, these MMSIs are
43+
currently only used by the U.S. Coast Guard.
44+
Src: https://www.navcen.uscg.gov/?pageName=mtmmsi
45+
46+
:param mmsi: str MMSI as decoded from AIS data.
47+
:return:
48+
"""
49+
sar = False
50+
_mmsi = str(mmsi)
51+
if _mmsi[:3] == "111":
52+
sar = True
53+
elif _mmsi[:5] in ["30386", "33885"]: # US Coast Guard
54+
sar = True
55+
return sar
56+
57+
def create_cot_event(message: dict):
58+
now = datetime.datetime.now(datetime.timezone.utc)
59+
stale = now + datetime.timedelta(minutes=2)
60+
61+
print(message['Message']['PositionReport'])
62+
print(message)
63+
64+
return CoT.Event(
65+
version="2.0",
66+
type="a-u-S-X-M",
67+
access="Undefined",
68+
uid="MMSI-{}".format(message['MetaData']['MMSI']),
69+
time=now,
70+
start=now,
71+
stale=stale,
72+
how="m-f",
73+
qos="2-i-c",
74+
point=CoT.Point(lat=float(message["Message"]["PositionReport"]["Latitude"]), lon=float(message["Message"]["PositionReport"]["Longitude"]), hae=9999999, ce=9999999, le=9999999),
75+
detail={"contact": {"callsign": message["MetaData"]["ShipName"]}},
76+
)
77+
78+
async def connect_ais_stream():
79+
async with websockets.connect("wss://stream.aisstream.io/v0/stream") as websocket:
80+
subscribe_message = {
81+
"APIKey": "",
82+
"BoundingBoxes": [[[-90, -180], [90, 180]]],
83+
"FilteringMMSI": ["368207620", "367719770", "211476060"],
84+
"FilderingMessageTypes": ["PositionReport"]
85+
}
86+
subscribe_message_json = json.dumps(subscribe_message)
87+
await websocket.send(subscribe_message_json)
88+
89+
async for message_json in websocket:
90+
message = json.loads(message_json)
91+
message_type = message["MessageType"]
92+
if message_type == "PositionReport":
93+
ais_message = message['Message']['PositionReport']
94+
cot_event = create_cot_event(message)
95+
data = cot_event.xml()
96+
b = bytes(data, encoding="utf-8")
97+
98+
with socket.create_connection((hostname, port)) as sock:
99+
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
100+
ssock.sendall(b)
101+
data = ssock.recv(1024)
102+
103+
104+
def main():
105+
asyncio.run(asyncio.run(connect_ais_stream()))
106+
107+
if __name__ == "__main__":
108+
main()

examples/pycot-to-tak-with-cert.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import socket
2+
import ssl
3+
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
4+
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
5+
6+
# Load the .p12 file
7+
p12_file_path = 'examples/admin.p12'
8+
p12_password = b'atakatak'
9+
10+
with open(p12_file_path, 'rb') as f:
11+
p12_data = f.read()
12+
13+
private_key, certificate, additional_certificates = load_key_and_certificates(p12_data, p12_password)
14+
15+
# Save cert and key to temp files
16+
with open('client_cert.pem', 'wb') as cert_file:
17+
cert_file.write(certificate.public_bytes(Encoding.PEM))
18+
19+
with open('client_key.pem', 'wb') as key_file:
20+
key_file.write(private_key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption()))
21+
22+
# Insecure context
23+
context = ssl._create_unverified_context()
24+
context.load_cert_chain(certfile='client_cert.pem', keyfile='client_key.pem')
25+
26+
# Connect to server
27+
hostname = 'x.x.x.x'
28+
port = 8089
29+
30+
import datetime
31+
import CoT
32+
33+
now = datetime.datetime.now(datetime.timezone.utc)
34+
stale = now + datetime.timedelta(minutes=2)
35+
36+
# Generate new CoT event
37+
py_cot = CoT.Event(
38+
version="2.0",
39+
type="a-u-G-U-U-S-R-S",
40+
access="Undefined",
41+
uid="Debug.Python",
42+
time=now,
43+
start=now,
44+
stale=stale,
45+
how="h-g-i-g-o",
46+
qos="2-i-c",
47+
point=CoT.Point(lat=2, lon=2, hae=9999999, ce=9999999, le=9999999),
48+
detail={"contact": {"callsign": "Debug.Python"}},
49+
)
50+
51+
data = py_cot.xml()
52+
b = bytes(data, encoding="utf-8")
53+
54+
with socket.create_connection((hostname, port)) as sock:
55+
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
56+
ssock.sendall(b)
57+
data = ssock.recv(1024)

examples/pycot-to-tak.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
detail={"contact": {"callsign": "Debug.Python"}},
2222
)
2323

24-
TAK_IP = "localhost"
25-
TAK_PORT = 8999
24+
TAK_IP = "x.x.x.x"
25+
TAK_PORT = 8089
2626

2727
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2828
sock.connect((TAK_IP, TAK_PORT))

0 commit comments

Comments
 (0)