#ifndef __IKONKE_COMMON_UTILS_H______________________________
#define __IKONKE_COMMON_UTILS_H______________________________
#include "ikk-module-def.h"


#define U16MERG(h,l)					((((uint16_t)(h)) << 8) | (l))
#define U32MERG(b3,b2,b1,b0)			((((uint32_t)(b3)) << 24) | (((uint32_t)(b2)) << 16) | (((uint32_t)(b1)) << 8) | (b0))
#define	GET_U32_L( x )					(uint32_t)( (x[3]<<24)+(x[2]<<16)+(x[1]<<8)+x[0] )
#define	GET_U32_B( x )					(uint32_t)( (x[0]<<24)+(x[1]<<16)+(x[2]<<8)+x[3] )
#define H3_UINT32(a)            (((a) >> 24) & 0xFF)
#define H2_UINT32(a)            (((a) >> 16) & 0xFF)
#define H1_UINT32(a)            (((a) >> 8) & 0xFF)
#define H0_UINT32(a)            ((a) & 0xFF)

#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)

#define UINT16_HL(a,b)        (((((uint16_t)(a)) << 8)&(0XFF00)) | ((0X00FF)&(b)))
#define UINT32_HL(a,b,c,d)    ( ((((uint32_t)(a)) << 24)&(0XFF000000)) | ((((uint32_t)(b)) << 16)&(0X00FF0000))| \
                                ((((uint32_t)(c)) << 8)&(0X0000FF00)) | ((0X000000FF)&(d)))
#define S_CMP(s1,s2)	(strcmp((s1),(s2)) == 0)
#define M_CMP(m1,m2,n)	(memcmp((m1),(m2),(n)) == 0)

// 子字符串解析
#define STRING_ITEM_NUM_MAX		8
#define STRING_ITEM_SIZE_MAX	48

typedef char (*StrSubItem)[STRING_ITEM_SIZE_MAX];

void SWAP_EUI64(uint8_t *ptr);

bool All_Same_Data(uint8_t *buffer,uint8_t value,uint8_t len);

/*	DESP: Convert OCT string to hex data stream.
	Auth: dingmz_frc.20191018.
*/
int kUtilsStr2Hex(char *octstr, unsigned char *phexout, int max_length );

/*	DESP: Convert hex data to OCT string stream.
	Auth: LMM_frc.20210607.
*/
void kUtilsHex2Str( uint8_t ucChar, uint8_t *pcResult );
#if 0
//typedef struct tag_data_type_info {
//	uint8_t datatype;
//	uint8_t length;
//}DataInfoSt;
//
//#define STATIC_DATA_INFO_DEF	{ 			\
//	{ZCL_DATA_TYPE_DATA8, 			1}, \
//	{ZCL_DATA_TYPE_DATA16, 			2}, \
//	{ZCL_DATA_TYPE_DATA24, 			3}, \
//	{ZCL_DATA_TYPE_DATA32, 			4}, \
//	{ZCL_DATA_TYPE_DATA40, 			5}, \
//	{ZCL_DATA_TYPE_DATA48, 			6}, \
//	{ZCL_DATA_TYPE_DATA56, 			7}, \
//	{ZCL_DATA_TYPE_DATA64, 			8}, \
//	{ZCL_DATA_TYPE_BITMAP16, 		2}, \
//	{ZCL_DATA_TYPE_BITMAP24, 		3}, \
//	{ZCL_DATA_TYPE_BITMAP32, 		4}, \
//	{ZCL_DATA_TYPE_BITMAP48, 		6}, \
//	{ZCL_DATA_TYPE_BITMAP64, 		8}, \
//	{ZCL_DATA_TYPE_BITMAP8, 		1}, \
//	{ZCL_DATA_TYPE_BOOLEAN, 		1}, \
//	{ZCL_DATA_TYPE_UINT8, 			1}, \
//	{ZCL_DATA_TYPE_ENUM16, 			2},	\
//	{ZCL_DATA_TYPE_ENUM8, 			1}, \
//	{ZCL_DATA_TYPE_SINGLE_PREC,		4}, \
//	{ZCL_DATA_TYPE_IEEE_ADDR,		8},	\
//	{ZCL_DATA_TYPE_INT16, 			2}, \
//	{ZCL_DATA_TYPE_UINT16, 			2}, \
//	{ZCL_DATA_TYPE_INT24, 			3}, \
//	{ZCL_DATA_TYPE_UINT24, 			3}, \
//	{ZCL_DATA_TYPE_UINT32, 			4}, \
//	{ZCL_DATA_TYPE_UINT32, 			4}, \
//	{ZCL_DATA_TYPE_INT48, 			6}, \
//	{ZCL_DATA_TYPE_INT56, 			7}, \
//	{ZCL_DATA_TYPE_INT8, 			1},	\
//	{ZCL_DATA_TYPE_UINT8, 			1}, \
//	{ZCL_DATA_TYPE_128_BIT_SEC_KEY, 16},\
//	{ZCL_DATA_TYPE_UTC, 			4},	\
//	{ZCL_DATA_TYPE_DATE, 			4},	\
//	{ZCL_DATA_TYPE_CLUSTER_ID, 		2},	\
//	{ZCL_DATA_TYPE_ATTR_ID, 		2},	\
//	{ZCL_DATA_TYPE_BAC_OID, 		4},	\
//}

