---
title: Decoder LTE – Bluetooth gateway
description: "[decode-lte-bluetooth-gateway.js](https://www.lansitec.com/wp-content/uploads/2026/08/decode-lte-bluetooth-gateway.js.zip)[Download](https://www.lansitec.com/wp-content/uploads/2026/08/decode-lte-bluetooth-gateway.js.zip) Below the full decoder code: ``` // Decode uplink function. // // Input is an object with the following fields: // - bytes = Byte array containing the uplink payload, e.g. [255, 230, 255, 0] // - fPort =…"
url: "https://www.lansitec.com/docs/decoders/decoder-lte-bluetooth-gateway/"
updated: "2026-08-26"
category: Decoders
---

# Decoder LTE – Bluetooth gateway

[decode-lte-bluetooth-gateway.js](https://www.lansitec.com/wp-content/uploads/2026/08/decode-lte-bluetooth-gateway.js.zip)[Download](https://www.lansitec.com/wp-content/uploads/2026/08/decode-lte-bluetooth-gateway.js.zip)

Below the full decoder code:

```
// Decode uplink function.
//
// Input is an object with the following fields:
// - bytes = Byte array containing the uplink payload, e.g. [255, 230, 255, 0]
// - fPort = Uplink fPort.
// - variables = Object containing the configconsoleured device variables.
//
// Output must be an object with the following fields:
// - data = Object representing the decoded payload.

// NB-IoT Bluetooth Gateway
function decodeUplink(input) {
  // bytes
  var bytes = input.bytes;
  // type
  var uplinkType = (bytes[0] >> 4) & 0x0f;

  switch (uplinkType) {
    case 0x01:
      return { data: decodeRegistration(bytes) };

    case 0x02:
      return { data: decodeHeartbeat(bytes) };

    case 0x06:
      return { data: decodeConfigParameterResponse(bytes) };

    case 0x07:
      return { data: decodeBleDeviceMessage(bytes) };

    default:
      return;
  }
}

// type: 0x1 Registration
function decodeRegistration(bytes) {
  var data = {};
  data.type = "Registration";

  data.deviceRssiSortEnable = (bytes[1] >> 1) & 0x01;

  data.bleReceivingEnable = (bytes[2] >> 7) & 0x01;

  data.heartbeatPeriod =
    (((bytes[6] << 8) & 0xff00) | (bytes[7] & 0xff)) * 30 + "s";

  data.bleDeviceReportInterval =
    (((bytes[14] << 8) & 0xff00) | (bytes[15] & 0xff)) * 5 + "s";

  data.bleReceivingDuration = bytes[16] & 0xff;

  data.version = ((bytes[17] << 8) & 0xff00) | (bytes[18] & 0xff);

  var imsi = "";
  for (let i = 0; i < 8; i++) {
    imsi += bytes[19 + i].toString(16).toUpperCase().padStart(2, "0");
  }
  data.imsi = imsi.substring(0, 15);
  data.messageId = ((bytes[27] << 8) & 0xff00) | (bytes[28] & 0xff);
  return data;
}
// type: 0x2 Heartbeat
function decodeHeartbeat(bytes) {
  var data = {};
  data.type = "HeartbeatMessage";
  var stateBitField = {};
  stateBitField.deviceRssiSortEnable = (bytes[1] >> 1) & 0x01;
  stateBitField.bleReceivingEnable = (bytes[2] >> 7) & 0x01;
  data.stateBitField = stateBitField;

  data.batteryVoltage = (bytes[5] & 0xff) * 0.1 + "V";
  data.batteryLevel = (bytes[6] & 0xff) + "%";
  data.bleReceivingCount = bytes[7] & 0xff;
  data.gnssOnCount = bytes[8] & 0xff;
  // temperature
  if (0 == ((bytes[9] >> 7) & 0x01)) {
    data.temperature = (((bytes[9] << 8) & 0xff00) | (bytes[10] & 0xff)) + "°C";
  } else {
    data.temperature =
      (((bytes[9] << 8) & 0xff00) | (bytes[10] & 0xff)) * -1 + "°C";
  }
  data.movementDuration =
    (((bytes[11] << 8) & 0xff00) | (bytes[12] & 0xff)) * 5 + "s";
  data.chargeDuration = ((bytes[15] << 8) & 0xff00) | (bytes[16] & 0xff);
  data.messageId = ((bytes[17] << 8) & 0xff00) | (bytes[18] & 0xff);
  return data;
}

// type: 0x6 Configuration Parameter Response
function decodeConfigParameterResponse(bytes) {
  var data = {};
  data.type = "ConfigurationParameterResponse";
  var parameter = [];
  let byteLength = bytes.length;
  var index = 0;
  while (index + 1 < byteLength) {
    var commandBitField = {};
    var parameterType = bytes[index + 1] & 0xff;
    commandBitField.parameterType = parameterType;
    var commandBitFieldLength = getCommandBitFieldLength(parameterType);
    if (commandBitFieldLength == 0x10) {
      var deviceReportRule = decodeDeviceReportRule(bytes, index);
      commandBitFieldLength = deviceReportRule.index;
      commandBitField.parameterValue = deviceReportRule;
      commandBitField.name = getParameterName(parameterType);
      commandBitField.parameterDefinition = "DeviceReportRule";
    } else {
      var parameterValue = getParameterValue(
        bytes,
        index,
        commandBitFieldLength
      );
      commandBitField.parameterValue = parameterValue;
      commandBitField.name = getParameterName(parameterType);
      commandBitField.parameterDefinition = getParameterDefinition(
        parameterType,
        parameterValue
      );
    }

    index = index + commandBitFieldLength;
    parameter.push(commandBitField);
  }
  data.parameter = parameter;
  return data;
}

// type: 0x7 BleDeviceMessage
function decodeBleDeviceMessage(bytes) {
  var data = {};
  data.type = "BleDeviceMessage";
  data.ruleType = bytes[0] & 0x0f;
  data.number = bytes[1] & 0x0f;
  for (let i = 0; i < data.number; i++) {
    var index = 2 + 5 * i;
    var major = (((bytes[index] << 8) & 0xff00) | (bytes[index + 1] & 0xff))
      .toString(16)
      .toUpperCase()
      .padStart(4, "0");
    var minor = (((bytes[index + 2] << 8) & 0xff00) | (bytes[index + 3] & 0xff))
      .toString(16)
      .toUpperCase()
      .padStart(4, "0");
    var rssi = bytes[index + 4] - 256 + "dBm";

    data["beacon" + (i + 1)] = major + minor;
    data["rssi" + (i + 1)] = rssi;
  }

  return data;
}

// decodeDeviceReportRule
function decodeDeviceReportRule(bytes, reportIndex) {
  var data = {};
  var index = reportIndex + 2;
  data.type = "DeviceReportRule";
  data.deviceTypeQuantity = bytes[index++] & 0xff;
  data.deviceTypeId = (bytes[index] >> 4) & 0x0f;
  data.filterAndDataBlockQuantity = bytes[index++] & 0x0f;
  var filterBlock = [];
  var dataBlock = [];
  var macBlock = [];
  for (let i = 0; i < data.filterAndDataBlockQuantity; i++) {
    var ruleType = bytes[index++] & 0xff;
    var startAddress = bytes[index++] & 0xff;
    var endAddress = bytes[index++] & 0xff;
    var filter = {};
    if (ruleType == 1) {
      filter.ruleType = "FilterBlock";
      filter.startAddress = byteToHex(startAddress);
      filter.endAddress = byteToHex(endAddress);
      var len = endAddress - startAddress;
      var filterValue = "";
      for (let j = 0; j < len + 1; j++) {
        filterValue += byteToHex(bytes[index + j]);
      }
      filter.value = filterValue;
      index = index + (endAddress - startAddress + 1);
      filterBlock.push(filter);
    } else if (ruleType == 2) {
      filter.ruleType = "DataBlock";
      filter.startAddress = byteToHex(startAddress);
      filter.endAddress = byteToHex(endAddress);
      dataBlock.push(filter);
    } else if (ruleType == 3) {
      filter.ruleType = "MACBlock";
      filter.startAddress = byteToHex(startAddress);
      filter.endAddress = byteToHex(endAddress);
      macBlock.push(filter);
    }
  }
  data.filterBlock = filterBlock;
  data.dataBlock = dataBlock;
  data.macBlock = macBlock;
  data.index = index;
  return data;
}

// getParameterValue hexString
function getParameterValue(bytes, index, length) {
  var hexString = "";
  for (var i = 2; i <= length; i++) {
    var hex = (bytes[index + i] & 0xff).toString(16).toUpperCase();
    hexString += hex.padStart(2, "0");
  }
  return hexString;
}

// getCommandBitFieldLength
function getCommandBitFieldLength(parameterType) {
  let lengths = {
    0x00: 3,
    0x01: 3,
    0x04: 3,
    0x07: 2,
    0x10: 0x10,
    0x20: 2,
    0x29: 2,
    0x2b: 2,
  };
  return lengths[parameterType] ?? 0;
}

// Parameter Name
function getParameterName(parameterType) {
  let name = {
    0x00: "SoftwareVersion",
    0x01: "HBPeriod",
    0x04: "DeviceReportInterval",
    0x07: "BleReceivingDuration",
    0x10: "DeviceReportRule",
    0x29: "BleReceivingEnable",
    0x2b: "DeviceRssiSortEnable",
  };
  return name[parameterType] ?? "No matching parameter names";
}

// Parameter Definition
function getParameterDefinition(parameterType, parameterValue) {
  var val = parseInt(parameterValue, 16);
  let name = {
    0x00: "SoftwareVersion",
    0x01: val * 30 + "s, The interval of the heartbeat message, unit: 30s",
    0x04: val * 5 + "s, The interval of BLE devices message report, unit: 5s",
    0x07: val * 1 + "s, The duration of Bluetooth receiving, unit 1s",
    0x29: val == 0 ? "Disable" : "Enable",
    0x2b: val == 0 ? "Disable" : "Enable",
  };
  return name[parameterType] ?? "No matching parameter names";
}

// Floating point conversion
function hex2float(num) {
  var sign = num & 0x80000000 ? -1 : 1;
  var exponent = ((num >> 23) & 0xff) - 127;
  var mantissa = 1 + (num & 0x7fffff) / 0x7fffff;
  return sign * mantissa * Math.pow(2, exponent);
}

function asciiToHex(str) {
  var hexString = "";
  for (let i = 0; i < str.length; i++) {
    var hex = str.charCodeAt(i).toString(16);
    hexString += hex.padStart(2, "0");
  }
  return hexString;
}

function hexStringToByteArray(hexString) {
  var byteArray = [];
  for (let i = 0; i < hexString.length; i += 2) {
    byteArray.push(parseInt(hexString.substr(i, 2), 16));
  }
  return new Uint8Array(byteArray);
}

function byteToHex(str) {
  return str.toString(16).toUpperCase().padStart(2, "0");
}
```
