Jump to content

Device Configuration Packet: Difference between revisions

From Transight Wiki
No edit summary
No edit summary
Line 293: Line 293:
}
}
</pre>
</pre>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Device Configuration Packet Parser</title>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; }
    textarea { width: 100%; height: 120px; font-family: monospace; }
    button {
      padding: 10px 20px; border-radius: 20px; 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; }
    th { background-color: #680022; color: white; }
  </style>
</head>
<body>
<h2>Device Configuration Packet Parser</h2>
<textarea id="packetInput" placeholder="Paste Device Configuration hex packet here..."></textarea><br>
<button onclick="parsePacket()">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);
  const max = 1 << bits.length;
  return val >= max / 2 ? val - max : val;
}
function bitsToAscii(bits) {
  return bits.match(/.{8}/g).map(b => String.fromCharCode(parseInt(b, 2))).join('').replace(/\0/g, '').trim();
}
function parseMobile(bits) {
  const isWithCountryCode = bits[0] === '1';
  const number = BigInt('0b' + bits.slice(1)).toString();
  return isWithCountryCode ? `+${number}` : number;
}
function parsePacket() {
  const hex = document.getElementById('packetInput').value.trim().toLowerCase();
  const resultBody = document.querySelector("#resultTable tbody");
  resultBody.innerHTML = "";
  if (!hex.startsWith("24")) {
    alert("Invalid Packet");
    return;
  }
  const bits = hexToBits(hex);
  const show = (key, value) => {
    const row = document.createElement("tr");
    row.innerHTML = `<td>${key}</td><td>${value}</td>`;
    resultBody.appendChild(row);
  };
  show("Start Byte", hex.slice(0, 2));
  show("Packet Type", bitsToInt(bits.slice(75, 80)));
  const imei = BigInt('0b' + bits.slice(25, 75)).toString();
  show("IMEI", imei);
  const timestamp = bitsToInt(bits.slice(80, 112));
  const timezoneRaw = bitsToSignedInt(bits.slice(112, 120));
  const offsetMins = timezoneRaw * 15;
  const localDate = new Date((timestamp + offsetMins * 60) * 1000).toISOString().replace("T", " ").replace(".000Z", "");
  show("DateTime", timestamp);
  show("TimeZone", `UTC${offsetMins >= 0 ? '+' : ''}${offsetMins / 60}`);
  show("DateTime (Local Time)", localDate);
  show("IgnitionSource", bitsToInt(bits.slice(120, 122)));
  show("CellOperator", bitsToInt(bits.slice(122, 126)));
  show("FuelSensorCount", bitsToInt(bits.slice(126, 128)));
  show("FuelSensorName", bitsToInt(bits.slice(128, 132)));
  show("FuelSensorBaudrate", bitsToInt(bits.slice(132, 144)));
  show("FuelSensorMode", bitsToInt(bits.slice(144, 146)));
  show("OneWireStatus", bitsToInt(bits.slice(146, 147)));
  show("OneWireType", bitsToInt(bits.slice(147, 150)));
  show("OneWireSensorCount", bitsToInt(bits.slice(150, 153)));
  show("OdometerMode", bitsToInt(bits.slice(153, 154)));
  show("SpeedThreshold", bitsToInt(bits.slice(154, 163)));
  show("HAT", bitsToInt(bits.slice(163, 175)));
  show("HBT", bitsToInt(bits.slice(175, 187)));
  show("RTT", bitsToInt(bits.slice(187, 196)));
  show("TAT", bitsToInt(bits.slice(196, 205)));
  show("ImmobilizerStatus", bitsToInt(bits.slice(205, 206)));
  show("ImmobilizerSpeed", bitsToInt(bits.slice(206, 215)));
  show("DigitalInStatus", bitsToInt(bits.slice(215, 219)));
  show("DigitalOutStatus", bitsToInt(bits.slice(219, 221)));
  show("AnalogInStatus", bitsToInt(bits.slice(221, 223)));
  show("SMSM1", parseMobile(bits.slice(223, 274)));
  show("SMSM2", parseMobile(bits.slice(274, 325)));
  show("NOOfIP", bitsToInt(bits.slice(325, 328)));
  show("IMMOBSrc", bitsToInt(bits.slice(328, 331)));
  const apnLen = bitsToInt(bits.slice(331, 336));
  const apnBits = bits.slice(336, 336 + apnLen * 8);
  show("APN", bitsToAscii(apnBits));
  // End Byte and CRC (last 2 bytes)
  const endByte = hex.slice(-4, -2);
  const crc = hex.slice(-2);
  show("End Byte", String.fromCharCode(parseInt(endByte, 16)));
  show("CRC", `0x${crc}`);
  show("CRC Status", "Valid (not implemented)"); // CRC logic can be added
}
</script>
</body>
</html>

Revision as of 05:37, 22 July 2025

Field Size (bits) Bit Range Description Breakdown
Header
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
Timezone 8 Timezone in quarter-hours 22 = +5:30 (22 × 15min = 330min = 5.5hr)
IGN Source 2 Source of ignition detection 0 - IGN PIN, 1 – Vibration, 2 - Voltage, 3 - GPS
Cell Operator 4
Fuel Sensor Count 2 Number of fuel sensors
Fuel Sensor Name 4 Refer sheet Enums
Fuel Sensor Baudrate 12 up to 115200
Fuel Sensor Mode 2
Onewire Status 1 Enable or disable
Onewire Sensor Type 3
Onewire Sensor Count 3
Odometer Mode 1 0 or 1 (Accumulated or Differential)
Speed Threshold 9 0–360
HAT 12 50–3500
HBT 12 50–3500
RTT 9 5–480
Tilt Angle Threshold 9 5–359
Immobilizer Status 1
Immobilizer Speed 9
Digital Input Status 4 3
Digital Output Status 2 0–3
Analog Input Status 2 0 or 1
SMS M1 51 MSB 1 - country code included, MSB 0 - no country code Remaining 50 bits = mobile number
SMS M2 51 Same format as SMS M1
Number of IPs 3 0–5
IMOBSRC 3
APN Length 5 Length in bytes
APN Variable Access Point Name Length defined by APN length
Tail
End Character 8 0 - 7 Ending character * ASCII value 42
CRC 8 8 - 15 XOR CRC from $ to * Excludes $ and *

OTA Packet (Type 4)

{
  "HEX": "240280e1cabd09208ca46822dde6160c00000006400400002168280000357c8b071280000000000002084d324d49534146452a6a",
  "ai_status": 0,
  "apn": 77,
  "apn_length": 8,
  "cell_op": 3,
  "dateTime": 1747115494,
  "dateTime_tz": "2025-05-13 11:21:34.000",
  "di_status": 0,
  "do_status": 0,
  "fs_baudrate": 0,
  "fs_count": 0,
  "fs_mode": 0,
  "fs_name": 0,
  "hat": 1,
  "hbt": 0,
  "ign_source": 0,
  "imbz_status": 2,
  "imei": 860187062240357,
  "immobilizer_speed": 20,
  "imobsrc": 0,
  "insert_time": "Tue, 13 May 2025 05:51:37 GMT",
  "no_ips": 2,
  "odometer_mode": 0,
  "onewire_count": 0,
  "onewire_status": 0,
  "onewire_type": 0,
  "packetType": 4,
  "rtt": 1,
  "send_time": "2025-05-13 11:21:34",
  "sms_m1": 918891011146,
  "sms_m2": 0,
  "speed_threshold": 25,
  "tilt_angle_threshold": 22,
  "timezone": 22
}


Device Configuration Packet Parser

Device Configuration Packet Parser


Parsed Output:

FieldValue