Python • AIS NMEA 0183

AISMixer

Platformă de procesare și rutare a fluxurilor AIS

Normalizează · Deduplică · Etichetează · Rutează · Redirecționează

Recepționați fluxuri AIS, transformați traficul receptoarelor într-un singur flux logic controlat și livrați-l către destinațiile UDP egress care au nevoie de el.

Codul-sursă al proiectului AISMixer este disponibil public sub licența CC BY-NC 4.0; licența nu permite utilizarea comercială.

Procesarea fluxurilor AIS

De la traficul receptoarelor la un flux curat, cu surse identificabile

AISMixer reunește transportul, asamblarea NMEA, metadatele, deduplicarea și livrarea într-un singur traseu de procesare aproape în timp real. Ecosistemul AISMixer include serviciul aismixer pentru procesarea și rutarea fluxurilor, nmea_sproxy, aismixerctl, transportul securizat, instrumentele de implementare și componentele conexe.

Ingress flexibil

Recepționează UDP simplu prin IPv4 sau IPv6 ori trafic de stație UDPSEC autentificat și criptat.

Extragerea propozițiilor AIS

Extrage atât !AIVDM, cât și !AIVDO din ieșirile reale ale receptoarelor și aplicațiilor.

Asamblare multipart

Asamblează fragmente sosite complet în afara ordinii în mesaje logice complete și le emite în ordinea ordinală.

Deduplicare aproape în timp real

Ia o singură decizie atomică la nivelul grupului pentru fiecare mesaj multipart complet, global în modul broadcast sau separat pentru fiecare destinație de rutare.

Metadate TAG controlate

Controlează NMEA TAG s, c și g pe tot ciclul de viață multipart, păstrând metadatele separate de identitatea de rutare.

Redirecționare selectivă

Redirecționează propozițiile acceptate către fiecare ieșire UDP configurată în modul broadcast sau către destinațiile denumite selectate prin rutare logică.

Prezentare vizuală pe scurt

Cum funcționează AISMixer

Un scurt tur vizual de la mai multe surse AIS, prin asamblare, deduplicare, gestionarea metadatelor TAG și rutare logică, până la ieșirile selectate, inclusiv nmea_sproxy și UDPSEC. Materialul video este în limba engleză.

Fundament al planului de date din campaniile C–F, pregătit pentru o implementare nativă

Procesare explicită, etape cu capacitate finită și egress unificat

Ingress-ul imuabil la nivel de octeți trece prin etape explicite, cu capacitate finită, într-un singur proces. După ce devine disponibilă capacitatea comună de procesare, fiecare cadru admis este asociat unui singur ProcessingSnapshot și procesat de PythonDataPlaneProcessor, care deține starea instanței și rămâne unicul procesor actual de producție și de referință. Acesta returnează un OutputBatch imuabil și ordonat, ale cărui valori ProcessorOutput transportă octeții exacți și ID-urile numerice ale destinațiilor prin handoff-ul egress cu capacitate finită.

Producători UDP / UDPSEC Coadă privată limitată cu IngressFrame pentru fiecare intrare
Admitere limitată la procesare Backpressure, apoi asocierea unui singur ProcessingSnapshot
PythonDataPlaneProcessor cu stare proprie Scanarea octeților, asamblare, politica TAG și deduplicare
Handoff limitat al unui OutputBatch ordonat Octeți exacți și destinații numerice explicite
Egress UDP unificat Expediere locală secvențială prin send_to_ids()

Limită ingress imuabilă

Producătorii UDP și UDPSEC integrați creează obiecte IngressFrame imuabile la nivel de octeți. Scanarea bytes-native și metadatele ParsedSentence parsate o singură dată transportă informațiile despre fragmente și TAG în procesare, fără extragere repetată.

Asocierea snapshot-ului după obținerea capacității

Capacitatea de procesare este obținută înainte ca un singur ProcessingSnapshot imuabil să fie asociat cadrului. Lucrul admis păstrează acel snapshot; cadrele care încă așteaptă capacitate pot observa o înlocuire ulterioară a rutării, locală procesului.

