Filtrado#
El firmware aplica varios filtros independientes y componibles para decidir qué
paquetes cruzan entre RF y APRS-IS. Viven principalmente en
main/aprs_filter.c y los usan tanto el IGate (components/igate/igate.c)
como el manejador INET→RF (main/aprs_service.c). Todos ellos se componen
con semántica AND: un paquete debe pasar cada filtro que aplique a su
dirección.
Importante
Estos filtros locales son enteramente distintos de la cadena de filtro de
servidor de APRS-IS (g_config.aprs_filter), que es texto libre reenviado
literalmente en la línea de login y aplicado por el servidor APRS-IS a lo que
envía hacia el cliente. Los filtros locales de abajo deciden qué empuja el
cliente hacia afuera, y qué retransmite por RF.
Clasificación por tipo de carga útil#
aprs_filter_classify_tnc2() / aprs_filter_classify_info() deciden a qué
único bit IGATE_FILT_* pertenece un paquete, trabajando sobre el
identificador de tipo de dato APRS (DTI) y — donde el DTI por sí solo es ambiguo
— sobre el símbolo que lleva el informe (_ → meteo, /N → boya):
Tipo |
Bit |
Notas |
|---|---|---|
Mensaje |
|
mensajes APRS |
Estado |
|
informes de estado |
Telemetría |
|
informes de telemetría |
Meteorología |
|
informe de posición con símbolo |
Objeto |
|
|
Ítem |
|
|
Consulta |
|
|
Boya |
|
informe de posición con símbolo |
Posición |
|
informe de posición simple |
Otro |
|
Capacidades de estación, formatos definidos por el usuario, radiogonio- metría Agrelo, balizas de locator Maidenhead y la característica de mapa reservada — los tipos de carga útil sin bit propio, agrupados aquí para que puedan retransmitirse en vez de descartarse en silencio. |
Una carga útil inclasificable — el tráfico de terceros (}) por encima de todo
— clasifica como 0, y aprs_filter_pass() nunca deja pasar 0:
desconocido significa «no retransmitir». Lo mismo ocurre con una máscara toda a
cero (todas las casillas desmarcadas): la máscara es una lista blanca de
tipos permitidos, exactamente como leen las casillas web.
Ambas direcciones usan el mismo clasificador y los mismos bits
(g_config.rf2inetFilter para RF→INET, g_config.inet2rfFilter para
INET→RF), así que las dos nunca pueden divergir.
Guarda de consulta genérica (obligatoria, ambas direcciones)#
Una carga útil cuyo primer byte es ? — una consulta genérica como
?APRS?, ?WX? o ?IGATE? — nunca se enruta, en ninguna dirección
(DROP_GENERIC_QUERY). Esta comprobación se ejecuta antes del filtro por
tipo de carga útil y no es uno de los bits componibles IGATE_FILT_*:
no se puede desactivar, y ningún estado de
rf2inetFilter/inet2rfFilter deja pasar una consulta genérica. Enrutar
una permitiría que una sola estación de RF desencadenara una respuesta de
respondedor de consultas de cada estación conectada a APRS-IS que implemente
uno, atribuyendo el indicativo de esta estación a la inundación resultante a
través del constructo qAR — lo mismo ocurre a la inversa para una
consulta genérica enrutada hacia RF.
Una consulta dirigida (:CALLSIGN :?APRSD, identificador de tipo de
dato :) no empieza por ? y no se ve afectada por esta guarda; se
clasifica como IGATE_FILT_MESSAGE y solo está sujeta al filtro ordinario
por tipo de carga útil de abajo, igual que cualquier otro mensaje.
IGATE_FILT_QUERY en sí sigue existiendo como salida de
aprs_filter_classify_info() / aprs_filter_classify_tnc2() y en
aprs_filter_type_name(), para la contabilidad propia del respondedor de
consultas local — pero ninguna casilla web se corresponde con él, ya que una
consulta que llega al filtro por tipo ya ha sobrevivido, por construcción, a
la guarda obligatoria de arriba.
Guarda de rango local (RF→INET)#
Cuando rf2inet_range_en está activo y rf2inet_range_km > 0, un paquete
cuya posición decodifica a más de esos kilómetros de «My Station»
(my_lat/my_lon) se descarta. La distancia es el círculo máximo
(aprs_filter_haversine_km()) entre los dos puntos. Los paquetes cuya posición
no se puede decodificar pasan esta comprobación. aprs_filter_decode_position()
soporta disposiciones sin comprimir (DDMM.hhN/DDDMM.hhW) y comprimidas
base-91 para los DTIs que llevan una posición únicamente en el campo de
información (!/=, //@, ; objeto, ) ítem), además de los
informes Mic-E (`` ` /”/0x1c/0x1d), cuya posición se reparte entre el
campo de información y el campo de destino AX.25 y es reconstruida por
``aprs_mice_decode() antes de aplicar la misma comprobación de rango.
Guarda de prefijo local (RF→INET)#
Cuando rf2inet_prefix_en está activo, el indicativo de origen debe empezar
por uno de los prefijos separados por comas de rf2inet_prefixes (p. ej.
EA,EB,EC). Insensible a mayúsculas; se ignora el espacio en blanco alrededor
de las entradas. Un indicativo coincide si empieza por cualquier prefijo listado
(aprs_filter_prefix_match()).
Lista blanca / negra de indicativos (budlist)#
Una lista de indicativos compartida (g_config.budlist[], indicativo base, sin
SSID) con un modo por dirección:
BUDLIST_OFF— el filtro de indicativos está deshabilitado para esta dirección.BUDLIST_WHITELIST— solo se permiten pasar los indicativos de la lista.BUDLIST_BLACKLIST— los indicativos de la lista se bloquean; el resto pasa.
aprs_filter_budlist_pass() compara sin distinguir mayúsculas y elimina
internamente cualquier sufijo -SSID, de modo que tanto los llamadores de RF
(solo indicativo base) como de INET (pueden llevar -SSID) pasan su indicativo
directamente.
Desempaquetado selectivo de terceros (solo INET→RF)#
Las cargas útiles de terceros (}) clasifican como 0 y nunca pasan por
defecto — re-enrutarlas sin restricción es la causa número uno de bucles de
IGate. Cuando inet2rf_3rdparty_unwrap_en está activo y
inet2rf_budlist_mode == BUDLIST_WHITELIST,
aprs_filter_classify_thirdparty_inner() evalúa la carga útil dentro de un
nivel de empaquetado } para que el llamador pueda retransmitirla — pero solo
tras verificar que el origen del paquete interior está a su vez en la lista
blanca. Nunca es un interruptor general de «retransmitir todo lo de terceros».
Validación del filtro de servidor#
aprs_filter_validate_server_string() comprueba la gramática de
g_config.aprs_filter antes de enviarse: cada término separado por espacios
debe ser <letra>/<args> con una letra de filtro conocida y la forma de
argumentos correcta para esa letra (r necesita exactamente 3 args numéricos,
p necesita al menos un prefijo, …). Valida solo la estructura, no si los
valores de coordenada/distancia son sensatos.
Filtrado del registro de tráfico#
igate_log_after_filters (Registrar después de los filtros en la página
IGate, desactivado por defecto) reutiliza los filtros anteriores como filtro de
visualización de la tabla de tráfico web y de las líneas correspondientes de
la consola serie: con la opción activa, solo se emite una entrada RX para
una trama que acepta
igate_log_accepts_frame() (Lista de Satélites Digipetidores,
rf2inetFilter, los filtros de rango y prefijo RF→INET, el filtro de
indicativos RF→INET) y una entrada RX-IS solo para una línea que acepta
igate_log_accepts_line() (la excepción de posición asociada, el filtro de
rango INET→RF, la máscara inet2rfFilter incluido el desempaquetado selectivo
de terceros, el filtro de indicativos INET→RF). El lado RF comparte
implementación con la ruta de pasarela; el lado INET→RF aplica las mismas
comprobaciones y en el mismo orden que inet2rfHandler(), posiciones de
seguimiento incluidas, así que el registro y la pasarela no pueden discrepar. No cambia nada de lo que se
pasarela, repite o transmite y ningún contador de descartes se mueve: una trama
omitida del registro se sigue tratando igual que antes.