From Lantronix Wiki!
Revision as of 13:02, 3 March 2017 by Ltrxmg42 (talk | contribs)
Jump to navigation Jump to search


The 1.5 firmware release for the xPico Wi-Fi includes several new features, especially around the area of how to use the USB port that is native to the xPico Wi-Fi. In addition, since Lantronix has now created more network services and applications than what can fit in the flash of the xPico Wi-Fi, we have created a Windows application called "Packager" that lets you choose which modules to build into a firmware image, without having to install the full SDK to create your own firmware.



When you double click on the xPicoWifi_1.5.0.0R9_Package.exe, you will open a self-contained graphical application to build a custom firmware image.

For example, this picture shows building an image with AES encryption, the Discovery protocol, NTP, Tunnel, User_Data, the Mux, and Usb_Acm. Note that everything there but the Usb_Acm come in the standard image. That's because the standard image has Bridge and Usb_Rndis by default, which means the USB port is a network protocol.

With the image built per this picture, the USB port of the xPico Wi-Fi will appear as a third serial port.

New USB features

USB to SoftAP

With 1.4 firmware, we introduced the ability to use the xPico Wi-Fi as a network adapter over USB using RNDIS. See the USB to Wi-Fi guide. This allows you to bridge from a USB host with a network stack to the infrastructure network that the xPico Wi-Fi is connected to via the client interface. The SoftAP interface of the xPico Wi-Fi still remains for another device to connect locally and configure the xPico Wi-Fi.


With 1.5 firmware, the functionality is expanded to let you choose to bridge to either the client interface (wlan0) or the SoftAP interface (ap0). See this screenshot that shows how to configure the Bridge to use either interface (or disable it).

USB Serial

Another option that is new to 1.5 is to use the USB port on the xPico Wi-Fi as an additional serial port. This requires that you create a firmware image that includes the Usb_Acm module using either the SDK or the Packager.


When you build this module to the firmware, it will add a third Line, called Line CDC_ACM to the xPico Wi-Fi. Connecting the xPico Wi-Fi's USB port to a USB Host will enumerate as a USB CDC ACM which emulates a serial port. For example, in Windows, it will add a COM port with the built in driver. Most Linux distributions will also include drivers to be able to use it.

As you can see from the picture on the left, you can configure the Line CDC_ACM to use any of the protocols that you can use with one of the UART lines.

Filesystem to serial

Requires firmware or later!

This feature creates a filesystem node for the serial ports available on the device. For example on standard firmware, that means there's nodes at:

  • /dev/line_1
  • /dev/line_2

If you built in CDC_ACM support into the firmware, then you would also have:

  • /dev/line_CDC_ACM

So how is this useful? Set the Protocol for the Line to None, and then you can use any of the existing methods for reading/writing to the filesystem to instead read/write to the serial ports.

For example, if in Command Line Interface, you can write to another serial port like this:

  • file system
  • upload /dev/line_1

Then send whatever data you want to output to Line 1.

Or read from line 1:

  • file system
  • cat /dev/line_1

Using WebDAV to serial

The xPico Wi-Fi supports WebDAV commands via the Filesystem WebAPI. That means that you can write files to the filesystem by doing an HTTP PUT to /fs/ and then the subdirectory.

So if you want to send a file to the serial port from the network:

curl -u admin:PASSWORD -T example.txt

Or maybe you want to upload a file very fast from a custom webpage:

<!DOCTYPE html>


<div id="fileSection">
    <div>Pick a file to send to the serial port</div>
    <br />
    <input type="file" id="file" name="file" />
    <div id="props">
      <div style="float:left;margin-right:10px;">File name: </div><div id="fileName"></div>
      <div style="float:left;margin-right:10px;">File Size: </div><div id="fileSize" style="float:left;"></div>
           <div style="margin-left:5px;">kBytes</div>
    <button id="uploadFile" type="button" style="visibility:hidden;" onclick="uploadFile()">Upload file</button>

  <script id="worker1" type="javascript/worker">
	var MAX_SIZE = 1024*1024;
	var data;
	var url;
	var start;
	var end;
	var sendData = function() {
		var xmlHttp = new XMLHttpRequest();
		xmlHttp.open('PUT', url+'/fs/dev/line_1', false);
		xmlHttp.onreadystatechange=function() {
			if (xmlHttp.readyState==4) {
				if (xmlHttp.status==201) {
					self.postMessage({size: end});
					if (end < data.byteLength) {
						end = (end+MAX_SIZE) < data.byteLength ? end+MAX_SIZE : data.byteLength;
					} else {
  // This worker sends the file via an HTTP request on a separate thread
  // It's done this way to avoid the browser from thinking that the script 
  // is unresponsive if the file is large
    self.onmessage = function(e) {
		data = e.data.data;
		url = e.data.url;
		start = 0;
		end = MAX_SIZE < data.byteLength ? MAX_SIZE : data.byteLength;
	var file;
	var blob = new Blob([document.querySelector('#worker1').textContent]);
	var worker = new Worker(window.URL.createObjectURL(blob));
	worker.onmessage = function(e) {
  var uploadFile = function() {
    var reader = new FileReader();
    reader.onloadend = function(e) {	// Called when we're done reading the file
      if (e.target.readyState == FileReader.DONE) {	 
		// Start the worker.
		worker.postMessage({data:e.target.result, url: window.location.protocol+'//'+window.location.hostname}, [e.target.result]); 
    reader.readAsArrayBuffer(file);	// Start the loading of the file as an arraybuffer
  function handleFileSelect(evt) {
    file = evt.target.files[0]; // File object
    document.getElementById("fileName").innerHTML = file.name
    document.getElementById("fileSize").innerHTML = (file.size/1024).toFixed(2);
    document.getElementById("uploadFile").style.visibility = "visible";
  window.onload = function() {
    // Check for the various File API support.
    if (window.File && window.FileReader && window.FileList && window.Blob) {
      document.getElementById('file').addEventListener('change', handleFileSelect, false);
    } else {
      alert('The File APIs are not fully supported in this browser.');


User level access controls

Requires firmware or later!

This feature allows you to have different access rights for different areas of the web server. For example, you might have an administrator who can change configuration, while you have a user that can view other files.

There are 4 levels of privileges for web pages: Admin, Tech, User, or None.

Setting privilege levels


You can configure a URI to a specific privilege level in the HTTP Server tab, under Security options. Here you can add multiple URIs, each with a different Authorization Type:

  • Digest to use the MD5 hashed authentication with a session nonce
  • Basic to use the Base64 encoded password
  • None to require no authentication

A common use case is to have the configuration web pages secured with the Admin role (which is the default for any URI not specified, including /) and your custom pages not secured. In that case, you would select None for your pages.

Here you can also configure which User Level has access to your URI: Admin, Tech, User, or None. In the case of None, no user has access to that URI.

Creating users


By default, the xPico Wi-Fi only has one user, the admin.