Procesor Python cu stare proprie

O singură instanță PythonDataPlaneProcessor cu durată lungă de viață deține starea mutabilă pentru asamblare, deduplicare, surse, metadate multipart și metricile procesorului. În prezent nu există procesor nativ sau binding-uri.

Octeți exacți în rezultate ordonate

Fiecare propoziție NMEA emisă este codificată UTF-8 o singură dată și devine un payload exact și imuabil într-un OutputBatch ordonat. Fiecare ProcessorOutput conține ID-uri numerice explicite ale destinațiilor; fragmentele multipart rămân payload-uri separate.

Backpressure și finalizare ordonată

Când o limită ingress privată, o limită comună de procesare sau limita egress atinge capacitatea, execuția așteaptă în loc să elimine elementul din coadă. Un lot nevid împiedică procesarea cadrelor următoare până la finalizarea expedierii locale secvențiale. Aceasta nu oferă persistență sau confirmarea livrării la distanță, iar UDP rămâne un transport cu pierderi.

Ciclu de viață fail-fast local procesului

Etapele asyncio esențiale au un singur ciclu de viață supravegheat, local procesului. Un eșec sau o finalizare neașteptată anulează și așteaptă task-urile surori. Nu există repornire automată, reîncercare, rollback, confirmare a livrării sau replay.

Aveți nevoie de semantica exactă a cazurilor marginale? Citiți contractul comportamental.

Responsabilitate explicită pentru ciclul de viață

Stare deterministă sub sarcină

Implementarea de referință face explicite starea păstrată, progresul duratei de viață, admiterea în capacitate, curățarea și observarea, fără a depinde de comportamentul accidental al containerelor.

Starea deduplicării

Identitatea este propoziția exactă sau tuplul multipart ordonat, într-o sferă globală ori separată pentru fiecare destinație. TTL-ul este determinist, duplicatele nu reîmprospătează păstrarea, iar intrările expirate sunt eliminate înaintea evacuării celei mai vechi intrări active.

Obiectul Python acceptă parametrul opțional max_entries; integrarea actuală a serviciului îl lasă la None, astfel încât această dimensiune este nelimitată în serviciul actual.

Starea asamblării multipart

Fragmentele ocupă poziții ordinale. Progresul unic reîmprospătează durata de viață a grupului; un duplicat exact nu o face. Conflictul, expirarea, eliminarea din cauza capacității, finalizarea și resetarea rămân rezultate distincte ale ciclului de viață și curăță contextul TAG asociat.

Obiectul Python acceptă parametrii opționali max_fragments_per_group și max_pending_groups; integrarea actuală a serviciului îi lasă pe amândoi la None.

Protecție anti-replay și sesiuni securizate

Înregistrările anti-replay pentru handshake, precum și sesiunile în așteptare și active, au TTL-uri monotone și limite stricte de capacitate. Fiecare nonce DATA admis rămâne însă memorat pentru întreaga epocă utilizabilă a cheii de trafic direcționale, fără TTL independent și fără eliminare cât timp acea epocă rămâne utilizabilă. Epuizarea invalidează în mod sigur (fail-closed) numai epoca de cheie afectată; recuperarea folosește un handshake autentificat nou, cu chei direcționale proaspete.

Un candidat în așteptare înlocuiește numai un candidat mai vechi pentru aceeași relație dintre listenerul fizic și peer și păstrează orice sesiune activă până când confirmarea criptată autentificată reușește. Sesiunile aceluiași peer pe listenere UDPSEC fizice separate sunt izolate unele de altele; limitele agregate de capacitate rămân la nivelul procesului. Toată starea securizată rămâne numai în memorie, este locală procesului și se pierde la repornire.

Stare observabilă a componentelor și runtime-ului

Proprietarii stării de deduplicare, asamblare și securitate expun snapshot-uri interne și imuabile ale ciclului de viață. Runtime-ul oferă separat vizualizări pull-based proaspete asupra cozilor, activității procesorului și egress-ului și traficului de intrare și de ieșire. Citirea oricărui tip de snapshot nu modifică starea procesării.

