Open Source Wi-Fi Bluetooth Micro Router Project

Here is a continuation of the project on the S7V30 platform using microcontrollers of the Synergy family. In the previous article, a bootloader with cryptographic protection functions for the firmware and SD card was developed. In this project, we expand the functionality of our bootloader by adding cryptographic communication channels via Wi-Fi and Bluetooth. We try not to compromise between speed and functionality. We need a device that could provide Wi-Fi access point services, a Wi-Fi station, Bluetooth LE peripherals and a Bluetooth LE central unit, and all this simultaneously. In addition, we will make a backup connection to the Internet via USB and implement a virtual COM port via Bluetooth Classic. The network stack should operate in multi-interface mode, that is, each of the internal servers (FTP, HTTP, Telnet, etc.) is accessible from all connected IP interfaces. We will manage through a minimalistic web interface with TLS 1.3 encryption, and upgrade the firmware through it.

Previous articles on the topic

Data packaging

In small embedded systems, the limited amount of internal flash memory is always a problem. Our device requires several relatively large data blocks to load into the Wi-Fi Bluetooth module. In order not to use external memory chips or an SD card, these blocks must be placed in the internal flash. To make the data take up less space, we used a compression algorithm Sixpack. This algorithm is not much inferior to the best archivers on personal computers. Thanks to it, we were able to compress binary files loaded into the module by one and a half times.

To make the process of transferring images of downloaded files to the project sources in C easier, I created a script in Python – Pack_BLOBs.py. It is located in the directory Tools/BLOBs_packer. The result of the script is files Infineon_BLOBs.c And Infineon_BLOBs.hwhere binary data is represented by data arrays compressed by the Sixpack algorithm. The arrays' placement in the microcontroller's memory is fixed, and they can be used by the running application after it has been flashed by the bootloader. The prefix Infineon files have because all binaries are intended for a module implemented on a chipset from Infineon.

Modification of the web interface

Screenshot of a connected Wi-Fi station and Wi-Fi access point

Screenshot of a connected Wi-Fi station and Wi-Fi access point

Appearance ChatGPT changed everything. No longer do we need frameworks to work with JScript and the DOM model of HTML pages. In fact, these frameworks impose their design on us by offering a supposedly simplified API. ChatGPT makes it easy to understand the wilds of any API. Now we can generate source texts without relying on any auxiliary script libraries and style libraries. Therefore, from JQuery we refuse. We switch to pure JScript. This makes our device's website extremely compact. We no longer need an external drive for web interface files. Everything fits into the internal flash memory of the microcontroller. The total memory space occupied by compressed page files, scripts and styles is only 14 KB. The script for compressing all files and generating the source code in C for the built-in web server is here –Tools/WEB_compressor_to_C/Compres_web_files.py

However, the built-in server still has access to files on the SD card. If necessary, you can write additional pages, styles, scripts to the SD card in the www directory.

The small size of HTML pages is also due to the fact that dynamic creation of the settings panel is used. That is, the settings panel is initially an empty HTML file. During operation, the browser receives this file from the device and JSON file with a full description of the settings and, based on this, builds a dynamic panel with input and editing forms.

For ease of refactoring and modification, all pages are created as separate files using the templating technique in Adobe Dreamweaver. The source materials can be found in the directory \SDcard_content\www .

Parameterization

In the built-in EEPROM module contains a database of parameters. The database is created traditionally for our products by the utility EMBPMAN.exe.It is located in the directory /Tools/Parameters_generator. In this utility, parameters are created and edited, their characteristics and hierarchy are set. As a result, the utility generates a file in C with a database embedded in the project. The utility can also generate a JSON file for upgrading module parameters online. The database file itself on the PC is located in the file ParamsDB.mdb This is a native MS Office database format. That is, the parameters can be manipulated directly in the environment. MS Access.

View of utility for creating a database with device parameters

View of utility for creating a database with device parameters

How to restore bootloader parameters

Sometimes you have to experiment with the device parameters and need to roll back to the previous step. To do this, you need to restore the previous configuration of the parameters. To do this, you should write a JSON file with the desired configuration to the sd card. The JSON file can be prepared using a software utility EMBPMAN.exe. This is the same utility with which the parameters themselves are created. The file must have the name BSettins.JSON and be written to the root directory of the SD card. After the bootloader is launched, it reads the data from this file and, if parsing and writing to the flash is successful, erases the file. The device parameters are stored in the internal eeprom of the microcontroller in 2 duplicate areas protected by CRC32 code to detect random distortions.

