예제 #1
0
static size_t
readPacket (BrailleDisplay *brl, InputPacket *packet) {
  const size_t length = 10;
  size_t offset = 0;

  while (1) {
    unsigned char byte;

    {
      int started = offset > 0;
      if (!gioReadByte(brl->gioEndpoint, &byte, started)) {
        if (started) logPartialPacket(packet->bytes, offset);
        return 0;
      }
    }

    if (!offset) {
      if (byte != 0XFA) {
        logIgnoredByte(byte);
        continue;
      }
    }

    packet->bytes[offset++] = byte;
    if (offset == length) {
      if (byte == 0XFB) {
        {
          int checksum = -packet->data.checksum;

          {
            size_t i;
            for (i=0; i<offset; i+=1) checksum += packet->bytes[i];
          }

          if ((checksum & 0XFF) != packet->data.checksum) {
            logInputProblem("Incorrect Input Checksum", packet->bytes, offset);
          }
        }

        logInputPacket(packet->bytes, offset);
        return length;
      }

      {
        const unsigned char *start = memchr(packet->bytes+1, packet->bytes[0], offset-1);
        const unsigned char *end = packet->bytes + offset;
        if (!start) start = end;
        logDiscardedBytes(packet->bytes, start-packet->bytes);
        memmove(packet->bytes, start, (offset = end - start));
      }
    }
  }
}
예제 #2
0
static int
readPacket (BrailleDisplay *brl, Packet *packet) {
  while (1) {
    int size = sizeof(PacketHeader);
    int hasPayload = 0;

    if (brl->data->inputCount >= sizeof(PacketHeader)) {
      if (brl->data->inputBuffer.packet.header.type & 0X80) {
        hasPayload = 1;
        size += brl->data->inputBuffer.packet.header.arg1 + 1;
      }
    }

    if (size <= brl->data->inputCount) {
      logInputPacket(brl->data->inputBuffer.bytes, size);

      if (hasPayload) {
        unsigned char checksum = 0;
        int index;

        for (index=0; index<size; index+=1)
          checksum -= brl->data->inputBuffer.bytes[index];

        if (checksum) logMessage(LOG_WARNING, "Input packet checksum error.");
      }

      memcpy(packet, &brl->data->inputBuffer, size);
      memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[size],
              brl->data->inputCount -= size);
      return size;
    }

  retry:
    {
      int count = gioReadData(brl->data->gioEndpoint,
                              &brl->data->inputBuffer.bytes[brl->data->inputCount],
                              size - brl->data->inputCount,
                              0);

      if (count < 1) {
        if (count == -1) {
          logSystemError("read");
        } else if ((count == 0) && (brl->data->inputCount > 0)) {
          if (gioAwaitInput(brl->data->gioEndpoint, 1000)) goto retry;
          if (errno != EAGAIN) count = -1;
          logPartialPacket(brl->data->inputBuffer.bytes, brl->data->inputCount);
          brl->data->inputCount = 0;
        }

        return count;
      }
      brl->data->acknowledgementsMissing = 0;

      if (!brl->data->inputCount) {
        static const unsigned char packets[] = {
          PKT_ACK, PKT_NAK,
          PKT_KEY, PKT_EXTKEY, PKT_BUTTON, PKT_WHEEL,
          PKT_INFO
        };
        int first;

        for (first=0; first<count; first+=1)
          if (memchr(packets, brl->data->inputBuffer.bytes[first], sizeof(packets)))
            break;

        if (first) {
          logDiscardedBytes(brl->data->inputBuffer.bytes, first);
          memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[first], count-=first);
        }
      }

      brl->data->inputCount += count;
    }
  }
}