diff --git a/app/Classes/Protocol/Zmodem.php b/app/Classes/Protocol/Zmodem.php index 500c0ca..f8d65be 100644 --- a/app/Classes/Protocol/Zmodem.php +++ b/app/Classes/Protocol/Zmodem.php @@ -1066,6 +1066,82 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface return $crc32 ? $this->ls_zrecvdata32($data,$len,$timeout) : $this->ls_zrecvdata16($data,$len,$timeout); } + /** + * Receive data subframe with CRC16, return frame type or error (may be -- timeout) + * + * @return mixed + */ + private function ls_recvdata16(string &$data,int &$len,int $timeout): int + { + if ($this->DEBUG) + Log::debug('+ Start',['m'=>__METHOD__,'d'=>$data]); + + $got = 0; /* Bytes total got */ + $incrc = self::LSZ_INIT_CRC16; /* Calculated CRC */ + $crc = 0; /* Received CRC */ + $frametype = self::LSZ_ERROR; /* Type of frame - ZCRC(G|W|Q|E) */ + $rcvdata = 1; /* Data is being received NOW (not CRC) */ + + while ($rcvdata && (($c = $this->ls_readzdle($timeout)) >= 0)) { + if($c < 256) { + $data .= chr($c&0xff); + + if (++$got > $this->ls_MaxBlockSize) + return self::LSZ_BADCRC; + + $incrc = $this->CRC16USD_UPDATE($c,$incrc); + + } else { + switch($c) { + case self::LSZ_CRCE: + case self::LSZ_CRCG: + case self::LSZ_CRCQ: + case self::LSZ_CRCW: + $rcvdata = 0; + $frametype = ($c & 0xff); + + $incrc = $this->CRC16USD_UPDATE($c,$incrc); + + break; + + default: + return self::LSZ_BADCRC; + } + } + } + + /* We finish loop by error in ls_readzdle() */ + if ($rcvdata) { + Log::error(sprintf('%s: ? Something strange or timeout [%d]',__METHOD__,$rc)); + + return $c; + } + + /* Loops ar unrolled */ + if (($c = $this->ls_readzdle($timeout)) < 0) + return $c; + + $crc = $c; + if (($c = $this->ls_readzdle($timeout)) < 0) + return $c; + + $crc <<= 8; + $crc |= $c; + + if ($this->DEBUG) + Log::debug(sprintf('CRC%d got %08x - calculated %08x',16,$incrc,$crc),['m'=>__METHOD__]); + + if ($incrc != $crc) + return self::LSZ_BADCRC; + + $len = $got; + + if ($this->DEBUG) + Log::debug('= End',['m'=>__METHOD__,'frametype'=>$frametype]); + + return $frametype; + } + /** * Receive data subframe with CRC32, return frame type or error (may be -- timeout) *