Monthly Archives: April 2021

Studying MicroPython’s Serial REPL

The beauty of Unix philosophy: piping data from one simple program to another, to do great work 😉

Sniffing the serial port to know better MicroPython Serial REPL (https://docs.micropython.org/en/latest/reference/repl.html) protocol:

echo 123 > test.txt
strace -s9999 -o output.log -eread,write ampy -p /dev/ttyACM put test.txt

Result:
read(9, “123\n”, 4096) = 4
read(9, “”, 4096) = 0
write(3, “\r\3\3”, 3) = 3
write(3, “\r\1”, 2) = 2
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “\4”, 1) = 1
read(3, “O”, 1) = 1
read(3, “K”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “M”, 1) = 1
read(3, “P”, 1) = 1
read(3, “Y”, 1) = 1
read(3, “:”, 1) = 1
read(3, ” “, 1) = 1
read(3, “s”, 1) = 1
read(3, “o”, 1) = 1
read(3, “f”, 1) = 1
read(3, “t”, 1) = 1
read(3, ” “, 1) = 1
read(3, “r”, 1) = 1
read(3, “e”, 1) = 1
read(3, “b”, 1) = 1
read(3, “o”, 1) = 1
read(3, “o”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
write(3, “\3”, 1) = 1
write(3, “\3”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “f = open(‘test.txt’, ‘wb’)”, 26) = 26
write(3, “\4”, 1) = 1
read(3, “OK”, 2) = 2
read(3, “\4”, 1) = 1
read(3, “\4”, 1) = 1
read(3, “>”, 1) = 1
write(3, “f.write(b’123\\n’)”, 17) = 17
write(3, “\4”, 1) = 1
read(3, “OK”, 2) = 2
read(3, “\4”, 1) = 1
read(3, “\4”, 1) = 1
read(3, “>”, 1) = 1
write(3, “f.close()”, 9) = 9
write(3, “\4”, 1) = 1
read(3, “OK”, 2) = 2
read(3, “\4”, 1) = 1
read(3, “\4”, 1) = 1
write(3, “\r\2”, 2) = 2
+++ exited with 0 +++

strace -s9999 -o output.log -eread,write ampy -p /dev/ttyACM1 ls

Result:
write(3, “\r\3\3”, 3) = 3
write(3, “\r\1”, 2) = 2
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “\4”, 1) = 1
read(3, “O”, 1) = 1
read(3, “K”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “M”, 1) = 1
read(3, “P”, 1) = 1
read(3, “Y”, 1) = 1
read(3, “:”, 1) = 1
read(3, ” “, 1) = 1
read(3, “s”, 1) = 1
read(3, “o”, 1) = 1
read(3, “f”, 1) = 1
read(3, “t”, 1) = 1
read(3, ” “, 1) = 1
read(3, “r”, 1) = 1
read(3, “e”, 1) = 1
read(3, “b”, 1) = 1
read(3, “o”, 1) = 1
read(3, “o”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
write(3, “\3”, 1) = 1
write(3, “\3”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “try: \n import os\nexcept ImportError:\n import uos as os\ndef listdir(directory):\n if directory == ‘/’: \n return sorted([directory + f for f in os.listdir(directory)])\n else:\n return sorted([directory + ‘/’ + f “, 256) = 256
write(3, “for f in os.listdir(directory)])\n\nprint(listdir(‘/’))\n”, 54) = 54
write(3, “\4”, 1) = 1
read(3, “OK”, 2) = 2
read(3, “[“, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “/”, 1)                         = 1
read(3, “f”, 1)                         = 1
read(3, “i”, 1)                         = 1
read(3, “l”, 1)                         = 1
read(3, “e”, 1)                         = 1
read(3, “.”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “x”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “,”, 1)                         = 1
read(3, ” “, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “/”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “e”, 1)                         = 1
read(3, “s”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “.”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “x”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “,”, 1)                         = 1
read(3, ” “, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “/”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “e”, 1)                         = 1
read(3, “s”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “1”, 1)                         = 1
read(3, “.”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “x”, 1)                         = 1
read(3, “t”, 1)                         = 1
read(3, “‘”, 1)                         = 1
read(3, “]”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “\4”, 1) = 1
read(3, “\4”, 1) = 1
write(3, “\r\2”, 2) = 2
write(1, “/file.txt\n”, 10) = 10
write(1, “/test.txt\n”, 10) = 10
write(1, “/test1.txt\n”, 11) = 11
+++ exited with 0 +++

strace -s9999 -o output.log -eread,write ampy -p /dev/ttyACM1 get test.txt

Result:
write(3, “\r\3\3”, 3) = 3
write(3, “\r\1”, 2) = 2
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, “>”, 1) = 1
read(3, ” “, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “\4”, 1) = 1
read(3, “O”, 1) = 1
read(3, “K”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “M”, 1) = 1
read(3, “P”, 1) = 1
read(3, “Y”, 1) = 1
read(3, “:”, 1) = 1
read(3, ” “, 1) = 1
read(3, “s”, 1) = 1
read(3, “o”, 1) = 1
read(3, “f”, 1) = 1
read(3, “t”, 1) = 1
read(3, ” “, 1) = 1
read(3, “r”, 1) = 1
read(3, “e”, 1) = 1
read(3, “b”, 1) = 1
read(3, “o”, 1) = 1
read(3, “o”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
write(3, “\3”, 1) = 1
write(3, “\3”, 1) = 1
read(3, “r”, 1) = 1
read(3, “a”, 1) = 1
read(3, “w”, 1) = 1
read(3, ” “, 1) = 1
read(3, “R”, 1) = 1
read(3, “E”, 1) = 1
read(3, “P”, 1) = 1
read(3, “L”, 1) = 1
read(3, “;”, 1) = 1
read(3, ” “, 1) = 1
read(3, “C”, 1) = 1
read(3, “T”, 1) = 1
read(3, “R”, 1) = 1
read(3, “L”, 1) = 1
read(3, “-“, 1) = 1
read(3, “B”, 1) = 1
read(3, ” “, 1) = 1
read(3, “t”, 1) = 1
read(3, “o”, 1) = 1
read(3, ” “, 1) = 1
read(3, “e”, 1) = 1
read(3, “x”, 1) = 1
read(3, “i”, 1) = 1
read(3, “t”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “>”, 1) = 1
write(3, “\nimport sys\nwith open(‘test.txt’, ‘rb’) as infile:\n while True:\n result = infile.read(32)\n if result == b”:\n break\n len = sys.stdout.write(result)\n”, 183) = 183
write(3, “\4”, 1) = 1
read(3, “OK”, 2) = 2
read(3, “1”, 1) = 1
read(3, “2”, 1) = 1
read(3, “3”, 1) = 1
read(3, “\r”, 1) = 1
read(3, “\n”, 1) = 1
read(3, “\4”, 1) = 1
read(3, “\4”, 1) = 1
write(3, “\r\2”, 2) = 2
write(1, “123\r\n”, 5) = 5
write(1, “\n”, 1) = 1
+++ exited with 0 +++

Optional:
-eread,write,ioctl

First, useful codes:
(http://www.physics.udel.edu/~watson/scen103/ascii.html)
Decimal | Ctrl char
1 | Ctrl+A
2 | Ctrl+B
3 | Ctrl+C
4 | Ctrl+D
5 | Ctrl+E

Some common conclusions (for the 3 tested cases):
1. Send Ctrl+C (3) twice
2. Send Ctrl+A (1) once
3. Wait for the message “raw REPL; CTRL-B to exit”
4. Send Ctrl+D (4)
5. Wait for “MPY: soft reboot”
6. Send Ctrl+C (3) twice again
7. Wait for the message “raw REPL; CTRL-B to exit”

8. Send the command / file, followed by Ctrl+D (4)
9. Repeat 8 as needed
10. To finish, send \r followed by Ctrl+B (2)

Wired Android Internet access without Wifi or 4G connections

My wife Silvia has been doing a systematic study about biological effects of wireless technologies on human health for some time now. Some publications are controversial, but we like to take the precautionary principle. More information about her studies is available at the website http://celularesaude.org/.

She is also collaborating with the SlowPhone moviment, and they are gathering really interesting information and promoting live events with prominent scientists in this area, such as Dr. Magda Havas and MSc. Sheena Symington.

More information about SlowPhone can be found at their YouTube channel:

www.youtube.com/Slowphone

In that context, she asked me for some way to use our smartphones at home in “Airplane mode”, but still with Internet access, which means, a wired connection. First, note that there are some proprietary / commercial solutions on the market, such as Ethernet Adapters for Android and Apple devices. However, it is possible to build your own solution using low cost hardware, or simply using your PC, so no hardware purchases are needed.

One of the best solutions I found is based on the Open Source Software gnirehtet (https://github.com/Genymobile/gnirehtet). You can download and use it to share your computer Internet connection with your phone over a USB cable, or you can build a “little box” that acts as a wired router for Android devices.

For this “little box” project, we decided to integrate such a tool on a Raspberry Pi low cost single board computer (https://www.raspberrypi.org/products/raspberry-pi-4-model-b/), which costs about 35 US dollars or less and is easily available in many parts of the world.

Uniting these tools, we can create a small box that can be connected to the Internet using Ethernet cable and providing reliable and high speed Internet access to one (or several) Android device(s) simultaneously. You just have to plug the phone, and it will have Internet access on Airplane mode. We have also tested it with 3 simultaneous phones accessing Internet through the same “little box”.

By the way, you may remember the tethering technology, which allows you to share your mobile phone Internet connection (4G/GSM) with your computer. What we do here is reverse tethering, where the mobile phone uses another wired connection instead of sharing its connection.

Finally, using Voice Over Wifi (VoWi-Fi) technology, it is possible to make and receive phone calls with your operator mobile phone number without any wireless connection active! But there is a trick for that, at the end of this text….

If you are interested, here is how to prepare build such “little box” for you:

Procedures:

1. Get a Raspberry Pi and a SD Card

We have tested the system with Raspberry Pi models 1, 2, 3 and 4 (must be model B). Any will serve. You will also need a SD Card of at least 8GB that will be erased / formatted to load the embedded Linux that we will prepare for this application. You can also buy a case for the Raspberry Pi, or build a case with a 3D Printer.

Raspberry Pi options:

https://www.raspberrypi.org/products/

Raspberry Pi Pico and Raspberry Pi Zero cannot be used for this project.

2. Download the Operating System (OS) for the Raspberry Pi Computer

Using a computer with a SD Card reader, go to the website:

https://www.raspberrypi.org/software/operating-systems/

Download Raspberry Pi OS. We have used:

Raspberry Pi OS Lite
Release 4th March 2021

3. Write Operating System (OS) image to the SD Card

Detailed instructions here:

https://www.raspberrypi.org/software/

For Linux users, just insert the SD Card on your PC and run these commands (after the download):

unzip 2021-03-04-raspios-buster-armhf-lite.zip
sudo dd if=2021-03-04-raspios-buster-armhf-lite.img of=/dev/mmcblk0

Be careful and verify that /dev/mmcblk0 is really your SD Card device, otherwise you might lose important information!

4. Turn on the Raspberry Pi with a network cable connected and login

Remove the written card from your PC and insert it on a Rapberry Pi computer module. To set up the system, you will need a monitor and keyboard. Later these accessories won’t be necessary anymore.

Power on the Raspberry Pi with the written card and wait for the login prompt. If the Raspberry Pi is powered with an Ethernet cable, it will automatically connect to the Internet using DHCP (automatic network configuration). Use the keyboard to access the Raspberry Pi terminal with this login and password:

Login: raspberry
Password: pi

If the login is successful, you will see a command prompt like this:

pi@raspberry:~$

After logging in, let’s start installing the required software.

5. Install RUST Language

The main component of this project is gnirehtet, which uses RUST Programming Language. So, we will install this language on the Raspberry Pi. Detailed explanation to install RUST is available here:

https://www.rust-lang.org/tools/install

One quick and direct way to install RUST, is by issuing this command:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Then, press 1 – Proceed with installation.

After some minutes, you will see:

“Rust is installed now. Great!”

6. Download required packages

Now we have to install some required software for our system. Still using the keyboard and the terminal (dark screen), run the following commands:

sudo su -

apt-get update

apt install adb

apt install git

Now, download gnirehtet source code with the following command:

git clone https://github.com/Genymobile/gnirehtet.git

7. Build the program

Before building the program, it is necessary to logout (exit) the current terminal session and login again. This will allow the environment to be prepared for the building process, specially due to RUST language installation. To logout, you can type exit and ENTER, or simply press Ctrl+D. Do it twice, until you see the login prompt again asking for login and password. After that, type the username and password again, and be sure to be logged in before issuing the following commands.

sudo su -

source /root/.cargo/env

cd /home/pi/gnirehtet/relay-rust

cargo build

After several “Downloaded” and “Compiling” messages, a “Finished” message will appear. If you got to here, congratulations, you have gnirehtet compiled and ready to use.

Now let’s test it!

8. Copy files to a common place

For easier testing, copy the built gnirehtet to a directory.

cd /home/pi/gnirehtet

cp relay-rust/target/debug/gnirehtet .

You also need to download the Android application that is automatically installed on the device to allow the reverse tethering to be setup automatically. You can build this App yourself, but for easier setup, you can use this prebuilt application by downloading it with wget download tool.

wget http://bipes.net.br/aroca/gnirehtet.apk

You can use the ls command to check if this file is present in the directory (folder).

9. Test gnirehtet

Enable Developer Options on the Android device

A few minutes ago we installed the program adb (Android Debug Bridge). Such tool is used to debug Android devices, and the process of reverse tethering need to issue commands using adb. In that way, USB debugging must be enabled on your Android device so we can proceed. This is done by going on the Android configuration menu, then clicking several times until you “become a developer” (More instructions here: https://developer.android.com/studio/debug/dev-options).

Enable USB debugging on the Android device

After enabling developer options, then we need to enable USB debugging. You will see this option on the new menu “Developer Options” that will appear on the configurations meno of your Android device.

After that, go back to the Raspberry Pi terminal and run:

./gnirehtet autorun

Turn on airplane mode of your Android device, and connect it to the the Raspberry Pi using a USB cable. Note that a data transfer USB cable must be used (cables for charging only will not work).

A message will appear on the phone asking to authorize USB debug. Permit it. You should now have full Internet access on your Android device using the USB cable, where data is routed by the USB cable and then by the Ethernet cable via the Raspberry Pi board.

And the magic is done!

Note that all these steps just need to be done once, as we were preparing our system. From now on, each time you want to use it, simply plug the cables (Ethernet to Raspberry, Power to Raspberry and USB between Raspberry and Android device and use!

Moreover, the system supports several phones / Android devices simultaneously using Internet shared by the Raspberry Pi!

10. Configure the system for automatic initialization on reboot

One last thing we have to do is configure the Raspberry Pi to automatically run gnirehtet when powered on. To configure automatic execution on initialization, edit the file /etc/rc.local, locate the last line, which will have the text exit 0, and before the last line add 2 lies as follows:

#(rc.local file will have several instructions - keep all of them)

cd /home/pi/gnirehtet

./gnirehtet autorun &

exit 0 #(this is the last line of rc.local - keep untouched)

If you never edited a file on Linux, use the nano file editor, by simply typing:

sudo nano /etc/rc.local

After doing the modifications and saving the file, turn off the Raspberry Pi, by uplugging the power adapter, and power it again. Finally, check if the system will work automatically after power on.

After these steps, you can move the device around your house and use where you prefer. No more keyboard or monitor needed!

10. Making and receiving phone calls on airplane mode

As mentioned, Voice Over Wifi (more details here: VoWi-Fi and here: Wi-Fi Calling (VoWi-Fi) ) technology allows Android Smartphones to make and receive phone calls using your operator mobile phone number over Wifi Network. Obviously, Wifi network relies on the TCP/IP protocol stack, so we can use our rever tethering system described here!

Unfortunately, there is a trick for that to work. VoWi-Fi check if you are connect to a WiFi network, a verification that is unnecessary, but implemented on the devices. The trick is to “lie” to your phone, telling that it is connected to a WiFi network, while the true is that it is connected to a wired connection!

In order to do that trick, one possible solution is to run FakeWifi application (https://repo.xposed.info/module/com.lemonsqueeze.fakewificonnection), which will simulate a WiFi connection, while, in fact, we are using a wired connection.

Final remarks

Everything we have done here, can be done on your computer also (Windows, Linux or MAC), so you can share your computer Internet connection with your Android device using a free USB port on your computer.

We have built three devices as described here and we are using this technology for about 4 months now (since December/2020). The system has been working reliably since then!

Finally, our many thanks and congratulations to the guys of GenyMobile (https://github.com/Genymobile/) for developing and sharing this awesome open source software: gnirehtet.