Ben Foxall ➑️ @benfoxall.bsky.social πŸ‘‹ (@benjaminbenben) on X

2 min read Original article β†—

user avatar

I'm wondering how they calculate signal 75%, so opened the captive portal url in dev tools and see what requests they're making. /system/connectivity_proxy.php seems likely

Signal indicator (four circles, three filled green).

Network tab in Chrome with request highlighted

user avatar

…it returns details of which modems are connected 🀯 I'm guessing it could handle up to 4 interfaces, but only two are plugged in (sierra-7710). I don't know much about this, but I'm guessing that with `"cellid": "01B40902"` you might be able to get an approximate location?

A JSON document, listing firmware versions and a list of modems

user avatar

The sources aren't minified (genuine πŸ’•) so you can find how they calculate the signal: 100%: there's 3+ LTE links (impossible on this train with it's two modems plugged in😭) 75%: there's a couple of LTE links 50%: there's only one LTE 25%: at least it's not gprs or edge πŸ€·β€β™€οΈ

Inspecting the source code for the portal:

 var techList = {
        'lte':'4G',
        'dc-hspa+':'3.5G',
        'hsdpa':'3G',
        'cdma':'3G',
        'hspa+':'3G',
        'umts':'3G',
        'gprs':'2G',
        'edge':'2G',
        'unknown':'Unknown'
    };

    var totalQuality = function(techs) {
        var greatLinks = 0;
        var okayLinks = 0;
        for (var i = 0; i < techs.length; i++) {
            if (techs[i] == '4G') {
                greatLinks++;
            } else if (techs[i] == '3.5G' || techs[i] == '3G') {
                okayLinks++;
            }
        }

        if (greatLinks >= 3) {
            return 4;
        } else if (greatLinks >= 2) {
            return 3;
        } else if (greatLinks >= 1) {
            return 2;
        } else if (okayLinks >= 1) {
            return 1;
        } else {
            return 0;
        }
    };

user avatar

The rendering of the element is nice and straightforward 😎

Source code for showing rating is basic if statement (a good thing!)

user avatar

user avatar

And you can search for ".on.icomera.com" and see other Trains!

Search results for on.icomera.com, listing different train providers

user avatar

Good news: not everything is public πŸ˜… Bad news: the private stuff feels scary 😭 The portal makes a few requests ombord.info/api/* …Which resolves to 192.168.10.1, an on-board server I guess?

Response from `dig www.ombord.info` which resolves to `192.168.10.1`

user avatar

The endpoints called are /system /user /position. (Shoutout to jsonp, I've missed you 😍) /system - Gives the version & name of the … train? /user – My connection details /position – the current location & speed of the train 🀩

user avatar

I was guessing some other endpoints and turns out `/users` is a thing! …you can see how many people are connected to the train, and how many are successfully registered I guess?

// 20230206204033
// https://www.ombord.info/api/jsonp/users/?callback=foo

foo({
  "version": "1.10",
  "total": "91",
  "online": "67"
});

user avatar

Free Wifi
/system
{
  "version": "1.10",
  "system": "80010206",
  "system_id": 80010206,
  "system_name": "Azuma800102"
}
/user
{
  "version": "1.10",
  "ip": "192.168.10.251",
  "mac": "00:00:00:00:00:BF",
  "online": "0",
  "timeleft": "0",
  "authenticated": "0",
  "userclass": "2",
  "expires": "Never",
  "timeused": "0",
  "data_download_used": "0",
  "data_upload_used": "0",
  "data_total_used": "0",
  "data_download_limit": "0",
  "data_upload_limit": "0",
  "data_total_limit": "0",
  "bandwidth_download_limit": "0",
  "bandwidth_upload_limit": "0",
  "cap_level": "0",
  "user_custom_state": ""
}
/position
{
  "version": "1.10",
  "time": "1675719672",
  "age": "0",
  "latitude": "51.939953",
  "longitude": "-0.244206",
  "altitude": "81.8",
  "speed": "35.98",
  "cmg": "135.74",
  "satellites": "26",
  "mode": "3"
}
/users
{
  "version": "1.10",
  "total": "81",
  "online": "60"
}

user avatar

I'm not sure of the `speed` value, so I worked it out with a speedometer app, Photo Booth, and Quicktime

user avatar

user avatar

Added a "download geojson" button just in time to see my route into London Kings Cross πŸŽ‰

Page with downloaded json files

Map of path plotted from geojson