Connection & Authentication
A Lixel device runs a built-in MQTT broker and RTSP service. Real-time control and the real-time point cloud go over MQTT; the real-time video goes over RTSP. The device supports both wired and wireless networking with other devices: wired over a USB cable, wireless over Wi-Fi.
Connection parameters
Each product model supports only one of the connection protocols (not both):
| Protocol | Port | Username | Password | Product model |
|---|---|---|---|---|
| MQTT | 1883 | — | — | K1 / L2PRO |
| MQTTS | 8883 | Provided by the vendor | Provided by the vendor | Known: K2 / H1 / F1 / Porcam use MQTTS (source: example project comments); other models follow the port the device actually exposes |
- MQTT version: V3.1.1
- Wired networking uses the fixed IP
192.168.55.1; for wireless networking the IP is obtained over Bluetooth. - In Quick Connect mode the device IP is fixed at
192.168.56.1.
Note: MQTTS uses TLS. The device uses a self-signed certificate, and the example clients disable certificate verification by default to work with it. When MQTTS is selected, pass the vendor-provided username and password. With verification off, the client cannot confirm it is really talking to the device; a man-in-the-middle on the same network can impersonate the device and read the requests (including the
openapi_key). Before production, switch to importing the device certificate and enabling verification.
USB connection
Devices running Linux, Windows, or Android share the network with the Lixel device over RNDIS; iOS devices use USB Tethering.
Lixel device (192.168.55.1) other device
+---------+ +---------+
| USB | <----- RNDIS / USB Tethering ----> | USB |
+---------+ +---------+
Wi-Fi connection
The device supports three wireless modes:
- Normal mode: another device acts as the hotspot.
- Quick Connect mode: the Lixel device acts as the hotspot.
- Bridge mode: a router is used.
All modes require network provisioning over Bluetooth first. The device accepts a Bluetooth connection to configure Wi-Fi so it can join a given network.
The device's Bluetooth name has 10 characters: most models use the fixed prefix XGR- plus the last 6 digits of the SN, e.g. XGR-A12345; some ODM models use a different prefix (e.g. PCAM). Follow the name you actually scan.
Lixel device other device
+---------+ +---------+
| BT | <----- Bluetooth (provisioning) --> | BT |
| WiFi | <----- WiFi (data) ---------------> | WiFi |
+---------+ +---------+
Provisioning flow
The BLE provisioning flow between the device and the client: the client, as the master, searches for and connects to the device (the slave); after connecting, the device first sends its current Wi-Fi status; if Wi-Fi is not connected, the client sends the Wi-Fi info (SSID and password) and the device joins the target network.
Lixel device client
+----------------------+ +----------------------+
| BLE slave mode | | BLE master mode |
+----------+-----------+ +----------+-----------+
| |
v <---- connecting ----> v
+----------------------+ +----------------------+
| send WiFi status | ------------------> | get WiFi status |
+----------+-----------+ +----+------------+----+
| | |
| WiFi not | | WiFi
| connected | | connected
| <------ send WiFi info ----------- | |
v v v
+----------------------+ +----------------------+
| connect to WiFi | | end |
+----------------------+ +----------------------+
OpenAPI Key authentication
An OpenAPI request is executed only after the device authenticates it. The request header must carry openapi_key, which the device uses to validate the request. When openapi_key is missing or wrong, the device still replies: error.code is EC_ProtoError (0x32040001), error.desc is openapi auth error, the response carries no business data, and request() returns normally without a timeout.
Requesting an OpenAPI Key
The OpenAPI Key is distributed by XGRIDS and cannot be generated by yourself. To obtain one:
- Request it through the XGRIDS business or technical support channel, stating the device model and intended use.
- XGRIDS checks and issues a key string.
- Fill it into the connection configuration; no extra activation step is needed.
Note: the key is bound to a specific device / authorization. Keep it safe; do not hard-code it into a public repository or share it with third parties.
Using it in code
Set ClientOptions.openapi_key, and request() / publish() fill it into the header automatically:
from example.core import ClientOptions, OpenApiClient
opts = ClientOptions(host="192.168.55.1", openapi_key="<provided by XGRIDS>")
with OpenApiClient(opts) as client:
... # header.openapi_key is filled automatically
Header fields
The first field of every request/response/report message is usually a Header:
| Field | Type | Description |
|---|---|---|
seq | uint32 | Frame sequence number |
stamp | sint64 | Frame timestamp. Device-reported frames are in microseconds, with the Unix epoch as the time base |
scaler | sint64 | Scale factor (used by point cloud, etc.) |
device_id | string | Device ID (generated by the device) |
session_id | string | Session ID (generated by the request/report side) |
openapi_key | string | API key (optional in the proto, but the device executes only requests with a valid key) |
The corresponding proto definition:
message Header {
uint32 seq = 1; // frame sequence number
sint64 stamp = 2; // frame timestamp
sint64 scaler = 3; // scale factor (positive: magnify, negative: shrink, 0: disable scaling)
string device_id = 4; // device ID (generated by the device)
string session_id = 5; // session ID (generated by the request/report side)
optional string openapi_key = 6; // API key (apply from XGRIDS)
}
Appendix: low-level provisioning interface
Note: this section is only for reference when you implement Bluetooth provisioning yourself (without an existing app). In most cases provisioning is done with the bundled tool or app, and you do not need these low-level definitions.
Provisioning reads and writes characteristics over the BLE GATT service. Android and iOS use different UUIDs:
/* Android GATT Characteristic Types */
#define UUID_GATT 0x1801
#define GATT_CHARAC_WIFI_INFO_SET 0x2AB0
#define GATT_CHARAC_WIFI_STATUS_GET 0x2AB1
/* iOS GATT Characteristic Types */
#define IOS_UUID_GATT 0x7F00
#define IOS_GATT_CHARAC_WIFI_INFO_SET 0x7F01
#define IOS_GATT_CHARAC_WIFI_STATUS_GET 0x7F02
The data structures for writing the Wi-Fi config and reading the Wi-Fi status:
#pragma pack(1)
/***********************************************************
* WiFi status information (device -> Android)
* ssid_len : 0 means WiFi is disconnected
* ssid : WiFi access point name
* ip_len : 0 means WiFi has no assigned IP
* ip : WiFi IP address
* auth_mode: Not used yet
* wifi_mode: 0 - STA mode 1 - AP mode (Quick Connect mode) 255 - ignore WiFi mode
**********************************************************/
typedef struct wifi_info_s {
uint8 ssid_len;
uint8 ssid[32];
uint8 passwd_len;
uint8 passwd[64];
uint8 auth_mode;
uint8 wifi_mode; // 0: Normal mode 1: Quick Connect mode 255: Only configure country code
uint8 country_code[2]; // Country code (ISO2)
} wifi_info_t;
typedef struct wifi_status_s {
uint8 ssid_len;
uint8 ssid[32];
uint8 ip_len;
uint8 ip[16];
uint8 connect_state; // 0 - Not connected 1 - Connected successfully 2 - Connecting 3 - Device scanning
uint8 wifi_mode; // 0: Normal mode 1: Quick Connect mode
uint8 country_code[2]; // Country code (ISO2)
} wifi_status_t;
#pragma pack()