Tag Archives: pi

STRATUX ADS-B Receiver – open ports inventory

While working on a service to read data published by the STRATUX open source ADS-B receiver, it became a big of a guessing game regarding which ports where open and what protocol they might support.

In the event others are interested, there is the the port inventory from a STRATUX v1.6r1 device built on 03-MAR-2021

PortProtocolServiceAnalysis
80tcphttp Golang net/http server AngularJS web interfae
8080tcphttp-proxy says Dump1090 but always returns 404 error
9977tcphttpJson Pi System Info – temp, memory, etc.
30001tcppago-services ?-TBD-
30002tcppago-services ?appears to be a string of hashstrings (e.g.: *8DAB1D28990C37BB78042B8E5676; )
30003tcpbasestationannounced as “ADS-B flight data”
30004tcplistenerThis is a binary “Beast” input port
30005tcpunknown-TBD- possibly some binary data stream (e.g.: ‘JXf#<' )
30006tcpADS JsonJson of partial ADS-B data – always seems to be missing loation and speed info
example:
{
  "Icao_addr": 11403422,
  "DF": 17,
  "CA": 5,
  "TypeCode": 4,
  "SubtypeCode": 6,
  "SBS_MsgType": 1,
  "SignalLevel": 0.000344,
  "Tail": "LEXUS05 ",
  "Squawk": null,
  "Emitter_category": 6,
  "OnGround": false,
  "Lat": null,
  "Lng": null,
  "Position_valid": false,
  "NACp": null,
  "Alt": null,
  "AltIsGNSS": false,
  "GnssDiffFromBaroAlt": null,
  "Vvel": null,
  "Speed_valid": false,
  "Speed": null,
  "Track": null,
  "Timestamp": "2021-03-05T17:16:47.203Z"
}
30104tcpunknown -TBD- possibly raw dump1090 data stream

Diving into the Port Data


Port 30002

Text stream of data, available via a tcp connection. Each message is a hash of some sort, value of which is undetermined at this point.

Here is an example of the message stream

*5DA8C3EA379B4F;
*02E195B70936B4;
*5DA21603EB2A06;
*02C60BB129C2D0;
*02C60BB129C2D0;
*8DAD21C1592DD7EF9896504E8E50;
*02E19718EEFD09;
*8DA1B52B596233C53D9901456D9D;
*8DA216035913378FE2327C198F8A;
*8DA2160399104987B8340BFCE929;
*8DA9942E585F100DBA20C5712D44;
*8DA9942E9908212C509814A6DF7A;

Port 30003

Text stream of data, available via a tcp connection. Each message is comma delimited, and appears to the the ICAO integer converted to Base16 hex.

Here is an example of the message stream

MSG,3,111,11111,A4AB64,111111,2021/03/06,17:16:35.554,2021/03/06,17:16:35.573,,8900,,,30.41666,-98.63536,,,,,,0 MSG,4,111,11111,A4AB64,111111,2021/03/06,17:16:35.554,2021/03/06,17:16:35.574,,,159,93,,,-448,,,,,0 MSG,3,111,11111,A313BF,111111,2021/03/06,17:16:35.587,2021/03/06,17:16:35.626,,36000,,,29.68039,-98.32875,,,,,,0 MSG,7,111,11111,A8DB58,111111,2021/03/06,17:16:35.602,2021/03/06,17:16:35.627,,5900,,,,,,,,,,0 MSG,3,111,11111,A2A18A,111111,2021/03/06,17:16:35.607,2021/03/06,17:16:35.627,,5625,,,29.66141,-98.47789,,,,,,0 MSG,4,111,11111,A2A18A,111111,2021/03/06,17:16:35.607,2021/03/06,17:16:35.628,,,221,248,,,128,,,,,0 MSG,7,111,11111,A8DB58,111111,2021/03/06,17:16:35.608,2021/03/06,17:16:35.628,,5900,,,,,,,,,,0 MSG,3,111,11111,A417D6,111111,2021/03/06,17:16:35.609,2021/03/06,17:16:35.628,,24000,,,30.09300,-97.62418,,,,,,0

Port 30005

Binary stream of data, available via a tcp connection.

Here is an example of the message stream

y# ??2??)k?????3]?Sx?l3??.?@?????B?xf~3??.??yRX??L?ma??3??/?8 q?!I????3??1Q???? Z?O??3??69???+(X??????-N2??6??”ᕸ?eP3??7??#??o???,???3??;W#??o#?t?l??Zg3??>?&???Y}?o? ???I3??C k??+(???P,2N?3??D????yR? ??-3?3??F,???Y??x?_??2??F6? ?8\`3??Hg???+?ȱ?/?2??I????p2??Ke`#ᕸ?eP2??P?]?+(??A2??U^ ?8\`2??Un<ᕸ???3??XWW???.X?????_?3??X????Y???{?+3??X?h%??o?B?`_?_b?2??Z?f???~?2??Z?j??p2??]- ??|+?3??_e? ??SxX??56S?J?3??_?????.@ ???2??`????2??e?F%]?o7C?3??jt??Sx?y%?`2??l/???? 3??n??????? ??-??3??q?U q? ?-0?Jc3??q?)???Y??)? T??2????7?8?}?2???γ 8إ?2????H ?FU3????|????Y??1??2???L?]?\g??2????E]??.???3??|?{??????>?0 2????]?\g??3????????!;

Port 30006

High volume text stream, available via tcp connection. Messages are in a Json format. Observation is that these always seem to lack geo-location, speed and altitude data.

Here is an example of the message stream

{“Icao_addr”:10627880,”DF”:11,”CA”:5,”TypeCode”:0,”SubtypeCode”:0,”SBS_MsgType”:8,”SignalLevel”:0.000816,”Tail”:null,”Squawk”:null,”Emitter_category”:null,”OnGround”:false,”Lat”:null,”Lng”:null,”Position_valid”:false,”NACp”:null,”Alt”:null,”AltIsGNSS”:false,”GnssDiffFromBaroAlt”:null,”Vvel”:null,”Speed_valid”:false,”Speed”:null,”Track”:null,”Timestamp”:”2021-03-06T17:34:12.129Z”} {“Icao_addr”:10645249,”DF”:11,”CA”:5,”TypeCode”:0,”SubtypeCode”:0,”SBS_MsgType”:8,”SignalLevel”:0.000846,”Tail”:null,”Squawk”:null,”Emitter_category”:null,”OnGround”:false,”Lat”:null,”Lng”:null,”Position_valid”:false,”NACp”:null,”Alt”:null,”AltIsGNSS”:false,”GnssDiffFromBaroAlt”:null,”Vvel”:null,”Speed_valid”:false,”Speed”:null,”Track”:null,”Timestamp”:”2021-03-06T17:34:12.139Z”} {“Icao_addr”:11402414,”DF”:4,”CA”:0,”TypeCode”:0,”SubtypeCode”:0,”SBS_MsgType”:5,”SignalLevel”:0.001636,”Tail”:null,”Squawk”:null,”Emitter_category”:null,”OnGround”:false,”Lat”:null,”Lng”:null,”Position_valid”:false,”NACp”:null,”Alt”:6075,”AltIsGNSS”:false,”GnssDiffFromBaroAlt”:null,”Vvel”:null,”Speed_valid”:false,”Speed”:null,”Track”:null,”Timestamp”:”2021-03-06T17:34:12.142Z”} {“Icao_addr”:10645249,”DF”:11,”CA”:5,”TypeCode”:28,”SubtypeCode”:1,”SBS_MsgType”:8,”SignalLevel”:0.000837,”Tail”:null,”Squawk”:null,”Emitter_category”:null,”OnGround”:false,”Lat”:null,”Lng”:null,”Position_valid”:false,”NACp”:null,”Alt”:null,”AltIsGNSS”:false,”GnssDiffFromBaroAlt”:null,”Vvel”:null,”Speed_valid”:false,”Speed”:null,”Track”:null,”Timestamp”:”2021-03-06T17:34:12.158Z”}

Installing CasperJS on Raspberry Pi

This is generally a simple process to install CapserJS on a *NIX box, but had not done this on a Raspberry Pi before, and ran into a couple of minor gotchas. This is a stripped down explanation of what I needed to do, but it will server as a reference for me, and maybe for some other people as well.

Prerequisites for installing CapserJS

  • Node
  • npm
  • PhantomJS

Node

Installing node is very simple, but you should grab root access to do it. This should be simple and run without any issues.

apt-get install nodejs


npm

The Node Package Manager will be used later to actually install CasperJS, once PhantomJS has been successfully installed.

apt-get install npm


PhantomJS

PhantomJS is a web automation framework, that CasperJS uses to run it’s extended suite of tools. NOTE. I found that I needed to modify my user’s (pi in this case) environment to tell Phantom that not to expect a console for rendering webpages; I’ll document that at the bottom.

apt-get install phantomjs


CasperJS

Installing CasperJS is done most simply via the npm (Node Package Manager):

npm install -g casperjs


Handling the PhantomJS Display Error

pi@raspberrypi:~ $ casperjs
QXcbConnection: Could not connect to display
PhantomJS has crashed. Please read the bug reporting guide at
and file a bug report.
Aborted

The fix is to add this line to the .bashrc file, which will stop the error. I simply added this to the last line of the file.

export QT_QPA_PLATFORM=offscreen

STRATUX – Add swap and logging partitions.

It’s back! The STRAUX project lives again. With a fresh build of Stratux, it’s time to re-configure the SD card for swap space (new!) and a large logging partition to keep a full filesystem from crashing the device.

Get Current Partition Information

Once logged into the Straux box, switch to the root user and interrogate the disk partitions.

pi@raspberrypi: sudo su -
root@raspberrypi: fdisk -l
[...]

Device Boot Start End Sectors Size Type
/dev/mmcblk0p1 8192 131071 122880 60M W95 FAT32 (LBA)
/dev/mmcblk0p2 131072 3700592 3569521 17.G Linux

The important aspects you will want to record as the End block ids for each partition, this is important in the next step, creating more partitions.

Creating the Extended Partition

First task is I want to create the extended partition that can be used for swap. This will eventually contain the swap and log partitions.

Running the fdisk tool, start to edit the partition. You will want to reference the base block of the device.. eg: /dev/mmcblk0

root@raspberrypi: fdisk /dev/mmcblk0

Command (m for help): p

Device Boot Start End Sectors Size Type
/dev/mmcblk0p1 8192 131071 122880 60M W95 FAT32 (LBA)
/dev/mmcblk0p2 131072 3700592 3569521 17.G Linux

Command (m for help): n

Partition type
p primary (2 primary, 0 extended)
l logical (numbered from 5)
Select (default p): l

At this point, the tool threw an error adding partition 5…

Partition 5 is already defined. Delete it before re-adding it

Listing the partitions shows this:

Device Boot Start End Sectors Size Type
/dev/mmcblk0p1 8192 131071 122880 60M W95 FAT32 (LBA)
/dev/mmcblk0p2 131072 3700592 3569521 1.7G Linux
/dev/mmcblk0p3 3700593 62333951 5863d359 28G Extended
/dev/mmcblk0p5 2191 4194446 4192256 2G Linux

Re-running ‘n option and letting it setup partition 6, got me where I wanted to be. This process didn’t seem like it worked right.. but the end result matches up with my goal of a huge partition and a smaller 2G to be used for swap:

Command (m for help): n

Partition type
p primary (2 primary, 0 extended)
l logical (numbered from 5)
Select (default p): l

Adding logical partition 6
First Sector: 4198400
Last Sector: 62333951

Created a new partition 6 of type 'Linux and a size of 27.7 GiB

Command (m for help): p
Device Boot Start End Sectors Size Type
/dev/mmcblk0p1 8192 131071 122880 60M W95 FAT32 (LBA)
/dev/mmcblk0p2 131072 3700592 3569521 1.7G Linux
/dev/mmcblk0p3 3700593 62333951 5863d359 28G Extended
/dev/mmcblk0p5 2191 4194446 4192256 2G Linux
/dev/mmcblk0p6 4198400 62333951 58135552 27.7G Linux

Command (m for help): w

.. this is where the Ending block of your p2 partition number comes into play. The starting sector will be the ending number of your last partition (3569521) + 1 for next sector:


First Sector: 3700593
Last Sector: 62333951 (this was the default/max)

Created a new partition 3 of type 'Extended' and of size 28 GiB

Command (m for help): n

Partition type
p primary (2 primary, 0 extended)
l logical (numbered from 5)
Select (default p): l

Adding the largest partition, for log file storage

Now repeat this process to add the 2nd new partition, this one will consume the rest of the device, and eventually will be where the `/log` directory is mounted.

root@raspberrypi: fdisk /dev/mmcblk0

Command (m for help): p

Device Boot Start End Sectors Size Type
/dev/mmcblk0p1 8192 131071 122880 60M W95 FAT32 (LBA)
/dev/mmcblk0p2 131072 3700592 3569521 1.7G Linux
/dev/mmcblk0p3 3700593 7895039 4194447 2G Extended

Command (m for help): n

Partition type
p primary (2 primary, 0 extended)
l logical (numbered from 5)
Select (default p): l

First Sector: 4194448

Stratux Webserver – what’s behind the scenes?

Stratux has a rich community of forums, and a lot of information about debugging Strtux, but so far good hacking information is really hard to find. One of the things of most interest to me was “What is severing up this webpage?”

Every search was a dead end, so I went back to my *NIX system administration roots and thought.. “Well, if someone wont admit what’s serving up the stream.. I’ll find out for myself.

Who’s Your Server? — gen_gdl90

A couple of quick commands told me which PID was hanging onto Port 80 and from there which process was associated with the PID:


root@raspberrypi:~# fuser 80/tcp
80/tcp: 3110
root@raspberrypi:~# ps aux | grep 3110
root 3110 51.9 2.9 973132 27600 ? Ssl 15:19 47:03 /usr/bin/gen_gdl90
root 6606 0.0 0.2 4276 1904 pts/0 S+ 16:50 0:00 grep 3110
What files does it have open?

Once I had an idea of who’m I was looking for, running lsof with the port number gave me 60 entries… and bingo.. there was the nugget of gold I was looking for:


root@raspberrypi:~# lsof -p 3110
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gen_gdl90 3110 root cwd DIR 179,2 4096 2 /
[...]
gen_gdl90 3110 root 35u IPv6 1849628 0t0 TCP StratuxWiFi.io:http->10.100.0.188:49157 (ESTABLISHED)
gen_gdl90 3110 root 36u IPv6 210216 0t0 TCP StratuxWiFi.io:http->10.100.0.188:64155 (ESTABLISHED)
gen_gdl90 3110 root 37u IPv6 1859641 0t0 TCP StratuxWiFi.io:http->10.100.0.188:49165 (ESTABLISHED)
gen_gdl90 3110 root 38u IPv6 1759876 0t0 TCP StratuxWiFi.io:http->10.100.0.188:65420 (ESTABLISHED)
gen_gdl90 3110 root 41u IPv6 1778784 0t0 TCP StratuxWiFi.io:http->10.100.0.188:65442 (CLOSE_WAIT)
gen_gdl90 3110 root 48r REG 179,2 146998 51146 /var/www/maui/js/angular.min.js
The Web Path

Once onto the trail of the web path, I see that this is an Angular based application (ugh.. I really despise Angular.. I just do.), and all based on some JS stuffs. I get it. for an app like this the two-way data binding of Angular is probably the right too; but I still do not (no do I have to) like it.


root@raspberrypi:~# cd /var/www/maui/
root@raspberrypi:/var/www/maui# ls -l
total 12
drwxr-xr-x 2 root root 4096 Mar 15 2016 css
drwxr-xr-x 2 root root 4096 Mar 15 2016 fonts
drwxr-xr-x 2 root root 4096 Mar 15 2016 js
root@raspberrypi:/var/www/maui#

What I was hoping to find was the location of the that status page.. but.. I believe that what I’m looking for now is the .JS file that manages that label. Initially this looked like a dead end…


root@raspberrypi:/var/www/maui# egrep -r Distance *
root@raspberrypi:/var/www/maui#

Realiazing this was some templating sub-directory, and the root was likely at /var/www, I ran another search that found the location of the desired string, and likely the location of the parts I’m looking for:


root@raspberrypi:~# cd ..
root@raspberrypi:/var/www# egrep -lnr 'Distance' *

plates/js/traffic.js
plates/traffic-help.html
plates/traffic.html

STRATUX – Filesystem Full; Managing disk space redux

Checking in with my Starux project this morning, I found it unresponsive. A physical check shows a flashing red light on the Pi… something has gone haywire, and I couldn’t SSH into the little thing, so a really hard cold restart was in order.

Following the restart I quickly shut Stratux back down to start performing diagnostics:


pi@raspberrypi:~ $ sudo su -

root@raspberrypi:~# service stratux stop

Diagnostics 101

Check Filesystem Health

The last time the little Stratux suddenly had problems it was a filesystem space issue ( previous article ). It turns out the boot drive space was OK but the new Logging partition was again, completely consumed:

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        1815440 1391284    331164  81% /
devtmpfs          469688       0    469688   0% /dev
tmpfs             474004       0    474004   0% /dev/shm
tmpfs             474004    6340    467664   2% /run
tmpfs               5120       4      5116   1% /run/lock
tmpfs             474004       0    474004   0% /sys/fs/cgroup
/dev/mmcblk0p1     61384   20400     40984  34% /boot
/dev/mmcblk0p4   8125880 8109496         0 100% /var/log

Locate the Culprit

There are a number of ways to locate large file on a *NIX system. My favorite tool is find. First thing I want to do is locate any file that is larger than 1 Gigabyte, and sure enough it located a massive sqlite database file. The same one that ate up all the space on the boot drive. So.. this is going to require some more extrodinary measures to maintain 100% 24×7 operational status.


root@raspberrypi:~# cd /var/log
root@raspberrypi:/var/log# find . -size +1G -exec ls -l {} \;
-rw-r--r-- 1 root root 7463211008 Apr 29 21:48 ./stratux.sqlite
Start Solving

First order of business is to move aside the massive database, but try to preserve the data for examination. Since the filesystem is full, I can’t zip this thing in place, so first some space needs to cleared on the device. The things I’m least interested in go first.. like the zipped syslogs and any other ‘archived’ file (those with a .# suffix).

-rw-r----- 1 root adm      728756 Apr 25 06:25 syslog.5.gz
-rw-r----- 1 root adm     2552845 Apr 26 06:25 syslog.4.gz
-rw-r----- 1 root adm     2447263 Apr 27 06:25 syslog.3.gz
-rw-r----- 1 root adm     2498089 Apr 28 06:25 syslog.2.gz
-rw-r----- 1 root adm    33735478 Apr 29 06:25 syslog.1
-rw-r----- 1 root adm       54307 Apr 30 05:19 debug.1
-rw-r----- 1 root adm      380928 Apr 30 05:19 kern.log.1
-rw-r----- 1 root adm   332365824 Apr 30 06:18 daemon.log.1
-rw-r----- 1 root adm       48723 Apr 30 06:25 auth.log.1
-rw-r----- 1 root adm           0 Apr 30 06:25 syslog.1.gz
-rw-r----- 1 root adm     1032192 Apr 30 06:25 messages.1

root@raspberrypi:/var/log# rm -f *.gz *\.[0-9]

But.. that’s not going to doe the complete trick, especially if after deleting files df still shows 100% utilization. You need to figure out what is holding which deleted file(s).

Normallyh, the best way to do that on *NIX is with lsof. Much to my chagrin, it was not available on the OS… so I had to go grab it. Thankfully I had the main filesystem on a different partition that still had enough space to install more tools! Once lsof was installed, grep through the list of open file handles and find those marked for delete.. and those are the processes that have handles pointing to those files. However, this didn’t help me with Rasperian Jessie. I know that a reboot will recover the space so.. that was the next step.. a brutal warm-boot.


root@raspberrypi:/var/log# lsof
-su: lsof: command not found

root@raspberrypi:/# apt-get install lsof
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libperl4-corelibs-perl
The following NEW packages will be installed:
libperl4-corelibs-perl lsof
...

root@raspberrypi:/var/log# lsof | grep deleted
root@raspberrypi:/var/log#

root@raspberrypi:/var/log# init 6

Archiving Massive SQLite Database

The first thing was to move aside the current database, and then restart stratux to verify it can created a new empty database for it’s purposes.. then shut it right back down again.


root@raspberrypi:/var/log# mv stratux.sqlite stratux.sqlite.1
root@raspberrypi:/var/log# service stratux start
root@raspberrypi:/var/log# ls -l
total 7291480
[...]
-rw-r--r-- 1 root root 4096 Apr 30 14:27 stratux.sqlite
-rw-r--r-- 1 root root 7466160128 Apr 30 14:24 stratux.sqlite.1
[...]
root@raspberrypi:/var/log# service stratux stop

A new empty database file has been created [ 4096 Apr 30 14:27 stratux.sqlite ]. This tells me that moving aside the current database file on a periodic basis, compressing and then archiving it should be sufficient to maintain operational status.

Logging Insanity

Before restarting Stratux, I zerod out these log files. Running for first a few moments these files were already reading up a lot of space. Tailing one of them I see that Stratux, with my current settings is logging A LOT of data to these log files. I feel this was my first error.. enabling too much logging. My settings look like this:

With those settings enabled, there are a lot of GPS and other events that I don’t really have a use for, being dumped into the Statux log.


-rw-r--r-- 1 root root 1361778 Apr 30 14:39 stratux.log

Turning OFF ‘Verbose Message Log’ made that insanity stop.

Replay logging is what is writing to the SQLite database. So the question is. how much of that data do I want to keep, and how much will I lose if I turn off the replay logs. I think that will be research for another day… right now the goal is to recover disk space by compressing the massive database file that was moved aside, and get Stratux stabilized again. Once compressed, check filesystem and file size!


root@raspberrypi:/var/log# gzip stratux.sqlite.1

root@raspberrypi:/var/log# df

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        1815440 1392384    330064  81% /
devtmpfs          469688       0    469688   0% /dev
tmpfs             474004       0    474004   0% /dev/shm
tmpfs             474004   12272    461732   3% /run
tmpfs               5120       4      5116   1% /run/lock
tmpfs             474004       0    474004   0% /sys/fs/cgroup
/dev/mmcblk0p4   8125880  681792   7008276   9% /var/log
/dev/mmcblk0p1     61384   20400     40984  34% /boot

root@raspberrypi:/var/log# ls -lktr --color --block-size=M stratux.sqlite*

-rw-r--r-- 1 root root 643M Apr 30 14:24 stratux.sqlite.1.gz
-rw-r--r-- 1 root root   8M Apr 30 15:21 stratux.sqlite
-rw-r--r-- 1 root root   1M Apr 30 15:22 stratux.sqlite-shm
-rw-r--r-- 1 root root   5M Apr 30 15:22 stratux.sqlite-wal

With the file compressed, it could be copied elsewhere for analysis.