enum STATUS_RESPONSE get_status_response(const uint8_t *rsp) { const unsigned int OFFSET_TO_CRC = 2; const unsigned int OFFSET_TO_RSP = 1; const unsigned int STATUS_LENGTH = 4; if (!is_crc_16_valid (rsp, STATUS_LENGTH - CRC_16_LEN, rsp + OFFSET_TO_CRC)) { CTX_LOG (DEBUG, "CRC Fail in status response"); return RSP_COMM_ERROR; } return *(rsp + OFFSET_TO_RSP); }
bool wakeup(int fd) { uint32_t wakeup = 0; unsigned char buf[4] = {0}; bool awake = false; /* The assumption here that the fd is the i2c fd. Of course, it may * not be, so this may loop for a while (read forever). This should * probably try for only so often before quitting. */ /* Perform a basic check to see if this fd is open. This does not guarantee it is the correct fd */ if(fcntl(fd, F_GETFD) < 0) perror("Invalid FD.\n"); while (!awake) { if (write(fd,&wakeup,sizeof(wakeup)) > 1) { CTX_LOG(DEBUG, "%s", "Device is awake."); // Using I2C Read if (read(fd,buf,sizeof(buf)) <= 0) { /* ERROR HANDLING: i2c transaction failed */ perror("Failed to read from the i2c bus.\n"); } else { assert(is_crc_16_valid(buf, 2, buf+2)); awake = true; } } } return awake; }
enum STATUS_RESPONSE read_and_validate (int fd, uint8_t *buf, unsigned int len) { uint8_t* tmp = NULL; const int PAYLOAD_LEN_SIZE = 1; const int CRC_SIZE = 2; enum STATUS_RESPONSE status = RSP_COMM_ERROR; unsigned int recv_buf_len = 0; bool crc_valid; unsigned int crc_offset; int read_bytes; const unsigned int STATUS_RSP = 4; assert (NULL != buf); recv_buf_len = len + PAYLOAD_LEN_SIZE + CRC_SIZE; crc_offset = recv_buf_len - 2; /* The buffer that comes back has a length byte at the front and a * two byte crc at the end. */ tmp = malloc_wipe (recv_buf_len); read_bytes = i2c_read (fd, tmp, recv_buf_len); /* First Case: We've read the buffer and it's a status packet */ if (read_bytes == recv_buf_len && tmp[0] == STATUS_RSP) { print_hex_string ("Status RSP", tmp, tmp[0]); status = get_status_response (tmp); CTX_LOG (DEBUG, status_to_string (status)); } /* Second case: We received the expected message length */ else if (read_bytes == recv_buf_len && tmp[0] == recv_buf_len) { print_hex_string ("Received RSP", tmp, recv_buf_len); crc_valid = is_crc_16_valid (tmp, tmp[0] - CRC_16_LEN, tmp + crc_offset); if (true == crc_valid) { wipe (buf, len); memcpy (buf, &tmp[1], len); status = RSP_SUCCESS; } else { perror ("CRC FAIL!\n"); } } else { CTX_LOG (DEBUG,"Read failed, retrying"); status = RSP_NAK; } free_wipe (tmp, recv_buf_len); return status; }