Код:
#include <windows.h>
#include <tchar.h>
#include <locale.h>
#include <stdio.h>
#include <conio.h>
//
BOOL ASCIIToCode( CHAR ch, CHAR*char_for_hash ){
ch = toupper( ch ); //преобразуем все в верхний регистр
if( strchr( "0123456789", ch ) ){
*char_for_hash = ch - '0';
}else if( (ch >= 'A') && (ch <= 'Z') ){
*char_for_hash = ch - 'A' + 10;
}else{
switch( ch ){
case '-':
*char_for_hash = 10 + 26;
break;
case '_':
*char_for_hash = 10 + 26 + 1;
break;
case '/':
*char_for_hash = 10 + 26 + 2;
break;
case ' ':
*char_for_hash = 10 + 26 + 3;
break;
default:
return FALSE;
}
}
*char_for_hash *= 2;
return TRUE;
}
//
USHORT Hash( BYTE Byte, BYTE nbit, USHORT CRC ){
for( INT i = 0; i < nbit; i++, Byte <<= 1){
if( ( Byte ^ ( CRC >> 8 ) ) & 0x80 ){
CRC <<= 1;
CRC ^= 0x8F57;
}else{
CRC <<= 1;
}
}
return CRC;
}
//
typedef union tagOwenHeader{
struct{
WORD Low : 8;
WORD Size : 4;
WORD Query : 1;
WORD High : 3;
};
BYTE Bytes[2];
}OWEN_HEADER, *POWEN_HEADER;
//
int _tmain( int argc, TCHAR *argv[] ) {
INT addr, size, Byte;
TCHAR query[2], cmd_fmt[2];
CHAR a_cmd[100];
BYTE Data[15];
BYTE Command[50];
OWEN_HEADER hdr;
INT l, i;
USHORT hash;
CHAR chfh;
//
_tsetlocale( LC_ALL, TEXT("Russian") );
//
loop:
do{
fflush( stdin );
_tprintf_s( TEXT("Введите адрес устройства (0-2047): ") );
}while( _tscanf_s( TEXT("%i"), &addr ) != 1 );
//
do{
fflush( stdin );
_tprintf_s( TEXT("Это запрос? (y/n): ") );
}while( _tscanf_s( TEXT("%1[yn]"), &query, sizeof(query)/sizeof(TCHAR) ) != 1 );
//
do{
fflush( stdin );
_tprintf_s( TEXT("Введите размер блока данных (2-17): ") );
}while( (_tscanf_s( TEXT("%i"), &size ) != 1) || (size < 2) || (size > 17) );
//
do{
fflush( stdin );
_tprintf_s( TEXT("команда будет введена строкой? (y-строка/n-HASH): ") );
}while( _tscanf_s( TEXT("%1[yn]"), &cmd_fmt, sizeof(cmd_fmt)/sizeof(TCHAR) ) != 1 );
//
switch( cmd_fmt[0] ){
case TEXT('y'):
cmd_loop:
do{
fflush( stdin );
_tprintf_s( TEXT("Введите имя команды (допустимый набор символов: [a-zA-Z0-9-_/ .]): ") );
}while( _tscanf_s( TEXT("%h[a-zA-Z0-9-_/ .]"), &a_cmd, sizeof(a_cmd)/sizeof(CHAR) ) != 1 );
//
_tprintf_s( TEXT("Имя команды: \"%hs\"\r\n"), a_cmd );
//
for( hash = 0, l = strlen( a_cmd ), i = 0 ; l-- ; ++i ){
if( a_cmd[i] != '.' ){
if( !ASCIIToCode( a_cmd[i], &chfh ) ){
goto cmd_loop;
}
if( a_cmd[i + 1] == '.' ){
++chfh;
}
hash = Hash( chfh << 1, 7, hash );
}
}
break;
case TEXT('n'):
do{
fflush( stdin );
_tprintf_s( TEXT("Введите HASH команды: ") );
}while( _tscanf_s( TEXT("%hi"), &hash ) != 1 );
break;
}
_tprintf_s( TEXT("HASH команды: 0x%.4hx\r\n"), hash );
//
for( i = 0, l = size - 2 ; l-- ; ++i ){
do{
fflush( stdin );
_tprintf_s( TEXT("Введите %i-й байт команды (0-255): "), i + 3 );
if( _tscanf_s( TEXT("%i"), &Byte ) != 1 ){
continue;
}
if( Byte < 0 || Byte > 255 ){
continue;
}
Data[i] = Byte;
break;
}while( TRUE );
}
//
hdr.Low = addr;
hdr.High = addr >> 8;
hdr.Query = ( query[0] == TEXT('y') ) ? 1 : 0;
hdr.Size = (BYTE)(size - 2);
Command[0] = hdr.Bytes[0];
Command[1] = hdr.Bytes[1];
Command[2] = (BYTE)(hash >> 8);
Command[3] = (BYTE)hash;
for( i = 0, l = size - 2 ; l-- ; ++i ){
Command[4 + i] = Data[i];
}
//
for( hash = 0, i = 0, l = 2 + size ; l-- ; ++i ){
hash = Hash( Command[i], 8, hash );
}
Command[2 + size] = (BYTE)(hash >> 8);
Command[3 + size] = (BYTE)hash;
//
_tprintf_s( TEXT("--------\r\nКоманда:\r\n") );
for( i = 0, l = 4 + size ; l-- ; ++i ){
_tprintf_s( TEXT("%.2x"), Command[i] );
}
_tprintf_s( TEXT("\r\n#") );
for( i = 0, l = 4 + size ; l-- ; ++i ){
_tprintf_s( TEXT("%c"), 'G' + ( Command[i] >> 4 ) );
_tprintf_s( TEXT("%c"), 'G' + ( Command[i] & 0x0f ) );
}
_tprintf_s( TEXT("\\r\r\n--------\r\n") );
//
do{
fflush( stdin );
_tprintf_s( TEXT("Продолжить? (y/n): ") );
}while( _tscanf_s( TEXT("%1[yn]"), &query, sizeof(query)/sizeof(TCHAR) ) != 1 );
//
if( query[0] == TEXT('y') ){
goto loop;
}
return 0;
}
несколько похожий код я использовал у себя в трансляторе этого протокола в SCPI форму, пока все работает