{"id":19720,"date":"2026-08-07T13:39:47","date_gmt":"2026-08-07T05:39:47","guid":{"rendered":"https:\/\/www.lansitec.com\/?post_type=docs&#038;p=19720"},"modified":"2026-08-07T13:39:55","modified_gmt":"2026-08-07T05:39:55","password":"","slug":"decoder-lte-bluetooth-gateway","status":"publish","type":"docs","link":"https:\/\/www.lansitec.com\/ko\/docs\/decoders\/decoder-lte-bluetooth-gateway\/","title":{"rendered":"LTE \ub514\ucf54\ub354 \u2013 \ube14\ub8e8\ud22c\uc2a4 \uac8c\uc774\ud2b8\uc6e8\uc774"},"content":{"rendered":"<div class=\"wp-block-file\"><a id=\"wp-block-file--media-8cc23e56-955b-45f5-bc80-29b826158e64\" href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-lte-bluetooth-gateway.js.zip\">decode-lte-bluetooth-gateway.js<\/a><a href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-lte-bluetooth-gateway.js.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-8cc23e56-955b-45f5-bc80-29b826158e64\">\ub2e4\uc6b4\ub85c\ub4dc<\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Below the full decoder code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Decode uplink function.\n\/\/\n\/\/ Input is an object with the following fields:\n\/\/ - bytes = Byte array containing the uplink payload, e.g. &#91;255, 230, 255, 0]\n\/\/ - fPort = Uplink fPort.\n\/\/ - variables = Object containing the configconsoleured device variables.\n\/\/\n\/\/ Output must be an object with the following fields:\n\/\/ - data = Object representing the decoded payload.\n\n\/\/ NB-IoT Bluetooth Gateway\nfunction decodeUplink(input) {\n  \/\/ bytes\n  var bytes = input.bytes;\n  \/\/ type\n  var uplinkType = (bytes&#91;0] >> 4) &amp; 0x0f;\n\n  switch (uplinkType) {\n    case 0x01:\n      return { data: decodeRegistration(bytes) };\n\n    case 0x02:\n      return { data: decodeHeartbeat(bytes) };\n\n    case 0x06:\n      return { data: decodeConfigParameterResponse(bytes) };\n\n    case 0x07:\n      return { data: decodeBleDeviceMessage(bytes) };\n\n    default:\n      return;\n  }\n}\n\n\/\/ type: 0x1 Registration\nfunction decodeRegistration(bytes) {\n  var data = {};\n  data.type = \"Registration\";\n\n  data.deviceRssiSortEnable = (bytes&#91;1] >> 1) &amp; 0x01;\n\n  data.bleReceivingEnable = (bytes&#91;2] >> 7) &amp; 0x01;\n\n  data.heartbeatPeriod =\n    (((bytes&#91;6] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;7] &amp; 0xff)) * 30 + \"s\";\n\n  data.bleDeviceReportInterval =\n    (((bytes&#91;14] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;15] &amp; 0xff)) * 5 + \"s\";\n\n  data.bleReceivingDuration = bytes&#91;16] &amp; 0xff;\n\n  data.version = ((bytes&#91;17] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;18] &amp; 0xff);\n\n  var imsi = \"\";\n  for (let i = 0; i &lt; 8; i++) {\n    imsi += bytes&#91;19 + i].toString(16).toUpperCase().padStart(2, \"0\");\n  }\n  data.imsi = imsi.substring(0, 15);\n  data.messageId = ((bytes&#91;27] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;28] &amp; 0xff);\n  return data;\n}\n\/\/ type: 0x2 Heartbeat\nfunction decodeHeartbeat(bytes) {\n  var data = {};\n  data.type = \"HeartbeatMessage\";\n  var stateBitField = {};\n  stateBitField.deviceRssiSortEnable = (bytes&#91;1] >> 1) &amp; 0x01;\n  stateBitField.bleReceivingEnable = (bytes&#91;2] >> 7) &amp; 0x01;\n  data.stateBitField = stateBitField;\n\n  data.batteryVoltage = (bytes&#91;5] &amp; 0xff) * 0.1 + \"V\";\n  data.batteryLevel = (bytes&#91;6] &amp; 0xff) + \"%\";\n  data.bleReceivingCount = bytes&#91;7] &amp; 0xff;\n  data.gnssOnCount = bytes&#91;8] &amp; 0xff;\n  \/\/ temperature\n  if (0 == ((bytes&#91;9] >> 7) &amp; 0x01)) {\n    data.temperature = (((bytes&#91;9] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;10] &amp; 0xff)) + \"\u00b0C\";\n  } else {\n    data.temperature =\n      (((bytes&#91;9] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;10] &amp; 0xff)) * -1 + \"\u00b0C\";\n  }\n  data.movementDuration =\n    (((bytes&#91;11] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;12] &amp; 0xff)) * 5 + \"s\";\n  data.chargeDuration = ((bytes&#91;15] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;16] &amp; 0xff);\n  data.messageId = ((bytes&#91;17] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;18] &amp; 0xff);\n  return data;\n}\n\n\/\/ type: 0x6 Configuration Parameter Response\nfunction decodeConfigParameterResponse(bytes) {\n  var data = {};\n  data.type = \"ConfigurationParameterResponse\";\n  var parameter = &#91;];\n  let byteLength = bytes.length;\n  var index = 0;\n  while (index + 1 &lt; byteLength) {\n    var commandBitField = {};\n    var parameterType = bytes&#91;index + 1] &amp; 0xff;\n    commandBitField.parameterType = parameterType;\n    var commandBitFieldLength = getCommandBitFieldLength(parameterType);\n    if (commandBitFieldLength == 0x10) {\n      var deviceReportRule = decodeDeviceReportRule(bytes, index);\n      commandBitFieldLength = deviceReportRule.index;\n      commandBitField.parameterValue = deviceReportRule;\n      commandBitField.name = getParameterName(parameterType);\n      commandBitField.parameterDefinition = \"DeviceReportRule\";\n    } else {\n      var parameterValue = getParameterValue(\n        bytes,\n        index,\n        commandBitFieldLength\n      );\n      commandBitField.parameterValue = parameterValue;\n      commandBitField.name = getParameterName(parameterType);\n      commandBitField.parameterDefinition = getParameterDefinition(\n        parameterType,\n        parameterValue\n      );\n    }\n\n    index = index + commandBitFieldLength;\n    parameter.push(commandBitField);\n  }\n  data.parameter = parameter;\n  return data;\n}\n\n\/\/ type: 0x7 BleDeviceMessage\nfunction decodeBleDeviceMessage(bytes) {\n  var data = {};\n  data.type = \"BleDeviceMessage\";\n  data.ruleType = bytes&#91;0] &amp; 0x0f;\n  data.number = bytes&#91;1] &amp; 0x0f;\n  for (let i = 0; i &lt; data.number; i++) {\n    var index = 2 + 5 * i;\n    var major = (((bytes&#91;index] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;index + 1] &amp; 0xff))\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var minor = (((bytes&#91;index + 2] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;index + 3] &amp; 0xff))\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var rssi = bytes&#91;index + 4] - 256 + \"dBm\";\n\n    data&#91;\"beacon\" + (i + 1)] = major + minor;\n    data&#91;\"rssi\" + (i + 1)] = rssi;\n  }\n\n  return data;\n}\n\n\/\/ decodeDeviceReportRule\nfunction decodeDeviceReportRule(bytes, reportIndex) {\n  var data = {};\n  var index = reportIndex + 2;\n  data.type = \"DeviceReportRule\";\n  data.deviceTypeQuantity = bytes&#91;index++] &amp; 0xff;\n  data.deviceTypeId = (bytes&#91;index] >> 4) &amp; 0x0f;\n  data.filterAndDataBlockQuantity = bytes&#91;index++] &amp; 0x0f;\n  var filterBlock = &#91;];\n  var dataBlock = &#91;];\n  var macBlock = &#91;];\n  for (let i = 0; i &lt; data.filterAndDataBlockQuantity; i++) {\n    var ruleType = bytes&#91;index++] &amp; 0xff;\n    var startAddress = bytes&#91;index++] &amp; 0xff;\n    var endAddress = bytes&#91;index++] &amp; 0xff;\n    var filter = {};\n    if (ruleType == 1) {\n      filter.ruleType = \"FilterBlock\";\n      filter.startAddress = byteToHex(startAddress);\n      filter.endAddress = byteToHex(endAddress);\n      var len = endAddress - startAddress;\n      var filterValue = \"\";\n      for (let j = 0; j &lt; len + 1; j++) {\n        filterValue += byteToHex(bytes&#91;index + j]);\n      }\n      filter.value = filterValue;\n      index = index + (endAddress - startAddress + 1);\n      filterBlock.push(filter);\n    } else if (ruleType == 2) {\n      filter.ruleType = \"DataBlock\";\n      filter.startAddress = byteToHex(startAddress);\n      filter.endAddress = byteToHex(endAddress);\n      dataBlock.push(filter);\n    } else if (ruleType == 3) {\n      filter.ruleType = \"MACBlock\";\n      filter.startAddress = byteToHex(startAddress);\n      filter.endAddress = byteToHex(endAddress);\n      macBlock.push(filter);\n    }\n  }\n  data.filterBlock = filterBlock;\n  data.dataBlock = dataBlock;\n  data.macBlock = macBlock;\n  data.index = index;\n  return data;\n}\n\n\/\/ getParameterValue hexString\nfunction getParameterValue(bytes, index, length) {\n  var hexString = \"\";\n  for (var i = 2; i &lt;= length; i++) {\n    var hex = (bytes&#91;index + i] &amp; 0xff).toString(16).toUpperCase();\n    hexString += hex.padStart(2, \"0\");\n  }\n  return hexString;\n}\n\n\/\/ getCommandBitFieldLength\nfunction getCommandBitFieldLength(parameterType) {\n  let lengths = {\n    0x00: 3,\n    0x01: 3,\n    0x04: 3,\n    0x07: 2,\n    0x10: 0x10,\n    0x20: 2,\n    0x29: 2,\n    0x2b: 2,\n  };\n  return lengths&#91;parameterType] ?? 0;\n}\n\n\/\/ Parameter Name\nfunction getParameterName(parameterType) {\n  let name = {\n    0x00: \"SoftwareVersion\",\n    0x01: \"HBPeriod\",\n    0x04: \"DeviceReportInterval\",\n    0x07: \"BleReceivingDuration\",\n    0x10: \"DeviceReportRule\",\n    0x29: \"BleReceivingEnable\",\n    0x2b: \"DeviceRssiSortEnable\",\n  };\n  return name&#91;parameterType] ?? \"No matching parameter names\";\n}\n\n\/\/ Parameter Definition\nfunction getParameterDefinition(parameterType, parameterValue) {\n  var val = parseInt(parameterValue, 16);\n  let name = {\n    0x00: \"SoftwareVersion\",\n    0x01: val * 30 + \"s, The interval of the heartbeat message, unit: 30s\",\n    0x04: val * 5 + \"s, The interval of BLE devices message report, unit: 5s\",\n    0x07: val * 1 + \"s, The duration of Bluetooth receiving, unit 1s\",\n    0x29: val == 0 ? \"Disable\" : \"Enable\",\n    0x2b: val == 0 ? \"Disable\" : \"Enable\",\n  };\n  return name&#91;parameterType] ?? \"No matching parameter names\";\n}\n\n\/\/ Floating point conversion\nfunction hex2float(num) {\n  var sign = num &amp; 0x80000000 ? -1 : 1;\n  var exponent = ((num >> 23) &amp; 0xff) - 127;\n  var mantissa = 1 + (num &amp; 0x7fffff) \/ 0x7fffff;\n  return sign * mantissa * Math.pow(2, exponent);\n}\n\nfunction asciiToHex(str) {\n  var hexString = \"\";\n  for (let i = 0; i &lt; str.length; i++) {\n    var hex = str.charCodeAt(i).toString(16);\n    hexString += hex.padStart(2, \"0\");\n  }\n  return hexString;\n}\n\nfunction hexStringToByteArray(hexString) {\n  var byteArray = &#91;];\n  for (let i = 0; i &lt; hexString.length; i += 2) {\n    byteArray.push(parseInt(hexString.substr(i, 2), 16));\n  }\n  return new Uint8Array(byteArray);\n}\n\nfunction byteToHex(str) {\n  return str.toString(16).toUpperCase().padStart(2, \"0\");\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>Below the full decoder code:<\/p>","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"doc_category":[338],"doc_tag":[],"class_list":["post-19720","docs","type-docs","status-publish","hentry","doc_category-decoders"],"year_month":"2026-08","word_count":859,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"\ub9c8\uc774\uc9c0","author_nicename":"maizi","author_url":"https:\/\/www.lansitec.com\/ko\/author\/maizi\/"},"doc_category_info":[{"term_name":"Decoders","term_url":"https:\/\/www.lansitec.com\/ko\/doc\/decoders\/"}],"doc_tag_info":[],"knowledge_base_info":[],"knowledge_base_slug":[],"_links":{"self":[{"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/docs\/19720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/comments?post=19720"}],"version-history":[{"count":1,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/docs\/19720\/revisions"}],"predecessor-version":[{"id":19728,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/docs\/19720\/revisions\/19728"}],"wp:attachment":[{"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/media?parent=19720"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/doc_category?post=19720"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.lansitec.com\/ko\/wp-json\/wp\/v2\/doc_tag?post=19720"}],"curies":[{"name":"\uc6cc\ub4dc\ud504\ub808\uc2a4","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}