#define GLOBAL_BUFFER_SIZE 	256

extern uint8_t g_u8GlobalBufferN1[];
extern uint8_t g_u8GlobalBufferN2[];
extern uint8_t g_u8GlobalLengthN1;
extern uint8_t g_u8GlobalLengthN2;

/*	DESP: 64bits大小端转换.
	Auth: dingmz_frc.20180627.
*/
extern uint64_t __CPU_ENDIAN_HTONLL__(uint64_t u64_host );
// 转换字节序
#define NT16(nv)	((unsigned short)(((nv) << 8) | ((nv) >> 8)))
#define NT32(nv)	((unsigned int)((NT16((nv) & 0xffff) << 16) | (NT16((nv) >> 16))))
#define NT64(nv)	__CPU_ENDIAN_HTONLL__(nv)


void NWK_AddRssi(uint16_t node_id, int8_t rssi);
bool NWK_DeleteRssiByNodeid(uint16_t node_id);
bool getEndDeviceRssiByNodeid(uint16_t node_id, int8_t *rssi, uint8_t *index);

/*	DESP: Gets the byte length of the specified data type.
 * 	Auth: dingmz_frc.20191025.
 * */
uint8_t kUtilsGetDataLength(uint8_t type );
/*	DESP: check whether the data set content is specified byte data!
 * 	Auth: dingmz_frc.20190520.
 * */
bool kUtilsCheckDataSetContext(void *data_set, uint8_t spec_v, int length );
/*	DESP: get the crc16 value of specific InstallCode.
 * 	Auth: dingmz_frc.20191007.
 * */
uint16_t kUtilsInstallCodeX25CRC16(uint8_t* u8InstallCode, uint8_t length );
/*	DESP: CRC16 algorithm.
 * 	Auth: dingmz_frc.20191018.
 * */
uint16_t kUtilsCRC16Sum(const unsigned char *msg, unsigned int length );
/*	DESP: 消息格式解析 - 字符串分段解析成子串.
	Auth: dingmz_frc.20180607.
*/
int	kUtilsStringSplit(char *string, char (*item)[STRING_ITEM_SIZE_MAX], char spec/*分隔符*/);

/*	DESP: Check whether the given string is a number.
 * 	Auth: dingmz_frc.20191023.
 * */
bool kUtilsIsNumber(char *string );
/*	DESP: Check whether the given string is OCT string.
 * 	Auth: dingmz_frc.20191023.
 * */
bool kUtilsIsOct(char *string );
/*	DESP: Gets the value[in 64-bits] of the specified length from the specified OCT string.
 * 	Note: expected output value max 64bits, so max length input is 16!!!
	Auth: dingmz_frc.20191018.
*/
uint64_t kUtilsOct2Value(char *oct, int length/* ≤ 16 */ );

/*	DESP: High precision random interface，value in[minNum, maxNum].
	Auth: dingmz_frc.20190701.
*/
uint32_t kUtilsGetRandNum(uint32_t minNum, uint32_t maxNum );
/*	DESP: Reverse uint8 array contents.
 * 	PARAM[bModifyOriginalData]: Note that this interface modifies the original data content When bModifyOriginalData is true!!!
	Auth: dingmz_frc.20191019.
*/
uint8_t *kUtilsReverseArrayU8int(uint8_t *org_data, int length, bool bModifyOriginalData );
/*	DESP: Check if it is a valid IEEE address.
 * 	Auth: dingmz_frc.20191106.
 * */
bool kUtilsIsValidEui64Addr(EmberEUI64 ineui64addr );

/*	DESP: 对一个buffer数据进行排序去除最大的和最小的滤波个数取平均值
	filter_num 滤波最大和最小的个数， 相等的
 * 	Auth: maozj.20191123.
 * */
uint32_t kUtilsGetAverage(uint32_t *buf, uint8_t len, uint8_t filter_num); //计算平均值

/*	DESP: Get the first endpoint containing the specified cluster with mask.
	Auth: dingmz_frc.20191024.
*/
uint8_t kCmdGetEndpointByCluserID(uint16_t cluster_id, uint8_t mask );
/*	Partition the filename.
	Auth: dingmz_frc.20180620.
*/
char *__FNAME__(char *dname);

/*	DESP: RewriteCustomMac
	Auth:
*/
uint32_t kRewriteCustomMacAddr(EmberEUI64 *eui64);
/*	DESP: ReadCustomMac
	Auth:
*/
void ReadCustomMacAddr(EmberEUI64 *eui64);
/*	DESP: SWAP_EUI64
	Auth:
*/
void SWAP_EUI64(uint8_t *ptr);
/*	DESP: Get the Data_Code.
	Auth: dingmz_frc.20191024.
*/
uint32_t Get_Date_Code( int8u * pData, int8u *pStr );
#endif
#endif
