EU/GDPR firmware speaking a JSON payload format over /cgi_gdpr?9.
Confirmed on a TP-Link EX220 (issue #254). Also believed to cover the TP-LINK NE200 5G modem, from whose capture it was built, and probably the VX800v — neither confirmed (issue #82).
Differences from gdprText, all measured from the NE200 capture:
| Concern | gdprText |
gdprJson |
|---|---|---|
| Command endpoint | /cgi_gdpr |
/cgi_gdpr?9 |
| Public key endpoint | /cgi/getParm |
/cgi/getGDPRParm |
| Login | own endpoint /cgi/login, envelope in the query string |
a command posted to /cgi_gdpr?9 |
| Default username | admin |
user |
| Credentials | username\npassword |
base64 fields inside JSON |
| Payload | bracketed text blocks | JSON envelope |
| Operations | 1, 2, … |
go, gl, cgi |
| Stack default | 0,0,0,0,0,0 |
0,0,0,0,0,0 |
| Batching | N actions per request | one action per request |
| Session cookie | loginErrorShow + JSESSIONID |
JSESSIONID only |
Responses come in two shapes: go and gl answer with a JSON envelope,
while cgi operations answer with the plain-text $.ret=<code> form that the
captured login response uses. decodeCommand handles both.
Encode a login payload
Encode a login payload
import { assertEquals } from "@std/assert"; import { gdprJson } from "./gdprJson.ts"; assertEquals( gdprJson.encodeLogin({ username: "user", password: "hunter2" }), '{"data":{"UserName":"dXNlcg==","Passwd":"aHVudGVyMg==","Action":"1",' + '"stack":"0,0,0,0,0,0","pstack":"0,0,0,0,0,0"},' + '"operation":"cgi","oid":"/cgi/login"}', );
One request per action
One request per action
import { assertEquals } from "@std/assert"; import { ACT } from "./dialect.ts"; import { gdprJson } from "./gdprJson.ts"; const batches = gdprJson.encodeCommands([ [ACT.GET, "DEV2_DEV_INFO"], [ACT.GL, "DEV2_LTE_SERVING_CELL_INFO"], ]); assertEquals(batches.length, 2); assertEquals(batches[0].indices, [0]); assertEquals(batches[1].indices, [1]);
Decode a list response
Decode a list response
import { assertEquals } from "@std/assert"; import { gdprJson } from "./gdprJson.ts"; const decoded = gdprJson.decodeCommand( '{"success":true,"data":[{"band":"n78"},{"band":"1"}]}', { payload: "", indices: [3] }, ); assertEquals(decoded.error, null); assertEquals(decoded.results, [[{ band: "n78" }, { band: "1" }]]);