AX25Lib

Warning

This is a pure JavaScript AX25 lib.

The following objects are provided by this lib :

  • class AX25Frame
  • class HDLCDecoder

Note that :
* The frame serializer will add 5 sync symbols (0x7E) at the before the start;
* The frame serializer will add 16 bits at 0 after the end, to make sure the modem FIRs are empty (see Modem Intro)

AX25Frame

class AX25Frame {
    constructor AX25Frame();
    useNRZI( boolean enable );

    // Manage callsigns
    setSrc( string srcCallSign);
    getSrc();
    setDst( string dstCallSign);
    getDst();

    // 
    setPayload( array Payload );
    getPayload();

    //
    Array getHDLCBits() ; 
}

HDLCDecoder

class HDLCDecoder {
    constructor HDLCDecoder();
    useNRZI( boolean enable );
    bool rxBit( bit );
    AX25Frame getAX25Frame();
}

Example

// assuming here the AX25lib is available in your code folder
include('AX25lib.js');


//
function printBits( x ) {
    var l=0 ;
    var m = '' ;
    while( l < x.length  ) {

         for( var b=0 ; (b<8) && (l<x.length) ; b++,l++) {
              if( x[l]>0 ) {
                  m = m + '1' ;
              } else {
                  m = m + '0' ;
              }
         }
         m = m + ' ' ;

    }
    print(m);
}

/----------- Generate TX Data
// Generate 16 bytes message
var L = 8 ;
var msg = new Array(L) ;
for( var i=0 ; i < L ; i++ ) {
    msg[i] = i ;
}

var tx_frame = new AX25Frame();
tx_frame.setSrc('F4GKR');
tx_frame.setDst('F5OEO');
tx_frame.setPayload( msg );
tx_frame.useNRZI(use_nrzi);
var tx_bits = tx_frame.getHDLCBits();

var txmodem = new GMSKModem('tx') ;

var samples_per_symbol = 20 ;
var sample_rate = 48e3 ;
var filter_delay = 3 ;
var bt = .35 ;

var bitrate = sample_rate / samples_per_symbol ; 
print('GMSK params :');
print(' Sample rate:' + sample_rate + ' Hz');
print(' Speed : '  + bitrate + ' Bits per second.') ; 

txmodem.configure({
    'sps' : samples_per_symbol,
    'delay' : filter_delay,
    'bt' : bt
});
var IQ = txmodem.modulateBits( tx_bits ) ;
IQ.setSampleRate(sample_rate);
IQ.append( DSP.tone(100, 20*8, sample_rate) );
print('We transmit ' + tx_bits.length + ' bits'); 
//----------- Receive data
var rx_modem = new GMSKModem('rx');
rx_modem.configure({
    'sps' : samples_per_symbol,
    'delay' : filter_delay,
    'bt' : bt
});

var rx_bits = rx_modem.demodulate(IQ);

var hdlc = new HDLCDecoder();
hdlc.useNRZI(use_nrzi);
// Send received bits one by one to the HDLC parser
// if a frame is detected, rxBit returns true
for( var i=0 ; i < rx_bits.length ; i++ ) {
     var bit = rx_bits[i] ;
     if( hdlc.rxBit(bit) == true ) {
         // A frame has been received
         print('we have a frame');  
         var frx = hdlc.getAX25Frame();
         print( 'From: ['+frx.getSrc() + '] to [' + frx.getDst() + ']');
         var payload = frx.getPayload();
         print( 'Message is :');
         hexprint(payload);
         print( 'CRC received ok :' + ( hdlc.isCRCOk() ? 'yes':'no'));
     }
}

This will print :

(GMSK_AX25:0)> GMSK params :
(GMSK_AX25:0)>  Sample rate:48000 Hz
(GMSK_AX25:0)>  Speed : 2400 Bits per second.
(GMSK_AX25:0)> We transmit 312 bits
(GMSK_AX25:0)> we have a frame
(GMSK_AX25:0)> From: [F4GKR ] to [F5OEO ]
(GMSK_AX25:0)> Message is :
(GMSK_AX25:0)> 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 
(GMSK_AX25:0)> CRC received ok :yes

Last update: January 5, 2022