From 2fdc6eabad95b60356dffcc975ea7fe4d5a87a48 Mon Sep 17 00:00:00 2001 From: Deon George Date: Wed, 21 Jul 2021 20:52:17 +1000 Subject: [PATCH] Revise CRC calls and use php's internal functions --- app/Classes/Protocol/EMSI.php | 4 +-- app/Classes/Protocol/Zmodem.php | 60 +++++++++++++------------------- app/Models/Setup.php | 7 +--- app/Traits/CRC.php | 27 --------------- app/helpers.php | 61 ++++++++------------------------- 5 files changed, 41 insertions(+), 118 deletions(-) diff --git a/app/Classes/Protocol/EMSI.php b/app/Classes/Protocol/EMSI.php index 46c7a52..3acb138 100644 --- a/app/Classes/Protocol/EMSI.php +++ b/app/Classes/Protocol/EMSI.php @@ -222,7 +222,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface $makedata = preg_replace('/0000/',sprintf('%04X',strlen($makedata)-14),$makedata,1); /* EMSI crc16 */ - $makedata .= sprintf('%04X',$this->CRC16USD(substr($makedata,2))); + $makedata .= sprintf('%04X',crc16(substr($makedata,2))); return $makedata; } @@ -277,7 +277,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface sscanf(substr($str,strlen($str)-4),"%04X",$l); /* Bad EMSI CRC */ - if ($l != ($x = $this->CRC16USD(substr($str,2,strlen($str)-6)))) { + if ($l != ($x = crc16(substr($str,2,strlen($str)-6)))) { Log::error(sprintf('%s: ! Bad EMSI_DAT CRC: [%04X], should be: [%04X]!',__METHOD__,$l,$x)); return 0; diff --git a/app/Classes/Protocol/Zmodem.php b/app/Classes/Protocol/Zmodem.php index f8d65be..f7715e7 100644 --- a/app/Classes/Protocol/Zmodem.php +++ b/app/Classes/Protocol/Zmodem.php @@ -688,7 +688,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface elseif ($c != self::LSZ_XONXOFF) return $c&0xff; - } while($c == self::LSZ_XONXOFF); + } while ($c == self::LSZ_XONXOFF); } /* We will be here only in case of DLE */ @@ -712,7 +712,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface $rr = $this->ls_readcanned($timeout); // @todo to implement $this->z_devrecv_c($rr,0); - } while($rr); + } while ($rr); $this->z_devsend_c(0); } @@ -792,12 +792,12 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface * @param int $i * @throws \Exception */ - private function ls_sendhex(int $c): void + private function ls_sendhex(int $i): void { - $hexdigitslower = "0123456789abcdef"; + $str = hexstr($i); + $this->ls_txLastSent = ord(substr($str,-1)); - $this->client->buffer_add(substr($hexdigitslower,($c&0xf0)>>4,1)); - $this->client->buffer_add(chr($this->ls_txLastSent = ord(substr($hexdigitslower,($c&0x0f),1)))); + $this->client->buffer_add($str); } /** @@ -1071,26 +1071,26 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface * * @return mixed */ - private function ls_recvdata16(string &$data,int &$len,int $timeout): int + private function ls_zrecvdata16(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) { + if ($this->DEBUG) + Log::debug(sprintf(' - got [%x] (%c)',$c,($c<31 ? 32 : $c)),['m'=>__METHOD__,'c'=>serialize($c)]); + + 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: @@ -1100,8 +1100,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface $rcvdata = 0; $frametype = ($c & 0xff); - $incrc = $this->CRC16USD_UPDATE($c,$incrc); - break; default: @@ -1128,6 +1126,8 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface $crc <<= 8; $crc |= $c; + $incrc = crc16($data.chr($frametype)); + if ($this->DEBUG) Log::debug(sprintf('CRC%d got %08x - calculated %08x',16,$incrc,$crc),['m'=>__METHOD__]); @@ -1156,7 +1156,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface Log::debug('+ Start',['m'=>__METHOD__,'d'=>$data]); $got = 0; /* Bytes total got */ - $incrc = self::LSZ_INIT_CRC32; /* 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) */ @@ -1171,8 +1170,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface if (++$got > $this->ls_MaxBlockSize) return self::LSZ_BADCRC; - $incrc = $this->CRC32_UPDATE($c,$incrc); - } else { switch ($c) { case self::LSZ_CRCE: @@ -1181,7 +1178,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface case self::LSZ_CRCW: $rcvdata = 0; $frametype = ($c&0xff); - $incrc = $this->CRC32_UPDATE($c,$incrc); break; @@ -1215,10 +1211,10 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface return $c; $crc |= ($c << 0x18); - $incrc = $this->CRC32_FINISH($incrc); + $incrc = crc32($data.chr($frametype)); if ($this->DEBUG) - Log::debug(sprintf('CRC%d got %08x - calculated %08x',32,$incrc,$crc),['m'=>__METHOD__,'crc'=>$crc,'test_crc32'=>sprintf('%08x',$this->CRC32($data))]); + Log::debug(sprintf('CRC%d got %08x - calculated %08x',32,$incrc,$crc),['m'=>__METHOD__]); if ($incrc != $crc) return self::LSZ_BADCRC; @@ -1353,7 +1349,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface if ($rxstatus) return ($rxstatus==self::RX_SKIP) ? self::ZSKIP : self::ZFERR; - } while(TRUE); + } while (TRUE); return self::LSZ_OK; } @@ -1990,15 +1986,10 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface if ($this->DEBUG) Log::debug(sprintf('%s: - CRC32',__METHOD__)); - $crc = self::LSZ_INIT_CRC32; - - for ($n=0;$nls_sendchar(ord($data[$n])); - $crc = $this->CRC32_UPDATE(ord($data[$n]),$crc); - } $this->client->buffer_add(chr(self::ZDLE).chr($frame)); - $crc = $this->CRC32_UPDATE($frame,$crc); /* *chat* @@ -2010,7 +2001,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface } */ - $crc = $this->CRC32_FINISH($crc); + $crc = crc32($data.chr($frame)); $this->ls_sendchar($crc&0xff); $crc >>= 8; $this->ls_sendchar($crc&0xff); @@ -2024,15 +2015,11 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface if ($this->DEBUG) Log::debug(sprintf('%s: - CRC16',__METHOD__)); - $crc = self::LSZ_INIT_CRC16; - for ($n=0;$nls_sendchar(ord($data[$n])); - $crc = $this->CRC16USD_UPDATE(ord($data[$n]),$crc); } $this->client->buffer_add(chr(self::ZDLE).chr($frame)); - $crc = $this->CRC16USD_UPDATE($frame,$crc); /* *chat* @@ -2044,7 +2031,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface } */ - $crc &= 0xffff; + $crc = crc16($data.chr($frame)); $this->ls_sendchar($crc >> 8); $this->ls_sendchar($crc&0xff); } @@ -2284,7 +2271,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface return $rc; } - } while( + } while ( /* Here is window, and we send more than window without ACK*/ /* Frame was ZCRCW and here is no ACK for it */ /* trys less than 10 */ @@ -2426,7 +2413,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface $trys++; } - switch (($rc=$this->ls_zrecvhdr($this->ls_rxHdr,$this->ls_HeaderTimeout))) { + switch ($rc=$this->ls_zrecvhdr($this->ls_rxHdr,$this->ls_HeaderTimeout)) { /* Ok, he want our file */ case self::ZRPOS: $pos = $this->ls_fetchlong($this->ls_rxHdr); @@ -2472,6 +2459,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface $crc = $this->CRC32_UPDATE($c,$crc); $crc = $this->CRC32_FINISH($crc); +dump([__METHOD__,'crc'=>$crc,'crc32'=>crc32(file_get_contents($send->name))]); if (($rc=$this->ls_zsendhhdr(self::ZCRC,$this->ls_storelong($crc))) < 0) return $rc; @@ -2524,15 +2512,13 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface } $this->ls_sendhex($frametype); - $crc = $this->CRC16USD_UPDATE($frametype,self::LSZ_INIT_CRC16); /* Send whole header */ for ($n=0;$nls_sendhex($hdr[$n]); - $crc = $this->CRC16USD_UPDATE((0xff&$hdr[$n]),$crc); } - $crc = ($crc&0xffff); + $crc = crc16(chr($frametype).join('',array_map(function($item) { return chr($item); },$hdr))); $this->ls_sendhex($crc >> 8); $this->ls_sendhex($crc&0xff); $this->client->buffer_add(chr(self::CR)); diff --git a/app/Models/Setup.php b/app/Models/Setup.php index cc5727e..6efc3f8 100644 --- a/app/Models/Setup.php +++ b/app/Models/Setup.php @@ -49,12 +49,7 @@ class Setup extends Model public static function product_id(int $c=self::PRODUCT_ID): string { - $x = substr(static::hexdigitslower,($c&0xf000)>>12,1); - $x .= substr(static::hexdigitslower,($c&0x0f00)>>8,1); - $x .= substr(static::hexdigitslower,($c&0x00f0)>>4,1); - $x .= substr(static::hexdigitslower,($c&0x000f),1); - - return $x; + return hexstr($c); } /* RELATIONS */ diff --git a/app/Traits/CRC.php b/app/Traits/CRC.php index b47fb18..a1ed300 100644 --- a/app/Traits/CRC.php +++ b/app/Traits/CRC.php @@ -4,38 +4,11 @@ namespace App\Traits; trait CRC { - private function CRC16USD(string $string): int - { - $crc = self::CRC16USD_INIT; - - for ($c=0;$cCRC16USD_UPDATE(ord($string[$c]),$crc); - - return $crc; - } - private function CRC16USD_UPDATE($b,$crc): int { return (self::crc16usd_tab[(($crc >> 8) ^ $b) & 0xff] ^ (($crc & 0x00ff) << 8)) & 0xffff; } - /** - * Calculate CRC32 - * - * @param string $string - * @param bool $finish - * @return int - */ - private function CRC32(string $string,bool $finish=TRUE): int - { - $crc = 0xffffffff; - - for ($i=0;$i>8) & 0x00ffffff)) & 0xffffffff; - - return $finish ? $this->CRC32_FINISH($crc) : $crc; - } - private function CRC32_FINISH($crc) { return ~$crc & 0xffffffff; diff --git a/app/helpers.php b/app/helpers.php index 5a0cc89..01146b3 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -54,56 +54,25 @@ if (! function_exists('hex_dump')) { } /** - * Split out an FTN address into its parts - * - * This function takes a fully qualified FTN address and splits it out into - * its components: - * Z:N/F.P@D + * Send a value has hex chars */ -if (! function_exists('ftn_address_split')) { - function ftn_address_split(string $address,$key=NULL) +if (! function_exists('hexstr')) { + function hexstr(int $int) { - if ($key AND ! in_array($key,['z','n','f','p','d'])) - { - throw new \Exception('Unknown key :'.$key.' for '.$address); + if ($int > 0xffff) + throw new Exception('Int too large for hexstr'); + + $hexdigitslower = '0123456789abcdef'; + $x = ''; + + if ($int > 0xff) { + $x .= substr($hexdigitslower,($int&0xf000)>>12,1); + $x .= substr($hexdigitslower,($int&0x0f00)>>8,1); } - //$data = "10:12/909"; - //$data = "10:12/909.5"; - //$data = "10:12/909@foo"; - //$data = "10:12/909.5@foo"; - $z = substr($address,0,strpos($address,':')); + $x .= substr($hexdigitslower,($int&0x00f0)>>4,1); + $x .= substr($hexdigitslower,($int&0x000f),1); - if ($key == 'z') - return $z; - - $x = strpos($address,':')+1; - $n = substr($address,$x,strpos($address,'/')-$x); - - if ($key == 'n') - return $n; - - $x = strpos($address,'/')+1; - $f = substr($address,$x, - (strpos($address,'.') ?: - (strpos($address,'@') ?: strlen($address)))-$x); - - if ($key == 'f') - return $f; - - $x = strpos($address,'.'); - $p = $x ? substr($address,$x+1,(strpos($address,'@') ?: strlen($address))-$x-1) : 0; - - if ($key == 'p') - return $p; - - // @todo We dont handle domain yet. - $x = strpos($address,'@'); - $d = $x ? substr($address,$x+1) : NULL; - - if ($key == 'd') - return $d; - - return ['z'=>$z,'n'=>$n,'f'=>$f,'p'=>$p,'d'=>$d]; + return $x; } } \ No newline at end of file