/** * Flush the chunk header by sending it to the wire. * * @return +1 if we were able to flush the whole header, 0 if we need * to be called again and -1 on errors.. */ static ssize_t chunk_flush_header(txdrv_t *tx) { struct attr *attr = tx->opaque; ssize_t offset; /* Offset within head[] for data to TX */ ssize_t r; g_assert(attr->head_len > 0); g_assert(attr->head_remain > 0); offset = attr->head_len - attr->head_remain; g_assert(offset >= 0); r = tx_write(tx->lower, &attr->head[offset], attr->head_remain); /* * If we were unable to flush everything, enable servicing from * the lower layer: it will call our service routine when it is * able to accept more data from us. */ if (r == -1) return -1; /* Bail out, we're probably dead already */ if (r != attr->head_remain) tx_srv_enable(tx->lower); if (r == 0) return 0; attr->head_remain -= r; g_assert(attr->head_remain >= 0); return 0 == attr->head_remain ? +1 : 0; /* +1 if we sent everything */ }
/** * Write data to the TX stack. */ static ssize_t browse_host_write(struct special_upload *ctx, const void *data, size_t size) { struct browse_host_upload *bh = cast_to_browse_host_upload(ctx); g_assert(bh->tx); return tx_write(bh->tx, data, size); }
/* sent the retransmit buffer */ static void tx_rtxpacket(void) { assert(g_rtxseqnum != 0); IF_TRACED(TRC_PACKET) dbgprintf("packetio_recv_handler: retranmitting response with seqnum=%d\n", g_rtxseqnum); END_TRACE tx_write(g_re_txbuf, g_re_tx_len); }
/** * Write data to the TX stack. */ static ssize_t thex_upload_write(struct special_upload *special_upload, const void *data, size_t size) { struct thex_upload *ctx = cast_to_thex_upload(special_upload); g_assert(ctx->tx); return tx_write(ctx->tx, data, size); }
/* usual way of sending a packet, potentially keeping a copy in the * rtx buffer and consuming a sequence number. */ static void tx_sendpacket(size_t nbytes, uint16_t thisSeqNum) { tx_write(g_txbuf, nbytes); /* if this is a reliable packet, then copy the g_txbuf aside to the * g_re_txbuf, and consume the sequence number. */ if (thisSeqNum) { memcpy(g_re_txbuf, g_txbuf, nbytes); g_rtxseqnum = thisSeqNum; g_re_tx_len = nbytes; } }
/* usual way of sending a packet, potentially keeping a copy in the * rtx buffer and consuming a sequence number. */ static void tx_sendpacket(size_t nbytes, uint16_t thisSeqNum) { tx_write(g_txbuf, nbytes); g_tx_len = nbytes; /* if this is a reliable packet, then copy the g_txbuf aside to the * g_re_txbuf, and consume the sequence number. */ if (thisSeqNum) { memcpy(g_re_txbuf, g_txbuf, nbytes); g_rtxseqnum = thisSeqNum; g_re_tx_len = nbytes; g_re_tx_opcode = g_opcode; // save the opcode that generated this response, for retry-checking } }
extern void AT91SAM7A2_uart_start (int port, DEV_serial_t * serial) { int c; CSP_USART_T *const uart = ports[port]; if ((c = serial->int_interface->tx_char (serial)) != ACE_EOF) { /* Interrupt Enable */ CSP_USART_SET_IER(uart, TXRDY | TXEMPTY); /* USART Tx Enable */ CSP_USART_SET_CR(uart, TXEN); tx_write (port, (char)c); } else { serial->int_interface->tx_finished (serial); } }
extern void AT91SAM7A2_uart_interrupt (int port, DEV_serial_t * serial) { CSP_USART_T *const uart = ports[port]; if ((CSP_USART_GET_SR(uart) & RXRDY) == RXRDY) { char c; c = CSP_USART_GET_RHR(uart); serial->int_interface->rx_char (serial, c); } else { if ((CSP_USART_GET_SR(uart) & USOVRE) == USOVRE) { serial->int_interface->rx_error (serial, DEV_SER_RX_OVERRUN); CSP_USART_SET_CR(uart, RSTSTA); } else if ((CSP_USART_GET_SR(uart) & FRAME) == FRAME) { serial->int_interface->rx_error (serial, DEV_SER_RX_FRAMING); CSP_USART_SET_CR(uart, RSTSTA); } else if ((CSP_USART_GET_SR(uart) & PARE) == PARE) { serial->int_interface->rx_error (serial, DEV_SER_RX_PARITY); CSP_USART_SET_CR(uart, RSTSTA); } } if ((CSP_USART_GET_SR(uart) & TXEMPTY) == TXEMPTY) { int c; if ((c = serial->int_interface->tx_char (serial)) == ACE_EOF) { CSP_USART_SET_CR(uart, TXDIS); CSP_USART_SET_IDR(uart, TXEMPTY); serial->int_interface->tx_finished (serial); } else { CSP_USART_SET_IER(uart, TXRDY); tx_write (port, (char)c); } } else if ((CSP_USART_GET_SR(uart) & TXRDY) == TXRDY) { int c; if ((c = serial->int_interface->tx_char (serial)) == ACE_EOF) { CSP_USART_SET_IDR(uart, TXRDY); } else { tx_write (port, (char)c); } } }
/** * Write ready-to-be-sent buffer to the lower layer. */ static void deflate_send(txdrv_t *tx) { struct attr *attr = tx->opaque; struct buffer *b; size_t len; /**< Amount of bytes to send */ ssize_t r; g_assert(attr->send_idx >= 0); /* We have something to send */ g_assert(attr->send_idx < BUFFER_COUNT); /* * Compute data to be sent. */ b = &attr->buf[attr->send_idx]; /* Buffer to send */ len = b->wptr - b->rptr; g_assert(len > 0 && len <= INT_MAX); /* * Write as much as possible. */ r = tx_write(tx->lower, b->rptr, len); if (tx_deflate_debugging(9)) { g_debug("TX %s: (%s) wrote %zu/%zu bytes (buffer #%d) [%c%c]", G_STRFUNC, gnet_host_to_string(&tx->host), r, len, attr->send_idx, (attr->flags & DF_FLOWC) ? 'C' : '-', (attr->flags & DF_FLUSH) ? 'f' : '-'); } if ((ssize_t) -1 == r) { tx_error(tx); return; } /* * If we wrote everything, we're done. */ if ((size_t) r == len) { if (tx_deflate_debugging(9)) { g_debug("TX %s: (%s) buffer #%d is empty", G_STRFUNC, gnet_host_to_string(&tx->host), attr->send_idx); } attr->send_idx = -1; /* Signals: is now free */ b->wptr = b->rptr = b->arena; /* Buffer is now empty */ return; } /* * We were unable to send the whole buffer. Enable servicing when * the lower layer will be ready for more input. */ b->rptr += r; g_assert(b->rptr < b->wptr); /* We haven't written everything */ tx_srv_enable(tx->lower); }