Device Info Packet: Difference between revisions
No edit summary |
No edit summary |
||
| Line 192: | Line 192: | ||
"vid": "\u0000\u0000\u0000\u0000", | "vid": "\u0000\u0000\u0000\u0000", | ||
"vn": "^\u0001\u0000\u0000^\u0001\u0000\u0000^\u0001" | "vn": "^\u0001\u0000\u0000^\u0001\u0000\u0000^\u0001" | ||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Device Info Packet Parser</title> | |||
<style> | |||
body { font-family: Arial, sans-serif; } | |||
textarea { width: 100%; height: 100px; font-family: monospace; } | |||
button { | |||
padding: 10px 20px; | |||
border-radius: 20px; | |||
margin-top: 10px; | |||
font-weight: bold; | |||
background-color: #680022; | |||
color: white; | |||
border: none; | |||
cursor: pointer; | |||
} | |||
button:hover { | |||
background-color: #4c0019; | |||
} | |||
table { width: 100%; border-collapse: collapse; margin-top: 20px; } | |||
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; } | |||
th { background-color: #680022; color: white; } | |||
</style> | |||
</head> | |||
<body> | |||
<h2>Device Info Packet Parser</h2> | |||
<textarea id="hexInput" placeholder="Paste Device Info Packet here..."></textarea><br> | |||
<button onclick="parseDeviceInfo()">Parse Packet</button> | |||
<h3>Parsed Output:</h3> | |||
<table id="resultTable"> | |||
<thead><tr><th>Field</th><th>Value</th></tr></thead> | |||
<tbody></tbody> | |||
</table> | |||
<script> | |||
function hexToBits(hex) { | |||
return hex.match(/.{1,2}/g).map(b => parseInt(b, 16).toString(2).padStart(8, '0')).join(''); | |||
} | |||
function bitsToInt(bits) { | |||
return parseInt(bits, 2); | |||
} | |||
function bitsToSignedInt(bits) { | |||
const val = parseInt(bits, 2); | |||
return val >= 2 ** (bits.length - 1) ? val - 2 ** bits.length : val; | |||
} | |||
function bitsToAscii(bits) { | |||
return bits.match(/.{1,8}/g).map(b => String.fromCharCode(parseInt(b, 2))).join('').replace(/\0/g, ''); | |||
} | |||
function bigIntFromBits(bits) { | |||
return BigInt('0b' + bits).toString(); | |||
} | |||
function parseDeviceInfo() { | |||
const hex = document.getElementById("hexInput").value.trim().toLowerCase(); | |||
const resultBody = document.querySelector("#resultTable tbody"); | |||
resultBody.innerHTML = ""; | |||
if (!hex || !hex.startsWith("24")) { | |||
alert("Invalid packet! Must start with 24 (hex for $)"); | |||
return; | |||
} | |||
const bits = hexToBits(hex); | |||
const output = (label, value) => { | |||
const row = document.createElement("tr"); | |||
row.innerHTML = `<td>${label}</td><td>${value}</td>`; | |||
resultBody.appendChild(row); | |||
}; | |||
const fields = [ | |||
["Start Character", 0, 8], | |||
["Length", 8, 18], | |||
["No of Packets", 19, 23], | |||
["IMEI", 24, 74], | |||
["Packet Type", 75, 79], | |||
["Time", 80, 111], | |||
["Time Zone", 112, 119], | |||
["ICCID", 120, 279], | |||
["VID", 280, 311], | |||
["CELLULAR_MODULE_FV NAME", 312, 351], | |||
["CELLULAR_MODULE_FV VERSION", 352, 431], | |||
["CELLULAR_MODULE_FV BUILD NO", 432, 471], | |||
["MCU_APP_MODULE_FV NAME", 472, 511], | |||
["MCU_APP_MODULE_FV VERSION", 512, 591], | |||
["MCU_APP_MODULE_FV BUILD NO", 592, 631], | |||
["MCU_BTL_MODULE_FV NAME", 632, 671], | |||
["MCU_BTL_MODULE_FV VERSION", 672, 751], | |||
["MCU_BTL_MODULE_FV BUILD NO", 752, 791], | |||
["VN", 792, 878], | |||
["HWINFO", 879, 958], | |||
["End Character", 959, 967], | |||
["CRC", 968, 976] | |||
]; | |||
for (const [label, start, end] of fields) { | |||
const val = bits.slice(start, end); | |||
switch (label) { | |||
case "IMEI": | |||
output(label, bigIntFromBits(val)); | |||
break; | |||
case "Time": | |||
const timestamp = bitsToInt(val); | |||
output(label, new Date(timestamp * 1000).toISOString()); | |||
break; | |||
case "Time Zone": | |||
const tz = bitsToSignedInt(val); | |||
const mins = tz * 15; | |||
const sign = mins >= 0 ? "+" : "-"; | |||
const h = Math.floor(Math.abs(mins) / 60); | |||
const m = Math.abs(mins % 60); | |||
output("Time Zone", `${mins} mins (UTC${sign}${h}:${m.toString().padStart(2, '0')})`); | |||
break; | |||
case "ICCID": | |||
case "VID": | |||
case "CELLULAR_MODULE_FV NAME": | |||
case "CELLULAR_MODULE_FV VERSION": | |||
case "CELLULAR_MODULE_FV BUILD NO": | |||
case "MCU_APP_MODULE_FV NAME": | |||
case "MCU_APP_MODULE_FV VERSION": | |||
case "MCU_APP_MODULE_FV BUILD NO": | |||
case "MCU_BTL_MODULE_FV NAME": | |||
case "MCU_BTL_MODULE_FV VERSION": | |||
case "MCU_BTL_MODULE_FV BUILD NO": | |||
case "VN": | |||
case "HWINFO": | |||
output(label, bitsToAscii(val).trim()); | |||
break; | |||
case "Start Character": | |||
output(label, String.fromCharCode(bitsToInt(val))); | |||
break; | |||
case "End Character": | |||
output(label, String.fromCharCode(bitsToInt(val))); | |||
break; | |||
case "CRC": | |||
output(label, bitsToInt(val).toString(16).toUpperCase().padStart(2, '0')); | |||
break; | |||
default: | |||
output(label, bitsToInt(val)); | |||
} | |||
} | |||
} | |||
</script> | |||
</body> | |||
</html> | |||
Revision as of 10:01, 16 July 2025
| Field | Size (bits) | Bit Range | Description | Breakdown |
|---|---|---|---|---|
| Header (10 Bytes) | ||||
| Start byte | 8 | 0–7 | Starting character $ (ASCII value 36) | |
| Data length | 12 | 08–19 | 2-byte length of the data following the header | |
| Number of data packets | 5 | 20–24 | Number of packets (0–32) | 0–32 |
| IMEI | 50 | 25–74 | Unique device identifier | |
| Packet type | 5 | 75–79 | Type of packet | 00 - Device Info |
| Data | ||||
| Time | 32 | UTC Timestamp | UTC time in seconds | |
| Time Zone | 8 | Timezone in quarter-hours (e.g., 22 = +5:30), quarter-hour increment means each unit represents 15 minutes. The value 22 represents 22 quarter hours. Ranges from -48 to 56, negative timezone to 2's complement representation | eg: 22 (+5:30) → 22×15=330 minutes → 330÷60=5.5 hours → 5 hours and 30 minutes | |
| ICCID | 160 | 20 Bytes, Character string | 8991000903297069053F | |
| VID | 32 | 4 Bytes, Character string | TRAN | |
| CELLULAR_MODULE_FV NAME | 40 | 5 Bytes, Character string | TSPJT | |
| CELLULAR_MODULE_FV VERSION | 80 | 10 Bytes, Character string | XX.YY.ZZZZ | |
| CELLULAR_MODULE_FV BUILD NO | 40 | 5 Bytes, Character string | YYDDD | |
| MCU_APP_MODULE_FV NAME | 40 | 5 Bytes, Character string | TSPJT | |
| MCU_APP_MODULE_FV VERSION | 80 | 10 Bytes, Character string | XX.YY.ZZZZ | |
| MCU_APP_MODULE_FV BUILD NO | 40 | 5 Bytes, Character string | YYDDD | |
| MCU_BTL_MODULE_FV NAME | 40 | 5 Bytes, Character string | TSPJT | |
| MCU_BTL_MODULE_FV VERSION | 80 | 10 Bytes, Character string | XX.YY.ZZZZ | |
| MCU_BTL_MODULE_FV BUILD NO | 40 | 5 Bytes, Character string | YYDDD | |
| VN | 80 | 10 Bytes, Character string | KL07CP8490 | |
| HWINFO | 88 | 11 Bytes, Character string | PCB-0220-AB | |
| Tail(2 Bytes) | ||||
| End Character | 8 | 0–7 | Starting character * (ASCII value 42) | |
| CRC | 8 | 8–15 | 8-bit XOR CRC of data starting from $ to * (excluding $ and *) | |
Sample Packet
"HEX": "2406e0e1cabd09208ca06822dac31638393931393530393132393633373932393630000000000545344324720322e20302e202020312020202030545344324e20312e20312e202020313235303935545344324220302e20302e2020203020202020305e0100005e0100005e015043422d303232302d41422a1c", "cmfv_build": "0", "cmfv_name": "TSD2G", "cmfv_version": "2. 0. 1", "dateTime": 1747114691, "dateTime_tz": "2025-05-13 11:08:11.000", "hwinfo_build": "PCB-0220-AB", "iccid": "8991950912963792962\u0000", "imei": 860187062240357, "insert_time": "Tue, 13 May 2025 05:38:15 GMT", "mcua_build": "25095", "mcua_name": "TSD2N", "mcua_version": "1. 1.1", "mcub_build": "0", "mcub_name": "TSD2B", "mcub_version": "0.0.0", "packetType": 0, "send_time": "2025-05-13 11:08:11", "timezone": 22, "vid": "\u0000\u0000\u0000\u0000", "vn": "^\u0001\u0000\u0000^\u0001\u0000\u0000^\u0001"
Device Info Packet Parser
Parsed Output:
| Field | Value |
|---|