Aceste vizualizări sunt locale procesului și nepersistente; nu reprezintă metrici distribuite sau un sistem de export Prometheus/time-series.

Locală prin proiectare. Această stare este nepersistentă și nu este partajată între procese. Runtime-ul actual supraveghează task-urile asyncio esențiale într-un singur proces; procesele coordonator/worker, IPC și sincronizarea stării între procese nu există încă.

Campania F — implementată

Limite pregătite pentru workeri într-un singur proces

Campania F a finalizat limitele observabile și cu capacitate finită din jurul runtime-ului Python actual. Starea mutabilă de procesare are un proprietar explicit la nivel de instanță, lucrul este admis numai când există capacitate, iar statisticile pull-based proaspete fac vizibilă activitatea etapelor fără să o modifice.

Ingress privat și limitat

Fiecare intrare UDP sau UDPSEC configurată are propria coadă limitată, astfel încât elementele acumulate de o intrare să nu consume capacitatea privată a alteia.

Admitere numai când există capacitate

Admiterea comună la procesare are capacitate finită. Un cadru primește ProcessingSnapshot imuabil numai după obținerea capacității, iar când capacitatea este atinsă, execuția așteaptă prin backpressure.

Stare deținută de instanța procesorului

O singură instanță a procesorului deține starea mutabilă pentru asamblare, deduplicare, surse, metadate multipart și metricile procesorului, în spatele unei limite explicite a ciclului de viață.

Egress limitat și ordonat

Un handoff limitat transportă fiecare OutputBatch nevid către expedierea locală secvențială. Bariera de finalizare păstrează ordinea procesării, dar nu confirmă primirea la distanță.

Observabilitate runtime pull-based

Snapshot-urile proaspete și imuabile acoperă starea cozilor și backpressure, activitatea procesorului și egress-ului, traficul de intrare brut și admis și mesajele și octeții pentru fiecare destinație.

Pregătirea pentru workeri este implementată; procesele worker nu sunt. Serviciul actual folosește încă un singur proces cu etape asyncio supravegheate. Nu există un coordonator, procese worker ingress sau egress separate, multiprocessing, IPC, rutare sau agregare de metrici între procese ori repornire și recuperare automată a workerilor. În prezent nu există procesor nativ sau binding-uri.

Rutare și zone logice

Exprimați politica fluxului prin identitățile surselor

Rutarea logică statică leagă surse ingress denumite de destinații UDP egress denumite, prin seturi reutilizabile de surse și rute ordonate. Numele rămân interfața de configurare și control, iar potrivirea din calea de producție folosește un plan numeric precompilat care conține numai destinațiile și le păstrează ordinea.

Ingress denumitSurse UDP și UDPSEC
Zone logiceSeturi de identități ale surselor
Rute ordonateSelectarea declarativă a destinațiilor
Egress denumitDestinații UDP selectate

Seturi compozabile de surse

Definiți zone cu include, union, intersection și difference.

Logice, nu geografice

Zonele sunt seturi de identități interne ale surselor, nu regiuni pe hartă, filtre MMSI, filtre pentru nave sau reguli aplicate payload-ului.

Ordine păstrată și calitate pentru fiecare destinație

Modul de rutare aplică deduplicarea separat pentru fiecare destinație logică, astfel încât o cale de expediere să nu o suprime pe alta. Ordinea configurată a destinațiilor se păstrează în expedierea secvențială.

Numele rămân interfața operatorilor. ID-urile numerice ale destinațiilor sunt locale procesului și nu sunt valori de configurare. Identificatorul source_id rămâne separat de valoarea NMEA TAG s emisă în aval.

Control local și observabilitate runtime

Controlați rutarea și inspectați activitatea runtime

Planul local opțional de control, printr-un socket POSIX din domeniul Unix, oferă operații de rutare și statistici runtime read-only agregate, per intrare și per ieșire, prin comanda aismixerctl instalată global.

