Integration Guide
Overview
This guide covers the integration of the miro EdgeCard mioty into a host system. It is intended for system integrators embedding the card into a product or gateway device.
Current firmware revisions are fully locked down. There is no SSH or serial console access. All configuration and management is performed through an HTTP API exposed by the card over its USB network interface.
Legacy firmware
If you are working with an older firmware revision that provides SSH access, refer to the legacy integration guide.
Host System Networking
The miro EdgeCard mioty exposes a USB CDC ECM network interface with a static IP address of 172.30.1.2/24. The host system must be configured with an address in the same subnet (e.g. 172.30.1.1) and must forward traffic on behalf of the card so it can reach the mioty service center.
The host network stack SHALL restrict access to 172.30.1.2 to localhost only. The Config API is unauthenticated; network-level isolation is the only access control in place.
The card requires the following outbound connections. The host SHALL permit these through its firewall or routing policy:
| Service | Protocol | Notes |
|---|---|---|
| BSSCI or MQTT | TCP | Port configurable via Config API |
| NTP | UDP 123 | Time synchronisation |
| Firmware updates | HTTPS or HTTP | RAUC bundle download |
The card does not require any inbound connections from the internet.
Replace eth1 with the host's uplink interface and eth2 with the USB CDC ECM interface.
Save to /etc/iptables/iptables.rules to survive reboots:
All subsequent API calls use the base address http://172.30.1.2/cgi-bin.
Security Requirements
The following requirements apply to all deployments. They are mandatory for compliance with EN 18031-1:2024 under EU Radio Equipment Directive 2022/30, Article 3(3)(d). Requirements use normative language: SHALL denotes a mandatory requirement; SHOULD denotes a strong recommendation.
Config API Access Control
The Config API at 172.30.1.2 is unauthenticated by design. The host network stack SHALL restrict access to 172.30.1.2 to localhost only. The Config API SHALL NOT be exposed to any external network interface, including any interface reachable from the internet or from other devices on the local network.
The iptables configuration in Host System Networking provides a forwarding baseline. The integrator is responsible for ensuring no rule exposes the Config API beyond the host.
BSSCI Transport Security
Unencrypted BSSCI connections are permitted only to a mioty Service Center running on the host system (loopback or isolated LAN segment). For any BSSCI connection to a Service Center reachable over an untrusted network, TLS SHALL be enabled. mTLS is strongly recommended. Certificate and key management is the responsibility of the system integrator.
See TLS Configuration for setup instructions.
MQTT Transport Security (NM Mode)
This requirement applies to the GWC-62-MY-868-NM variant only.
Unencrypted MQTT connections are permitted only to a broker running on the host system. TLS SHALL be enabled for any connection to an external broker. mTLS is strongly recommended.
Physical Access Control
The host system enclosure SHALL prevent unauthorised physical access to the installed gateway card. Physical access to the card provides direct access to the Config API. See the Overview for mechanical requirements.
Firmware Updates
The system integrator SHALL apply Miromico security firmware updates within a timeframe appropriate to the severity of the vulnerability, as stated in the Miromico security advisory. Miromico provides security updates for a minimum of 5 years from the last date of manufacture.
System Time at Boot
The host system SHOULD set the card system time via /cgi-bin/time after each boot, before NTP
synchronisation is established. This ensures correct certificate validation and license expiry
checking from first startup. See Set System Time.
Initial Setup
Boot Sequence
Complete the following steps in order on boot:
- Verify the card is reachable:
GET /cgi-bin/status - Set system time:
POST /cgi-bin/time - Configure BSSCI or MQTT endpoint:
POST /cgi-bin/config - Verify operation:
GET /cgi-bin/status
Check Device Status
Before configuring the card, verify it is reachable and note the device ID. The device ID is required when requesting a license.
Set System Time
The card does not have a hardware real-time clock. Set the system time on every boot before performing any operation that involves certificate validation (TLS connections, firmware updates).
License
The card ships with a license for the BS (Base Station) feature pre-installed. No license installation is required for initial operation.
Check License Status
Use GET /cgi-bin/license to query the installed licenses and their current feature validity.
expiry: null means the feature has no expiry date. valid: false on a feature means it has
expired. An empty licenses array means no license is installed.
Install License
The license API (POST /cgi-bin/license) allows field license upgrades. The license file is
provided as a signed JSON object by Miromico. Install it with:
BS Configuration
The BS is configured via POST /cgi-bin/config. The request body is a JSON object with a bs
block containing the configuration and top-level control flags.
Configuration can be applied as persistent (stored on the card, survives reboot) or temporary (active until the next reboot). Omitting a parameter leaves its current value unchanged.
Parameter Reference
Top-level request fields
| Field | Type | Default | Description |
|---|---|---|---|
bs |
object | Configuration block. Contains bsi, mps, and optional TLS fields. |
|
persistent |
boolean | false |
true stores the configuration to flash; false applies it only until the next reboot. |
restart |
boolean | true |
true restarts the BS service immediately after applying the configuration. Required for changes to take effect without a full reboot. |
reset |
boolean | false |
true discards any active temporary configuration and reverts to the stored persistent configuration. Cannot be combined with persistent. |
bs.bsi Base Station Identity
| Field | Type | Default | Description |
|---|---|---|---|
uniqueBaseStationId |
string | 00-00-00-00-00-00-00-00 |
EUI-64 identifier, hyphen-separated. Must be unique across all base stations connected to the same service center. See Base Station ID. |
baseStationName |
string | mioty-bsm |
Human-readable name reported to the service center. Used for display and logging. |
baseStationInfo |
string | "" |
Optional free-text description of the installation site or deployment context. |
baseStationVendor |
string | "" |
Optional vendor identifier reported to the service center. |
baseStationModel |
string | "" |
Optional model identifier reported to the service center. |
serviceCenterAddr |
string | 172.30.1.1 |
Hostname or IP address of the mioty Service Center (BSSCI endpoint). |
serviceCenterPort |
string | 16017 |
TCP port of the mioty Service Center. |
tlsAuthRequired |
string | "false" |
Set to "true" to enable TLS for the BSSCI connection. Requires tlsCaCert, tlsCert, and tlsKey. See TLS Configuration. |
bs.mps Modulation and Physical Layer Settings
| Field | Type | Default | Description |
|---|---|---|---|
profile |
string | eu868 |
Radio frequency profile. Determines the operating band and channel plan. Supported value: eu868 (863-870 MHz, EU). |
bs TLS fields (required when tlsAuthRequired is "true")
| Field | Type | Description |
|---|---|---|
tlsCaCert |
string | PEM-encoded CA certificate used to verify the service center's server certificate. |
tlsCert |
string | PEM-encoded client certificate presented by the base station during mTLS handshake. |
tlsKey |
string | PEM-encoded private key corresponding to tlsCert. |
PEM values must be passed as single-line strings with literal \n escape sequences.
See TLS Configuration for the conversion procedure.
bs Feature Flags
These flags enable optional BS capabilities. Each flag is omitted from the default configuration
(equivalent to disabled). Set to true to enable. Each POST rewrites all flags from scratch;
omitting a flag or setting it to false clears any previously-set value.
| Field | Type | Description |
|---|---|---|
varmac |
boolean | Enable variable MAC ID mode. When enabled, the BS accepts endpoint frames with variable MAC addresses. |
ulp |
boolean | Enable ULP (Ultra Low Power) physical layer. |
hdr |
boolean | Enable HDR (High Data Rate) physical layer. |
emu |
boolean | Enable emulator mode with virtual endpoints for testing without physical devices. |
plmli |
boolean | Enable PHY MAC layer interface (PLMLI). |
recon |
boolean | Enable debug and measurement interfaces. Use during integration and diagnostics only. |
Factory Default Configuration
The default persistent configuration applied at the factory is equivalent to:
<module name="root">
<module name="bsi">
<parameter name="uniqueBaseStationId">00-00-00-00-00-00-00-00</parameter>
<parameter name="baseStationName">mioty-bsm</parameter>
<parameter name="baseStationInfo"/>
<parameter name="baseStationVendor"></parameter>
<parameter name="baseStationModel"></parameter>
<parameter name="serviceCenterAddr">172.30.1.1</parameter>
<parameter name="serviceCenterPort">16017</parameter>
<parameter name="tlsAuthRequired">false</parameter>
</module>
<module name="mps">
<parameter name="profile">eu868</parameter>
</module>
</module>
Base Station ID
uniqueBaseStationId must be unique across all base stations connected to the service center.
The recommended approach is to derive it from the host system's MAC address by inserting ff-fe
after the third octet.
For example, if the host MAC address is 9c:65:f9:61:07:c7, the base station ID becomes
9c-65-f9-ff-fe-61-07-c7.
Read Current Configuration
Use GET /cgi-bin/config to read back the active BS configuration. Returns the temporary config
if one is active, otherwise the persistent config. Returns HTTP 400 if no config has been applied yet.
Persistent Configuration
Persistent configuration is stored on the card and survives reboots. This is the appropriate choice for production deployments.
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{
"bs": {
"bsi": {
"uniqueBaseStationId": "9c-65-f9-ff-fe-61-07-c7",
"baseStationName": "my-gateway-01",
"serviceCenterAddr": "eu3.loriot.io",
"serviceCenterPort": "727",
"tlsAuthRequired": "false"
},
"mps": {
"profile": "eu868"
}
},
"persistent": true,
"restart": true
}' \
http://172.30.1.2/cgi-bin/config | jq .
Temporary Configuration
Temporary configuration is lost when the card reboots. It is useful for testing or for dynamic configuration applied by the host at runtime.
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{
"bs": {
"bsi": {
"uniqueBaseStationId": "9c-65-f9-ff-fe-61-07-c7",
"serviceCenterAddr": "eu3.loriot.io",
"serviceCenterPort": "727",
"tlsAuthRequired": "false"
},
"mps": {
"profile": "eu868"
}
},
"persistent": false,
"restart": true
}' \
http://172.30.1.2/cgi-bin/config | jq .
Note
Temporary configuration must be re-applied after every reboot.
Resetting Configuration
To discard any active temporary configuration and revert to the stored persistent configuration:
TLS Configuration
When tlsAuthRequired is "true", the BSSCI connection to the service center is authenticated
and encrypted using TLS. mTLS is strongly recommended; provide all three of the following files:
| File | Description |
|---|---|
root_ca.cer |
CA certificate used to verify the service center |
bstation.cer |
Client certificate presented by the base station |
bstation.key |
Private key corresponding to the client certificate |
PEM files must be converted to single-line strings with literal \n sequences before embedding
in JSON.
CA=$(awk '{printf "%s\\n", $0}' root_ca.cer)
CERT=$(awk '{printf "%s\\n", $0}' bstation.cer)
KEY=$(awk '{printf "%s\\n", $0}' bstation.key)
curl -s -X POST \
-H "Content-Type: application/json" \
-d "{
\"bs\": {
\"bsi\": {
\"uniqueBaseStationId\": \"9c-65-f9-ff-fe-61-07-c7\",
\"serviceCenterAddr\": \"eu3.loriot.io\",
\"serviceCenterPort\": \"727\",
\"tlsAuthRequired\": \"true\"
},
\"mps\": {
\"profile\": \"eu868\"
},
\"tlsCaCert\": \"$CA\",
\"tlsCert\": \"$CERT\",
\"tlsKey\": \"$KEY\"
},
\"persistent\": true,
\"restart\": true
}" \
http://172.30.1.2/cgi-bin/config | jq .
Certificate values truncated for readability:
{
"bs": {
"bsi": {
"uniqueBaseStationId": "9c-65-f9-ff-fe-61-07-c7",
"serviceCenterAddr": "eu3.loriot.io",
"serviceCenterPort": "727",
"tlsAuthRequired": "true"
},
"mps": {
"profile": "eu868"
},
"tlsCaCert": "-----BEGIN CERTIFICATE-----\nMIIB....\n-----END CERTIFICATE-----\n",
"tlsCert": "-----BEGIN CERTIFICATE-----\nMIIB....\n-----END CERTIFICATE-----\n",
"tlsKey": "-----BEGIN PRIVATE KEY-----\nMIIE....\n-----END PRIVATE KEY-----\n"
},
"persistent": true,
"restart": true
}
Important
The system time must be valid before applying TLS configuration. Set the time using
/cgi-bin/time as described in Initial Setup.
Firmware Update
The card firmware can be updated in the field. The card downloads a RAUC bundle from an HTTP server and installs it. The bundle URL is passed in the update request and can point to any server reachable by the card.
If the host has internet access and NAT is configured as described above:
Trigger the Update
Set the system time before triggering the update, then start the install:
Monitor Progress
The install runs in the background. Poll the status endpoint until the state is no longer
installing:
Possible states are idle, installing, success, failed, and timeout. On failure, the
error and log fields contain details from the installer.
Reboot
After a successful update, reboot the card to activate the new firmware:
The USB connection will drop during reboot. Wait 30-60 seconds, then use GET /cgi-bin/status
to confirm the card is back online.
Diagnostics
The card exposes recent system journal entries via the errors endpoint. This is useful for verifying that the BS service has started and connected to the service center, or for diagnosing connection issues.
Fetch last 100 lines and show only entries with priority 0-3 (error and above):
Antenna Recommendation
The miro EdgeCard mioty has been certified using the 2JW1115-C952B 868/915 MHz ISM antenna from 2J Antennas. This antenna is ground-plane independent and suitable for enclosure mounting without a metal backplane.
The card exposes a U.FL connector. Connect the antenna using a U.FL to SMA adapter cable.
Antenna Selection
Reads or sets the antenna selection for RX and TX.
Note
This endpoint requires the recon interface to be enabled. Set "recon": true in the
POST /cgi-bin/config request before using this endpoint.
Read
No request body required.
| Field | Type | Description |
|---|---|---|
rxant |
string | Antenna selected for RX ("0" or "1") |
txant |
string | Antenna selected for TX ("0" or "1") |
Set
| Field | Type | Description |
|---|---|---|
rxant |
integer | Antenna selected for RX (0 or 1) |
txant |
integer | Antenna selected for TX (0 or 1) |
At least one of rxant or txant must be provided.
Returns HTTP 200 with an empty JSON object {} on success.
Example Command