void *read_serial_packet(serial_source src, int *len) /* Effects: Read the serial source src. If a packet is available, return it. If in blocking mode and no packet is available, wait for one. Returns: the packet read (in newly allocated memory), with *len is set to the packet length, or NULL if no packet is yet available and the serial source is in non-blocking mode */ { read_and_process(src, TRUE); for (;;) { struct packet_list *entry; entry = pop_protocol_packet(src, P_PACKET_NO_ACK); if (entry) { uint8_t *packet = entry->packet; *len = entry->len; free(entry); return packet; } if (src->non_blocking && serial_source_empty(src)) return NULL; source_wait(src, NULL); read_and_process(src, src->non_blocking); } }
int write_serial_packet(serial_source src, const void *packet, int len) /* Effects: writes len byte packet to serial source src Returns: 0 if packet successfully written, 1 if successfully written but not acknowledged, -1 otherwise */ { struct timeval deadline; src->send.seqno++; if (write_framed_packet(src, P_PACKET_ACK, src->send.seqno, packet, len) < 0) return -1; gettimeofday(&deadline, NULL); add_timeval(&deadline, ACK_TIMEOUT); for (;;) { struct packet_list *entry; read_and_process(src); entry = pop_protocol_packet(src, P_ACK); if (entry) { uint8_t acked = entry->packet[0]; free(entry->packet); free(entry); if (acked == src->send.seqno) return 0; } else if (source_wait(src, &deadline) < 0) return 1; } }