aciodrv: support multi-sized response packets by divining the packet size

This commit is contained in:
Will Xyen
2021-01-14 10:57:38 -08:00
parent 241f0f65ec
commit 4cba227d1c
2 changed files with 18 additions and 11 deletions
+17 -10
View File
@@ -109,7 +109,7 @@ static bool aciodrv_device_send(struct aciodrv_device_ctx* device, const uint8_t
return true; return true;
} }
static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *buffer, int size) static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *buffer, int max_resp_size)
{ {
uint8_t recv_buf[512]; uint8_t recv_buf[512];
int recv_size = 0; int recv_size = 0;
@@ -124,13 +124,11 @@ static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *bu
read = aciodrv_port_read(device->fd, recv_buf, 1); read = aciodrv_port_read(device->fd, recv_buf, 1);
} while (recv_buf[0] == AC_IO_SOF); } while (recv_buf[0] == AC_IO_SOF);
if (read > 0) {
size += 1;
if (read > 0) {
/* recv_buf[0] is already the first byte of the message. /* recv_buf[0] is already the first byte of the message.
now read until nothing's left */ now read until nothing's left */
recv_size++; recv_size++;
size--;
/* important: we have to know how much data we expect /* important: we have to know how much data we expect
and have to read until we reach the requested amount. and have to read until we reach the requested amount.
@@ -138,7 +136,8 @@ static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *bu
need to handle escaping (which relies on an up to need to handle escaping (which relies on an up to
date recv_buf[recv_size]) we loop until we get a date recv_buf[recv_size]) we loop until we get a
non-zero read. */ non-zero read. */
while (size > 0) { size_t expected_size = offsetof(struct ac_io_message, cmd.nbytes) + 1;
while (recv_size < expected_size) {
do { do {
read = aciodrv_port_read(device->fd, recv_buf + recv_size, 1); read = aciodrv_port_read(device->fd, recv_buf + recv_size, 1);
} while (read == 0); } while (read == 0);
@@ -165,15 +164,23 @@ static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *bu
} }
recv_size += read; recv_size += read;
size -= read;
if (recv_size > offsetof(struct ac_io_message, cmd.nbytes)) {
// header + data + checksum
expected_size = offsetof(struct ac_io_message, cmd.raw) + ((struct ac_io_message*)recv_buf)->cmd.nbytes + 1;
}
} }
#ifdef AC_IO_MSG_LOG #ifdef AC_IO_MSG_LOG
aciodrv_device_log_buffer("Recv (1)", recv_buf, recv_size); aciodrv_device_log_buffer("Recv (1)", recv_buf, recv_size);
log_warning("Expected %d got %d", recv_buf[4], recv_size - 6); log_warning("Expected %d got %d", max_resp_size - 6, recv_buf[4]);
#endif #endif
/* recv_size - 1: omit checksum for checksum calc */ /* recv_size - 1: omit checksum for checksum calc */
if ((recv_size - 1) > max_resp_size) {
log_warning("Expected %d got %d", max_resp_size - 6, recv_buf[4]);
return -1;
}
for (int i = 0; i < recv_size - 1; i++) { for (int i = 0; i < recv_size - 1; i++) {
checksum += recv_buf[i]; checksum += recv_buf[i];
buffer[i] = recv_buf[i]; buffer[i] = recv_buf[i];
@@ -334,7 +341,7 @@ bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx* device, ui
return true; return true;
} }
bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int resp_size) bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int max_resp_size)
{ {
msg->cmd.seq_no = device->msg_counter++; msg->cmd.seq_no = device->msg_counter++;
int send_size = offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes; int send_size = offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes;
@@ -353,9 +360,9 @@ bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_messa
uint16_t req_code = msg->cmd.code; uint16_t req_code = msg->cmd.code;
#ifdef AC_IO_MSG_LOG #ifdef AC_IO_MSG_LOG
log_info("Beginning recv: (%d b)", resp_size); log_info("Beginning recv: (%d b)", max_resp_size);
#endif #endif
if (aciodrv_device_receive(device, (uint8_t *) msg, resp_size) <= 0) { if (aciodrv_device_receive(device, (uint8_t *) msg, max_resp_size) <= 0) {
return false; return false;
} }
+1 -1
View File
@@ -48,7 +48,7 @@ bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx* device, ui
* @param resp_size Size of the expecting response. * @param resp_size Size of the expecting response.
* @return True on success, false on error. * @return True on success, false on error.
*/ */
bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int resp_size); bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int max_resp_size);
/** /**
* Close the previously opened ACIO device. * Close the previously opened ACIO device.