Не получается посчитать CRC

webmaster_Chris

Новичок
И так :)) Задача :) приходит пакет по сокету, который мы их bin2hex переводим. Получаем 41 03 56 89 60 34 06 01 61 45 69 00 00 00 00 00 00 00 00

Далее на такой пакет нужно устройству ответить это 4103568960340601610000000000 + CRC... Цитирую документацию:

При «авторизации» отправляются поля 1, 2, 5 (1+17+1=19 байт) (должен получить ответ CRC в виде resp_crc=xx, где xx – «посчитанная» сервером CRC)

CRC включает в себя все переданные байты (кроме самого байта CRC).
Перед передачей первого байта CRC устанавливается в 0x3B (GPRS_CRC=0x3B).
Функция расчета CRC (для каждого передаваемого байта):
void CRC (byte) {GPRS_CRC+=0x56^byte; GPRS_CRC++; GPRS_CRC^=0xC5+byte; GPRS_CRC--;}
т.е. пакет ответа получился 14 байт (без учета CRC) получается 56*14 отбрасываем последние цыфры, тоесть 784 -> 78 это CRC 16-ый байт.


Т.е. ответ 41035689603406016100000000003B78, через функцию:

PHP:
define('HEX2BIN_WS', " \t\n\r");                                                                                                                             
                                                                                                                                                             
function hex2bin($hex_string) {                                                                                                                              
$pos = 0;                                                                                                                                                    
$result = '';                                                                                                                                                
while ($pos < strlen($hex_string)) {                                                                                                                         
 if (strpos(HEX2BIN_WS, $hex_string{$pos}) !== FALSE) {                                                                                                      
 $pos++;                                                                                                                                                     
  } else {                                                                                                                                                   
 $code = hexdec(substr($hex_string, $pos, 2));                                                                                                               
 $pos = $pos + 2;                                                                                                                                            
 $result .= chr($code);                                                                                                                                      
}                                                                                                                                                            
}                                                                                                                                                            
return $result;                                                                                                                                              
}
засылаю устройству.. а в ответ нифига.. где я ошибаюсь, помогите подумать
 

webmaster_Chris

Новичок
Ну ладно CRC считается вот так:

PHP:
$GPRS_CRC=0x3B;                                                                                              
                                                                                                                                                             
$n=0;                                                                                                        
                                                                                                                                                             
while ($n<18){                                                                                               
 $GPRS_CRC+=0x56^$hex[$n];                                                                                    
 $GPRS_CRC++;                                                                                                 
 $GPRS_CRC^=0xC5+$hex[$n];                                                                                    
 $GPRS_CRC--;                                                                                                 
  $n++;                                                                                                        
}
но как посылать ответ то?
 

cDLEON

Онанист РНРСlub
А что за устройство которому ты засылаешь ? Или нам телепата включать ?
GPRS_CRC - это один байт ?
 

webmaster_Chris

Новичок
Устройство AutoFon Mayak 4.5

Да GPRS_CRC это один байт... Даже скжу больше, вот что пишет их разработчик:

Расмотрим на примере, что от маяка пришел вот такой пакет авторизации:

41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07

в документации написано: crc передается ОДНИМ БАЙТОМ!
ответ должен быть из 10 байт: 9 из них - resp_crc=, а 10-й - сама crc.

То есть, для данного случая это будет выглядеть так:
resp_crc= - это 9 байт: 72 65 73 70 11 63 72 63 3D
сама crc - 10-й байт - (в данном случае - 07)

Итого ответ серверу на пакет авторизации должен выглядеть так
72 65 73 70 11 63 72 63 3D 07
нихрена не понимаю откуда взялось 72 65 73 70 11 63 72 63 3D....
 

Вурдалак

Продвинутый новичок
Бред какой-то написан, честное слово. Уже начиная с первой строчки. С какого хрена ты трогаешь функцию bin2hex()? Зачем она тебе нужна? С какого хрена у тебя ответ получился в 14 байт? В документации тоже какая-то хрень написана: в ответе должны быть все переданные байты (их же передали 19) и CRC. 19 + 1 = 20, с какого хрена в примере их меньше? Бредятина. Подмена определений. То
CRC включает в себя все переданные байты
, то
crc передается ОДНИМ БАЙТОМ!
Бред.

т.е. пакет ответа получился 14 байт (без учета CRC) получается 56*14 отбрасываем последние цыфры, тоесть 784 -> 78 это CRC 16-ый байт
— это вообще написано под действием алкоголя, по-моему.
 

webmaster_Chris

Новичок
Приветствую! На самом деле там 19 байт - 1, т.е. в расчете CRC используется 18 байт, т.к. 19-й это и есть CRC... Но как ответить на пакет я не понимаю.. Пример вот есть: Это от устройства 41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07, а ответ ему должет бть такой 72 65 73 70 11 63 72 63 3D 07... Перебрал все... ну никак не получается.. формула расчета выше... но где ошибаюсь до сих пор не пойму...

Описание самого протокола: http://forum.autofon.ru/download/file.php?id=1&sid=1d57773fbd02e07da7d0d35e780d9733
 

Вурдалак

Продвинутый новичок
Я так понял, что resp — просто некий ответ, который удовлетворяет требованиям какой-то спецификации. А вот последний байт ты и высчитываешь. Т.е. «resp_crc=xx» следует понимать как «ответ из 9-ти байт + CRC-код». Я так думаю.

Подсчёт CRC, кстати, такой:
PHP:
<?php

function crc($bytes)
{
    $r = 0x3B;

    for($i = 0; $i < strlen($bytes); $i++)
    {
        $r += 0x56 ^ ord($bytes[$i]);
        $r++;
        $r ^= 0xC5 + ord($bytes[$i]);
        $r--;
    }
    
    return $r & 0xFF;
}

printf('%02X', crc("\x41\x03\x56\x89\x50\x38\x77\x67\x98\x45\x68\x00\x00\x00\x00\x00\x00\x00"));
 

webmaster_Chris

Новичок
Если бы так было, то вот это 41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07 было бы равно вот этому 73 70 11 63 72 63 3D 07... тем неменее первое - 19 байт, второе 8... Так как получилось второе.. если формула:

CRC включает в себя все переданные байты (кроме самого байта CRC).
Перед передачей первого байта CRC устанавливается в 0x3B (GPRS_CRC=0x3B).
Функция расчета CRC (для каждого передаваемого байта):
void CRC (byte) {GPRS_CRC+=0x56^byte; GPRS_CRC++; GPRS_CRC^=0xC5+byte; GPRS_CRC--;}
А при той формуле, учитывая то, что поле 1 (41) должно входить в это получается 55... в примере же приведено 73... вот где то упускаю момент... ((
 

webmaster_Chris

Новичок
07 действительно получилось, но вот это откуда взялось: 73 70 11 63 72 63 3D и вот он crc 07
 

Вурдалак

Продвинутый новичок
Если каждому запросу по какому-то алгоритму однозначно строится ответ, то тут сервер-клиент не нужен: этот «ответ» можно было бы получить сразу на локальной машине. И вообще я не понимаю что ты такое делаешь, что сам не представляешь что и для чего это нужно?
 

webmaster_Chris

Новичок
73 70 11 63 72 63 3D = "resp_crc=" вот что это оказывается... ))) Представлять то представляю, но с устртройствами такого плана работал... очень давно... Спасибо за помощь!
 

Вурдалак

Продвинутый новичок
Я чё-то явно не понимаю: какой смысл в бинарном протоколе писать прямо фразу «resp_crc=»? Для кого?
 
Сверху