fusion/common/kpacket.h

185 lines
5.1 KiB
C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************
File name : kpacket.h
Module : pal
Author : amir.liang
Version : 0.1
Created on : 2021-09-16
Description :
included files required by os environment
Modify History:
1. Date: Author: Modification:
20230424 amir use os_lock instead of mutex.
*************************************************/
#ifndef __PACKET_H__
#define __PACKET_H__
#include <stdint.h>
#include "hdef.h"
#include "hmutex.h"
#include "hatomic.h"
#ifndef OK
#define OK (char)(0)
#endif
#ifndef NG
#define NG (char)(1)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================*/
/*1. do not use kpacket with stack memory */
/*2. payload address must be algin 4 */
/*===========================================*/
#define KPACKET_DEBUG 1U
#if KPACKET_DEBUG
#define KPACKET_LOG hlogd
#else
#define KPACKET_LOG(...)
#endif
#define OS_PACKET_MAGIC 0xcafe
/*
*kpacket_put_int: 按int推数据到value, 协议方pop_int对应有即可
*如: kpacket_put_int(kp, 123); val = kpacket_pop_int(kp, -1) val应该是123
*/
typedef struct {
uint16_t checksum; /* crc16 , just for TLV, include OS_PACKET_MAGIC */
uint16_t magic; /* OS_PACKET_MAGIC */
uint16_t T; /*TLV T: 0~65535 */
uint32_t L; /*TLV L: total size of value */
char V[0]; /*TLV V: the addr of value */
}TLV;
TLV *TLV_init(char *buf, uint32_t cap);
typedef struct{
hatomic_t ref; /*引用计数, 创建时为1, 当减到值为0时将释放kpacket内存 */
uint32_t capacity; /*内存容量,主要是 value能存的数据大小 = sizeof(kpacket) + len(value) */
uint32_t offset; /*仅用于标识 value的offset*/
TLV tlv;
}kpacket;
/*
* packet_pool_size recommend 4K
* 初始化时必先 init
*/
void kpacket_init(uint32_t packet_pool_size);
/*
*
* 填充完所有数时计算并保存checksum到kpacket, 返回checksum
*/
uint16_t kpacket_checksum(kpacket *packet);
/*
*
* 仅计算并返回checksum 并不保存在kpacket
*/
uint16_t kpacket_calc_checksum(kpacket *packet);
/*
*
*/
kpacket *kpacket_slab_alloc(uint32_t size);
/*
*
*/
void kpacket_slab_free(kpacket *packet);
#define kpacket_inc(_packet) ({\
hatomic_inc(&_packet->ref);/*没锁,有风险*/\
KPACKET_LOG("%s packet:%p, inc_ref:%d\n", __func__, _packet, _packet->ref);\
})
#define kpacket_dec(_packet) ({\
if (_packet->ref == 0){\
hloge("%s Error... hv_free_packet:%p, dec_ref should not be:%d\n", __func__, _packet, _packet->ref);\
}\
hatomic_dec(&_packet->ref);/*没锁,可能有风险*/\
if (_packet->ref == 0){\
KPACKET_LOG("%s free_packet:%p, dec_ref:%d ..............\n", __func__, _packet, _packet->ref);\
kpacket_slab_free(_packet);/*os_packet_delete(_packet);*/\
}else KPACKET_LOG("%s :%p, dec_ref:%d\n", __func__, _packet, _packet->ref);\
})
#define os_packet_valid(__packet) ({int32_t _ret;\
if (__packet && __packet-->tlv.magic == OS_PACKET_MAGIC){\
_ret = 1;\
}else{\
KPACKET_LOG("%s err packet:%p(!NULL), packet magic:%X(=%X)\n",__func__, __packet, __packet?__packet-->tlv.magic:0, OS_PACKET_MAGIC);\
_ret = 0;\
}\
_ret;})
#define kpacket(_event, _capacity)({\
kpacket *_packet = kpacket_slab_alloc(sizeof(kpacket) + _capacity);\
if (_packet){\
_packet->tlv.magic = OS_PACKET_MAGIC;\
_packet->tlv.T = _event;\
_packet->ref = 1;\
_packet->capacity = _capacity;\
_packet->tlv.L = 0;\
_packet->offset = 0;\
}else{\
hloge("%s kpacket_create outofmemory", __func__);\
}\
_packet;})
/*do not call os_packet_delete normally, use atomic_dec(packet) instead */
#if 0
#define os_packet_delete(_hv_free_packet)({\
if (os_packet_valid(_hv_free_packet)){\
if (_hv_free_packet->ref == 0) {\
hv_free(_hv_free_packet);\
hloge("%s os_packet_hv_free packet:%p",__func__, _hv_free_packet);\
}else{\
hloge("%s os_packet_hv_free error packet->ref:%d",__func__, _hv_free_packet->ref);\
}\
}else{\
hloge("%s os_packet_hv_free error",__func__);\
}\
})
#endif
uint32_t kpacket_put_int(kpacket *p, int32_t val);
uint32_t kpacket_put_string(kpacket *p, const char *str);//including '\0'
uint32_t kpacket_put_data(kpacket *p, const char *data, uint32_t len);
uint32_t kpacket_put_data1data2(kpacket *p, const char *data, uint32_t len, const char *data2, uint32_t len2);
//data move to 'zero' and dataLen be 0
void kpacket_reset(kpacket *p);
uint32_t kpacket_get_freesize(const kpacket *p);
uint32_t kpacket_pop_int(kpacket *p_box, const int32_t defVal);
const char *kpacket_pop_string(kpacket *p_box, const char *defVal);
uint32_t kpacket_pop_data(kpacket *p_box, char **data);
uint32_t kpacket_pop_reset(kpacket *p_box);
void kpacket_dump(kpacket *p);
void kpacket_test(void);
#ifdef __cplusplus
}
#endif
#endif /*_OS_TYPE_H__ */