Revise CRC calls and use php's internal functions

This commit is contained in:
Deon George 2021-07-21 20:52:17 +10:00
parent 7cd3b814bb
commit 2fdc6eabad
5 changed files with 41 additions and 118 deletions

View File

@ -222,7 +222,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
$makedata = preg_replace('/0000/',sprintf('%04X',strlen($makedata)-14),$makedata,1); $makedata = preg_replace('/0000/',sprintf('%04X',strlen($makedata)-14),$makedata,1);
/* EMSI crc16 */ /* EMSI crc16 */
$makedata .= sprintf('%04X',$this->CRC16USD(substr($makedata,2))); $makedata .= sprintf('%04X',crc16(substr($makedata,2)));
return $makedata; return $makedata;
} }
@ -277,7 +277,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
sscanf(substr($str,strlen($str)-4),"%04X",$l); sscanf(substr($str,strlen($str)-4),"%04X",$l);
/* Bad EMSI CRC */ /* 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)); Log::error(sprintf('%s: ! Bad EMSI_DAT CRC: [%04X], should be: [%04X]!',__METHOD__,$l,$x));
return 0; return 0;

View File

@ -792,12 +792,12 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
* @param int $i * @param int $i
* @throws \Exception * @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($str);
$this->client->buffer_add(chr($this->ls_txLastSent = ord(substr($hexdigitslower,($c&0x0f),1))));
} }
/** /**
@ -1071,26 +1071,26 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
* *
* @return mixed * @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) if ($this->DEBUG)
Log::debug('+ Start',['m'=>__METHOD__,'d'=>$data]); Log::debug('+ Start',['m'=>__METHOD__,'d'=>$data]);
$got = 0; /* Bytes total got */ $got = 0; /* Bytes total got */
$incrc = self::LSZ_INIT_CRC16; /* Calculated CRC */
$crc = 0; /* Received CRC */ $crc = 0; /* Received CRC */
$frametype = self::LSZ_ERROR; /* Type of frame - ZCRC(G|W|Q|E) */ $frametype = self::LSZ_ERROR; /* Type of frame - ZCRC(G|W|Q|E) */
$rcvdata = 1; /* Data is being received NOW (not CRC) */ $rcvdata = 1; /* Data is being received NOW (not CRC) */
while ($rcvdata && (($c = $this->ls_readzdle($timeout)) >= 0)) { while ($rcvdata && (($c = $this->ls_readzdle($timeout)) >= 0)) {
if ($this->DEBUG)
Log::debug(sprintf(' - got [%x] (%c)',$c,($c<31 ? 32 : $c)),['m'=>__METHOD__,'c'=>serialize($c)]);
if ($c < 256) { if ($c < 256) {
$data .= chr($c&0xff); $data .= chr($c&0xff);
if (++$got > $this->ls_MaxBlockSize) if (++$got > $this->ls_MaxBlockSize)
return self::LSZ_BADCRC; return self::LSZ_BADCRC;
$incrc = $this->CRC16USD_UPDATE($c,$incrc);
} else { } else {
switch($c) { switch($c) {
case self::LSZ_CRCE: case self::LSZ_CRCE:
@ -1100,8 +1100,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
$rcvdata = 0; $rcvdata = 0;
$frametype = ($c & 0xff); $frametype = ($c & 0xff);
$incrc = $this->CRC16USD_UPDATE($c,$incrc);
break; break;
default: default:
@ -1128,6 +1126,8 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
$crc <<= 8; $crc <<= 8;
$crc |= $c; $crc |= $c;
$incrc = crc16($data.chr($frametype));
if ($this->DEBUG) if ($this->DEBUG)
Log::debug(sprintf('CRC%d got %08x - calculated %08x',16,$incrc,$crc),['m'=>__METHOD__]); 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]); Log::debug('+ Start',['m'=>__METHOD__,'d'=>$data]);
$got = 0; /* Bytes total got */ $got = 0; /* Bytes total got */
$incrc = self::LSZ_INIT_CRC32; /* Calculated CRC */
$crc = 0; /* Received CRC */ $crc = 0; /* Received CRC */
$frametype = self::LSZ_ERROR; /* Type of frame - ZCRC(G|W|Q|E) */ $frametype = self::LSZ_ERROR; /* Type of frame - ZCRC(G|W|Q|E) */
$rcvdata = 1; /* Data is being received NOW (not CRC) */ $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) if (++$got > $this->ls_MaxBlockSize)
return self::LSZ_BADCRC; return self::LSZ_BADCRC;
$incrc = $this->CRC32_UPDATE($c,$incrc);
} else { } else {
switch ($c) { switch ($c) {
case self::LSZ_CRCE: case self::LSZ_CRCE:
@ -1181,7 +1178,6 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
case self::LSZ_CRCW: case self::LSZ_CRCW:
$rcvdata = 0; $rcvdata = 0;
$frametype = ($c&0xff); $frametype = ($c&0xff);
$incrc = $this->CRC32_UPDATE($c,$incrc);
break; break;
@ -1215,10 +1211,10 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
return $c; return $c;
$crc |= ($c << 0x18); $crc |= ($c << 0x18);
$incrc = $this->CRC32_FINISH($incrc);
$incrc = crc32($data.chr($frametype));
if ($this->DEBUG) 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) if ($incrc != $crc)
return self::LSZ_BADCRC; return self::LSZ_BADCRC;
@ -1990,15 +1986,10 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
if ($this->DEBUG) if ($this->DEBUG)
Log::debug(sprintf('%s: - CRC32',__METHOD__)); Log::debug(sprintf('%s: - CRC32',__METHOD__));
$crc = self::LSZ_INIT_CRC32; for ($n=0;$n<strlen($data);$n++)
for ($n=0;$n<strlen($data);$n++) {
$this->ls_sendchar(ord($data[$n])); $this->ls_sendchar(ord($data[$n]));
$crc = $this->CRC32_UPDATE(ord($data[$n]),$crc);
}
$this->client->buffer_add(chr(self::ZDLE).chr($frame)); $this->client->buffer_add(chr(self::ZDLE).chr($frame));
$crc = $this->CRC32_UPDATE($frame,$crc);
/* /*
*chat* *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); $this->ls_sendchar($crc&0xff);
$crc >>= 8; $crc >>= 8;
$this->ls_sendchar($crc&0xff); $this->ls_sendchar($crc&0xff);
@ -2024,15 +2015,11 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
if ($this->DEBUG) if ($this->DEBUG)
Log::debug(sprintf('%s: - CRC16',__METHOD__)); Log::debug(sprintf('%s: - CRC16',__METHOD__));
$crc = self::LSZ_INIT_CRC16;
for ($n=0;$n<strlen($data);$n++) { for ($n=0;$n<strlen($data);$n++) {
$this->ls_sendchar(ord($data[$n])); $this->ls_sendchar(ord($data[$n]));
$crc = $this->CRC16USD_UPDATE(ord($data[$n]),$crc);
} }
$this->client->buffer_add(chr(self::ZDLE).chr($frame)); $this->client->buffer_add(chr(self::ZDLE).chr($frame));
$crc = $this->CRC16USD_UPDATE($frame,$crc);
/* /*
*chat* *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 >> 8);
$this->ls_sendchar($crc&0xff); $this->ls_sendchar($crc&0xff);
} }
@ -2426,7 +2413,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
$trys++; $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 */ /* Ok, he want our file */
case self::ZRPOS: case self::ZRPOS:
$pos = $this->ls_fetchlong($this->ls_rxHdr); $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_UPDATE($c,$crc);
$crc = $this->CRC32_FINISH($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) if (($rc=$this->ls_zsendhhdr(self::ZCRC,$this->ls_storelong($crc))) < 0)
return $rc; return $rc;
@ -2524,15 +2512,13 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
} }
$this->ls_sendhex($frametype); $this->ls_sendhex($frametype);
$crc = $this->CRC16USD_UPDATE($frametype,self::LSZ_INIT_CRC16);
/* Send whole header */ /* Send whole header */
for ($n=0;$n<count($hdr);$n++) { for ($n=0;$n<count($hdr);$n++) {
$this->ls_sendhex($hdr[$n]); $this->ls_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 >> 8);
$this->ls_sendhex($crc&0xff); $this->ls_sendhex($crc&0xff);
$this->client->buffer_add(chr(self::CR)); $this->client->buffer_add(chr(self::CR));

View File

@ -49,12 +49,7 @@ class Setup extends Model
public static function product_id(int $c=self::PRODUCT_ID): string public static function product_id(int $c=self::PRODUCT_ID): string
{ {
$x = substr(static::hexdigitslower,($c&0xf000)>>12,1); return hexstr($c);
$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;
} }
/* RELATIONS */ /* RELATIONS */

View File

@ -4,38 +4,11 @@ namespace App\Traits;
trait CRC trait CRC
{ {
private function CRC16USD(string $string): int
{
$crc = self::CRC16USD_INIT;
for ($c=0;$c<strlen($string);$c++)
$crc = $this->CRC16USD_UPDATE(ord($string[$c]),$crc);
return $crc;
}
private function CRC16USD_UPDATE($b,$crc): int private function CRC16USD_UPDATE($b,$crc): int
{ {
return (self::crc16usd_tab[(($crc >> 8) ^ $b) & 0xff] ^ (($crc & 0x00ff) << 8)) & 0xffff; 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<strlen($string);$i++)
$crc = (self::crc32_tab[($crc^ord($string[$i])) & 0xff] ^ (($crc>>8) & 0x00ffffff)) & 0xffffffff;
return $finish ? $this->CRC32_FINISH($crc) : $crc;
}
private function CRC32_FINISH($crc) private function CRC32_FINISH($crc)
{ {
return ~$crc & 0xffffffff; return ~$crc & 0xffffffff;

View File

@ -54,56 +54,25 @@ if (! function_exists('hex_dump')) {
} }
/** /**
* Split out an FTN address into its parts * Send a value has hex chars
*
* This function takes a fully qualified FTN address and splits it out into
* its components:
* Z:N/F.P@D
*/ */
if (! function_exists('ftn_address_split')) { if (! function_exists('hexstr')) {
function ftn_address_split(string $address,$key=NULL) function hexstr(int $int)
{ {
if ($key AND ! in_array($key,['z','n','f','p','d'])) if ($int > 0xffff)
{ throw new Exception('Int too large for hexstr');
throw new \Exception('Unknown key :'.$key.' for '.$address);
$hexdigitslower = '0123456789abcdef';
$x = '';
if ($int > 0xff) {
$x .= substr($hexdigitslower,($int&0xf000)>>12,1);
$x .= substr($hexdigitslower,($int&0x0f00)>>8,1);
} }
//$data = "10:12/909"; $x .= substr($hexdigitslower,($int&0x00f0)>>4,1);
//$data = "10:12/909.5"; $x .= substr($hexdigitslower,($int&0x000f),1);
//$data = "10:12/909@foo";
//$data = "10:12/909.5@foo";
$z = substr($address,0,strpos($address,':'));
if ($key == 'z') return $x;
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];
} }
} }