IP Configuration Packet: Difference between revisions
No edit summary |
No edit summary |
||
| Line 150: | Line 150: | ||
} | } | ||
</pre> | </pre> | ||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>IP Configuration Packet Parser</title> | |||
<style> | |||
body { font-family: Arial, sans-serif; padding: 20px; } | |||
textarea { width: 100%; height: 100px; font-family: monospace; } | |||
button { | |||
padding: 10px 20px; border-radius: 20px; font-weight: bold; | |||
background-color: #680022; color: white; border: none; | |||
} | |||
button:hover { background-color: #4c0019; } | |||
table { width: 100%; border-collapse: collapse; } | |||
th, td { border: 1px solid #ccc; padding: 8px; } | |||
th { background-color: #680022; color: white; } | |||
</style> | |||
</head> | |||
<body> | |||
<h2>IP Configuration Packet Parser</h2> | |||
<textarea id="packetInput" placeholder="Paste IP Configuration packet here..."></textarea><br> | |||
<button onclick="parsePacket()">Parse Packet</button> | |||
<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(byte => parseInt(byte, 16).toString(2).padStart(8, '0')).join(''); | |||
} | |||
function bitsToInt(bits) { | |||
return parseInt(bits, 2); | |||
} | |||
function bitsToSignedInt(bits) { | |||
const val = parseInt(bits, 2); | |||
const max = 2 ** bits.length; | |||
return val >= max / 2 ? val - max : val; | |||
} | |||
function bigIntFromBits(bits) { | |||
return BigInt('0b' + bits).toString(); | |||
} | |||
function bitsToAscii(bits) { | |||
return bits.match(/.{8}/g).map(b => String.fromCharCode(parseInt(b, 2))).join(''); | |||
} | |||
function addRow(label, value) { | |||
const row = document.createElement("tr"); | |||
row.innerHTML = `<td>${label}</td><td>${value}</td>`; | |||
document.querySelector("#resultTable tbody").appendChild(row); | |||
} | |||
function parsePacket() { | |||
const hex = document.getElementById("packetInput").value.trim(); | |||
const resultBody = document.querySelector("#resultTable tbody"); | |||
resultBody.innerHTML = ""; | |||
if (!hex.startsWith("24")) { | |||
alert("Invalid packet (must start with 0x24)"); | |||
return; | |||
} | |||
const bits = hexToBits(hex); | |||
const imei = bigIntFromBits(bits.slice(25, 75)); // Corrected IMEI (50 bits) | |||
addRow("IMEI", imei); | |||
const packetType = bitsToInt(bits.slice(75, 80)); // 5 bits | |||
addRow("Packet Type", packetType); | |||
const ts = bitsToInt(bits.slice(80, 112)); | |||
const timezoneRaw = bitsToSignedInt(bits.slice(112, 120)); | |||
const tzOffsetMin = timezoneRaw * 15; | |||
const localTime = new Date((ts + tzOffsetMin * 60) * 1000).toISOString().replace("T", " ").split(".")[0]; | |||
addRow("DateTime (Epoch)", ts); | |||
addRow("TimeZone", timezoneRaw); | |||
addRow("DateTime (Local)", localTime); | |||
const ipIndex = bitsToInt(bits.slice(120, 122)); // 2 bits | |||
const status = bitsToInt(bits.slice(123, 124)); // 1 bit | |||
const fsMode = bitsToInt(bits.slice(124, 125)); // 1 bit | |||
const protocol = bitsToInt(bits.slice(125, 127)); // 2 bits | |||
addRow("IP Index", ipIndex); | |||
addRow("Status", status); | |||
addRow("FS Mode", fsMode); | |||
addRow("Protocol", protocol); // 0=HTTP, 1=HTTPS, 2=TCP | |||
const rateOn = bitsToInt(bits.slice(128, 144)); // 16 bits | |||
const rateOff = bitsToInt(bits.slice(144, 160)); // 16 bits | |||
const rateSleep = bitsToInt(bits.slice(160, 176)); // 16 bits | |||
addRow("Update Rate (Ign ON)", `${rateOn}s`); | |||
addRow("Update Rate (Ign OFF)", `${rateOff}s`); | |||
addRow("Update Rate (Sleep)", `${rateSleep}s`); | |||
const urlLengthBytes = bitsToInt(bits.slice(176, 183)); // 7 bits = bytes | |||
const urlBits = bits.slice(184, 184 + urlLengthBytes * 8); | |||
const url = bitsToAscii(urlBits).split('*')[0]; // Remove garbage after '*' | |||
addRow("URL Length", urlLengthBytes * 2); // actual in bits for output match | |||
addRow("URL", url); | |||
} | |||
</script> | |||
</body> | |||
</html> | |||
Revision as of 04:24, 22 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 | 8 - 19 | 2-byte length of the data following the header | |
| Number of data packets | 5 | 20 - 24 | Number of packets | 0–32 |
| IMEI | 50 | 25 - 74 | Unique device identifier | |
| Packet type | 5 | 75 - 79 | Type of packet | 02 - OTA Packet |
| Data | ||||
| Time | 32 | UTC Timestamp | UTC time in seconds | |
| Time Zone | 8 | Timezone in quarter-hours | 22 = +5:30; each unit = 15 min; ranges -48 to 56 | |
| IP index | 3 | IP type index | 0: Transight IP, 1: Customer IP | |
| Status | 1 | OTA status | 0 - Disabled, 1 - Enabled | |
| FS mode | 1 | Fuel Sensor mode | 0 - FIFO, 1 - LIFO | |
| Protocol | 3 | Communication protocol | 0 - HTTP, 1 - HTTPS, 2 - TCP, 3 - MQTT | |
| Update rate (motion/Ign On) | 16 | Reporting interval while in motion | In seconds | |
| Update rate (halt/Ign Off) | 16 | Reporting interval during halt | In seconds | |
| Update rate (Sleep) | 16 | Sleep mode reporting interval | In seconds | |
| URL length | 8 | Length of URL field | In number of bytes | |
| URL | Varies | URL data | Length given by URL length | |
| Tail (2 Bytes) | ||||
| End Character | 8 | 0 - 7 | Ending character | * (ASCII value 42) |
| CRC | 8 | 8 - 15 | Checksum | 8-bit XOR from $ to * (excluding $ and *) |
{
"HEX": "2401e0e1cabd09208ca56822dde716320005000100028831352e3233352e392e36363a35303333372a82",
"dateTime": 1747115495,
"dateTime_tz": "2025-05-13 11:21:35.000",
"fsMode": 0,
"imei": 860187062240357,
"insert_time": "Tue, 13 May 2025 05:51:37 GMT",
"ipIndex": 1,
"packetType": 5,
"protocol": 2,
"send_time": "2025-05-13 11:21:35",
"status": 1,
"timezone": 22,
"upRateIgOff": 1,
"upRateIgOn": 5,
"upRateSleep": 2,
"url": "15.235.9.66:50337",
"urlLength": 136
}
IP Configuration Packet Parser
| Field | Value |
|---|