Stare și modificări atomice ale rutării

Inspectați generația activă, zonele, rutele și destinațiile; înlocuiți un snapshot validat sau dezactivați rutarea pentru a reveni la modul legacy broadcast. Verificările opționale ale generației resping actualizările învechite.

Statistici runtime agregate

runtime.statistics raportează starea cozilor limitate și backpressure, activitatea procesorului și activitatea egress-ului într-o singură interogare pull proaspătă și locală procesului.

Trafic de intrare și de ieșire

runtime.statistics.inputs separă traficul de transport de cadrele acceptate. runtime.statistics.outputs raportează expedierile locale, mesajele și octeții pentru fiecare destinație.

Interfață locală pentru operatori

Folosiți aismixerctl pentru modificări locale ale rutării și inspecția read-only a activității runtime, cu ieșire lizibilă pentru operatori și JSON pentru automatizări one-shot.

Limita statisticilor read-only. Statisticile sunt păstrate în memorie, sunt locale procesului, nepersistente și se resetează la repornire. Nu reprezintă istoric persistent, metrici distribuite sau un sistem Prometheus/time-series. Expedierea UDP locală reușită nu reprezintă confirmarea livrării la distanță.

Control intenționat local. Rutele runtime nu persistă după repornire, fișierele de configurare nu sunt rescrise, iar adaptoarele nu sunt create dinamic. Permisiunile socketului Unix reprezintă limita actuală de autorizare; nu există token de control la nivelul aplicației.

Controlul punctelor terminale de rețea

Limitați sursele permise și adresele-sursă de ieșire

Controalele simple la nivelul aplicației facilitează integrarea punctelor terminale IPv4 și IPv6 în politica mai largă de firewall și rutare a operatorului.

Ingress allow_from

Limitați listener-ele UDP și UDPSEC la adrese IP literale sau rețele CIDR, inclusiv printr-o regulă explicită de blocare totală.

Adresă de ieșire source_ip

Asociați un socket egress cu o adresă-sursă IPv4 sau IPv6 literală și limitați rezolvarea destinației la aceeași familie de adrese.

Parte a unei limite stratificate

Aceste politici completează regulile de firewall și rutare ale sistemului de operare; nu le înlocuiesc.

source_ip reprezintă asocierea unei adrese-sursă, nu selectarea interfeței, a tabelei de rutare, marcarea socketului sau SDN.

Ciclul de viață UDPSEC

Transport autentificat cu stare locală limitată

Traseul UDPSEC actual din codul-sursă dintre nmea_sproxy și serviciul aismixer folosește identități ECDSA P-256 pe termen lung configurate, ECDHE efemer P-256 semnat, chei AES-256-GCM direcționale proaspete și dovada criptată a posesiei cheilor prin confirmarea cu secvența zero înainte ca clientul să considere stabilită o sesiune nouă.

ClientHello autentificat Semnat cu cheia de identitate, cu o cheie efemeră P-256 nouă
ECDHE efemer P-256 Secret comun nou pentru acest handshake
HKDF-SHA256 Chei C2S și S2C independente
Confirmare criptată cu secvența zero Ping C2S, apoi pong S2C
Sesiune activă Ping-ul autentificat promovează; pong-ul autentificat finalizează

Acord efemer autentificat al cheilor

La fiecare stabilire a unei sesiuni, fiecare endpoint generează o pereche nouă de chei efemere P-256 pentru ECDHE. Cheile P-256 de identitate pe termen lung autentifică numai schimbul, prin semnături ECDSA peste digesturi SHA-256 canonice ale transcriptului, distincte pentru fiecare rol; ele nu participă la acordul de chei ECDHE.

HKDF-SHA256 derivă chei C2S și S2C independente din secretul comun și transcriptul autentificat. AES-256-GCM protejează datele și traficul de control criptat.

Confirmare reciprocă criptată

