By dave | August 2, 2019

Menu library remote connectivity tutorial

TcMenu has considerable out of the box remote connectivity on Arduino. Supporting Ethernet2 library, UipEthernet library, ESP8266 WiFi, ESP32 WiFi and Serial (including Bluetooth Serial). It is recommended that this guide is read in conjunction with the embedded library reference docs.

A typical remote menu application designed using the library will be able to accept connections from any source that can communicate using TagVal protocol. On the Arduino side, there will be an object instance named remoteServer provided by the plugin. This instance will look after one or more remote connections, each of which are represented by an instance of TagValueRemoteConnector. Each connector is given a number, with the first one being 0 and so on. TcMenu embedded library can theoretically handle up to 6 such connections at the moment. In most cases, memory and hardware constraints would probably hit much sooner than that.

Each connector needs a transport, which at the moment is always TagValueTransport and a CombinedMessageProcessor to handle incoming messages. For ethernet builds the remoteServer variable is of type EthernetTagValServer and SerialTagValServer for serial builds.

Authentication in tcMenu is actually achieved by the client application sending the name and UUID field while joining. No messages other than heartbeats can be processed until the join is successfully completed. During join message processing the provided details are passed to the currently setup authentication manager, that will either allow or deny the connection.

It should be noted that TagVal is presently not encrypted and only suitable for use in local area networks. There is a plan to provide optional encryption components soon.

There is a second type of connection called pairing, this is used to add another application (name and UUID pair) to the list of allowed connections. In this mode the Arduino / embedded device immediately shows the following dialog upon receiving a pairing request. Only when the ACCEPT button is pressed will the new application credentials be stored.

device: pairing mode

Pairing mode on the embedded device

Setting up an Authentication Manager

Remote Authentication is achieved by providing the remoteServer with an instance of AuthenticationManager using the setAuthenticator(AuthenticationManager* authManager) method. By default the remoteServer will not provide any authentication, creating an instance of NoAuthenticationManager on demand.

When authentication is required, persisted to EEPROM

If you want to support authentication and save the credentials that have been paired between power offs, then use the EepromAuthenticatorManager; which supports loading and saving to a given location in EEPROM. By default the class can store up to 6 pairs of credentials, but can be adjusted by providing the desired number in the constructor. Each pairing uses about 60 bytes of EEPROM. In addition to this, an additional 16 bytes are allocated for the secure menu password. This is the password that must be matched to enter any secure menu. The initial secure menu password is 1234.

The first parameter to initialise below is an EepromAbstraction object, see AVR and Arduino EEPROM example and I2C AT24 EEPROM example. Also see the ESP tcMenu packaged example that shows how to use the EEPROM class with ESP8266 / ESP32.

// Variable declaration - must be globally visible
EepromAuthenticatorManager eepromAuth;

// then during setup
eepromAuth.initialise(&eepromAbstraction, startLocationInRom);
remoteServer.setAuthenticator(&eepromAuth); 

When no authentication is required

If you don’t want any authentication whatsoever, there is nothing to do, that is the default state in the remoteServer. However, if you want to be explicit, you set up as follows:

// Variable declaration - must be globally visible
NoAuthenticationManager noAuth;

// then during setup
remoteServer.setAuthenticator(&noAuth); 

When upfront readonly authentication is required

If you want to authenticate against a few known application instances (name, UUID pairs), without allowing pairing of additional devices then you can use the the ReadOnlyAuthenticationManager. To use it we simply create an array of AuthBlock and pass it to the constructor.

// Variable declarations - must be globally visible
const AuthBlock authBlocks[] PROGMEM = {
    { "name1", "11111111-1111-1111-1111-111111111111" }, 
    { "name2", "22222222-2222-2222-2222-222222222222" }
};
int authArrayLength = 2;
const char secureMenuPassword[] PROGMEM = "1234";
ReadOnlyAuthenticationManager roAuth(authBlocks, authArrayLength, secureMenuPassword);

// then during setup
remoteServer.setAuthenticator(&roAuth);

Alternatively, if you are not interested in any remote pairings, but just want a read only authenticator to deal with secure menu passwords, simply construct as follows instead:

const char secureMenuPassword[] PROGMEM = "1234";
ReadOnlyAuthenticationManager roAuth(secureMenuPassword);

This second variant will not authenticate any remote clients, but will provide secure menu authentication.

Adding connectivity and authentication management menu items

It is also possible to add connectivity menu items your menu. There are several available options, including RemoteMenuItem that displays all current connections and EepromAuthenicationInfoMenuItem that displays all current authentication pairs. Both of these items are runtime menu items so can easily be added in code as follows.

Let’s assume there is a menu item called menuConnectivity, of type submenu with one child item named menuIpAddress. We will now add two more items to manage the connections and authentication.

// Here we create two additional menus, that will be added manually to handle the connectivity
// status and authentication keys. We link the authentication item to the remote monitor item.
// These are created as globals.
RemoteMenuItem menuRemoteMonitor(1001, 2);
EepromAuthenicationInfoMenuItem menuAuthKeyMgr(1002, &authManager, &menuRemoteMonitor);

// later in setup..
 
// here we link our new menus with the existing menu (menuIpAddress)
menuIpAddress.setNext(&menuAuthKeyMgr);

// and we add the first connector to the monitor
menuRemoteMonitor.addConnector(remoteServer.getRemoteConnector(0));

// The remote menu item will take over as comms listener, ONLY if you also need to 
// listen for comms changes, daisy chain as follows
menuRemoteMonitor.registerCommsNotification(onCommsChange);

// and lastly you really don't want the authenication information going to remotes.
menuAuthKeyMgr.setLocalOnly(true);

Back to tcMenu main page

Other pages within this category

comments powered by Disqus

We use cookies to analyse traffic and to personalise content. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Please see our privacy policy should you need more information or wish to adjust your settings.

Send a message
X

This message will be securely transmitted to Nutricherry LTD servers.