diff --git a/README.md b/README.md index a5ff2ac..5ba23d7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The goal is to develop and test a distributed messaging application based on an ## Prerequisites -This project was developed for execution on Raspberry Pi Zero W. The rabian image used during development and testing can be found in the repository [`./rasbian_image/`]() directory. Installation directions can be found in Raspberry's website [here](https://www.raspberrypi.org/documentation/installation/installing-images/linux.md). +This project was developed for execution on Raspberry Pi Zero W. The rabian image used during development and testing can be found in the repository [`./rasbian_image/`](https://gitlab.com/apostolof-ece-auth-gr/authRTESFinalAssignment/tree/master/rasbian_image) directory. Installation directions can be found in Raspberry's website [here](https://www.raspberrypi.org/documentation/installation/installing-images/linux.md). There are two ways of connecting to the system. By connecting to the port denoted "USB", a new network interface will appear, Raspberry's IP is 192.168.0.1/24 in that network, so you need to configure a static IP for your PC in the range 192.168.0.[2-254]. @@ -68,7 +68,7 @@ Reach out to me: ## License -[![Beerware License](https://img.shields.io/badge/license-beerware%20%F0%9F%8D%BA-blue.svg)](https://gitlab.com/apostolof-ece-auth-gr/authRTESTask1/blob/master/LICENSE.md) +[![Beerware License](https://img.shields.io/badge/license-beerware%20%F0%9F%8D%BA-blue.svg)](https://gitlab.com/apostolof-ece-auth-gr/authRTESFinalAssignment/blob/master/LICENSE.md) --- -In Mesopotamian mythology, Zaqar is the messenger of the god Sin. He relays these messages to mortals through his power over their dreams and nightmares. \ No newline at end of file +In Mesopotamian mythology, Zaqar is the messenger of the god Sin. He relays these messages to mortals through his power over their dreams and nightmares. \ No newline at end of file diff --git a/lib/circ_buff.c b/lib/circ_buff.c new file mode 100644 index 0000000..66a055c --- /dev/null +++ b/lib/circ_buff.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include + +#include "circ_buff.h" + +// Defines the circular buffer structure +struct circ_buf_t { + char** buffer; + size_t head; + size_t tail; + size_t max; // of the buffer + bool full; +}; + +// Private Functions + +static void advance_pointer(cbuf_handle_t cbuf) { + assert(cbuf); + + if(cbuf->full) { + cbuf->tail = (cbuf->tail + 1) % cbuf->max; + } + + cbuf->head = (cbuf->head + 1) % cbuf->max; + + // We mark full because we will advance tail on the next time around + cbuf->full = (cbuf->head == cbuf->tail); +} + +static void retreat_pointer(cbuf_handle_t cbuf) { + assert(cbuf); + + cbuf->full = false; + cbuf->tail = (cbuf->tail + 1) % cbuf->max; +} + +// APIs + +cbuf_handle_t circ_buf_init(char** buffer, size_t size) { + assert(buffer && size); + + cbuf_handle_t cbuf = malloc(sizeof(circ_buf_t)); + assert(cbuf); + + cbuf->buffer = buffer; + cbuf->max = size; + circ_buf_reset(cbuf); + + assert(circ_buf_empty(cbuf)); + + return cbuf; +} + +void circ_buf_free(cbuf_handle_t cbuf) { + assert(cbuf); + free(cbuf); +} + +void circ_buf_reset(cbuf_handle_t cbuf) { + assert(cbuf); + + cbuf->head = 0; + cbuf->tail = 0; + cbuf->full = false; +} + +size_t circ_buf_size(cbuf_handle_t cbuf) { + assert(cbuf); + + size_t size = cbuf->max; + + if(!cbuf->full) { + if(cbuf->head >= cbuf->tail) { + size = (cbuf->head - cbuf->tail); + } + else { + size = (cbuf->max + cbuf->head - cbuf->tail); + } + } + + return size; +} + +size_t circ_buf_capacity(cbuf_handle_t cbuf) { + assert(cbuf); + + return cbuf->max; +} + +void circ_buf_put(cbuf_handle_t cbuf, char data) { + assert(cbuf && cbuf->buffer); + + strcpy(cbuf->buffer[cbuf->head], data); + + advance_pointer(cbuf); +} + +int circ_buf_get(cbuf_handle_t cbuf, char* data) { + assert(cbuf && data && cbuf->buffer); + + int r = -1; + + if(!circ_buf_empty(cbuf)) { + strcpy(data, cbuf->buffer[cbuf->tail]); + retreat_pointer(cbuf); + + r = 0; + } + + return r; +} + +bool circ_buf_empty(cbuf_handle_t cbuf) { + assert(cbuf); + + return (!cbuf->full && (cbuf->head == cbuf->tail)); +} + +bool circ_buf_full(cbuf_handle_t cbuf) { + assert(cbuf); + + return cbuf->full; +} diff --git a/lib/circ_buff.h b/lib/circ_buff.h new file mode 100644 index 0000000..b0f8a1f --- /dev/null +++ b/lib/circ_buff.h @@ -0,0 +1,44 @@ +/* + * Implementation of a simple circular buffer data structure. + * Based on the example and guide found here: + * https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc +*/ +#ifndef CIRC_BUFF_H_ +#define CIRC_BUFF_H_ + +#include + +// Circular buffer structure +typedef struct circ_buf_t circ_buf_t; +// and handle type +typedef circ_buf_t* cbuf_handle_t; + +// Initializes a circular buffer structure and returns the circular buffer handle. +// Pass in a storage buffer and size. +cbuf_handle_t circ_buf_init(char** buffer, size_t size); + +// Frees a circular buffer structure. Does not free data buffer! +void circ_buf_free(cbuf_handle_t cbuf); + +// Resets the circular buffer to empty, head == tail. Data not cleared! +void circ_buf_reset(cbuf_handle_t cbuf); + +// Adds data, even if the buffer is full. Old data is overwritten. +void circ_buf_put(cbuf_handle_t cbuf, char data); + +// Retrieves a value from the buffer. +int circ_buf_get(cbuf_handle_t cbuf, char* data); + +// Checks if the buffer is empty. +bool circ_buf_empty(cbuf_handle_t cbuf); + +// Checks if the buffer is full. +bool circ_buf_full(cbuf_handle_t cbuf); + +// Checks the capacity of the buffer. +size_t circ_buf_capacity(cbuf_handle_t cbuf); + +// Checks the number of elements stored in the buffer. +size_t circ_buf_size(cbuf_handle_t cbuf); + +#endif //CIRC_BUFF_H_