Clientul confirmă sesiunea în așteptare printr-un ping C2S criptat cu secvența zero. Serverul o promovează numai după autentificarea ping-ului și răspunde cu un pong criptat cu secvența zero folosind cheia S2C a sesiunii promovate; clientul consideră sesiunea stabilită numai după autentificarea acelui pong.

Datagramele fără legătură, malformate, criptate cu o cheie veche sau care au secvența ori sursa greșită nu confirmă candidatul și nici nu prelungesc termenul-limită fix de confirmare.

Actualizare coordonată și stare locală

Ambele endpoint-uri trebuie actualizate împreună. După confirmare, mesajele NMEA DATA, schimburile ping/pong pentru verificarea activității și închiderea best-effort sunt autentificate și criptate. O verificare a activității rămasă fără răspuns sau reîmprospătarea planificată opțională a sesiunii pornește proactiv un handshake ECDHE semnat nou, cu chei direcționale proaspete; UDPSEC nu memorează și nu retransmite payload-uri NMEA în timpul recuperării.

Recuperarea folosește un handshake autentificat nou. UDPSEC nu are resetare în clar, recuperare NOSESSION, control de downgrade sau revenire automată la UDP simplu. Pachetele DATA pentru sesiuni vechi necunoscute sunt ignorate fără răspuns de recuperare în clar. Starea securizată a sesiunilor și protecției anti-replay rămâne numai în memorie, este locală procesului, nepersistentă și se pierde la repornire.

UDPSEC funcționează prin NAT sau CGNAT cât timp adresa și portul sursă observate de server rămân stabile. Reasocierea adresei sau portului ori schimbarea rețelei necesită un handshake autentificat nou; sesiunea existentă nu este migrată automat.

Forward secrecy, în limitele implementate: compromiterea ulterioară a unei chei de identitate pe termen lung nu permite, prin ea însăși, reconstruirea cheilor sesiunilor deja încheiate, dacă vechile chei private efemere și secretele ECDHE brute nu mai există și niciun endpoint nu a fost compromis cât timp acestea se aflau în memorie. Compromiterea actuală a unei chei de identitate permite uzurparea identității în sesiuni viitoare. Această proprietate implementată este susținută de validare inginerească, nu de verificare criptografică formală.

Limita transportului: UDPSEC autentifică și criptează pachetele de date și de control în domeniul său, dar nu dovedește identitatea sau poziția navei, originea fizică ori absența spoofing-ului AIS, nu garantează livrarea sau ordinea UDP, nu protejează endpoint-uri compromise și nu oferă rezistență completă la atacuri de refuz al serviciului. Nu ascunde adresele IP ale participanților, temporizarea sau lungimile pachetelor și nici identificatorul stației din ClientHello, transmis în clar.

Citiți politica de securitate, contractul comportamental, ghidul nmea_sproxy și Wiki-ul pentru limitele detaliate.

nmea_sproxy și receptoare AIS fizice

Conectați receptoare AIS de rețea sau fizice prin nmea_sproxy

nmea_sproxy este proxy-ul de la stație care conectează o singură intrare AIS locală, UDP, serială fizică ori serială virtuală prin USB, la o singură ieșire de rețea: UDPSEC sau UDP simplu configurat explicit.

Receptor AIS fizic
port serial sau dispozitiv serial virtual prin USB
nmea_sproxy
UDPSEC sau UDP simplu pe o rețea declarată explicit ca fiind de încredere
Ieșire de rețea aismixer prin UDPSEC sau un consumator prin UDP simplu, într-o rețea de încredere

Intrări locale implementate

  • UDP de la un receptor local conectat la rețea sau de la o aplicație AIS.
  • Intrare serială fizică prin nmea_sproxy, inclusiv dispozitive seriale virtuale prin USB puse la dispoziție de sistemul de operare.

Ieșiri implementate

  • UDPSEC autentificat și criptat, folosind ciclul de viață limitat al sesiunilor descris mai sus.
  • UDP simplu explicit pentru o rețea LAN, un VPN sau o limită echivalentă declarată de încredere.

Model clar al relației

