boolean SHT1x::measure(int& result, uint8_t& crc2, uint8_t command) { boolean error; uint8_t temp; start_sequence(); error = send_byte(command); #ifdef __USE_CRC__ crc.reset(); crc.update(command); #endif /* __USE_CRC__ */ wait_for_measurement(); temp = receive_byte(LOW); #ifdef __USE_CRC__ crc.update(temp); #endif /* __USE_CRC__ */ result = temp << 8; temp = receive_byte(LOW); #ifdef __USE_CRC__ crc.update(temp); #endif /* __USE_CRC__ */ result += temp; crc2 = receive_byte(HIGH); #ifdef __USE_CRC__ crc.update(crc.bit_reverse(crc2)); // Now CRC should equal 0. #endif /* __USE_CRC__ */ return error; }
boolean SHT1x::status_register_read(uint8_t& result, uint8_t& crc2) { boolean error; start_sequence(); error = send_byte(SHT1X_CMD_READ_STATUS); result = receive_byte(LOW); crc2 = receive_byte(HIGH); return error; }
BYTE RcvAPDU(void) { iso7816_buffer[0] = receive_byte(); if(iso7816_buffer[0] == 0xFF) { iso7816_buffer[1] = receive_byte(); iso7816_buffer[2] = receive_byte(); iso7816_buffer[3] = receive_byte(); if(iso7816_buffer[1] == 0x10 && PPSFlag == 0) // PPS { PPS(); // Set baud rate PPSFlag = 1; // PPS is enabled for the 1st time only } } else if(iso7816_buffer[0] == 0x00) { iso7816_buffer[1] = receive_byte(); iso7816_buffer[2] = receive_byte(); iso7816_buffer[3] = receive_byte(); iso7816_buffer[4] = receive_byte(); if((iso7816_buffer[1] == WRFLASH || iso7816_buffer[1] == UDFLASH || iso7816_buffer[1] == ERFLASH || (iso7816_buffer[1] == DESOPER && iso7816_buffer[3] != 0x10)) && iso7816_buffer[4] != 0) { send_byte(iso7816_buffer[1]); Rx_n_Bytes(iso7816_buffer[4]); } return 1; } return 0; }
void device::send_byte( int16_t byte ) { /* In a tight send loop a second exception may be triggered * before the first one has been reached a handler -> * "terminate called after throwing an instance of 'raspbiec_error'" */ //if (lasterror != IEC_OK) return; for(long msec = 0; msec < IEC_TIMEOUT_MS; msec+=IEC_WAIT_MS) { int ret = write(devfd, &byte, sizeof byte); if ( ret > 0 ) { return; } else if (ret < 0) { if (errno == EIO) { receive_byte(); // Read the IEC bus error code } if (lasterror < 0) { throw raspbiec_error(lasterror); } else { lasterror = IEC_GENERAL_ERROR; throw raspbiec_error(IEC_GENERAL_ERROR); } } nanosleep(&timeout, NULL); } throw raspbiec_error(IEC_READ_TIMEOUT); }
int8_t I2C::read_byte(uint8_t slaveAddress,uint8_t regAddress,uint8_t* data,uint16_t numToRead) { uint8_t i = 0; start(); send_7bits_address(slaveAddress); I2C_Cmd(_I2Cx,ENABLE); send_byte(regAddress); start(); send_7bits_address(slaveAddress + 1); while(numToRead) { if(numToRead == 1) { send_no_ack(); stop(); } receive_byte(data); data++; numToRead--; i++; } send_ack(); return i; }
int8_t SOFTI2C::read_byte(uint8_t slave_address,uint8_t reg_address,uint8_t* data,uint16_t num_to_read) { int8_t ret = 0; int i = 0; start(); if (send_7bits_address(slave_address) == -1) ret = -1; if (send_byte(reg_address) == -1) ret = -2; start(); if (send_7bits_address(slave_address + 1) == -1) ret = -3; while(num_to_read) { *data++ = receive_byte(); num_to_read--; i++; if(num_to_read == 0) { send_no_ack(); stop(); ret = 0; } else send_ack(); } return ret; }
uint8_t SHA204I2C::receive_bytes(uint8_t count, uint8_t *data) { if (DEBUG()>=DEBUG_INFO) {Serial.println(F("* DEBUG * receive_bytes()")); Serial.flush();} if (DEBUG()>=DEBUG_TRACE) {Serial.print(F("* DEBUG * count = "));Serial.println(count);Serial.flush();} uint8_t i; int available_bytes = Wire.requestFrom(deviceAddress(), count); if (DEBUG()>=DEBUG_TRACE) {Serial.print(F("* DEBUG * available_bytes = "));Serial.println(available_bytes);Serial.flush();} if (available_bytes > count) { if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_bytes() FAIL available_bytes > count, available_bytes = "));Serial.println(available_bytes); Serial.flush();} return I2C_FUNCTION_RETCODE_COMM_FAIL; } for (i = 0; i < available_bytes; i++) { while (!Wire.available()); // Wait for byte that is going to be read next *data++ = Wire.read(); // Store read value } if (available_bytes < count) { if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_bytes() WARNING available_bytes < count, available_bytes = "));Serial.println(available_bytes); Serial.flush();} reset_io(); if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_bytes() TRY to read bytes = "));Serial.println(count-available_bytes); Serial.flush();} uint8_t d; uint8_t *pd; pd = &d; for (i=0; i <(count-available_bytes); i++){ d = 0xFF; receive_byte(pd); if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_bytes() TRY receive_byte() = 0x"));Serial.println(d,HEX); Serial.flush();} *data++ = *pd; } } return I2C_FUNCTION_RETCODE_SUCCESS; }
void flush_device(int fd, long timeout) { while (is_data_available(fd, 0)) { receive_byte(fd, timeout); } }
unsigned char receive_byte_with_handshake() { unsigned char byte; signal_byte_ready(); wait_for_remote_ready(); byte = receive_byte(); signal_byte_not_ready(); wait_for_remote_notready(); return byte; }
//! Receive multiple bytes static status_t receive_bytes(const i2c_bus *bus, uint8 *readBuffer, ssize_t readLength) { TRACE("%s: (length = %ld)\n", __func__, readLength); for (; readLength > 0; --readLength, ++readBuffer) { status_t status = receive_byte(bus, readBuffer, readLength > 1); if (status != B_OK) return status; } return B_OK; }
unsigned char Read_AD(unsigned char chn) { unsigned char ad_data; start(); send_byte(0x90); send_byte(0x40 | chn); start(); send_byte(0x91); ad_data = receive_byte(); sendACK(1); stop(); return ad_data; }
int8_t I2C::read_byte(uint8_t slaveAddress,uint8_t regAddress,uint8_t* data) { start(); send_7bits_address(slaveAddress); I2C_Cmd(_I2Cx,ENABLE); send_byte(regAddress); start(); send_7bits_address(slaveAddress + 1); send_no_ack(); stop(); receive_byte(data); send_ack(); return 0; }
int16_t device::receive_byte(long timeout_ms) { // Note: timeout will work only if devfd is in non-blocking mode if (timeout_ms == timeout_default) timeout_ms = IEC_TIMEOUT_MS; long msec = 0; for(;;) { int16_t readbyte; int ret = read(devfd, &readbyte, sizeof readbyte); if (ret > 0) { if (readbyte < 0) lasterror = readbyte; return readbyte; } else if (ret < 0) { if (errno == EIO) { receive_byte(); // Read the IEC bus error code } else if (errno == EINTR) { throw raspbiec_error(IEC_SIGNAL); } if (lasterror < 0) { throw raspbiec_error(lasterror); } else { lasterror = IEC_GENERAL_ERROR; throw raspbiec_error(IEC_GENERAL_ERROR); } } if (timeout_ms != timeout_infinite) { if (msec >= timeout_ms) break; msec+=IEC_WAIT_MS; } nanosleep(&timeout, NULL); } throw raspbiec_error(IEC_WRITE_TIMEOUT); }
size_t device::receive_from_bus(std::vector<unsigned char>& data_buf, long timeout_ms) { int blocks = -1; size_t received = 0; int16_t byte; try { while(IEC_EOI != (byte = receive_byte(timeout_ms))) { if (IEC_PREV_BYTE_HAS_ERROR == byte) { printf("error at byte #0x%04X\n", received); //..but continue } else if ( byte < 0 ) // Some other error { throw raspbiec_error(byte); } else { data_buf.push_back(byte); ++received; if (verbose && (int)(received/254) > blocks) { blocks = received/254; printf("\r%d blocks", blocks); fflush(stdout); } } } } catch (raspbiec_error &e) { if (verbose && blocks != -1) printf("\r%d blocks\n",(received+253)/254); throw; } if (verbose && blocks != -1) printf("\r%d blocks\n",(received+253)/254); return received; }
void receive_response(int fd, char* response, int len, long timeout) { for (int i = 0; i < len; i++) { response[i] = 0; } for (int i = 0; i < len; i++) { char c_in = receive_byte(fd, timeout); if (c_in == '\r') { return; } response[i] = c_in; } }
void serial_readwrite_task(void *pvParameters) { serial_str_msg msg; char ch; int curr_char; int done; /* Prepare the response message to be queued. */ strcpy(msg.str, "Got:"); while (1) { curr_char = 4; done = 0; do { /* Receive a byte from the RS232 port (this call will * block). */ ch = receive_byte(); /* If the byte is an end-of-line type character, then * finish the string and inidcate we are done. */ if ((ch == '\r') || (ch == '\n')) { msg.str[curr_char] = '\n'; msg.str[curr_char+1] = '\0'; done = -1; /* Otherwise, add the character to the * response string. */ } else { msg.str[curr_char++] = ch; } } while (!done); /* Once we are done building the response string, queue the * response to be sent to the RS232 port. */ while (!xQueueSendToBack(serial_str_queue, &msg, portMAX_DELAY)); } }
/** * Async listener for pty. This listens on the pty and * any received bytes get passed to the receive_byte function. * * @param arg a void* cast state blob */ void *listener_proc(void *arg) { uart_state_t *state = (uart_state_t*)arg; int res; uint8_t byte; while(1) { res = read(state->pty, &byte, sizeof(byte)); if(res < 0) { perror("read"); exit(EXIT_FAILURE); } if(res == 0) { /* file closed out from end of us */ WARN("EOF on pty"); exit(EXIT_FAILURE); } receive_byte(state, byte); DEBUG("got byte $%02x", byte); } }
irom i2c_error_t i2c_receive(int address, int length, uint8_t *bytes) { int current; i2c_error_t error; if(!i2c_flags.init_done) return(i2c_error_no_init); if(state != i2c_state_idle) return(i2c_error_invalid_state_not_idle); state = i2c_state_header_send; if((error = send_header(address, i2c_direction_receive)) != i2c_error_ok) return(error); for(current = 0; current < length; current++) { state = i2c_state_data_receive_data; if((error = receive_byte(&bytes[current])) != i2c_error_ok) return(error); state = i2c_state_data_receive_ack_send; if((error = send_ack((current + 1) < length)) != i2c_error_ok) return(error); } state = i2c_state_stop_send; if((error = send_stop()) != i2c_error_ok) return(error); state = i2c_state_idle; return(i2c_error_ok); }
int8_t SOFTI2C::read_byte(uint8_t slave_address,uint8_t reg_address,uint8_t* data) { int8_t ret = 0; start(); if (send_7bits_address(slave_address) == -1) ret = -1; if (send_byte(reg_address) == -1) ret = -2; start(); if (send_byte(slave_address + 1) == -1) ret = -3; *data = receive_byte(); send_no_ack(); stop(); return ret; }
uint8_t SHA204I2C::receive_response(uint8_t size, uint8_t *response) { if (DEBUG()>=DEBUG_INFO) {Serial.println(F("* DEBUG * receive_response()")); Serial.flush();} if (DEBUG()>=DEBUG_TRACE) {Serial.print(F("* DEBUG * size = "));Serial.println(size);Serial.flush();} uint8_t count; uint8_t i2c_status; // Receive count byte. i2c_status = receive_byte(response); if (DEBUG()>=DEBUG_TRACE) {Serial.print(F("* DEBUG * receive_response() receive count byte i2c_status = "));Serial.println(i2c_status);Serial.flush();} if (DEBUG()>=DEBUG_TRACE) {Serial.print(F("* DEBUG * receive_response() count byte content = "));Serial.println(response[0]);Serial.flush();} if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) { if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_response() FAIL 1, i2c_status{1} = "));Serial.println(i2c_status,HEX);Serial.flush();} return SHA204_COMM_FAIL; } //#define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response //#define SHA204_BUFFER_POS_STATUS (1) //! buffer index of status byte in status response //#define SHA204_BUFFER_POS_DATA (1) //! buffer index of first data byte in data response count = response[SHA204_BUFFER_POS_COUNT]; if ((count < SHA204_RSP_SIZE_MIN) || (count > size)) { if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_response() FAIL 2, read count size invalid, count = "));Serial.println(count);Serial.flush();} if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * size = "));Serial.println(size);Serial.flush();} return SHA204_INVALID_SIZE; } i2c_status = receive_bytes(count - 1, &response[SHA204_BUFFER_POS_DATA]); if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) { if (DEBUG()>=DEBUG_WARN) {Serial.print(F("* DEBUG * receive_response() FAIL 3, i2c_status{1} = "));Serial.println(i2c_status,HEX);Serial.flush();} return SHA204_COMM_FAIL; } return SHA204_SUCCESS; }
device::Command device::receive_command(int device_number, int &chan) { int16_t iec_byte; int dev_state = DEV_IDLE; int command_device_number = -1; bool under_atn = false; int secondary = -1; Command tmpcmd = Unknown; int tmpchan = -1; try { /* Command loop: receive a command under ATN */ for(;;) { iec_byte = receive_byte(timeout_infinite); if (IEC_ASSERT_ATN == iec_byte) { under_atn = true; continue; } if (IEC_DEASSERT_ATN == iec_byte) { under_atn = false; break; } if (under_atn) { iec_byte = -iec_byte; if (CMD_UNLISTEN == iec_byte) { dev_state = DEV_IDLE; tmpcmd = Unlisten; } else if (CMD_UNTALK == iec_byte) { dev_state = DEV_IDLE; tmpcmd = Untalk; } else if (CMD_IS_TALK(iec_byte)) { dev_state = DEV_TALK; command_device_number = CMD_GETDEV(iec_byte); } else if (CMD_IS_LISTEN(iec_byte)) { dev_state = DEV_LISTEN; command_device_number = CMD_GETDEV(iec_byte); } else if (CMD_IS_DATA_CLOSE_OPEN(iec_byte)) { secondary = iec_byte; } else { dev_state = DEV_IDLE; } } } /* Command loop */ /* Decode the command received under ATN */ bool thisDev = (command_device_number == device_number); if (DEV_LISTEN == dev_state) { if (CMD_IS_OPEN(secondary)) { tmpcmd = thisDev ? Open : OpenOtherDevice; tmpchan = CMD_GETSEC(secondary); } else if (CMD_IS_CLOSE(secondary)) { tmpcmd = thisDev ? Close : CloseOtherDevice; tmpchan = CMD_GETSEC(secondary); } else if (CMD_IS_DATA(secondary)) { tmpcmd = thisDev ? Save : SaveOtherDevice; tmpchan = CMD_GETSEC(secondary); } } else if (DEV_TALK == dev_state) { if (CMD_IS_DATA(secondary)) { tmpcmd = thisDev ? Load : LoadOtherDevice; tmpchan = CMD_GETSEC(secondary); } } } catch( raspbiec_error &e ) { if (e.status() != IEC_SIGNAL) { throw; } tmpcmd = Exit; } chan = tmpchan; return tmpcmd; }
/** * @brief Recieves data from UART and writes to multiple blocks of SD card * @return unsigned char - response byte */ unsigned char sd_write_multiple_blocks(unsigned long start_block, unsigned long total_blocks) { unsigned char response, data; unsigned int i, retry = 0; unsigned long block_counter = 0, size; response = sd_send_command(WRITE_MULTIPLE_BLOCKS, start_block); //write a Block command if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set) SD_CS_ASSERT; while( block_counter < total_blocks ) { i = 0; do { data = receive_byte(); if(data == 0x08) //'Back Space' key pressed { if(i != 0) { transmit_byte(data); transmit_byte(' '); transmit_byte(data); i--; size--; } continue; } transmit_byte(data); buffer[i++] = data; if(data == 0x0d) { transmit_byte(0x0a); buffer[i++] = 0x0a; } if(i == 512) break; } while (data != '~'); spi_transmit(0xfc); //Send start block token 0xfc (0x11111100) for(i = 0; i < 512; i++) //send 512 bytes data spi_transmit(buffer[i]); spi_transmit(0xff); //transmit dummy CRC (16-bit), CRC is ignored here spi_transmit(0xff); response = spi_receive(); if((response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted { //AAA='101'-data rejected due to CRC error SD_CS_DEASSERT; //AAA='110'-data rejected due to write error return response; } while(!spi_receive()) //wait for SD card to complete writing and get idle if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } spi_receive(); //extra 8 bits block_counter++; } spi_transmit(0xfd); //send 'stop transmission token' retry = 0; while(!spi_receive()) //wait for SD card to complete writing and get idle if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } SD_CS_DEASSERT; spi_transmit(0xff); //just spend 8 clock cycle delay before reasserting the CS signal // re assertion of the CS signal is required to verify if card is still busy SD_CS_ASSERT; while(!spi_receive()) //wait for SD card to complete writing and get idle if(retry++ > 0xfffe) { SD_CS_DEASSERT; return 1; } SD_CS_DEASSERT; return 0; }
/****************** ********************** 函数名:HD7279读取函数 功 能:对HD7279读取原始键值 输 入:无 返 回:键盘原始键值 备 注:HD7279的控制函数 ******************************************/ unsigned char read7279(void) { send_byte(0x15); //发送读取指令 return(receive_byte()); //返回键值 }
int main(int argc, char** argv) { int baud_rate = default_baud_rate; const char* device_filename = default_device_filename; const char* firmware_filename = 0; long timeout = default_timeout; int c; opterr = 0; while ((c = getopt (argc, argv, "b:d:f:ht:")) != -1) { switch (c) { case 'b': { baud_rate = atoi(optarg); if (baud_rate != 9600) { printf("Reset device to 9600 baud for reprogramming!\n"); return 1; } break; } case 'd': { device_filename = optarg; break; } case 'f': { firmware_filename = optarg; break; } case 'h': { print_usage(argv[0]); return 1; } case 't': { timeout = atol(optarg); break; } default: { print_usage(argv[0]); return 1; } } } if (!firmware_filename) { printf("Required argument firmware filename missing\n\n"); print_usage(argv[0]); return 1; } if (optind < argc) { printf("Too many arguments given\n\n"); print_usage(argv[0]); return 1; } printf("Writing new firmware file %s to device %s with baud rate %d...\n", firmware_filename, device_filename, baud_rate); printf("Reading firmware file...\n"); FILE* fd_firmware = fopen(firmware_filename, "r"); if (!fd_firmware) { int e = errno; printf("Could not open firmware file %s for reading: %s\n", firmware_filename, strerror(e)); return 1; } int firmware_lines = 0; firmware* firmware_data = 0; firmware* last_data = 0; char new_line[80]; while (fscanf(fd_firmware, "%s[^\n]", new_line) > 0) { int len = strlen(new_line); if (len != 67) { printf("Length with invalid length of %d in firmware file\n", len); return 1; } firmware_lines++; firmware* new_data = new firmware; new_data->line = new char[len + 1]; strcpy(new_data->line, new_line); new_data->next = 0; if (!firmware_data) { firmware_data = new_data; } if (last_data) { last_data->next = new_data; } last_data = new_data; } fclose(fd_firmware); printf("Read %d lines from firmware file\n", firmware_lines); printf("Opening device...\n"); int fd_device = open(device_filename, O_RDWR); if (fd_device == -1) { int e = errno; printf("Could not open device %s for communication: %s\n", device_filename, strerror(e)); return 1; } printf("Setting serial parameters...\n"); struct termios new_termios; tcgetattr(fd_device, &new_termios); switch (baud_rate) { case 300: { cfsetispeed(&new_termios,B300); cfsetospeed(&new_termios,B300); break; } case 600: { cfsetispeed(&new_termios,B600); cfsetospeed(&new_termios,B600); break; } case 1200: { cfsetispeed(&new_termios,B1200); cfsetospeed(&new_termios,B1200); break; } case 2400: { cfsetispeed(&new_termios,B2400); cfsetospeed(&new_termios,B2400); break; } case 4800: { cfsetispeed(&new_termios,B4800); cfsetospeed(&new_termios,B4800); break; } case 9600: { cfsetispeed(&new_termios,B9600); cfsetospeed(&new_termios,B9600); break; } case 19200: { cfsetispeed(&new_termios,B19200); cfsetospeed(&new_termios,B19200); break; } case 38400: { cfsetispeed(&new_termios,B38400); cfsetospeed(&new_termios,B38400); break; } case 57600: { cfsetispeed(&new_termios,B57600); cfsetospeed(&new_termios,B57600); break; } case 115200: { cfsetispeed(&new_termios,B115200); cfsetospeed(&new_termios,B115200); break; } case 230400: { cfsetispeed(&new_termios,B230400); cfsetospeed(&new_termios,B230400); break; } default: { printf("Unsurported baud rate %d\n", baud_rate); return 1; } } cfmakeraw(&new_termios); new_termios.c_oflag &= ~(ONLCR | OCRNL | ONLRET | ONOCR); tcsetattr(fd_device, TCSANOW, &new_termios); struct termios cmp_termios; tcgetattr(fd_device, &cmp_termios); if (new_termios.c_cflag != cmp_termios.c_cflag) { printf("Could not set serial communication parameters\n"); return 1; } printf("Waiting for device to settle...\n\n"); sleep(2); flush_device(fd_device, timeout); // enter_command_modus(fd_device, timeout); // info_command(fd_device, "ATVR", 2, timeout); // execute_command(fd_device, "ATPG", "OK", timeout); usleep(100000); send_bytes(fd_device, "~Y"); char c_in = receive_byte(fd_device, timeout); if (c_in != '3') { printf("Invalid response received\n"); exit(1); } send_bytes(fd_device, "W"); c_in = receive_byte(fd_device, timeout); if (c_in != 'W') { printf("Invalid response received\n"); exit(1); } firmware* data = firmware_data; int lines = 0; while (data != 0) { c_in = receive_byte(fd_device, timeout); if (c_in != 'R') { printf("Invalid response received\n"); exit(1); } send_bytes(fd_device, data->line); c_in = receive_byte(fd_device, timeout); if (c_in != 'A') { printf("Invalid response received\n"); exit(1); } data = data->next; lines++; printf("<> Sent %d of %d lines...\r", lines, firmware_lines); fflush(stdout); } printf("\n"); c_in = receive_byte(fd_device, timeout); if (c_in != 'R') { printf("Invalid response received\n"); exit(1); } c_in = receive_byte(fd_device, timeout); if (c_in != 'y') { printf("Invalid response received\n"); exit(1); } send_bytes(fd_device, "X"); printf("\nAll OK, XRF successfully reprogrammed!\n\n"); printf("Waiting for device to settle...\n\n"); sleep(2); flush_device(fd_device, timeout); enter_command_modus(fd_device, timeout); info_command(fd_device, "ATVR", 2, timeout); close(fd_device); return 0; }
/* Returns 0 on success, 1 on corrupt packet, -1 on error (timeout): */ static int receive_packet(char *data, int *length, int use_crc, int timeout){ int i; unsigned int packet_size, sum; char c; *length = 0; if(receive_byte(&c, timeout) < 0) return -1; switch(c){ case SOH: packet_size = PACKET_SIZE; break; case STX: packet_size = PACKET_1K_SIZE; break; case EOT: return 0; case CAN: if(receive_byte(&c, timeout) == 0 && c == CAN){ *length = -1; return 0; } default: /* This case could be the result of corruption on the first octet * of the packet, but it's more likely that it's the user banging * on the terminal trying to abort a transfer. Technically, the * former case deserves a NAK, but for now we'll just treat this * as an abort case. */ *length = -1; return 0; } *data = c; for(i = 1; i < (packet_size + (use_crc ? PACKET_OVERHEAD_CRC : PACKET_OVERHEAD)); ++i) if(receive_byte(data + i, timeout) < 0) return -1; /* Just a sanity check on the sequence number/complement value. * Caller should check for in-order arrival. */ if(data[PACKET_SEQNO_INDEX] != (data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff) return 1; if(use_crc){ /* It seems odd that the CRC doesn't cover the three preamble bytes. */ if(crc16_buf(data + PACKET_HEADER, packet_size + PACKET_TRAILER_CRC) != 0) return 1; } else { for(i = PACKET_HEADER, sum = 0; i < packet_size + PACKET_HEADER; ++i) sum += data[i]; if((sum & 0xff) != (data[i] & 0xff)) return 1; } *length = packet_size; return 0; }