/** * get data from ring buffer */ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length) { rt_size_t size; RT_ASSERT(rb != RT_NULL); /* whether has enough data */ size = rt_ringbuffer_data_len(rb); /* no data */ if (size == 0) return 0; /* less data */ if (size < length) length = size; if (rb->buffer_size - rb->read_index > length) { /* copy all of data */ memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); /* this should not cause overflow because there is enough space for * length of data in current mirror */ rb->read_index += length; return length; } memcpy(&ptr[0], &rb->buffer_ptr[rb->read_index], rb->buffer_size - rb->read_index); memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0], length - (rb->buffer_size - rb->read_index)); /* we are going into the other side of the mirror */ rb->read_mirror = ~rb->read_mirror; rb->read_index = length - (rb->buffer_size - rb->read_index); return length; }
/** * get a character from a ringbuffer */ rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch) { RT_ASSERT(rb != RT_NULL); /* ringbuffer is empty */ if (!rt_ringbuffer_data_len(rb)) return 0; /* put character */ *ch = rb->buffer_ptr[rb->read_index]; if (rb->read_index == rb->buffer_size-1) { rb->read_mirror = ~rb->read_mirror; rb->read_index = 0; } else { rb->read_index++; } return 1; }
static rt_uint8_t wrtnode2r_spi_stm32_get_read_buf_len(void) { return (rt_uint8_t)rt_ringbuffer_data_len(&spi_bridge.read_buf); }
/* process rx data */ static void process_rx(struct telnet_session* telnet, rt_uint8_t *data, rt_size_t length) { rt_size_t rx_length, index; for (index = 0; index < length; index ++) { switch(telnet->state) { case STATE_IAC: if (*data == TELNET_IAC) { rt_mutex_take(telnet->rx_ringbuffer_lock, RT_WAITING_FOREVER); /* put buffer to ringbuffer */ rt_ringbuffer_putchar(&(telnet->rx_ringbuffer), *data); rt_mutex_release(telnet->rx_ringbuffer_lock); telnet->state = STATE_NORMAL; } else { /* set telnet state according to received package */ switch (*data) { case TELNET_WILL: telnet->state = STATE_WILL; break; case TELNET_WONT: telnet->state = STATE_WONT; break; case TELNET_DO: telnet->state = STATE_DO; break; case TELNET_DONT: telnet->state = STATE_DONT; break; default: telnet->state = STATE_NORMAL; break; } } break; /* don't option */ case STATE_WILL: case STATE_WONT: send_option_to_client(telnet, TELNET_DONT, *data); telnet->state = STATE_NORMAL; break; /* won't option */ case STATE_DO: case STATE_DONT: send_option_to_client(telnet, TELNET_WONT, *data); telnet->state = STATE_NORMAL; break; case STATE_NORMAL: if (*data == TELNET_IAC) telnet->state = STATE_IAC; else if (*data != '\r') /* ignore '\r' */ { rt_mutex_take(telnet->rx_ringbuffer_lock, RT_WAITING_FOREVER); /* put buffer to ringbuffer */ rt_ringbuffer_putchar(&(telnet->rx_ringbuffer), *data); rt_mutex_release(telnet->rx_ringbuffer_lock); } break; } data ++; } rt_mutex_take(telnet->rx_ringbuffer_lock, RT_WAITING_FOREVER); /* get total size */ rx_length = rt_ringbuffer_data_len(&telnet->rx_ringbuffer); rt_mutex_release(telnet->rx_ringbuffer_lock); /* indicate there are reception data */ if ((rx_length > 0) && (telnet->device.rx_indicate != RT_NULL)) telnet->device.rx_indicate(&telnet->device, rx_length); return; }