Fix select() not being used even if its available. config.h has to be included

before any HAVE_### macros may be used! Cleanup comments and group related
function descriptions.
This commit is contained in:
mmdolze
2011-02-27 11:36:44 +00:00
parent 2d57d0c7f3
commit 471fbc593e
2 changed files with 84 additions and 103 deletions
+1
View File
@@ -23,6 +23,7 @@ v.0.5dev (ongoing development)
* hd44780/imon: Add charmap for NEC uPD16314 and make it configurable * hd44780/imon: Add charmap for NEC uPD16314 and make it configurable
* Pyramid: Convert set_char to 8 byte bitmap, add support for bignum * Pyramid: Convert set_char to 8 byte bitmap, add support for bignum
* Convert set_char of drivers bayrad, lb216, lcterm, mtc_s16209x, wirz-sli * Convert set_char of drivers bayrad, lb216, lcterm, mtc_s16209x, wirz-sli
* CFontzPacket: Fix not using select() even if its available
v0.5.4 v0.5.4
* Update driver includes and LDFLAGS (fixed glk and bayrad binding error) * Update driver includes and LDFLAGS (fixed glk and bayrad binding error)
+78 -98
View File
@@ -1,9 +1,9 @@
/** \file server/drivers/CFontz633io.c /** \file server/drivers/CFontz633io.c
* IO routines for the drivers \c CFontzPacket and \c CFontz633. * I/O routines for the \c CFontzPacket driver. Currently the CFA-631,
* CFA-533, CFA-633 and CFA-635 LCDs use this type of protocol.
*/ */
/* interfacing routines for the CrystalFontz CFA-631, CFA-633 and CFA-635 LCDs /*-
=========================================================================== ===========================================================================
633 Test code for linux. 633 Test code for linux.
Copyright 2002, David GLAUDE Copyright 2002, David GLAUDE
@@ -47,31 +47,28 @@
*/ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> /* only required for debugging */
#if defined(HAVE_SYS_SELECT_H) #if defined(HAVE_SYS_SELECT_H)
# include <sys/select.h> # include <sys/select.h>
#else #else
# include <sys/time.h> # include <sys/time.h>
# include <sys/types.h> # include <sys/types.h>
#endif /* defined(HAVE_SYS_SELECT_H) */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif #endif
#include "CFontz633io.h" #include "CFontz633io.h"
#include "report.h"
/* Return values for the check_for_packet() */
#define TRY_AGAIN 0 #define TRY_AGAIN 0
#define GOOD_MSG 1 #define GOOD_MSG 1
#define GIVE_UP 2 #define GIVE_UP 2
/* define CFONTZ633_WRITE_DELAY to use select when waiting for packet acknowledgement */ /* define CFONTZ633_WRITE_DELAY to use select when waiting for packet acknowledgement */
#if !defined(CFONTZ633_WRITE_DELAY) #if !defined(CFONTZ633_WRITE_DELAY)
# define CFONTZ633_WRITE_DELAY 250 # define CFONTZ633_WRITE_DELAY 250
@@ -88,18 +85,17 @@ static void print_packet(COMMAND_PACKET *packet);
#endif #endif
/* global variables */ /** \addtogroup CFA_KeyRing
KeyRing keyring; *
ReceiveBuffer receivebuffer;
/*
* KeyRing handling functions. * KeyRing handling functions.
* This separates the producer from the consumer. * This separates the producer from the consumer.
* It is just a small fifo of unsigned char. * It is just a small fifo of unsigned char.
* @{
*/ */
/* Global variable */
KeyRing keyring;
/** /**
* Initialize/empty key ring by resetting its read & write pointers. * Initialize/empty key ring by resetting its read & write pointers.
* \param kr Pointer to KeyRing. * \param kr Pointer to KeyRing.
@@ -120,8 +116,6 @@ void EmptyKeyRing(KeyRing *kr)
int AddKeyToKeyRing(KeyRing *kr, unsigned char key) int AddKeyToKeyRing(KeyRing *kr, unsigned char key)
{ {
if (((kr->head + 1) % KEYRINGSIZE) != (kr->tail % KEYRINGSIZE)) { if (((kr->head + 1) % KEYRINGSIZE) != (kr->tail % KEYRINGSIZE)) {
//debug(RPT_DEBUG, "%s: add key: %d", __FUNCTION__, key);
kr->contents[kr->head % KEYRINGSIZE] = key; kr->contents[kr->head % KEYRINGSIZE] = key;
kr->head = (kr->head + 1) % KEYRINGSIZE; kr->head = (kr->head + 1) % KEYRINGSIZE;
return 1; return 1;
@@ -149,11 +143,9 @@ unsigned char GetKeyFromKeyRing(KeyRing *kr)
kr->tail = (kr->tail + 1) % KEYRINGSIZE; kr->tail = (kr->tail + 1) % KEYRINGSIZE;
} }
//if (retval)
// debug(RPT_DEBUG, "%s: remove key: %d", __FUNCTION__, retval);
return retval; return retval;
} }
/** @} */
@@ -239,7 +231,7 @@ send_packet(int fd, COMMAND_PACKET *out, COMMAND_PACKET *in)
write(fd, CRC, 2); write(fd, CRC, 2);
/**** TEST STUFF ****/ /**** TEST STUFF ****/
// print_packet(out); //print_packet(out);
/* Every time we send a message, we also check for an incoming one. */ /* Every time we send a message, we also check for an incoming one. */
test_packet(fd, 0x40 | out->command, in); test_packet(fd, 0x40 | out->command, in);
@@ -315,11 +307,22 @@ get_crc(unsigned char *buf, int len, int seed)
} }
/* circular buffer: */ /** \addtogroup CFA_ReceiveBuffer
/* v peek */ *
/* -------------------------------------------------- */ * ReceiveBuffer handling functions.
/* ^ tail ^ head */ * The receive buffer is a circular buffer of bytes with the possibility to
* 'peek' into received bytes.
*
*\verbatim
* | v peek |
* |--------------------------------------------------|
* | ^ tail ^ head |
*\endverbatim
* @{
*/
/* Global variable */
ReceiveBuffer receivebuffer;
/** /**
* Initialize/empty receive buffer by resetting its pointers. * Initialize/empty receive buffer by resetting its pointers.
@@ -355,30 +358,22 @@ void SyncReceiveBuffer(ReceiveBuffer *rb, int fd, unsigned int number)
if (!retval) if (!retval)
return; return;
#endif /* defined(HAVE_SELECT) && defined(CFONTZ633_WRITE_DELAY) && (CFONTZ633_WRITE_DELAY > 0) */ #endif
if (number > MAX_DATA_LENGTH) if (number > MAX_DATA_LENGTH)
number = MAX_DATA_LENGTH; number = MAX_DATA_LENGTH;
BytesRead = read(fd, buffer, number); BytesRead = read(fd, buffer, number);
if (BytesRead == -1) { if (BytesRead > 0) {
/* this should not happen with the select() above */
//debug(RPT_WARNING, "%s: ~~~Problem reading: %s", __FUNCTION__, strerror(errno));
}
else {
int i; int i;
//debug(RPT_DEBUG, "%s: read %d bytes:", __FUNCTION__, BytesRead);
/* wrap write pointer to the receive buffer */ /* wrap write pointer to the receive buffer */
rb->head %= RECEIVEBUFFERSIZE; rb->head %= RECEIVEBUFFERSIZE;
/* store the bytes read */ /* store the bytes read wrapping at the buffer end */
for (i = 0; i < BytesRead; i++) { for (i = 0; i < BytesRead; i++) {
//debug(RPT_DEBUG, "%s: reading byte %02x", __FUNCTION__, buffer[i]);
rb->contents[rb->head] = buffer[i]; rb->contents[rb->head] = buffer[i];
/* increment write pointer (wrap if needed) */
rb->head = (rb->head + 1) % RECEIVEBUFFERSIZE; rb->head = (rb->head + 1) % RECEIVEBUFFERSIZE;
} }
} }
@@ -487,7 +482,7 @@ unsigned char PeekByte(ReceiveBuffer *rb)
return(return_byte); return(return_byte);
} }
/** @} */
/** /**
@@ -497,9 +492,10 @@ unsigned char PeekByte(ReceiveBuffer *rb)
* \param in Pointer to COMMAND_PACKET structure to write the response to. * \param in Pointer to COMMAND_PACKET structure to write the response to.
* \retval 1 Expected response received. * \retval 1 Expected response received.
* \retval 0 Expected response not received. * \retval 0 Expected response not received.
*/ *
/* I should use the value GIVE_UP and not reenter if there is no extra * \todo check_for_packet is always called with MAX_DATA_LENGTH. This doesn't
* byte read from the serial port * do any harm, but passing that parameter is useless then. Additionally
* one complete packet is MAX_DATA_LENGTH + 4 (command, length, CRC).
*/ */
static int static int
test_packet(int fd, unsigned char response, COMMAND_PACKET *in) test_packet(int fd, unsigned char response, COMMAND_PACKET *in)
@@ -537,27 +533,19 @@ test_packet(int fd, unsigned char response, COMMAND_PACKET *in)
} }
return 1; return 1;
#endif /* defined(HAVE_SELECT) && defined(CFONTZ633_WRITE_DELAY) && (CFONTZ633_WRITE_DELAY > 0) */ #endif
} }
/*============================================================================
* check_for_packet()
*
* check_for_packet() will see if there is a valid packet in the input buffer.
* If there is, it will copy it into incoming_command and return 1. If there
* is not it will return 0. incoming_packet may get partially filled with
* garbage if there is not a valid packet available.
*----------------------------------------------------------------------------
*/
/** /**
* Check for a packet to read. * Check for a packet to read. If there is a valid packet in the input buffer
* it will copy it into \c in and return GOOD_MSG. If there is no enough data
* available for a valid packet it returns GIVE_UP.
*
* \param fd File handle to read from. * \param fd File handle to read from.
* \param in Pointer to COMMAND_PACKET structure to write the response to. * \param in Pointer to COMMAND_PACKET structure to write the response to.
* \param expected_length Expected response length. * \param expected_length Expected response length.
*
* \retval GIVE_UP No message and we should not retry until new input. * \retval GIVE_UP No message and we should not retry until new input.
* \retval TRY_AGAIN No message but we should try again immediately. * \retval TRY_AGAIN No message but we should try again immediately.
* \retval GOOD_MSG Message correctly identified. * \retval GOOD_MSG Message correctly identified.
@@ -570,83 +558,78 @@ check_for_packet(int fd, COMMAND_PACKET *in, unsigned char expected_length)
SyncReceiveBuffer(&receivebuffer, fd, expected_length); SyncReceiveBuffer(&receivebuffer, fd, expected_length);
//First off, there must be at least 4 bytes available in the input stream /*
//for there to be a valid command in it (command, length, no data, CRC). * There must be at least 4 bytes available in the input stream for
* there to be a valid command in it (command, length, no data, CRC).
*/
if (BytesAvail(&receivebuffer) < 4) { if (BytesAvail(&receivebuffer) < 4) {
//debug(RPT_INFO, "%s: not enough bytes available for even the smallest message", __FUNCTION__); return(GIVE_UP);
return(GIVE_UP); /* We don't need to retry before more byte are received */
} }
/* Look into the buffer without removing the data. */ /* Look into the buffer without removing the data. */
SyncPeekPointer(&receivebuffer); SyncPeekPointer(&receivebuffer);
/* look at potential command byte */ /*
* Look at potential command byte. If it is not a valid command
* discard it and try again.
*/
in->command = PeekByte(&receivebuffer); in->command = PeekByte(&receivebuffer);
if ((in->command & 0x3F) > MAX_COMMAND) {
/* Only commands 0 through MAX_COMMAND are valid */
if (MAX_COMMAND < (0x3F & in->command)) {
/* Throw out one byte of garbage. Next pass through should re-sync. */
GetByte(&receivebuffer); GetByte(&receivebuffer);
//debug(RPT_INFO, "%s: unknown command", __FUNCTION__);
return(TRY_AGAIN); return(TRY_AGAIN);
} }
/* There is a valid command byte. Get the data_length. */ /*
* Get the data_length and check it is within valid range. If not
* discard it and try again.
*/
in->data_length = PeekByte(&receivebuffer); in->data_length = PeekByte(&receivebuffer);
if (in->data_length > MAX_DATA_LENGTH) {
/* The data length must be within reason. */
if (MAX_DATA_LENGTH < in->data_length) {
//Throw out one byte of garbage. Next pass through should re-sync.
GetByte(&receivebuffer); GetByte(&receivebuffer);
//debug(RPT_INFO, "%s: too long packet: %d", __FUNCTION__, in->data_length);
return(TRY_AGAIN); return(TRY_AGAIN);
} }
// Now there must be at least in->data_length + sizeof(CRC) bytes /*
// still available for us to continue. * Now there must be at least in->data_length + sizeof(CRC) bytes
* still available for us to continue. If not give up and try again
* if more bytes are available.
*/
if ((int) PeekBytesAvail(&receivebuffer) < (in->data_length + 2)) { if ((int) PeekBytesAvail(&receivebuffer) < (in->data_length + 2)) {
//It looked like a valid start of a packet, but it does not look return(GIVE_UP);
//like the complete packet has been received yet.
//debug(RPT_INFO, "%s: not enough read to check the complete message", __FUNCTION__);
return(GIVE_UP); /* Let's not return until more byte are available */
} }
/* There is enough data to make a packet. Transfer over the data. */ /* There is enough data to make a packet. Transfer over the data. */
for (i = 0; i < in->data_length; i++) for (i = 0; i < in->data_length; i++)
in->data[i] = PeekByte(&receivebuffer); in->data[i] = PeekByte(&receivebuffer);
//Now move over the CRC: convert CRC bytes to CRC manually to avoid endianness issues /* Convert CRC bytes to CRC manually to avoid endianess issues */
in->crc = PeekByte(&receivebuffer); in->crc = PeekByte(&receivebuffer);
in->crc |= PeekByte(&receivebuffer) << 8; in->crc |= PeekByte(&receivebuffer) << 8;
//Compute the expected CheckSum /* Compute the expected checksum and compare it to the received one. */
testcrc = get_crc((unsigned char *) in, in->data_length+2, 0xFFFF); testcrc = get_crc((unsigned char *) in, in->data_length+2, 0xFFFF);
//Now check the CRC.
if (in->crc == testcrc) { if (in->crc == testcrc) {
//This is a good packet. Remove the packet from the serial buffer. /* This is a good packet. Remove it from the serial buffer. */
AcceptPeekedData(&receivebuffer); AcceptPeekedData(&receivebuffer);
//Let our caller know that incoming_command has good stuff in it.
/* print_packet(in); */ /**** TEST STUFF ****/
//print_packet(in);
return(GOOD_MSG); return(GOOD_MSG);
} }
/* The CRC did not match. Toss out one byte of garbage. /*
* Next pass through should re-sync. * The CRC did not match. Toss out one byte of garbage. Next pass
* through should re-sync.
*/ */
GetByte(&receivebuffer); GetByte(&receivebuffer);
//debug(RPT_INFO, "%s: wrong CheckSum: computed %04x / real %04x",
// __FUNCTION__, testcrc, in->crc);
return(TRY_AGAIN); return(TRY_AGAIN);
} }
#ifdef DEBUG #ifdef DEBUG
/* /*
* This is a debugging function. * This prints a hex dump of a packet to stderr.
* It should be removed or compiled in conditionally.
* Currently it is still using printf for debugging.
*/ */
static void static void
print_packet(COMMAND_PACKET *packet) print_packet(COMMAND_PACKET *packet)
@@ -658,11 +641,8 @@ print_packet(COMMAND_PACKET *packet)
len = packet->data_length; len = packet->data_length;
fprintf(stderr, "Message (%d,%d) %d [", top, cmd, len); fprintf(stderr, "Message (%d,%d) %d [", top, cmd, len);
//There is enough data to make a packet. Transfer over the data.
for (i = 0; i < packet->data_length; i++) for (i = 0; i < packet->data_length; i++)
fprintf(stderr, " %02x", packet->data[i]); fprintf(stderr, " %02x", packet->data[i]);
fprintf(stderr, " ] %02x %02x .\n", packet->crc & 0xFF, (packet->crc >> 8) & 0xFF); fprintf(stderr, " ] %02x %02x .\n", packet->crc & 0xFF, (packet->crc >> 8) & 0xFF);
} }
#endif /* DEBUG */ #endif