O intrare locală este asociată unei singure ieșiri configurate. Fiecare potrivire AIS NMEA acceptată este redirecționată fără blocuri TAG de intrare, prefixe, octeți din jur și terminatori. nmea_sproxy nu mixează, nu distribuie către mai multe ieșiri, nu rutează, nu deduplică și nu asamblează AIS multipart.

Un receptor de rețea poate trimite UDP local către nmea_sproxy sau direct către serviciul aismixer, în funcție de instalare. Procesul principal al serviciului aismixer nu citește direct porturi seriale. UDP-ul simplu folosit într-o zonă declarată de încredere nu oferă criptare UDPSEC, autentificare, protecție anti-replay sau verificarea activității.

Implementare OpenWrt la marginea rețelei

Rulați serviciul aismixer sau serviciul nmea_sproxy pe OpenWrt

Depozitul AISMixer APK semnat pentru OpenWrt 25.12 publică versiunea 0.2.1-r1 a pachetelor Python/procd pentru arhitecturile x86_64 și mips_24kc.

Pachete semnate

Instalați aismixer sau nmea_sproxy. Dependența comună aismixer-common este adăugată automat la instalarea oricăruia dintre cele două pachete.

Indexuri de depozit publicate:

Ambele arhitecturi folosesc aceeași cheie publică a depozitului; instalați-o în /etc/apk/keys/ înainte de a folosi oricare dintre cele două indexuri.

SHA-256 al cheii: 170d30219e0e05d59898cd8ccd5ec9804e915df7882ab56b8e869ef6e99c8f9c

Două roluri la marginea rețelei

Serviciul aismixer poate rula pe un dispozitiv periferic sau router cu OpenWrt. nmea_sproxy poate rula independent lângă un receptor cu intrare UDP sau serială. Ieșirea poate fi UDP simplu, iar UDPSEC poate proteja legătura de rețea către serviciul aismixer.

nmea_sproxy acceptă intrare serială fizică, inclusiv dispozitive seriale virtuale prin USB puse la dispoziție de sistemul de operare. Dispozitivele CDC ACM apar de obicei ca /dev/ttyACM*, iar adaptoarele USB-UART ca /dev/ttyUSB*. Driverul de nucleu necesar poate fi deja inclus în imaginea OpenWrt; în caz contrar, poate fi necesar pachetul kmod corespunzător, de exemplu kmod-usb-acm pentru CDC ACM. UART-ul nativ și intrarea UDP nu necesită un driver serial USB.

Încredere UDPSEC explicită

Pachetele nu includ chei private. Fluxul init OpenWrt al serviciului aismixer pregătește identitatea locală și, când există o cheie privată validă, poate reface cheia publică pereche. nmea_sproxy poate crea perechea canonică a stației numai când ambele fișiere lipsesc; o pereche de chei a proxy-ului parțială, invalidă sau neconcordantă produce un refuz fail-closed fără înlocuire automată. Încrederea UDPSEC este întotdeauna configurată manual: instalați cheia publică aismixer la stație și autorizați cheia publică a stației în aismixer.

Arhitectura pachetului. PKGARCH:=all descrie payload-ul Python și shell independent de arhitectură; nu face pachetul disponibil în feed-ul fiecărei arhitecturi. Feed-urile construite, publicate și validate în prezent sunt x86_64 și mips_24kc, fără a exclude intenționat alte ținte potrivite. Selectați arhitectura feed-ului configurat pe dispozitiv; nu o determinați folosind apk --print-arch.

Spațiu disponibil pentru scriere. Runtime-ul Python și dependențele necesită considerabil mai mult spațiu disponibil pentru scriere decât o instalare OpenWrt minimală. Verificați spațiul liber din overlay înainte de instalare; extroot este o opțiune de implementare OpenWrt atunci când spațiul intern disponibil pentru scriere este limitat.

