Webserver

Note

This feature is available only with a License - Contact us for more details

The Virtual Machine contains a simple HTTP Web server than can be turned on to publish local files or run 'server side scripts'. It is in particular possible to map a URL path to a JavaScript Virtual Machine script that will be called.

WARNING:
Only a subset of the internal commands are available for published a JS Script. See the relevant section for reference.

How to use the WebServer:

  • Configure the scripting engine (via the .conf file in installation path) and specify the root folder (published as '/') and the TCP port to be used (by default, port is 8080)
  • The root path ("/") can be changed, and this MUST be done before the WebServer has been started. To do so, use the System.setWebRoot() function
  • If scripts have to be published, use the WebServer object and call the addHandler() method for each script to be exposed.
  • call the start() method.

Note

There is one unique WebServer running in the Virtual Machine. Different tasks can use the WebServer API and add handlers, but they all impact the same object. Typically, calling the start() method from two tasks will start the server only once...

Webserver object

object Webserver {
    constructor Webserver( [String a_name] );
    bool addHandler( string path, string handler_script [, bool password_required ] );
    bool removeHandler( string path );

    bool start();

    bool addUser( string user_login, string user_password) ;
    bool delUser( string user_login );

    bool publishQueue( string path, 'queue_name', format_specifier );
    bool publishDDC( string path, DDCBankChannel object );

    remoteControl( string path, string MBoxName );
    addIQUploadQueue( string path, string QueueName );

    // WebSocket management
    addWS( string path, string wstopic ) ;
    wsPost( string wstopic, Object data );
    wsPostIQSpectrum( string wstopic, IQData [, fft_size, rf_channel] ) ;

  }

.addHandler

Maps an existing JS script to a URL. Internally, the Virtual Machine will run a specific thread for this JS, accepting up to 10 concurrent connections.

Example :

We have a script callback.js like this:

sendResponse('Inside the callback<br/>');
var p = getParameter('name');
if( p.length > 0 ) {
    sendResponse('Hello:' + name );
}
We want this to be published as http://machine_adress:confirued_port/hello :

 var server = new WebServer('www');
 server.addHandler('/hello', 'callback.js');
 server.start();

Assuming we only want user john to be able to reach this page, we would have to do

 var server = new WebServer('www');
 server.addUser('john', 'a_password_for_john');
 server.addHandler('/hello', 'callback.js', true);
 server.start();

.removeHandler

.addUser

Adds or update a user definition.

bool addUser( string user_name, string user_password);

Passwords are stored (encrypted) in a file called 'passwords.txt' located in the conf folder.
The method returns true when the operation has been performed, raises an exception when parameters are not valid.

 var server = new WebServer('www');
 server.addUser('john', 'a_password_for_john');
 server.addUser('admin', 'a_password_for_admin');

.delUser

Delete credentials for one existing user.

bool delUser( string user_login );

.publishStream IQQueues

This function enables remote downloading of IQ data from a IQQueue. One task will produce the IQData and push them in an existing queue. When a htpp connection is received, the IQ samples will be sent using the given format. Multiple connections (10 max) are managed, the Virtual Machine handling IQ copy for the different users.

In this mode the script has to produce and push the IQ samples continuously.

 var server = new WebServer('www');
 server.publishStream( '/iq', 'rx_queue', 'CF32');

The following example servers a 100 kHz wide IQ channel from a RTLSDR receiver.

Data will be available as raw IQ CF32 on http://[address:port]/iq and can be downloaded with the following command :
curl -o test.cf32 http://host:8080/iq

// create working queues and objects
var fifo_from_rx = Queues.create( 'input'); 
var IQBlock = new IQData('iq');

// open RX 
var rx = Soapy.makeDevice( {'query' : 'driver=rtlsdr' });
if( rx.isAvailable() ) {
   // set sample rate
   if( rx.setRxSampleRate( 2e6 )) {
      print('Sample rate changed');
   }
} else {
   print('device is already used, we do not change Sampling Rate');
}

rx.setRxCenterFreq( 466.0 );

print('connect queue to receiver');
// engage streaming
if( !fifo_from_rx.ReadFromRx( rx ) ) {
    print('Cannot stream from rx');
    exit();
}

var ddcs = new DDCBank( rx, 2) ; 
var channel = ddcs.createChannel(100e3 );
channel.setOffset( 100e3 );

var w = new WebServer('demo');
w.publishQueue('/iq', 'web_queue', 'CF32'); 

// now connect to the web queue
var fifo_to_web = Queues.create( 'web_queue'); 
print('starting rx process, ');
if( channel.start() == false ) {
    print(' error starting channel ' );
    exit();
}
for( ; ; ) {
    var iq = channel.getIQ(true); // load samples from DDC queue into IQData object
    if( iq.getLength() == 0 ) {
        break ;
    }
    fifo_to_web.enqueue( iq );    // write the samples in the output queue
}

.publishDDC

In this mode, the Virtual Machine handles automatically the production of the IQ samples when required.

var rx = Soapy.makeDevice( {'query' : 'driver=rtlsdr' });
if( rx.isAvailable() ) {
   // set sample rate
   if( rx.setRxSampleRate( 2e6 )) {
      print('Sample rate changed');
   }
} else {
   print('device is already used, we do not change Sampling Rate');
}

rx.setRxCenterFreq( 466.0 );

print('Creating DDC');
var ddcs = new DDCBank( rx, 2) ; 
var channel = ddcs.createChannel(100e3 );
channel.setOffset( 100e3 );


print('Web config');
var w = new WebServer('demo');
w.publishDDC('/iq', channel, 'CF32'); 

print('Running.');
w.start();

Web Virtual Machine

The scripts published through the web server are running a specific version of the Virtual Machine for security reasons. Only a subset of commands are then available.

The following Modules are available in a Web script :

A typical Web script would then have to send instructions through MailBoxes to other 'normal' running tasks.

Instruction set

getParameter

sendHeader

sendResponse

load

print

MBoxPost

MBoxCheck

MBoxExists

MBoxPop

Last update: December 23, 2022