Ejemplo n.º 1
0
 private function parseVariableData()
 {
     $i = 19;
     $record_num = 0;
     //mbus_utils::mylog("Read and parse variable data blocks from dataarray[$i-" . ($this->dataarray_len - 2) . "]");
     while ($i < $this->dataarray_len - 2) {
         $record_num++;
         $this->varrecords[$record_num]["general"]["StartBytePosition"] = $i;
         $dif = $this->dataarray[$i];
         $record_data_len = $dif & 0x7;
         $this->varrecords[$record_num]["dif"]["Data"] = mbus_utils::ByteToHex($dif);
         $this->varrecords[$record_num]["dif"]["DataLength"] = $record_data_len;
         if ($record_data_len == 0) {
             //mbus_utils::mylog("0x20 indicates no data, skip reading VIF.");
             $i++;
             unset($this->varrecords[$record_num]);
             // Clear any data from the record.
             $record_num--;
             continue;
         }
         $this->varrecords[$record_num]["dif"]["DataTypeOrLength"] = mbus_utils::getDataFieldType($dif);
         $this->varrecords[$record_num]["dif"]["ExtensionBitSet"] = ($dif & 0x80) == 0x80 ? "Yes" : "No";
         $this->varrecords[$record_num]["dif"]["StorageNumLSB"] = $dif & 0x40;
         /**
          * The manufacturer data header (MDH) is made up by the character 0Fh or 1Fh and indicates the beginning of the manufacturer
          * specific part of the user data and should be omitted, if there is no manufacturer specific data.
          */
         if (($dif & 0xff) == 0xf || ($dif & 0xff) == 0x1f) {
             if (($dif & 0xff) == 0x1f) {
                 mbus_utils::mylog("0x1F indicates manufacturer specific part of the user data and more data to follow...");
             } else {
                 // mbus_utils::mylog("0x0F indicates  manufacturer specific part of the user data and no more data.");
             }
             $this->varrecords[$record_num]["dif"]["data_type"] = "Manufacturer Data";
             $i++;
             //mbus_utils::mylog("Just copy the remaining data as it is vendor specific");
             while ($i < $this->dataarray_len - 2) {
                 $this->varrecords[$record_num]["data"][] = $this->dataarray[$i];
                 $i++;
                 // Increment byte pointer.
             }
             $this->varrecords[$record_num]["general"]["EndBytePosition"] = $i - 1;
             continue;
         }
         // DIFE
         // If bit 8 is set then this means there is another DIFE to come.
         $dife_count = 1;
         while (($this->dataarray[$i] & 0x80) == 0x80) {
             //mbus_utils::mylog("Found DIF extension " . $i);
             $i++;
             // Increment byte pointer.
             $dife = $this->dataarray[$i];
             $this->varrecords[$record_num]["dife"][$dife_count]["Data"] = mbus_utils::ByteToHex($dife);
             $this->varrecords[$record_num]["dife"][$dife_count]["ExtensionBitSet"] = ($dife & 0x80) == 0x80 ? "Yes" : "No";
             $this->varrecords[$record_num]["dife"][$dife_count]["Unit"] = $dife & 0x40;
             $this->varrecords[$record_num]["dife"][$dife_count]["Tariff"] = $dife & 0x30;
             $this->varrecords[$record_num]["dife"][$dife_count]["storage_num_msb"] = mbus_utils::ByteToHex($dife & 0xf);
             $dife_count++;
         }
         $i++;
         // Increment byte pointer.
         // VIF (Value Information Block)
         $vif = $this->dataarray[$i];
         $this->varrecords[$record_num]['vif']['Data'] = mbus_utils::ByteToHex($vif);
         $this->varrecords[$record_num]["vif"]["ExtensionBitSet"] = ($vif & 0x80) == 0x80 ? "Yes" : "No";
         $this->varrecords[$record_num]["vif"]["UnitAndMultiplier"] = mbus_utils::ByteToHex($vif & 0x7f);
         // VIFE
         //mbus_utils::mylog("VIF extension value [" . dechex(($this->dataarray[$i]) & 0x80) . "]");
         $vife_count = 1;
         while (($this->dataarray[$i] & 0x80) == 0x80) {
             //mbus_utils::mylog("Found VIF extension " . $i);
             $this->varrecords[$record_num]['vife'][$vife_count]['data'] = mbus_utils::ByteToHex($this->dataarray[$i + 1]);
             $vife_count++;
             $i++;
             // Increment byte pointer.
         }
         $i++;
         // Increment byte pointer to first byte of real data.
         // If Variable Length data field, then need to determine the length.
         if (($dif & 0xd) == 0xd) {
             // mbus_utils::mylog("Calculate data length from the first byte of actual data.");
             if ($this->dataarray[$i] <= 0xbf) {
                 $record_data_len = $this->dataarray[$i++];
                 // Note that 0x0A is a newline ascii character and it seems to be after the characters but not included in the length!
                 $this->varrecords[$record_num]["dif"]["data_type"] = 'Variable ASCII String';
                 if ($this->dataarray[$i + $record_data_len] == 0xa) {
                     //mbus_utils::mylog("Found new line at end of string that is not included in the length. Adding 1 to length.");
                     $record_data_len += 1;
                 }
             } else {
                 if ($this->dataarray[$i] >= 0xc0 && $this->dataarray[$i] <= 0xcf) {
                     $record_data_len = ($this->dataarray[$i++] - 0xc0) * 2;
                     $this->varrecords[$record_num]["dif"]["data_type"] = 'Variable Postive BCD';
                 } else {
                     if ($this->dataarray[$i] >= 0xd0 && $this->dataarray[$i] <= 0xdf) {
                         $record_data_len = ($this->dataarray[$i++] - 0xd0) * 2;
                         $this->varrecords[$record_num]["dif"]["data_type"] = 'Variable Negative BCD';
                     } else {
                         if ($this->dataarray[$i] >= 0xe0 && $this->dataarray[$i] <= 0xef) {
                             $record_data_len = $this->dataarray[$i++] - 0xe0;
                             $this->varrecords[$record_num]["dif"]["data_type"] = 'Variable Binary';
                         } else {
                             if ($this->dataarray[$i] >= 0xf0 && $this->dataarray[$i] <= 0xfa) {
                                 $record_data_len = $this->dataarray[$i++] - 0xf0;
                                 $this->varrecords[$record_num]["dif"]["data_type"] = 'Variable Floating Point';
                             }
                         }
                     }
                 }
             }
         }
         //mbus_utils::mylog("Copy [" . $record_data_len . "] bytes of data.");
         $this->varrecords[$record_num]['dif']['Function'] = mbus_utils::getFunctionField(($dif & 0x30) >> 4);
         $this->varrecords[$record_num]['vif']['Unit'] = mbus_utils::vif_unit_lookup($vif);
         if ($this->varrecords[$record_num]['vif']['Unit'] == 'Plain Text' && $this->varrecords[$record_num]["dif"]["data_type"] != 'Variable ASCII String') {
             // First byte of data is length.
             $record_data_len = $this->dataarray[$i++];
             // Get the value for the VIF data type.
             $this->varrecords[$record_num]["vif"]["DataLength"] = $record_data_len;
             for ($j = 0; $j < $record_data_len; $j++) {
                 $this->varrecords[$record_num]["data"][] = $this->dataarray[$i];
                 $i++;
             }
             // Replace "Plain Text" with unit from data.
             $this->varrecords[$record_num]['vif']['Unit'] = mbus_utils::getValue($dif, $vif, $this->varrecords[$record_num]["data"]);
             // Set the actual value data length to the dif record.
             $record_data_len = $this->varrecords[$record_num]["dif"]["DataLength"];
             // Set $vif to nothing so it doesn't think the next bit of data is plain text.
             $vif = 0x0;
             // Clear data out.
             unset($this->varrecords[$record_num]["data"]);
         }
         // Must be after parsing DIF and VIF as both of these can determine length.
         $this->varrecords[$record_num]["dif"]["DataLength"] = $record_data_len;
         //mbus_utils::mylog("Record [" . $record_num . "] Length [" . $record_data_len . "]");
         for ($j = 0; $j < $record_data_len; $j++) {
             $this->varrecords[$record_num]["data"][] = $this->dataarray[$i];
             $i++;
         }
         $this->varrecords[$record_num]['Value'] = mbus_utils::getValue($dif, $vif, $this->varrecords[$record_num]["data"]);
         $this->varrecords[$record_num]["general"]["EndBytePosition"] = $i - 1;
         $sbp = $this->varrecords[$record_num]['general']['StartBytePosition'];
         $ebp = $this->varrecords[$record_num]['general']['EndBytePosition'];
         if ($sbp < $ebp) {
             for ($i = $sbp; $i <= $ebp; $i++) {
                 $this->varrecords[$record_num]['general']['DataInclHeader'] .= mbus_utils::ByteToHex($this->dataarray[$i]);
             }
         }
     }
     return true;
 }