In addition, the settings file can be created from the bootloader terminal menu. The file will have the name Psetins.json. In order for it to take effect, it must be renamed to BSettins.JSON.

Creating Certificates for TLS 1.3

The use of the modern network traffic encryption standard TLS 1.3 requires the use of elliptic curve certificates. The RSA algorithm for TLS 1.2 previously used in the bootloader is not suitable here.

The Synergy software package supports hardware encryption algorithm based on elliptic curves. But only for one type of curve – secp256r1. To avoid problems with the certificate for the device's web server, I created a command script – Tools/WEB_Сertificate_generation_with_EC_key/Certificates_generator.cmd. The configuration file for this script is also located there. The result of the script are secret keys and certificates for the client and server. The client in this case will be the user's PC browser. The server certificate is written to the flash memory of the device. To facilitate the task of converting certificates into arrays in the C language, a script was created in Python – Converter_to_C.py. As a result of the script's operation, the following files appear: WEB_server_certificate.c, WEB_server_certificate.h. They need to be added to the web server directory. These files are compiled together with the project.

To prevent browsers on the user's computer from issuing warnings about an invalid web server certificate, you need to import the generated client certificate CA.crt to the list of root certificates of the computer. Thanks to the client root certificate, browsers can establish encrypted secure communication with the device. Usually, a unique server certificate is generated for each device based on a single root certificate. Therefore, browsers are able to identify each client separately and a compromise of the server certificate does not lead to a compromise of all similar devices.

An important circumstanceThe configuration for generating the server certificate must contain the correct DNS and IP addresses by which the device will be accessed.

For example, these:

[ alternate_names ]

DNS.1       = localhost
DNS.2       = S7V30

IP.1 = 192.168.137.1
IP.2 = 192.168.1.1

Otherwise, even if the root self-signed certificate is imported into the browser system, the device's website will still be marked as unsafe.

For example, let's say the host name is set as S7V3 in the device settings and the mDNS service will distribute it across the network after connecting. Then the browser, accessing the name S7V3, will be able to open the page on the device, but it will be marked as unsafe. In order for it to be accepted as safe, the host name must be S7V30, i.e. correspond to the one specified in the certificate configuration in the example above.

And of course, the root certificate CA.crt is a secret and must be transmitted through secure, reliable channels.

Routing

Internet Protocol Stack NetX Duo as part of a real-time operating system Azure RTOS has two routing mechanisms.

The first mechanism is to set up direct routes from one interface to another using an API function nx_ip_static_route_add And nx_ip_static_route_delete.

In the second case, it is used NAT (Network Address Translation) server. NAT server allows one external IP address to access multiple nodes of the internal network. With the help of NAT server we can organize direct access from the Internet to each individual node in the internal network served by our device. The internal network can be organized either through USB CDC ECM Host interface, or through the interface WiFi access points. In this case, each device must have a unique port number within the internal network, through which it will be accessed.

An important condition for the operation of the NAT server in NetX Duo is the need to place all interfaces within one IP structure of the type NX_IP. How many different interfaces can a structure support? NX_IP configured when the stack is compiled.

If you create interfaces on different IP structures, then direct routing and NAT server will not work between them. These subnets will be completely isolated from each other. Which can also be useful.

Porting the Bluetooth stack

Because we use the module on the chip of the company Infineon then to organize the Bluetooth stack we take a library BTSTACK Library. The library is posted in the form of pre-compiled library files. There are many of them for different platforms. Our version lies here. This is a library for the IAR compiler for the ARM Cortex M4 microprocessor core with a hardware float-point coprocessor. Dual Mode here means that the library supports both the old Bluetooth Classic and the new Bluetooth LE

But one library is not enough, in addition to it, patches for a specific module and chip are needed. We take patches from here. Our module is a LWB5+ series module with the identifier 453-00045R. This is a module with one built-in antenna without antenna diversification. So the archive with the name is suitable for us laird-lwb5plus-sdio-sa-firmware-11.171.0.24.tar.bz2 . Modules can also be implemented with the diversification of two external antennas or with the implementation of the m2m or USB protocol. Therefore, you need to be careful when choosing the firmware.

The library from Infineon requires porting to a real-time operating system. Porting involves implementing about a dozen functions that use operating system services, including muticks, flags, and dynamic memory allocation operations. Infineon provides a separate library that facilitates porting – tstack-integration.

Majority porting examples implemented for the FreeRTOS operating system. You can find rare porting examples on RTOS ThreadX. RTOS ThreadX is a direct ancestor of Azure RTOS. Everything is of extremely dubious quality.

