acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

AX25.h (13812B)

      1 #if !defined(_RADIOLIB_RADIOLIB_AX25_H)
      2 #define _RADIOLIB_RADIOLIB_AX25_H
      3 
      4 #include "../../TypeDef.h"
      5 
      6 #if !defined(RADIOLIB_EXCLUDE_AX25)
      7 
      8 #include "../PhysicalLayer/PhysicalLayer.h"
      9 #include "../AFSK/AFSK.h"
     10 
     11 // macros to access bits in byte array, from http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html
     12 #define SET_BIT_IN_ARRAY(A, k)                                  ( A[(k/8)] |= (1 << (k%8)) )
     13 #define CLEAR_BIT_IN_ARRAY(A, k)                                ( A[(k/8)] &= ~(1 << (k%8)) )
     14 #define TEST_BIT_IN_ARRAY(A, k)                                 ( A[(k/8)] & (1 << (k%8)) )
     15 #define GET_BIT_IN_ARRAY(A, k)                                  ( (A[(k/8)] & (1 << (k%8))) ? 1 : 0 )
     16 
     17 // CRC-CCITT calculation macros
     18 #define XOR(A, B)                                               ( ((A) || (B)) && !((A) && (B)) )
     19 #define CRC_CCITT_POLY                                          0x1021      //  generator polynomial
     20 #define CRC_CCITT_POLY_REVERSED                                 0x8408      //  CRC_CCITT_POLY in reversed bit order
     21 #define CRC_CCITT_INIT                                          0xFFFF      //  initial value
     22 
     23 // maximum callsign length in bytes
     24 #define RADIOLIB_AX25_MAX_CALLSIGN_LEN                          6
     25 
     26 // flag field                                                         MSB   LSB   DESCRIPTION
     27 #define RADIOLIB_AX25_FLAG                                      0b01111110  //  7     0     AX.25 frame start/end flag
     28 
     29 // address field
     30 #define RADIOLIB_AX25_SSID_COMMAND_DEST                         0b10000000  //  7     7     frame type: command (set in destination SSID)
     31 #define RADIOLIB_AX25_SSID_COMMAND_SOURCE                       0b00000000  //  7     7                 command (set in source SSID)
     32 #define RADIOLIB_AX25_SSID_RESPONSE_DEST                        0b00000000  //  7     7                 response (set in destination SSID)
     33 #define RADIOLIB_AX25_SSID_RESPONSE_SOURCE                      0b10000000  //  7     7                 response (set in source SSID)
     34 #define RADIOLIB_AX25_SSID_HAS_NOT_BEEN_REPEATED                0b00000000  //  7     7                 not repeated yet (set in repeater SSID)
     35 #define RADIOLIB_AX25_SSID_HAS_BEEN_REPEATED                    0b10000000  //  7     7                 repeated (set in repeater SSID)
     36 #define RADIOLIB_AX25_SSID_RESERVED_BITS                        0b01100000  //  6     5     reserved bits in SSID
     37 #define RADIOLIB_AX25_SSID_HDLC_EXTENSION_CONTINUE              0b00000000  //  0     0     HDLC extension bit: next octet contains more address information
     38 #define RADIOLIB_AX25_SSID_HDLC_EXTENSION_END                   0b00000001  //  0     0                         address field end
     39 
     40 // control field
     41 #define RADIOLIB_AX25_CONTROL_U_SET_ASYNC_BAL_MODE              0b01101100  //  7     2     U frame type: set asynchronous balanced mode (connect request)
     42 #define RADIOLIB_AX25_CONTROL_U_SET_ASYNC_BAL_MODE_EXT          0b00101100  //  7     2                   set asynchronous balanced mode extended (connect request with module 128)
     43 #define RADIOLIB_AX25_CONTROL_U_DISCONNECT                      0b01000000  //  7     2                   disconnect request
     44 #define RADIOLIB_AX25_CONTROL_U_DISCONNECT_MODE                 0b00001100  //  7     2                   disconnect mode (system busy or disconnected)
     45 #define RADIOLIB_AX25_CONTROL_U_UNNUMBERED_ACK                  0b01100000  //  7     2                   unnumbered acknowledge
     46 #define RADIOLIB_AX25_CONTROL_U_FRAME_REJECT                    0b10000100  //  7     2                   frame reject
     47 #define RADIOLIB_AX25_CONTROL_U_UNNUMBERED_INFORMATION          0b00000000  //  7     2                   unnumbered information
     48 #define RADIOLIB_AX25_CONTROL_U_EXHANGE_IDENTIFICATION          0b10101100  //  7     2                   exchange ID
     49 #define RADIOLIB_AX25_CONTROL_U_TEST                            0b11100000  //  7     2                   test
     50 #define RADIOLIB_AX25_CONTROL_POLL_FINAL_ENABLED                0b00010000  //  4     4     control field poll/final bit: enabled
     51 #define RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED               0b00000000  //  4     4                                   disabled
     52 #define RADIOLIB_AX25_CONTROL_S_RECEIVE_READY                   0b00000000  //  3     2     S frame type: receive ready (system ready to receive)
     53 #define RADIOLIB_AX25_CONTROL_S_RECEIVE_NOT_READY               0b00000100  //  3     2                   receive not ready (TNC buffer full)
     54 #define RADIOLIB_AX25_CONTROL_S_REJECT                          0b00001000  //  3     2                   reject (out of sequence or duplicate)
     55 #define RADIOLIB_AX25_CONTROL_S_SELECTIVE_REJECT                0b00001100  //  3     2                   selective reject (single frame repeat request)
     56 #define RADIOLIB_AX25_CONTROL_INFORMATION_FRAME                 0b00000000  //  0     0     frame type: information (I frame)
     57 #define RADIOLIB_AX25_CONTROL_SUPERVISORY_FRAME                 0b00000001  //  1     0                 supervisory (S frame)
     58 #define RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME                  0b00000011  //  1     0                 unnumbered (U frame)
     59 
     60 // protocol identifier field
     61 #define RADIOLIB_AX25_PID_ISO_8208                              0x01
     62 #define RADIOLIB_AX25_PID_TCP_IP_COMPRESSED                     0x06
     63 #define RADIOLIB_AX25_PID_TCP_IP_UNCOMPRESSED                   0x07
     64 #define RADIOLIB_AX25_PID_SEGMENTATION_FRAGMENT                 0x08
     65 #define RADIOLIB_AX25_PID_TEXNET_DATAGRAM_PROTOCOL              0xC3
     66 #define RADIOLIB_AX25_PID_LINK_QUALITY_PROTOCOL                 0xC4
     67 #define RADIOLIB_AX25_PID_APPLETALK                             0xCA
     68 #define RADIOLIB_AX25_PID_APPLETALK_ARP                         0xCB
     69 #define RADIOLIB_AX25_PID_ARPA_INTERNET_PROTOCOL                0xCC
     70 #define RADIOLIB_AX25_PID_ARPA_ADDRESS_RESOLUTION               0xCD
     71 #define RADIOLIB_AX25_PID_FLEXNET                               0xCE
     72 #define RADIOLIB_AX25_PID_NET_ROM                               0xCF
     73 #define RADIOLIB_AX25_PID_NO_LAYER_3                            0xF0
     74 #define RADIOLIB_AX25_PID_ESCAPE_CHARACTER                      0xFF
     75 
     76 // AFSK tones in Hz
     77 #define RADIOLIB_AX25_AFSK_MARK                                 1200
     78 #define RADIOLIB_AX25_AFSK_SPACE                                2200
     79 
     80 // tone duration in us (for 1200 baud AFSK)
     81 #define RADIOLIB_AX25_AFSK_TONE_DURATION                        833
     82 
     83 /*!
     84   \class AX25Frame
     85 
     86   \brief Abstraction of AX.25 frame format.
     87 */
     88 class AX25Frame {
     89   public:
     90     /*!
     91       \brief Callsign of the destination station.
     92     */
     93     char destCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1];
     94 
     95     /*!
     96       \brief SSID of the destination station.
     97     */
     98     uint8_t destSSID;
     99 
    100     /*!
    101       \brief Callsign of the source station.
    102     */
    103     char srcCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1];
    104 
    105     /*!
    106       \brief SSID of the source station.
    107     */
    108     uint8_t srcSSID;
    109 
    110     /*!
    111       \brief Number of repeaters to be used.
    112     */
    113     uint8_t numRepeaters;
    114 
    115     /*!
    116       \brief The control field.
    117     */
    118     uint8_t control;
    119 
    120     /*!
    121       \brief The protocol identifier (PID) field.
    122     */
    123     uint8_t protocolID;
    124 
    125     /*!
    126       \brief Number of bytes in the information field.
    127     */
    128     uint16_t infoLen;
    129 
    130     /*!
    131       \brief Receive sequence number.
    132     */
    133     uint8_t rcvSeqNumber;
    134 
    135     /*!
    136       \brief Send sequence number.
    137     */
    138     uint16_t sendSeqNumber;
    139 
    140     #if !defined(RADIOLIB_STATIC_ONLY)
    141       /*!
    142         \brief The info field.
    143       */
    144       uint8_t* info;
    145 
    146       /*!
    147         \brief Array of repeater callsigns.
    148       */
    149       char** repeaterCallsigns;
    150 
    151       /*!
    152         \brief Array of repeater SSIDs.
    153       */
    154       uint8_t* repeaterSSIDs;
    155     #else
    156       /*!
    157         \brief The info field.
    158       */
    159       uint8_t info[RADIOLIB_STATIC_ARRAY_SIZE];
    160 
    161       /*!
    162         \brief Array of repeater callsigns.
    163       */
    164       char repeaterCallsigns[8][RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1];
    165 
    166       /*!
    167         \brief Array of repeater SSIDs.
    168       */
    169       uint8_t repeaterSSIDs[8];
    170     #endif
    171 
    172     /*!
    173       \brief Overloaded constructor, for frames without info field.
    174 
    175       \param destCallsign Callsign of the destination station.
    176 
    177       \param destSSID SSID of the destination station.
    178 
    179       \param srcCallsign Callsign of the source station.
    180 
    181       \param srcSSID SSID of the source station.
    182 
    183       \param control The control field.
    184     */
    185     AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control);
    186 
    187     /*!
    188       \brief Overloaded constructor, for frames with C-string info field.
    189 
    190       \param destCallsign Callsign of the destination station.
    191 
    192       \param destSSID SSID of the destination station.
    193 
    194       \param srcCallsign Callsign of the source station.
    195 
    196       \param srcSSID SSID of the source station.
    197 
    198       \param control The control field.
    199 
    200       \param protocolID The protocol identifier (PID) field. Set to zero if the frame doesn't have this field.
    201 
    202       \param info Information field, in the form of null-terminated C-string.
    203     */
    204     AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, const char* info);
    205 
    206     /*!
    207       \brief Default constructor.
    208 
    209       \param destCallsign Callsign of the destination station.
    210 
    211       \param destSSID SSID of the destination station.
    212 
    213       \param srcCallsign Callsign of the source station.
    214 
    215       \param srcSSID SSID of the source station.
    216 
    217       \param control The control field.
    218 
    219       \param protocolID The protocol identifier (PID) field. Set to zero if the frame doesn't have this field.
    220 
    221       \param info Information field, in the form of arbitrary binary buffer.
    222 
    223       \param infoLen Number of bytes in the information field.
    224     */
    225     AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, uint8_t* info, uint16_t infoLen);
    226 
    227     /*!
    228       \brief Copy constructor.
    229 
    230       \param frame AX25Frame instance to copy.
    231     */
    232     AX25Frame(const AX25Frame& frame);
    233 
    234     /*!
    235       \brief Default destructor.
    236     */
    237     ~AX25Frame();
    238 
    239     /*!
    240       \brief Overload for assignment operator.
    241 
    242       \param frame rvalue AX25Frame.
    243     */
    244     AX25Frame& operator=(const AX25Frame& frame);
    245 
    246     /*!
    247       \brief Method to set the repeater callsigns and SSIDs.
    248 
    249       \param repeaterCallsigns Array of repeater callsigns in the form of null-terminated C-strings.
    250 
    251       \param repeaterSSIDs Array of repeater SSIDs.
    252 
    253       \param numRepeaters Number of repeaters, maximum is 8.
    254 
    255       \returns \ref status_codes
    256     */
    257     int16_t setRepeaters(char** repeaterCallsigns, uint8_t* repeaterSSIDs, uint8_t numRepeaters);
    258 
    259     /*!
    260       \brief Method to set receive sequence number.
    261 
    262       \param seqNumber Sequence number to set, 0 to 7.
    263     */
    264     void setRecvSequence(uint8_t seqNumber);
    265 
    266     /*!
    267       \brief Method to set send sequence number.
    268 
    269       \param seqNumber Sequence number to set, 0 to 7.
    270     */
    271     void setSendSequence(uint8_t seqNumber);
    272 };
    273 
    274 /*!
    275   \class AX25Client
    276 
    277   \brief Client for AX25 communication.
    278 */
    279 class AX25Client {
    280   public:
    281     /*!
    282       \brief Constructor for 2-FSK mode.
    283 
    284       \param phy Pointer to the wireless module providing PhysicalLayer communication.
    285     */
    286     explicit AX25Client(PhysicalLayer* phy);
    287 
    288     #if !defined(RADIOLIB_EXCLUDE_AFSK)
    289     /*!
    290       \brief Constructor for AFSK mode.
    291 
    292       \param audio Pointer to the AFSK instance providing audio.
    293     */
    294     explicit AX25Client(AFSKClient* audio);
    295 
    296     /*!
    297       \brief Set AFSK tone correction offset. On some platforms, this is required to get the audio produced by the setup to match the expected 1200/2200 Hz tones.
    298 
    299       \param mark Positive or negative correction offset for mark audio frequency in Hz.
    300 
    301       \param space Positive or negative correction offset for space audio frequency in Hz.
    302 
    303       \returns \ref status_codes
    304     */
    305     int16_t setCorrection(int16_t mark, int16_t space);
    306     #endif
    307 
    308     // basic methods
    309 
    310     /*!
    311       \brief Initialization method.
    312 
    313       \param srcCallsign Callsign of the source station.
    314 
    315       \param srcSSID 4-bit SSID of the source station (in case there are more stations with the same callsign). Defaults to 0.
    316 
    317       \param preambleLen Number of "preamble" bytes (RADIOLIB_AX25_FLAG) sent ahead of the actual AX.25 frame. Does not include the first RADIOLIB_AX25_FLAG byte, which is considered part of the frame. Defaults to 8.
    318 
    319       \returns \ref status_codes
    320     */
    321     int16_t begin(const char* srcCallsign, uint8_t srcSSID = 0x00, uint8_t preambleLen = 8);
    322 
    323     /*!
    324       \brief Transmit unnumbered information (UI) frame.
    325 
    326       \param str Data to be sent.
    327 
    328       \param destCallsign Callsign of the destination station.
    329 
    330       \param destSSID 4-bit SSID of the destination station (in case there are more stations with the same callsign). Defaults to 0.
    331 
    332       \returns \ref status_codes
    333     */
    334     int16_t transmit(const char* str, const char* destCallsign, uint8_t destSSID = 0x00);
    335 
    336     /*!
    337       \brief Transmit arbitrary AX.25 frame.
    338 
    339       \param frame Frame to be sent.
    340 
    341       \returns \ref status_codes
    342     */
    343     int16_t sendFrame(AX25Frame* frame);
    344 
    345 #if !defined(RADIOLIB_GODMODE)
    346   private:
    347 #endif
    348     friend class APRSClient;
    349 
    350     PhysicalLayer* _phy;
    351     #if !defined(RADIOLIB_EXCLUDE_AFSK)
    352     AFSKClient* _audio;
    353     uint32_t _afskMark;
    354     uint32_t _afskSpace;
    355     #endif
    356 
    357     char _srcCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1] = {0, 0, 0, 0, 0, 0, 0};
    358     uint8_t _srcSSID = 0;
    359     uint16_t _preambleLen = 0;
    360 
    361     static uint16_t getFrameCheckSequence(uint8_t* buff, size_t len);
    362 
    363     void getCallsign(char* buff);
    364     uint8_t getSSID();
    365 };
    366 
    367 #endif
    368 
    369 #endif