Siguranță la prima pornire. Hook-urile pachetului activează și pornesc aismixer în timpul instalării, iar configurația inclusă inițial conține listenere UDP simple cu acces larg. Aplicați în prealabil reguli de firewall sau izolare de rețea și verificați spațiul disponibil pentru scriere. Opriți serviciul imediat după instalare, configurați listenerele și autorizarea UDPSEC, apoi porniți-l și verificați-l.

# Feed-uri publicate în prezent: x86_64 sau mips_24kc
AISMIXER_ARCH='x86_64'

wget -O /etc/apk/keys/aismixer-openwrt.pem \
  https://aismixer.net/openwrt/keys/aismixer-openwrt.pem

REPO_FILE=/etc/apk/repositories.d/customfeeds.list
REPO_URL="https://aismixer.net/openwrt/25.12/${AISMIXER_ARCH}/packages.adb"

grep -qxF "$REPO_URL" "$REPO_FILE" 2>/dev/null || {
  printf '\n# AISMixer OpenWrt 25.12 %s repository\n%s\n' \
    "$AISMIXER_ARCH" "$REPO_URL" >> "$REPO_FILE"
}

apk update
apk add aismixer
/etc/init.d/aismixer stop
vi /etc/aismixer/config.yaml
vi /etc/aismixer/authorized_keys.yaml
/etc/init.d/aismixer start
/etc/init.d/aismixer status
logread -e aismixer

Versiunea pachetelor. Pachetele 0.2.1-r1 publicate folosesc o revizie fixată a sursei și pot rămâne în urma modificărilor ulterioare din main. Verificați revizia pachetului, lista de modificări și versiunile publicate înainte de a presupune că sunt incluse consolidări mai noi.

Validare cap la cap. Calea de implementare pentru mips_24kc a fost validată cap la cap cu intrare AIS serială fizică, nmea_sproxy, UDPSEC autentificat, procesare prin serviciul aismixer, funcționarea serviciilor prin procd, control local și observabilitate runtime.

Doar punctul terminal de lângă receptor. Folosiți apk add nmea_sproxy în loc de apk add aismixer pentru a instala independent proxy-ul de la stație. Consultați README, ghidul nmea_sproxy și ghidul de implementare OpenWrt pentru pașii compleți de implementare și configurare a încrederii.

Implementare și operare pentru familia Debian

Un ciclu de viață pentru familia Debian și systemd, conceput pentru instalări reale

Pentru gazde Debian și Raspberry Pi OS cu systemd, implementarea gestionată din depozit menține aliniate fișierele de runtime, starea operatorului, controlul local al rutării și statisticile runtime read-only. OpenWrt folosește calea APK/procd descrisă mai sus.

Serviciu systemd gestionat din depozit

Serviciul aismixer creează /run/aismixer cât timp rulează și acceptă socketul local opțional de control.

Instalare, actualizare și dezinstalare

Scripturile pentru ciclul de viață gestionează rularea ca root sau prin sudo și întrețin fișierele runtime și unitățile de serviciu instalate. Updaterul AISMixer repornește serviciul și poate porni un serviciu inactiv; updaterul nmea_sproxy reîncarcă systemd, dar nu pornește și nu repornește instanțele proxy. Consultați README și ghidul nmea_sproxy.

Starea operatorului este păstrată

Fluxurile normale de instalare, actualizare și dezinstalare păstrează configurația operatorului și cheile criptografice.

CLI global pentru operatori

Fluxul de instalare plasează aismixerctl în /usr/local/bin pentru rutare runtime locală și statistici read-only.

Documentație și starea proiectului

Funcționalitățile implementate sunt separate clar de pașii următori

Wiki-ul este ghidul detaliat pentru arhitectură, configurare, rutare, securitate și operare. Roadmap-ul separă fundamentul finalizat de activitatea viitoare fără a promite termene.

