/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#ifndef ATSC30_COMMON_NET_BUF_H
#define ATSC30_COMMON_NET_BUF_H

#include <linux/types.h>

/*
 * net_buf data structure
 *
 * -----------------------------------------------------------------------
 * | used_area(shall not prepend)   |  data area       |    free area    |
 * -----------------------------------------------------------------------
 * |                                |                  |                 |
 * start(data)                 offset        offset + len          tot_size
 *
 */

typedef struct net_buf {
	u8 *data;
	u32 offset;
	u32 len;
	u32 tot_size;
} net_buf_t;

#define net_buf_valid(buf) \
	(((buf).data != NULL) \
			&& ((buf).tot_size > 0) \
			&& ((buf).offset + (buf).len <= (buf).tot_size))

#define net_buf_empty(buf) \
	((buf).len == 0)
#define net_buf_free_size(buf) \
	((buf).tot_size - (buf).len)
#define net_buf_data_size(buf) \
	((buf).len)
#define net_buf_get_val(buf, index) \
	((buf).data[index + (buf).offset])
#define net_buf_get_first_byte_val(buf) \
	((buf).data[(buf).offset])
#define net_buf_get_ptr(buf, index) \
	(&(buf).data[(index) + (buf).offset])

#define NET_BUF_UNDERFLOW_CHECK(buf, size) \
	({ \
		bool __ret = (buf).len < (size); \
		if (__ret) \
			pr_err("buf len[%d] < size[%d]", \
					(buf).len, \
					(size)); \
		__ret; \
	})

net_buf_t net_buf_get_sub_buf(
		const net_buf_t buf,
		const u32 sub_buf_start,
		const u32 sub_buf_len);

void net_buf_consume(
		net_buf_t *const buf,
		const u32 size);
bool net_buf_append_raw_data(
		net_buf_t *const buf,
		const u8 *const data,
		const u32 size);
u8 *net_buf_append_one_byte(
		net_buf_t *const buf,
		const u8 data);
bool net_buf_append_buf(
		net_buf_t *const dst,
		const net_buf_t src);
net_buf_t net_buf_init_empty(
		u8 *data,
		const u32 buf_len);
net_buf_t net_buf_init_full(
		u8 *data,
		const u32 buf_len);
void net_buf_reset(
		net_buf_t *const buf);
void net_buf_dump(
		int log_level,
		int log_module,
		net_buf_t *const buf);
void net_buf_dump_info(
		int log_level,
		int log_module,
		net_buf_t *const buf);

#endif /* ATSC30_COMMON_NET_BUF_H */

