Modbus

Parents 5b6407edfe8e
Children 4f584251c73d
fix bug: frame data read from network was potentially being moved inside buffer (lb_normalize()) before it was processed by caller to read_frame()
  • +9 -1
    mb_ds_util.h
  • +15 -2
    mb_rtu.c
  • --- a/mb_ds_util.h Wed Jun 02 11:09:57 2021 +0100
    +++ b/mb_ds_util.h Sun Jun 06 22:40:06 2021 +0100
    @@ -97,6 +97,7 @@
    int data_start; /* offset within *data were valid data starts */
    int data_end; /* offset within *data were valid data ends */
    int max_data_start; /* optimization parameter! When should it be normalised? */
    + int marked_for_purge; /* Number of bytes to be deleted in next call to lb_data_purge() */
    } lb_buf_t;
    /* NOTE: lb = Linear Buffer */
    @@ -111,6 +112,7 @@
    buf->data_size = size;
    buf->data_start = 0;
    buf->data_end = 0;
    + buf->marked_for_purge = 0;
    buf->max_data_start = max_data_start;
    buf->data = (u8 *)malloc(size);
    return buf->data;
    @@ -143,8 +145,13 @@
    buf->data_end = buf->data_size - 1;
    }
    +static inline void lb_data_mark_for_purge(lb_buf_t *buf, int count) {
    + buf->marked_for_purge += count;
    +}
    +
    static inline u8 *lb_data_purge(lb_buf_t *buf, int count) {
    - buf->data_start += count;
    + buf->data_start += count + buf->marked_for_purge;
    + buf->marked_for_purge = 0;
    if (buf->data_start > buf->data_end)
    buf->data_start = buf->data_end;
    @@ -156,6 +163,7 @@
    static inline void lb_data_purge_all(lb_buf_t *buf) {
    buf->data_start = buf->data_end = 0;
    + buf->marked_for_purge = 0;
    }
    static inline u8 *lb_free(lb_buf_t *buf) {
    --- a/mb_rtu.c Wed Jun 02 11:09:57 2021 +0100
    +++ b/mb_rtu.c Sun Jun 06 22:40:06 2021 +0100
    @@ -1422,8 +1422,11 @@
    #endif
    /* set the data pointer */
    *recv_data_ptr = lb_data(&(buf->data_buf));
    - /* remove the frame bytes off the buffer */
    - lb_data_purge(&(buf->data_buf), frame_length);
    + /* Mark the frame bytes to be deleted off the buffer by the next call to lb_data_purge() */
    + /* Notice that we cannot delete the frame bytes right away, as they will still be accessed by whoever
    + * called read_frame(). We can only delete this data on the next call to read_frame()
    + */
    + lb_data_mark_for_purge(&(buf->data_buf), frame_length);
    /* reset the search_history flag */
    buf->frame_search_history = 0;
    /* if the buffer becomes empty, then reset boundary flag */
    @@ -1532,6 +1535,16 @@
    *recv_data_ptr = NULL;
    /*===================================*
    + * Delete any previously received data that has already been returned as a valid frame in *
    + *===================================*/
    + /* Delete any previously received data that has already been returned as a valid frame in
    + * the previous invocation of read_frame().
    + * Notice that the data that will be deleted hass ben marked for deletion by calling
    + * lb_data_mark_for_purge() in return_frame()
    + */
    + lb_data_purge(&(recv_buf->data_buf), 0);
    +
    + /*===================================*
    * Check for frame in left over data *
    *===================================*/
    /* If we have any data left over from previous call to read_frame()