Implementat acum

  • Valori IngressFrame imuabile la nivel de octeți, scanare bytes-native, metadate parsate o singură dată și PythonDataPlaneProcessor ca unic procesor actual de producție și de referință.
  • Cozi ingress private și limitate, admitere comună și limitată la procesare, handoff egress limitat, backpressure, starea deținută de instanța procesorului și asocierea ProcessingSnapshot la admitere.
  • Rutare compilată bazată numai pe destinații numerice, octeți exacți și imuabili codificați o singură dată pentru fiecare propoziție emisă, rezultate OutputBatch ordonate și o barieră locală și ordonată de finalizare egress.
  • Zone logice și deduplicare per destinație, actualizări atomice ale rutării locale procesului, aismixerctl interactiv și statistici read-only agregate, per intrare și per ieșire.
  • Asamblare multipart deterministă, gestionarea TAG s/c/g și deduplicare globală sau per destinație.
  • UDPSEC cu ECDHE efemer P-256 autentificat, identități ECDSA P-256 pe termen lung configurate, chei AES-256-GCM direcționale proaspete, confirmarea criptată a posesiei cheilor, date și verificări ale activității autentificate și criptate, închidere best-effort autentificată și criptată, protecție anti-replay DATA pe întreaga epocă a cheii, stare limitată fail-closed și izolarea sesiunilor pe listener fizic.
  • Pentru fiecare proces sau instanță systemd nmea_sproxy, o intrare UDP sau serială spre o ieșire UDPSEC ori o ieșire plain-UDP configurată explicit pentru o rețea de încredere, plus controale endpoint IPv4/IPv6.
  • Implementare pentru familia Debian cu RuntimeDirectory systemd, scripturi pentru ciclul de viață care gestionează privilegiile, păstrarea stării operatorului și CLI global pentru operatori, alături de implementarea APK/procd semnată pentru OpenWrt 25.12, publicată pentru x86_64 și mips_24kc.

Activități planificate

  • Un proces coordonator și procese worker ingress și egress reale și separate.
  • IPC, distribuirea snapshot-urilor de rutare și supravegherea între procese, politici de repornire și recuperare a workerilor și agregarea metricilor acolo unde este necesar.
  • Un viitor procesor nativ și binding-uri în spatele contractelor stabilite, cu verificare diferențială a conformității; în prezent nu există o astfel de implementare și nu se afirmă rezultate de performanță.
  • O arhitectură mai largă pentru adaptoarele ingress și egress, dincolo de traseele UDP actuale.

Comunitatea proiectului

Comunitate și contact

Alegeți canalul public potrivit conversației. Discussions, Ideas și Q&A îi ajută și pe alți utilizatori, iar defectele reproductibile trebuie raportate în Issues. Contactul privat rămâne disponibil în profilul responsabilului de întreținere de mai jos.

Explorați discuțiile

Explorați conversațiile publice despre proiect, anunțurile, experiențele de implementare, testele în teren și alte subiecte ale comunității.

Explorați GitHub Discussions

Propuneți o idee

GitHub Discussions este potrivit pentru propuneri de arhitectură, idei de integrare, experiențe de implementare, testare AIS în teren și colaborări academice sau de cercetare care pot fi discutate public.

Deschideți Ideas

Raportați o problemă

Folosiți GitHub Issues pentru defecte reproductibile și activități concrete în depozitul proiectului, nu pentru corespondență privată generală.

Deschideți GitHub Issues

Adresați o întrebare în Q&A

Folosiți Q&A pentru întrebări concrete despre instalare, configurare, utilizare, arhitectură și operare.

Deschideți Q&A

Fondator și responsabil de întreținere

Iliyan Iliev, PhD

Fondator, inițiator și responsabil de întreținerea AISMixer

Dezvoltator și cercetător în sisteme backend și de rețea, interesat de procesarea AIS/NMEA, securitatea maritimă și regională, transport și turism.

Dezvoltare asistată de IA: ChatGPT sprijină analiza arhitecturală, planificarea, documentația și revizuirea. OpenAI Codex sprijină analiza depozitului, implementarea, testarea și validarea. Anthropic Claude Code sprijină revizuirea depozitului, preluarea implementării, verificarea încrucișată, testarea și validarea. Aceste instrumente sunt utilizate sub conducerea fondatorului; deciziile și responsabilitatea finală pentru proiect rămân umane.