Skip to content

Commit

Permalink
add pbuf safe functions for memory management
Browse files Browse the repository at this point in the history
  • Loading branch information
MaJerle committed Jul 12, 2023
1 parent d2f0f21 commit ae4b967
Show file tree
Hide file tree
Showing 11 changed files with 299 additions and 312 deletions.
54 changes: 27 additions & 27 deletions lwesp/src/api/lwesp_netconn.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,20 @@
typedef struct lwesp_netconn {
struct lwesp_netconn* next; /*!< Linked list entry */

lwesp_netconn_type_t type; /*!< Netconn type */
lwesp_port_t listen_port; /*!< Port on which we are listening */
lwesp_netconn_type_t type; /*!< Netconn type */
lwesp_port_t listen_port; /*!< Port on which we are listening */

size_t rcv_packets; /*!< Number of received packets so far on this connection */
lwesp_conn_p conn; /*!< Pointer to actual connection */
size_t rcv_packets; /*!< Number of received packets so far on this connection */
lwesp_conn_p conn; /*!< Pointer to actual connection */
uint16_t conn_val_id; /*!< Connection validation ID that changes between every connection active/closed operation */

lwesp_sys_mbox_t mbox_accept; /*!< List of active connections waiting to be processed */
lwesp_sys_mbox_t mbox_receive; /*!< Message queue for receive mbox */
size_t mbox_receive_entries; /*!< Number of entries written to receive mbox */

lwesp_linbuff_t buff; /*!< Linear buffer structure */
lwesp_linbuff_t buff; /*!< Linear buffer structure */

uint16_t conn_timeout; /*!< Connection timeout in units of seconds when
uint16_t conn_timeout; /*!< Connection timeout in units of seconds when
netconn is in server (listen) mode.
Connection will be automatically closed if there is no
data exchange in time. Set to `0` when timeout feature is disabled. */
Expand Down Expand Up @@ -111,7 +111,7 @@ flush_mboxes(lwesp_netconn_t* nc, uint8_t protect) {
if (pbuf != NULL && (uint8_t*)pbuf != (uint8_t*)&recv_closed) {
LWESP_DEBUGF(LWESP_CFG_DBG_NETCONN | LWESP_DBG_TYPE_TRACE | LWESP_DBG_LVL_WARNING,
"[LWESP NETCONN] flush mboxes. Clearing pbuf 0x%p\r\n", (void*)pbuf);
lwesp_pbuf_free(pbuf); /* Free received data buffers */
lwesp_pbuf_free_s(&pbuf); /* Free received data buffers */
}
}
lwesp_sys_mbox_delete(&nc->mbox_receive); /* Delete message queue */
Expand Down Expand Up @@ -149,14 +149,14 @@ netconn_evt(lwesp_evt_t* evt) {
* A new connection has been active
* and should be handled by netconn API
*/
case LWESP_EVT_CONN_ACTIVE: { /* A new connection active is active */
if (lwesp_conn_is_client(conn)) { /* Was connection started by us? */
nc = lwesp_conn_get_arg(conn); /* Argument should be already set */
case LWESP_EVT_CONN_ACTIVE: { /* A new connection active is active */
if (lwesp_conn_is_client(conn)) { /* Was connection started by us? */
nc = lwesp_conn_get_arg(conn); /* Argument should be already set */
if (nc != NULL) {
nc->conn = conn; /* Save actual connection */
nc->conn_val_id = conn->val_id; /* Get value ID */
} else {
close = 1; /* Close this connection, invalid netconn */
close = 1; /* Close this connection, invalid netconn */
}

/* Is the connection server type and we have known listening API? */
Expand All @@ -170,7 +170,7 @@ netconn_evt(lwesp_evt_t* evt) {
"[LWESP NETCONN] Cannot create new structure for incoming server connection!\r\n");

if (nc != NULL) {
nc->conn = conn; /* Set connection handle */
nc->conn = conn; /* Set connection handle */
nc->conn_val_id = conn->val_id;
lwesp_conn_set_arg(conn, nc); /* Set argument for connection */

Expand Down Expand Up @@ -199,7 +199,7 @@ netconn_evt(lwesp_evt_t* evt) {
lwesp_conn_set_arg(conn, NULL); /* Reset argument */
lwesp_netconn_delete(nc); /* Free memory for API */
}
lwesp_conn_close(conn, 0); /* Close the connection */
lwesp_conn_close(conn, 0); /* Close the connection */
close = 0;
}
break;
Expand All @@ -219,7 +219,7 @@ netconn_evt(lwesp_evt_t* evt) {
lwesp_conn_recved(conn, pbuf); /* Notify stack about received data */
#endif /* !LWESP_CFG_CONN_MANUAL_TCP_RECEIVE */

lwesp_pbuf_ref(pbuf); /* Increase reference counter */
lwesp_pbuf_ref(pbuf); /* Increase reference counter */
LWESP_DEBUGW(LWESP_CFG_DBG_NETCONN | LWESP_DBG_TYPE_TRACE, nc == NULL,
"[LWESP NETCONN] Data receive -> netconn is NULL!\r\n");
LWESP_DEBUGW(LWESP_CFG_DBG_NETCONN | LWESP_DBG_TYPE_TRACE, nc->conn_val_id != conn->val_id,
Expand All @@ -230,18 +230,18 @@ netconn_evt(lwesp_evt_t* evt) {
|| !lwesp_sys_mbox_putnow(&nc->mbox_receive, pbuf)) {
LWESP_DEBUGF(LWESP_CFG_DBG_NETCONN,
"[LWESP NETCONN] Could not put receive packet. Ignoring more data for receive!\r\n");
lwesp_pbuf_free(pbuf); /* Free pbuf */
lwesp_pbuf_free_s(&pbuf); /* Free pbuf */
return lwespOKIGNOREMORE; /* Return OK to free the memory and ignore further data */
}
++nc->mbox_receive_entries; /* Increase number of packets in receive mbox */
++nc->mbox_receive_entries; /* Increase number of packets in receive mbox */
#if LWESP_CFG_CONN_MANUAL_TCP_RECEIVE
/* Check against 1 less to still allow potential close event to be written to queue */
if (nc->mbox_receive_entries >= (LWESP_CFG_NETCONN_RECEIVE_QUEUE_LEN - 1)) {
conn->status.f.receive_blocked = 1; /* Block reading more data */
}
#endif /* LWESP_CFG_CONN_MANUAL_TCP_RECEIVE */
#endif /* LWESP_CFG_CONN_MANUAL_TCP_RECEIVE */

++nc->rcv_packets; /* Increase number of packets received */
++nc->rcv_packets; /* Increase number of packets received */
LWESP_DEBUGF(LWESP_CFG_DBG_NETCONN | LWESP_DBG_TYPE_TRACE,
"[LWESP NETCONN] Received pbuf contains %d bytes. Handle written to receive mbox\r\n",
(int)lwesp_pbuf_length(pbuf, 0));
Expand Down Expand Up @@ -311,8 +311,8 @@ lwesp_netconn_new(lwesp_netconn_type_t type) {
lwesp_core_unlock();
a = lwesp_mem_calloc(1, sizeof(*a)); /* Allocate memory for core object */
if (a != NULL) {
a->type = type; /* Save netconn type */
a->conn_timeout = 0; /* Default connection timeout */
a->type = type; /* Save netconn type */
a->conn_timeout = 0; /* Default connection timeout */
if (!lwesp_sys_mbox_create(&a->mbox_accept, LWESP_CFG_NETCONN_ACCEPT_QUEUE_LEN)) {
LWESP_DEBUGF(LWESP_CFG_DBG_NETCONN | LWESP_DBG_TYPE_TRACE | LWESP_DBG_LVL_DANGER,
"[LWESP NETCONN] Cannot create accept MBOX\r\n");
Expand Down Expand Up @@ -573,17 +573,17 @@ lwesp_netconn_accept(lwesp_netconn_p nc, lwesp_netconn_p* client) {
}
if ((uint8_t*)tmp == (uint8_t*)&recv_closed) {
lwesp_core_lock();
listen_api = NULL; /* Disable listening at this point */
listen_api = NULL; /* Disable listening at this point */
lwesp_core_unlock();
return lwespERRWIFINOTCONNECTED; /* Wifi disconnected */
} else if ((uint8_t*)tmp == (uint8_t*)&recv_not_present) {
lwesp_core_lock();
listen_api = NULL; /* Disable listening at this point */
listen_api = NULL; /* Disable listening at this point */
lwesp_core_unlock();
return lwespERRNODEVICE; /* Device not present */
}
*client = tmp; /* Set new pointer */
return lwespOK; /* We have a new connection */
*client = tmp; /* Set new pointer */
return lwespOK; /* We have a new connection */
}

/**
Expand Down Expand Up @@ -654,15 +654,15 @@ lwesp_netconn_write(lwesp_netconn_p nc, const void* data, size_t btw) {
}

/* Step 3 */
if (nc->buff.buff == NULL) { /* Check if we should allocate a new buffer */
if (nc->buff.buff == NULL) { /* Check if we should allocate a new buffer */
nc->buff.buff = lwesp_mem_malloc(sizeof(*nc->buff.buff) * LWESP_CFG_CONN_MAX_DATA_LEN);
nc->buff.len = LWESP_CFG_CONN_MAX_DATA_LEN; /* Save buffer length */
nc->buff.ptr = 0; /* Save buffer pointer */
}

/* Step 4 */
if (nc->buff.buff != NULL) { /* Memory available? */
LWESP_MEMCPY(&nc->buff.buff[nc->buff.ptr], d, btw); /* Copy data to buffer */
if (nc->buff.buff != NULL) { /* Memory available? */
LWESP_MEMCPY(&nc->buff.buff[nc->buff.ptr], d, btw); /* Copy data to buffer */
nc->buff.ptr += btw;
} else { /* Still no memory available? */
return lwesp_conn_send(nc->conn, data, btw, NULL, 1); /* Simply send directly blocking */
Expand Down
3 changes: 1 addition & 2 deletions lwesp/src/apps/http_server/lwesp_http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,8 +1083,7 @@ http_evt(lwesp_evt_t* evt) {
}
#endif /* HTTP_SUPPORT_POST */
if (hs->p != NULL) {
lwesp_pbuf_free(hs->p); /* Free packet buffer */
hs->p = NULL;
lwesp_pbuf_free_s(&hs->p); /* Free packet buffer */
}
if (hs->rlwesp_file_opened) { /* Is file opened? */
uint8_t is_static = hs->rlwesp_file.is_static;
Expand Down
2 changes: 2 additions & 0 deletions lwesp/src/include/lwesp/lwesp_pbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ extern "C" {

lwesp_pbuf_p lwesp_pbuf_new(size_t len);
size_t lwesp_pbuf_free(lwesp_pbuf_p pbuf);
size_t lwesp_pbuf_free_s(lwesp_pbuf_p* pbuf);
void* lwesp_pbuf_data(const lwesp_pbuf_p pbuf);
size_t lwesp_pbuf_length(const lwesp_pbuf_p pbuf, uint8_t tot);
uint8_t lwesp_pbuf_set_length(lwesp_pbuf_p pbuf, size_t new_len);
lwespr_t lwesp_pbuf_take(lwesp_pbuf_p pbuf, const void* data, size_t len, size_t offset);
size_t lwesp_pbuf_copy(lwesp_pbuf_p pbuf, void* data, size_t len, size_t offset);

lwespr_t lwesp_pbuf_cat(lwesp_pbuf_p head, const lwesp_pbuf_p tail);
lwespr_t lwesp_pbuf_cat_s(lwesp_pbuf_p head, lwesp_pbuf_p* tail);
lwespr_t lwesp_pbuf_chain(lwesp_pbuf_p head, lwesp_pbuf_p tail);
lwesp_pbuf_p lwesp_pbuf_unchain(lwesp_pbuf_p head);
lwespr_t lwesp_pbuf_ref(lwesp_pbuf_p pbuf);
Expand Down
14 changes: 14 additions & 0 deletions lwesp/src/include/lwesp/lwesp_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ extern "C" {
} \
} while (0)

/**
* \brief Assert an input parameter if in valid range, return 0 from function on failure
* \note Since this is a macro, it may only be used on a functions where return status is of type \ref lwespr_t enumeration
* \param[in] c: Condition to test
*/
#define LWESP_ASSERT0(c) \
do { \
if (!(c)) { \
LWESP_DEBUGF(LWESP_CFG_DBG_ASSERT, "Assert failed in file %s on line %d: %s\r\n", __FILE__, (int)__LINE__, \
#c); \
return 0; \
} \
} while (0)

/**
* \brief Align `x` value to specific number of bytes, provided by \ref LWESP_CFG_MEM_ALIGNMENT configuration
* \param[in] x: Input value to align
Expand Down

0 comments on commit ae4b967

Please sign in to comment.