static int readBytes (unsigned char *buffer, int size, size_t *length) { *length = 0; while (*length < size) { unsigned char byte; if (!serialReadChunk(serialDevice, buffer, length, 1, 0, 100)) { return 0; } byte = buffer[*length - 1]; if ((*length == 1) && (byte == ACK)) { *length = 0; continue; } if (byte == CR) { logBytes(LOG_DEBUG, "Read", buffer, *length); return 1; } } return 0; }
/* "+" packets are silently discarded, since they are only disturbing us */ static ssize_t brl_readPacket(BrailleDisplay *brl, void *p, size_t size) { size_t offset = 0; static unsigned char ack = 04; static unsigned char nack = 05; static int apacket = 0; static unsigned char prefix, checksum; unsigned char ch; static unsigned char buf[MAXPACKETSIZE]; static unsigned char *q; if ((p==NULL) || (size<2) || (size>MAXPACKETSIZE)) return 0; while (serialReadChunk(serialDevice,&ch,&offset,1,0,1000)) { if (ch==0x02) { apacket = 1; prefix = 0xff; checksum = 0; q = &buf[0]; } else if (apacket) { if (ch==0x01) { prefix &= ~(0x40); } else if (ch==0x03) { if (checksum==0) { serialWriteData(serialDevice,&ack,1); apacket = 0; q--; if (buf[0]!='+') { memcpy(p,buf,(q-buf)); return q-&buf[0]; } } else { serialWriteData(serialDevice,&nack,1); apacket = 0; return 0; } } else { if ((q-&buf[0])>=size) { logMessage(LOG_WARNING,"Packet too long: discarded"); apacket = 0; return 0; } ch &= prefix; prefix |= 0x40; checksum ^= ch; (*q) = ch; q++; } } offset = 0; } return 0; }
static int readPacket (BrailleDisplay *brl, unsigned char *packet, int length) { size_t offset = 0; int size = -1; while (offset < length) { const unsigned char *byte = &packet[offset]; if (!serialReadChunk(serialDevice, packet, &offset, 1, 0, 1000)) { if (errno == EAGAIN) { if (!offset) return 0; logPartialPacket(packet, offset); } return -1; } if (offset == 1) { if (*byte) { logDiscardedByte(packet[0]); offset = 0; } } else { if (offset == 2) { switch (*byte) { default: size = 1; break; } size += offset; } if (offset == size) { logInputPacket(packet, offset); return offset; } } } logTruncatedPacket(packet, offset); return 0; }