Interfaces¶
Interfaces are the connection points of a station. They are responsible for serializing packets out to other stations. Interfaces are not responsible for tracking connection state or routing packets-- that is the job of the Frame Router. Instead, they are only responsible for sending and receiving packets 'over the air'.
Some examples are in order. The simplest useful interface is the file interface . This simulates the arrival of packets by reading characters from a file, pretending each character arrives as a packet in a message frame.
By contrast, a serial interface is planned which will handle sending packets over KISS mode to a TNC.
Creating new interfaces¶
Aside from the existing interfaces, you can create your own! This could allow you to interface with a new type of hardware, or to simulate a new type of connection. For example, you could create a new interface which sends packets over a TCP connection, or which builds them out of HTTP requests. As long as you can come up with a way to serialize and deserialize packets, you can create a new interface.
The best way to learn how to create a new interface is to look at the existing interfaces, and to read the documentation for the interface base class, detailed below.
pax25.interfaces.types.Interface
¶
The interface base class, which defines the required functions for an interface. All the actual functions must be defined on the subclass-- this base class just raises NotImplementedError for all of them.
Attributes:
| Name | Type | Description |
|---|---|---|
listening |
bool
|
bool flag to indicate whether the interface is up and listening for packets. |
name |
str
|
str name of the interface as instantiated, for internal reference. |
station |
Station
|
Station the interface is initialized for. |
sudo |
bool
|
Whether this interface can be used for superuser connections. |
settings |
S
|
Current settings on the interface. |
Source code in pax25/interfaces/types.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
gateway: bool
property
¶
Whether this interface can be used to connect to the outside world.
listening: bool
property
¶
Returns a flag indicating that the interface is active and listening.
settings: S
property
¶
Returns a copy of our settings that's (mostly) safe to manipulate.
sudo: bool
property
¶
Whether connections from this interface should automatically be given administrative access.
__init__(name: str, settings: S, station: Station)
¶
Initialize the interface. The interface will be initialized with its name, settings, and the station it is being initialized for.
Under what conditions to set sudo is up to you, but it is set to False by default. The sudo flag indicates whether this interface can be used for superuser connections.
It does not automatically mean that connections on this interface will be treated as superuser connections, but the base Application class will consider a user a superuser if they are connected to an interface while its sudo flag is True, and their name matches the station's default name.
Source code in pax25/interfaces/types.py
install(station: Station, *, name: str, settings: S) -> Self
classmethod
¶
Installs this interface on a station.
Source code in pax25/interfaces/types.py
reload_settings(settings: S) -> None
async
¶
send_frame(frame: Frame) -> None
¶
Send this frame out on this interface.
NOTE: While this function is a synchronous function, the implementation must queue the frame for processing asynchronously. The reason is that if the frame is processed synchronously, it will be tied in with the same codepath that sent the frame. This can result in unpredictable behavior such as a connection sending out another frame before it has a chance to increase its frame counter.
Source code in pax25/interfaces/types.py
shutdown() -> None
async
¶
This handles any cleanup needed to bring this interface offline, closing whatever read loops are in effect.
start() -> None
¶
Interfaces should implement a 'start' function. This function should create the read-loop in a non-blocking manner-- specifically, it should create an async loop. See example implementations for how this is done.