Адаптеры & Конвертеры > Z-397 WEB

Запаковка, распаковка пакетов по протоколу Advanced

(1/2) > >>

pitbullko:
Доброго времени, пытаюсь разобраться в инструкции к протоколу advanced. И никак не могу понять как упаковываются/распаковываются пакеты, почему-то очень скудное объяснение в мануале.
Запаковать пакет у меня получилось(делал как в демо базе), а вот прочитать никак не получается. Может ли кто привести примеры распаковки получаемого пакета или хотябы написать алгоритм распаковки?
Может есть более расширенный мануал чем этот? https://www.ironlogic.ru/il_new.nsf/file/ru_protocol_description_advanced_v2.pdf

gsa:
Добрый день. Вот моя функция распаковки ответа от конвертера на C++:

--- Код: ---UINT_PTR DecodePack(vector<BYTE> &oDst, LPCBYTE pPack, UINT_PTR nCount)
{
LPCBYTE pIn = pPack;
LPCBYTE pEof = (pPack + nCount);
BYTE nCS = 0;
INT i;
BYTE a[4];
BYTE b;

oDst.clear();
pIn++;
while (pIn < pEof)
{
for (i = 0; i < 4; i++)
{
b = *pIn;
if (b > 0x7F)
b ^= 0xCA;
a[i] = b;
pIn++;
}
b = (*pIn++) ^ 0xCA;
for (i = 0; i < 4; i++)
if ((b & (1 << i)) > 0)
a[i] |= 0x80;
AppendByteArray(oDst, a, _countof(a));
}
if (oDst[1] > oDst.size()) // если реальный размер пакета > размера декодированного
{
return 0; // некорректный пакет
}
pIn = oDst.data();
pEof = oDst.data() + oDst[1];
while (pIn < pEof)
nCS += *pIn++;
if (nCS != 255)
{
return 0; // ошибка CRC
}
oDst.resize(oDst[1]);
return oDst.size();
}

--- Конец кода ---

pitbullko:
Наверное я чего-то недопонимаю. Отправляю запрос на чтение лицензии. Приходит ответ:
Data: 1e 4f  c6 c2 cb cb  cb ea 7f 7f c6 7f 7f 7f 7f c5 0d
После преобразования получаю, что длина пакета = 22, хотя должна быть 12.
Пробовал уже по-всякому, и никак. И тестовой базой в аксессе, и по примеру выше и по мануалу, все равно не то.

gsa:
В функции входящие 5 байт преобразуются в 4 байта (кроме кода канала 0x1E и завершающего символа 0d), поэтому размер данных результата должен быть меньше входящих данных.

gsa:
Вот функция декодирования пакета на Delphi:

--- Код: ---function TAdvancedProto.DecodeCvtPack(AData: PByte; ACount: Integer;
    var VPacketId, VLicenseN, VCmd: Byte; var VParams: Cardinal;
    var VBody: TByteBuffer): HResult;
  procedure _DecodeCvt5to4(AIn5: PByte; VOut4: PByte);
  var
    pOut: PByte;
    I: Integer;
    b: Byte;
  begin
    pOut := VOut4;
    for I := 0 to 3 do
    begin
      pOut^ := AIn5^;
      Inc(AIn5);
      if pOut^ > $7F then
        pOut^ := pOut^ xor $CA;
      Inc(pOut);
    end;

    pOut := VOut4;
    b := AIn5^ xor $CA;
    for I := 0 to 3 do
    begin
      if (b and (1 shl I)) <> 0 then
        pOut^ := pOut^ or $80;
      Inc(pOut);
    end;
  end;
var
  nChannel, nCS, nHdrSize: Byte;
  I, nPkSize, nBlockCnt: Integer;
  pOut, pIn, pInEnd: PByte;
begin
  if ACount < 9 then
    Exit(GC_E_BAD_CVT_RESPONSE); // Размер пакета слишком мал

  nChannel := AData^;
  Inc(AData);
  Dec(ACount);
  if (AData + ACount - 1)^ = $0d then
  begin
    Dec(ACount);
    if ACount < 8 then
      Exit(GC_E_BAD_CVT_RESPONSE); // Размер пакета слишком мал
  end;

  // Преобразуем 5 -> 4
  nBlockCnt := (ACount div 5);
  m_rTempBuf.Size := (nBlockCnt * 4);
  pIn := AData;
  pOut := m_rTempBuf.Memory;
  for I := 1 to nBlockCnt do
  begin
    _DecodeCvt5to4(pIn, pOut);
    Inc(pIn, 5);
    Inc(pOut, 4);
  end;

  // Читаем заголовок 4-8 байт
  if TChannel(nChannel) = cnUpdateFw then
    nHdrSize := 6
  else
    nHdrSize := 8;

  nPkSize := m_rTempBuf[1];
  // Если указанный размер пакета > размера декодированного,
  if nPkSize > m_rTempBuf.Size then
    Exit(GC_E_BAD_CVT_RESPONSE); // Некорректный пакет

  VLicenseN := m_rTempBuf[2];
  VPacketId := m_rTempBuf[3];

  VCmd := m_rTempBuf[4];
  VParams := 0;
  Move(m_rTempBuf.Memory[5], VParams, 3);

  // Считаем контрольную сумму
  nCS := 0;
  pIn := m_rTempBuf.Memory;
  pInEnd := pIn + nPkSize;
// Выключаем Overflow checking
{$IFOPT Q+}
{$DEFINE CKOVERFLOW}
{$Q-}
{$ENDIF}
  while pIn <> pInEnd do
  begin
    Inc(nCS, pIn^);
    Inc(pIn);
  end;
{$IFDEF CKOVERFLOW}
{$UNDEF CKOVERFLOW}
{$Q+}
{$ENDIF}
  if nCS <> $ff then
    Exit(GC_E_BAD_CVT_RESPONSE); // ошибка CRC

  VBody.SetData(@m_rTempBuf.Memory[nHdrSize], nPkSize - nHdrSize);

  Result := S_OK;
end;

--- Конец кода ---

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии