/*---------------------------------------------------------------------------*/ int serial_line_input_byte(unsigned char c) { static uint8_t overflow = 0; /* Buffer overflow: ignore until END */ if(IGNORE_CHAR(c)) { return 0; } if(!overflow) { /* Add character */ if(ringbuf_put(&rxbuf, c) == 0) { /* Buffer overflow: ignore the rest of the line */ overflow = 1; } } else { /* Buffer overflowed: * Only (try to) add terminator characters, otherwise skip */ if(c == END && ringbuf_put(&rxbuf, c) != 0) { overflow = 0; } } /* Wake up consumer process */ //printf("wake up consumer process\n"); process_poll(&serial_line_process); return 1; }
/*---------------------------------------------------------------------------*/ void sci3_writeb(unsigned char c) { watchdog_periodic(); #if 1 /* Put the outgoing byte on the transmission buffer. If the buffer is full, we just keep on trying to put the byte into the buffer until it is possible to put it there. */ while(ringbuf_put(&txbuf, c) == 0); /* If there is no transmission going, we need to start it by putting the first byte into the UART. */ if(transmitting == 0) { transmitting = 1; /* Loop until the transmission buffer is available. */ /*while((IFG2 & UTXIFG1) == 0);*/ //TXBUF1 = ringbuf_get(&txbuf); SCI3.SCR3.BYTE |= 0x04; /* */ SCI3.SSR.BYTE &= ~0x04; /* reset TxEI request */ } #else /* TX_WITH_INTERRUPT */ /* Loop until the transmission buffer is available. */ while (!(SCI3.SSR.BIT.TDRE)); /* Transmit the data. */ SCI3.TDR = c; SCI3.SSR.BIT.TDRE = 0; #endif /* TX_WITH_INTERRUPT */ }
// port2 static void uart2_handler(void) { register unsigned int isr; volatile mml_uart_regs_t *reg_uart = (volatile mml_uart_regs_t*)MML_UART2_IOBASE; // int status = 0; unsigned char c; /** Retrieve ISR */ isr = reg_uart->isr; if( isr & (MML_UART_IER_FFRXIE_MASK | MML_UART_IER_OVERIE_MASK)) { mml_uart_interrupt_clear(MML_UART_DEV2, MML_UART_IER_FFRXIE_MASK | MML_UART_IER_OVERIE_MASK); while( 1 ) { if( mml_uart_read_char(MML_UART_DEV2, &c) == NO_ERROR ) { if (extra_handler) extra_handler(c); //else if (!rb_write_byte(&gRevLb[2], c)) break; else if( ringbuf_put(&gRevFifo[2], c) < 0) break; } else { break; } } } }
ISR(USART1_RX_vect, ISR_BLOCK) { uint8_t receivedByte; if (ringbuf_elements(&USARTtoUSB_Buffer) >= ringbuf_size(&USARTtoUSB_Buffer) - 1 ) return; receivedByte = UDR1; // TODO check for callback Code // set var if waiting for normal reply. // if not awaiting normal reply and receivedByte == 42 call callback. if(!jennic_in_programming_mode && opCode < 0){ if(receivedByte == 42){ callback(); return; } opCode = receivedByte; return; } // removed if condition cause we need the serial in even if theres no USB Connection // if (USB_DeviceState == DEVICE_STATE_Configured) { ringbuf_put(&USARTtoUSB_Buffer, receivedByte); // } }
/*---------------------------------------------------------------------------*/ void uart1_writeb(unsigned char c) { watchdog_periodic(); #if TX_WITH_INTERRUPT /* Put the outgoing byte on the transmission buffer. If the buffer is full, we just keep on trying to put the byte into the buffer until it is possible to put it there. */ while(ringbuf_put(&txbuf, c) == 0); /* If there is no transmission going, we need to start it by putting the first byte into the UART. */ if(transmitting == 0) { transmitting = 1; UCA0TXBUF = ringbuf_get(&txbuf); } #else /* TX_WITH_INTERRUPT */ /* Loop until the transmission buffer is available. */ while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer ready to receive new byte UCA0TXBUF = c; //c; // Output character #endif /* TX_WITH_INTERRUPT */ }
void usart3_writebuff(unsigned char* buf, int len) { while (len) { /* check the empty items in the ringbuff */ while (ringbuf_put(&txbuf, *buf) == 0); buf++; len--; #ifndef USART3_TX_USE_DMA1_CH4 if (transmitting == 0) { transmitting = 1; USART3->DR = ringbuf_get(&txbuf); /* put in UART */ USART3->CR1 |= USART_CR1_TXEIE; /* enable TX register empty int */ } #else if ((DMA1_Stream3->CR & DMA_SxCR_EN ) != DMA_SxCR_EN ) { /* set the start address of your data */ DMA1_Stream3->M0AR = (uint32_t) txbuf.data + txbuf.get_ptr; /* set the length of your data */ DMA1_Stream3->NDTR = (txbuf.put_ptr - txbuf.get_ptr) & txbuf.mask; if (DMA1_Stream3->NDTR > (txbuf.mask + 1 - txbuf.get_ptr)) { DMA1_Stream3->NDTR = txbuf.mask + 1 - txbuf.get_ptr; } dma_length = DMA1_Stream3->NDTR; /* Enable transfer by setting EN bit */ DMA1_Stream3->CR |= DMA_SxCR_EN; } #endif } }
/*---------------------------------------------------------------------------*/ void uart1_writeb(unsigned char c) { watchdog_periodic(); #if TX_WITH_INTERRUPT /* Put the outgoing byte on the transmission buffer. If the buffer is full, we just keep on trying to put the byte into the buffer until it is possible to put it there. */ while(ringbuf_put(&txbuf, c) == 0); /* If there is no transmission going, we need to start it by putting the first byte into the UART. */ if(transmitting == 0) { transmitting = 1; /* Loop until the transmission buffer is available. */ /*while((IFG2 & UTXIFG1) == 0);*/ TXBUF1 = ringbuf_get(&txbuf); } #else /* TX_WITH_INTERRUPT */ /* Loop until the transmission buffer is available. */ while((IFG2 & UTXIFG1) == 0); /* Transmit the data. */ TXBUF1 = c; #endif /* TX_WITH_INTERRUPT */ }
/*---------------------------------------------------------------------------*/ void uart1_writeb(unsigned char c) { watchdog_periodic(); #if TX_WITH_INTERRUPT /* * Put the outgoing byte on the transmission buffer. If the buffer * is full, we just keep on trying to put the byte into the buffer * until it is possible to put it there. */ while(ringbuf_put(&txbuf, c) == 0); /* * If there is no transmission going, we need to start it by putting * the first byte into the UART. */ if(transmitting == 0) { transmitting = 1; SC1_DATA = ringbuf_get(&txbuf); INT_SC1FLAG = INT_SCTXFREE; INT_SC1CFG |= INT_SCTXFREE; } #else /* TX_WITH_INTERRUPT */ /* Loop until the transmission buffer is available. */ while((INT_SC1FLAG & INT_SCTXFREE) == 0); /* Transmit the data. */ SC1_DATA = c; INT_SC1FLAG = INT_SCTXFREE; #endif /* TX_WITH_INTERRUPT */ }
/*---------------------------------------------------------------------------*/ void ssi0_isr(void) { uint8_t data, i, data_count = 0; PRINTF("INFO: ISR SR=%lx RIS=%lx MIS=%lx\r\n", REG(SSI0_BASE+SSI_SR), REG(SSI0_BASE+SSI_RIS), REG(SSI0_BASE+SSI_MIS)); /* while there are data in the SPI FIFO (Receive FIFO Not Empty) */ while(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE) { /* Crappy delay, because SSI can't handle all situations? * Without that delay, receiving long messages (8 bytes long) is impossible and we loose 8th byte. * In theory it shouldn't happened, because after CS goes HIGH we are checking if RX FIFO is not empty. * But it is always empty and we loose 8th byte. Handling shorter messages is not a problem. */ for(i = 0; i < 12; i++) { asm("nop"); } /* Get data from FIFO */ data = REG(SSI0_BASE + SSI_DR); /* Only when we are connected (avoid noise on SPI) */ if(connected) { if(start_of_frame == 1) { /* if transmission just started, look for initial byte */ if((data & 0xf0) == 0x50) { /* get payload size from initial byte */ data_count = (data & 0x0f); /* check if payload size is bigger than 7 bytes, if yes it means we encountered error */ if(data_count > 7) { /* if we encountered error, request SSI reset */ ssi_reset_request = 1; continue; } /* if initial byte has been found, mark that transmission is pending */ start_of_frame = 0; /* clear SSI reset request (maybe it was set accidentally?) */ ssi_reset_request = 0; } else { /* if initial byte not found, omit current byte (it should normally never happened) and request SSI reset */ /* sometimes SSI hangs and receives bytes shifted for a few bits, so we need to reset SSI if received frame is wrong */ PRINTF("WARN: omitting: %02x\r\n", data); /* if initial byte is other than 0x5x, it looks that something went wrong or master requests SSI reset */ ssi_reset_request = 1; continue; } } else { /* if transmission is pending and if there is still data that we should collect */ if(data_count > 0) { /* store data into ringbuffer */ ringbuf_put(&spi_rx_buf, data); data_count--; } } } } /* Clear all interrupt flags */ REG(SSI0_BASE + SSI_ICR) = SSI_ICR_RTIC | SSI_ICR_RORIC; }
size_t ringbuf_copy(struct ringbuf *to, struct ringbuf *from, size_t size) { size_t tocopy = MIN(ringbuf_space(to), size); uint8_t *cbuf = XCALLOC(MTYPE_TMP, tocopy); tocopy = ringbuf_peek(from, 0, cbuf, tocopy); size_t put = ringbuf_put(to, cbuf, tocopy); XFREE(MTYPE_TMP, cbuf); return put; }
/*---------------------------------------------------------------------------*/ void uart0_writeb(unsigned char c) { if (nrf_drv_uart_tx(&c, 1) == NRF_ERROR_BUSY) { while (ringbuf_put(&txbuf, c) == 0) { __WFE(); } } }
static int uart_handler(unsigned char c) { if(!ringbuf_put(&uart_ring_buffer, (uint8_t)c)) { fprintf(stderr, "uart: Ring buffer is full, missed data\n"); return 0; } return 1; }
void CDC_In_Task() { /* Read bytes from the USB OUT endpoint and transmit to jennic if programming mode */ if ( ringbuf_elements(&USBtoUSART_Buffer) < ringbuf_size(&USBtoUSART_Buffer)-2 ) { // TODO check int16_t type int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC1_Interface); if ( !(ReceivedByte < 0) ) ringbuf_put(&USBtoUSART_Buffer, ReceivedByte); } }
STATIC void dupterm_task_handler(os_event_t *evt) { while (1) { int c = call_dupterm_read(); if (c < 0) { break; } ringbuf_put(&input_buf, c); } mp_hal_signal_input(); }
/*---------------------------------------------------------------------------*/ void spi_writeb(uint8_t b) { if(connected) { /* put byte into ringbuffer, so the ISR can get them and send over SPI */ ringbuf_put(&spi_tx_buf, b); /* Notify master that we have data to send */ GPIO_SET_PIN(SPI_INT_PORT_BASE, SPI_INT_PIN_MASK); PRINTF("INFO: put %02x\r\n", b); } }
void USB_CDC_task(void) { #if defined(USB_POLLING) // Interrupt or polling method. If using polling, must call // this function periodically. This function will take care // of processing and responding to SETUP transactions // (such as during the enumeration process when you first // plug in). USB hosts require that USB devices should accept // and process SETUP packets in a timely fashion. Therefore, // when using polling, this function should be called // regularly (such as once every 1.8ms or faster** [see // inline code comments in usb_device.c for explanation when // "or faster" applies]) In most cases, the USBDeviceTasks() // function does not take very long to execute (ex: <100 // instruction cycles) before it returns. USBDeviceTasks(); #endif /* If the USB device isn't configured yet, we can't really do anything * else since we don't have a host to talk to. So jump back to the * top of the while loop. */ if (USBGetDeviceState() < CONFIGURED_STATE) { /* Jump back to the top of the while loop. */ return; } /* If we are currently suspended, then we need to see if we need to * issue a remote wakeup. In either case, we shouldn't process any * keyboard commands since we aren't currently communicating to the host * thus just continue back to the start of the while loop. */ if (USBIsDeviceSuspended() == true) { /* Jump back to the top of the while loop. */ return; } // Tx task uint16_t length = 0; while (ringbuf_num(&usb_tx)) { writeBuffer[length++] = ringbuf_pop(&usb_tx); if (length >= CDC_DATA_IN_EP_SIZE) { break; } } if (length) { USB_CDC_send(length); } // Rx task length = USB_CDC_get(); if (length) { for (uint16_t i = 0; i < length; i++) { ringbuf_put(&usb_rx, readBuffer[i]); } } }
void USB_task(void) { char data; // rx operation while (usb_char_get(&data)) { ringbuf_put(&usb_rx, data); } // tx operation while (ringbuf_num(&usb_tx)) { data = ringbuf_pop(&usb_tx); usb_char_send(data); } USBDeviceTasks(); }
int main() { ringbuf *r; size_t sz; int rc; char *d; r = ringbuf_new(11); printf("putting 7 bytes into buffer of sz 11\n"); rc = ringbuf_put(r, z, 7); printf("put: %s\n", (rc == -1) ? "failed" : "ok"); printf("consuming 7\n"); ringbuf_mark_consumed(r, 7); printf("next put of > 4 bytes wraps buffer, writing 5\n"); rc = ringbuf_put(r, z, 5); printf("put: %s\n", (rc == -1) ? "failed" : "ok"); sz = ringbuf_get_next_chunk(r, &d); printf("chunk sz %lu: sz, %.*s\n", sz, (int)sz, d); printf("reading 3, of 5 available\n"); ringbuf_mark_consumed(r, 3); printf("next read is last byte before wrapping\n"); sz = ringbuf_get_next_chunk(r, &d); printf("chunk sz %lu: sz, %.*s\n", sz, (int)sz, d); ringbuf_mark_consumed(r, 1); printf("next read starts reading from wrapped part\n"); sz = ringbuf_get_next_chunk(r, &d); printf("chunk sz %lu: sz, %.*s\n", sz, (int)sz, d); ringbuf_mark_consumed(r, 1); printf("nothing left\n"); sz = ringbuf_get_pending_size(r); printf("size = %lu\n", sz); ringbuf_free(r); return 0; }
static void uart0_handler(void) { register unsigned int isr; volatile mml_uart_regs_t *reg_uart = (volatile mml_uart_regs_t*)MML_UART0_IOBASE; int status = 0; unsigned char c; /** Retrieve ISR */ isr = reg_uart->isr; if( isr & (MML_UART_IER_FFTXOIE_MASK | MML_UART_IER_FFTXHIE_MASK) ) { mml_uart_interrupt_clear(MML_UART_DEV0, MML_UART_IER_FFTXOIE_MASK | MML_UART_IER_FFTXHIE_MASK); while( 1 ) { mml_uart_port_status(MML_UART_DEV0, &status); if( !(status & MML_UART_STATUS_TX_FULL) ) { if( ringbuf_get(&gSendFifo[0], &c) >= 0) //if (rb_read_byte(&gSendLb[0], &c)) reg_uart->dr = c; else break; } else { break; } } } if( isr & (MML_UART_IER_FFRXIE_MASK | MML_UART_IER_OVERIE_MASK)) { mml_uart_interrupt_clear(MML_UART_DEV0, MML_UART_IER_FFRXIE_MASK | MML_UART_IER_OVERIE_MASK); while( 1 ) { if( mml_uart_read_char(MML_UART_DEV0, &c) == NO_ERROR ) { if( ringbuf_put(&gRevFifo[0], c) < 0) break; //if (!rb_write_byte(&gRevLb[0], c)) break; } else { break; } } } }
void usart3_writeb(unsigned char c) { // watchdog_periodic(); /* Put the outgoing byte on the transmission buffer. If the buffer is full, we just keep on trying to put the byte into the buffer until it is possible to put it there. */ while (ringbuf_put(&txbuf, c) == 0); /* If there is no transmission going, we need to start it by putting the first byte into the UART. */ if (transmitting == 0) { transmitting = 1; USART3->DR = ringbuf_get(&txbuf); /* put in UART */ USART3->CR1 |= USART_CR1_TXEIE; /* enable TX register empty int */ } }
void CDC_Arduino_In_Task() { uint16_t bytes = CDC_Device_BytesReceived(&VirtualSerial_CDC0_Interface); while(bytes--){ /* Read bytes from the USB OUT endpoint and store it for the Arduino Serial Class */ if ( ringbuf_elements(&serialRx_Buffer) < ringbuf_size(&serialRx_Buffer)-2 ) { int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC0_Interface); if ( !(ReceivedByte < 0) ) ringbuf_put(&serialRx_Buffer, ReceivedByte); } else{ return; } } // end while }
STATIC void dupterm_task_handler(os_event_t *evt) { static byte lock; if (lock) { return; } lock = 1; while (1) { int c = call_dupterm_read(); if (c < 0) { break; } ringbuf_put(&input_buf, c); } mp_hal_signal_input(); lock = 0; }
int main() { ringbuf *r; size_t sz; int rc; char *d; char buf[32+11]; /* room for struct ring + 11 bytes of ring */ r = ringbuf_take(buf,sizeof(buf)); printf("gave buffer (ringbuf_take) expecting 11 free bytes\n"); sz = ringbuf_get_freespace(r); printf("buffer has %lu free bytes\n", sz); printf("putting 7 bytes into buffer of sz 11\n"); rc = ringbuf_put(r, z, 7); printf("put: %s\n", (rc == -1) ? "failed" : "ok"); sz = ringbuf_get_freespace(r); printf("buffer has %lu free bytes\n", sz); printf("consuming 3\n"); ringbuf_mark_consumed(r, 3); sz = ringbuf_get_freespace(r); printf("buffer has %lu free bytes\n", sz); sz = ringbuf_get_next_chunk(r, &d); printf("chunk sz %lu: sz, %.*s\n", sz, (int)sz, d); printf("marking clear\n"); ringbuf_clear(r); sz = ringbuf_get_freespace(r); printf("buffer has %lu free bytes\n", sz); printf("nothing left\n"); sz = ringbuf_get_pending_size(r); printf("pending size = %lu\n", sz); sz = ringbuf_get_freespace(r); printf("buffer has %lu free bytes\n", sz); /* do not ringbuf_free(r); since we used ringbuf_take */ return 0; }
void EP6_OUT_Callback(void) { uint16_t USB_Rx_Cnt; /* Get the received data buffer and update the counter */ USB_Rx_Cnt = USB_SIL_Read(EP6_OUT, USB_Rx_Buffer); /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the USART Xfer */ ringbuf_put(&rx_rb, USB_Rx_Buffer, USB_Rx_Cnt); /* Enable the receive of data on EP4 */ SetEPRxValid(ENDP6); if (rx_cb != NULL) { rx_cb(ringbuf_available(&rx_rb), NULL); } }
static void rvidcc_write_lowlevel(const void *ptr, size_t len) { size_t rem; ringbuf_put(&dcc_outbuf, (unsigned char*)ptr, len); ringbuf_advance_write(&dcc_outbuf, len & ~0x3); // advance whole words /* ensure excess bytes up to word boundary are null */ rem = (len & 0x3); if (rem) { for (; rem < 4; rem++) *(dcc_outbuf.writePtr + rem) = '\0'; ringbuf_advance_write(&dcc_outbuf, sizeof(unsigned long)); // advance remainder word } RVIDCC_ENABLE_WRITE_INTERRUPT; }
int xbee_input_handler(unsigned char c) { static uint8_t overflow = 0; if(!overflow) { /* Add character */ if(ringbuf_put(&rxbuf, c) == 0) { overflow = 1; } } else { /* Buffer overflowed, no handling at the moment */ while(1); overflow = 0; } /* Wake up consumer process */ process_poll(&xbee_process); return 1; }
/*---------------------------------------------------------------------------*/ static void cs_isr(uint8_t port, uint8_t pin) { int d, i; /* check if ISR comes from CS pin */ if((port != SPI_CS_PORT) && (pin != SPI_CS_PIN)) { return; } /* CS goes HIGH, End of Transmission */ if(GPIO_READ_PIN(SPI_CS_PORT_BASE, SPI_CS_PIN_MASK)) { /* check if something left in RX FIFO after transaction, and put all remain data into RX ringbuffer */ while(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE) { d = REG(SSI0_BASE + SSI_DR); ringbuf_put(&spi_rx_buf, d); PRINTF("ERR: Something left in FIFO!\r\n"); } /* pass received data to upper level driver via callback */ d = ringbuf_get(&spi_rx_buf); while(d != -1) { if(input_callback) { input_callback((unsigned char)d); } d = ringbuf_get(&spi_rx_buf); } /* mark that there is no start of frame phase */ /* TODO: is it necessary? */ start_of_frame = 0; /* check if TX FIFO is not empty */ if(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)) { /* if TX FIFO is not empty, reset SSI to flush TX FIFO it is possible that previous transaction has been failed, so complete frame has not been transmitted. Eg. NBR has been turned off during transmission */ PRINTF("ERR: TX FIFO not empty after transaction!\r\n"); ssi_reset_request = 3; } if(ssi_reset_request) { /* if reset request is active, perform SSI reset */ PRINTF("WARN: SSI reset request %u\r\n", ssi_reset_request); ssi_reconfigure(1); ssi_reset_request = 0; } } else { /* CS goes LOW, Start of Transmission */ start_of_frame = 1; /* fill TX FIFO with data only if we were connected */ if(connected) { /* get number of elements in ringbuffer */ d = ringbuf_elements(&spi_tx_buf); /* send that number to master with characteristic upper nibble */ d = 0x50 | (d > 7 ? 7 : d); REG(SSI0_BASE + SSI_DR) = d; for(i = 0; i < 7; i++) { if(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)) { /* Error, we shouldn't overflow TX FIFO */ PRINTF("ERR: TX FIFO overflow!\r\n"); break; } d = ringbuf_get(&spi_tx_buf); if(d == -1) { REG(SSI0_BASE + SSI_DR) = 0xff; } else { REG(SSI0_BASE + SSI_DR) = d; } } /* If the CS interrupt was triggered due to slave requesting SPI transfer, * we clear the INT pin, as the transfer has now been completed. */ if(ringbuf_elements(&spi_tx_buf) == 0) { GPIO_CLR_PIN(SPI_INT_PORT_BASE, SPI_INT_PIN_MASK); } } else { /* mark we are connected */ connected = 1; } } }
size_t uart0_write(uint8_t *pData, size_t DataSize) { volatile mml_uart_regs_t *reg_uart = (volatile mml_uart_regs_t*)MML_UART0_IOBASE; uint8_t *pBuf = (uint8_t *)pData; size_t size = DataSize; uint32_t counts = 100000; int32_t status = 0; uint8_t c; while( size ) { if( ringbuf_put(&gSendFifo[0], *pBuf) >= 0 ) //if (rb_write_byte(&gSendLb[0], *pBuf)) { pBuf++; size--; counts = 100000; } else { mml_uart_port_status(MML_UART_DEV0, &status); if( status & MML_UART_STATUS_TX_EMPTY ) { while( 1 ) { mml_uart_port_status(MML_UART_DEV0, &status); if( !(status & MML_UART_STATUS_TX_FULL) ) { if( ringbuf_get(&gSendFifo[0], &c) >= 0 ) //if (rb_read_byte(&gSendLb[0], &c)) { reg_uart->dr = c; } else { break; } } else { break; } } } if( !counts ) break; if( counts > 1 ) counts -= 1; else counts = 0; } } mml_uart_port_status(MML_UART_DEV0, &status); if( status & MML_UART_STATUS_TX_EMPTY ) { while( 1 ) { mml_uart_port_status(MML_UART_DEV0, &status); if( !(status & MML_UART_STATUS_TX_FULL) ) { if( ringbuf_get(&gSendFifo[0], &c) >= 0 ) //if (rb_read_byte(&gSendLb[0], &c)) { reg_uart->dr = c; } else { break; } } else { break; } } } return (DataSize - size); }
void tx_send(uint8_t asciicode) { ringbuf_put(&tx_buf, asciicode); PIE1bits.TX1IE = 1; }
void rvidcc_process(void) { unsigned int sentinel = 0; int compsize = 0; /* Process received data */ while (ringbuf_available_data(&dcc_inbuf) >= sizeof(unsigned int)) { int bytes; unsigned char *buf; /* Search for start sentinel */ sentinel = to_little_endian(*(unsigned int *)dcc_inbuf.readPtr); compsize = sentinel & 0xffff; /* Discard if not a start sentinel */ if ((sentinel & START_MASK) != START_SENTINEL || compsize > sizeof(dcc_temp_source) || compsize <= 0) { ringbuf_advance_read(&dcc_inbuf, sizeof(unsigned int)); continue; } /* Sentinel found, come back later if not enough data */ bytes = ringbuf_available_data(&dcc_inbuf); if (bytes < compsize + sizeof(unsigned int)) break; /* Copy to a contiguous buffer */ ringbuf_get(&dcc_inbuf, dcc_temp_source, compsize + sizeof(unsigned int)); sentinel &= 0xffff0000; buf = dcc_temp_source + sizeof(unsigned int); bytes = compsize; /* Round up to nearest whole word */ if (compsize & 0x3) compsize = (compsize + 4) & ~0x3; /* advance by packet size + sentinel */ ringbuf_advance_read(&dcc_inbuf, compsize + sizeof(unsigned int)); /* allow more data to be received */ RVIDCC_ENABLE_READ_INTERRUPT; /* Process TTY or IP packet accordingly */ if (sentinel == UNCOMP_TTY_START) { ringbuf_put(&dcc_tty_inbuf, buf, bytes); ringbuf_advance_write(&dcc_tty_inbuf, bytes); } else { if (bytes == 4) /* ARP 'is this IP address you?' */ { if (rvidcc_cb_has_addr(buf)) rvidcc_transmit_ip_packet(buf, 4); } else if (bytes == 6) /* set MAC address */ rvidcc_cb_set_mac_address(buf); else rvidcc_cb_ip_packet_received(buf, (size_t)bytes); } } }