As part of the integration of WiFi and Bluetooth stacks from Infineon, I had to completely rewrite the porting layer to Azure RTOS. The drivers were significantly modified and their operation was accelerated. For communication via UART The module uses a mechanism DMA. The connection speed is equal to 4 mb/s. Bluetooth and Wi-Fi work in the module simultaneously and it has a special mechanism preventing conflicts between these two protocols. The porting layer is equipped with a debug output to the channel RTT via adapter SWD interface. Enabling or disabling debug output is controlled by a macro during compilation. There is also an output of diagnostic messages to a log file saved to the SD card. It is also controlled by a macro.

Since we have a Dual mode library, computers will see our module as two different devices when scanning the air. To communicate with the module, it is enough to bind to one of them. For the binding to be successful, you must press the BT3 button on the module before doing it. The module remembers the bound clients and there is no need to repeat the binding during subsequent connections.

BT3 button location

BT3 button location

Configuring Bluetooth Stack

After the stack is ported and starts working on our microcontroller, it needs to be given useful functions. Useful functions are defined by a database of a special format. In a modern Bluetooth stack, it is not customary to simply take and transmit data over the air. This was the case in earlier versions, in particular in a virtual COM port. Now any data sent via Bluetooth has a pre-defined meaning, type, access features and a unique long identifier. But there is no need to worry about the packaging and validity of data, to format them into packages or other artifacts. But you need to worry about variable identifiers, channel numbers, operation codes and data authentication. In addition, all operations become asynchronous. In short, everything has become more complicated in the name of interoperability. Therefore, it is not possible to simply manually organize data for exchange via Bluetooth. Special tools are used for this – database generators. The saddest thing is that the format of these databases for Bluetooth stacks from different manufacturers is seriously different.

In our case we use tools from Infineon. The Bluetooth database generator is not supplied separately. You need to download the entire ModusToolbox package. It will include the utility bt-configurator.exe. The path to it will look something like this: C:\Users\\ModusToolbox\tools_3.2\bt-configurator\bt-configurator.exe

The utility supports generation for several types of chips with different capabilities. Here you need to be careful with the choice of type. To make the task easier, I have created a ready-made configuration file for this utility – Infineon_BLE_config.cybt. If you open it in the utility, the required chip type will be selected automatically. To make it even easier, I created a link bt-configurator.lnk

Opening the utility via the link bt-configurator.lnk we will see the following window

Opening the utility via the link bt-configurator.lnk we will see the following window

To create profiles for modern Bluetooth 5, use the GATT Settings tab

To create a virtual COM port for Bluetooth Classic, use the Service Discovery Settings tab:

Don't forget to configure the service protocols L2CAP, PSM, BR/EDR ERTM:

The result of the utility will be the creation of a directory GeneratedSource with database files. These files will be overwritten every time you close the utility and should not be edited.

In this case, I created a custom service to manage the connection details of the Wi-Fi station to the access point.

Applications for working via Bluetooth

Infineon offers an app for Android and iOS – AIROC™ Bluetooth® Connect App. Sources for Android are lying here. The application is interesting primarily because of its open source code. It is easy to modify and compiles without problems in Android Studio. But it lacks some debugging properties.

Since modern standards Bluetooth LE is distinguished by its unique interoperability, then applications from any manufacturer are suitable for working with our module. For more subtle debugging of interaction via Bluetooth, I would recommend the program nRF Connectwhich is available for both desktops and mobile devices. There you can view detailed data exchange logs and bit fields of important structures.

Now let's try to take off with all this. Setting up task priorities.

Setting up task priorities is an important matter. The performance of the entire system and even the risk of it freezing may depend on how correctly the task priorities are set. The matter is complicated by the fact that many third-party libraries organize tasks with priorities set according to their own internal considerations. They do not agree with the order generally accepted in the application. This situation often forces one to resort to editing the source codes of third-party libraries.

As for the Azure RTOS operating system, task priorities are set in .h user configuration files. There they can simply be erased so as not to interfere.

In libraries from Infineon I'll also have to make some adjustments to remove the announcement of priorities in inappropriate places.

I have centralized the declaration of all priorities in one header file. thread_priorities.h. The central idea is that the main application tasks should have priority over all other auxiliary and communication tasks. How is the hard real-time requirement for the module's critical tasks met?

This is what we get as a result:

List of active tasks with their priorities in the IAR debugger

List of active tasks with their priorities in the IAR debugger

The whole project Here

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *