/** 
 * @file serial.h
 * @brief 串口通信(同步IO方式)
 * @author niujiuru
 * @date 2014-07-14 created
 * @note 2021-04-13 打开串口时允许设置奇偶校检位
 * @note 2021-04-23 打开串口时区分开有数据和无数据两种不同状态下的用户回调
 * @note 2021-04-25 新增"serial_printf_recv_buffer()"函数, 打印接收缓存区
 * @note 2021-04-27 新增"serial_recvThrd_isAlive()"函数, 判断接收线程是否还在
 * @note 2021-08-20 新增"serial_get_log_prefix()"函数, 获取日志打印前缀字符串
 * @note 2025-10-11 打开串口时新增"__O_CLOEXEC"
 */
#ifndef __SERIAL_H__
#define __SERIAL_H__

#ifdef __cplusplus
extern "C"
{
#endif

/* 数据接收处理(用户回调); "wParam"指向打开的串口句柄, "lParm"指向用户数据;
   "返回值 < 0"时表示处理失败, 将不再调用该用户回调, "返回值 >= 0"时表示处理成功,
   接收数据空闲时, 延时一段"返回值"时间(ms)后, 继续调用该用户回调 */
typedef int (*PSerialRecvHandler)(unsigned long wParam, unsigned long lParam);

/* 空闲接收处理(用户回调); "wParam"指向打开的串口句柄, "lParm"指向用户数据;
   "返回值 < 0"时表示处理失败, 将不再调用该用户回调, "返回值 >= 0"时表示处理成功,
   接收数据空闲时, 延时一段"返回值"时间(ms)后, 继续调用该用户回调 */
typedef int (*PSerialIdleHandler)(unsigned long wParam, unsigned long lParam);

/* 打开串口(8个数据位1个停止位), NULL失败, NOT NULL成功 */
void *serial_open(const char *serialName, int baudrate, const char *parityCheck /* "odd"-奇校检; "even"-偶校检; NULL或其它无效值-无校检 */, \
                  PSerialRecvHandler pRecvHandler, PSerialIdleHandler pIdleHandler, void *pUserData);

/* 关闭串口 */
void serial_close(void *hSerial, int timeout);

/* 获取日志打印前缀 */
char *serial_get_log_prefix(const void *hSerial);

/* 发送数据, -1失败, >=0发送的字节数 */
int serial_send_data(const void *hSerial, const unsigned char *data, int len);

/* 取得接收缓存区, NULL失败, NOT NULL成功 */
const unsigned char *serial_get_recv_buffer(const void *hSerial);

/* 取得接收缓存区中当前有效数据的字节数, -1失败, 返回值>=0 */
int serial_get_recv_buffer_bytes(const void *hSerial);

/* 清空接收缓存区 */
void serial_clear_recv_buffer(const void *hSerial);

/* 打印接收缓存区 */
void serial_printf_recv_buffer(const void *hSerial, int logLevel);

/* 判断接收线程是否还在 */
bool serial_recvThrd_isAlive(const void *hSerial);

/* 暂停接收线程接收数据 */
void serial_recvThrd_pause(const void *hSerial);

/* 继续接收线程接收数据 */
void serial_recvThrd_resume(const void *hSerial);

#ifdef _DEBUG
/* 向接收缓存中写入数据(一般用于仿真串口输入, 模拟测试时使用) */
void serial_write_recv_buffer(const void *hSerial, const unsigned char *hex, int hexCnt);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __SERIAL_H__ */
