Files
kunlun/export/inc/utils/iot_utils_api.h
2024-09-28 14:24:04 +08:00

511 lines
15 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef IOT_UTILS_API_H
#define IOT_UTILS_API_H
/* os shim includes */
#include "os_types_api.h"
#include "os_mem_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup MISC_APIs MISC APIs
* @brief MISC APIs
*
*
*/
/** @addtogroup MISC_APIs
* @{
*
*/
#if !defined(max)
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if !defined(min)
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define IOT_ABS(x) ((x) > 0 ? (x) : -(x))
#define IOT_ARRAY_CNT(a) (sizeof(a) / sizeof(a[0]))
/* used for ceil if the numerator and denumerator is int */
#define iot_ceil(numerator, denumerator) \
(((numerator) + ((denumerator) - 1)) / (denumerator))
/**
* @brief BUILD_BUG_ON() - raise build error if the condition is not true.
* this macro is useful for checks in compilation time.
* @param condition: verify condition
*/
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - (2 * (!(condition)))]))
/**
* @brief container_of() - cast a member of a structure to the containing
* structure.
* @param ptr: the pointer to the member
* @param type: the type of the container struct this is embedded in
* @param member: the name of the member within the struct
*/
#define container_of(ptr, type, member) ( \
(type *)((uint8_t *)ptr - ((size_t) &((type *)0)->member)))
/* mac address length */
#define IOT_MAC_ADDR_LEN 6
/* ip4 address length */
#define IOT_IP4_ADDR_LEN 4
/* meter address length */
#define IOT_METER_ADDR_LEN 12
/* maximum value of BCD codes */
#define IOT_MAC_BCD_MAX 0x99
/* broadcast mac address for downlink proxy broadcast */
extern const uint8_t bcast_mac[];
/**
* @brief iot_mac_addr_uint8_array_to_long_int() - transform mac address
* uint8_t[6] to a long long int.
* @param mac_addr: the uint8_t[6] mac address
*/
#define iot_mac_addr_uint8_array_to_long_int(mac_addr) \
((uint64_t)mac_addr[0] << (40) | \
(uint64_t)mac_addr[1] << (32) | \
(uint64_t)mac_addr[2] << (24) | \
(uint64_t)mac_addr[3] << (16) | \
(uint64_t)mac_addr[4] << (8) | \
(uint64_t)mac_addr[5] << (0))
/**
* @brief iot_uint64_to_mac_addr() - transform a long long int to mac address
* uint8_t[6].
* @param int64val: the long int mac address
* @param mac_addr: the uint8_t[6] mac address
*/
#define iot_uint64_to_mac_addr(int64val, mac_addr) \
{ \
mac_addr[0] = (((uint64_t)int64val) >> 40) & 0xFF; \
mac_addr[1] = (((uint64_t)int64val) >> 32) & 0xFF; \
mac_addr[2] = (((uint64_t)int64val) >> 24) & 0xFF; \
mac_addr[3] = (((uint64_t)int64val) >> 16) & 0xFF; \
mac_addr[4] = (((uint64_t)int64val) >> 8) & 0xFF; \
mac_addr[5] = (((uint64_t)int64val) >> 0) & 0xFF; \
}
/* get lower 32bit value of an unsigned long long */
#define iot_uint64_lower32(int64val) ((uint32_t)((int64val) & 0xFFFFFFFF))
/* get higer 32bit value of an unsigned long long */
#define iot_uint64_higher32(int64val) ((uint32_t)((int64val) >> 32))
/**
* calculate memory size for an aligned buffer - returns the next highest
* multiple of alignment. alignment must be a multiple of 2.
* (e.g. IOT_MEM_ALIGN_SIZE(3, 4) and IOT_MEM_ALIGN_SIZE(4, 4) will both
* yield 4 for align == 4).
*/
#define IOT_MEM_ALIGN_SIZE(size, align) (((size) + align - 1U) & ~(align - 1U))
/** Calculate safe memory size for an aligned buffer when using an unaligned
* type as storage. This includes a safety-margin on (align - 1) at the
* start (e.g. if buffer is uint8_t[] and actual data will be uint32_t*)
* alignment must be a multiple of 2.
*/
#define IOT_MEM_ALIGN_BUFFER(size, align) (((size) + align - 1U))
/**
* align a memory pointer to the alignment defined by align so that
* (ADDR % ALIGN == 0). alignment must be a multiple of 2.
*/
#define IOT_MEM_ALIGN(addr, align) ((void *)(((uint32_t)(addr) + align - 1) \
& ~(uint32_t)(align - 1)))
#define iot_counter_inc(__cnt) \
do { \
(__cnt)++; \
if ((__cnt) == 0) \
(__cnt)--; \
} while (0)
/**
* @brief iot_mac_addr_cpy() - copy mac address
* @param dst: pointer to destination mac address
* @param src: pointer to source mac address
*/
static inline void iot_mac_addr_cpy(uint8_t* dst, uint8_t* src)
{
os_mem_cpy(dst, src, IOT_MAC_ADDR_LEN);
}
/**
* @brief iot_meter_addr_cpy() - copy meter address
* @param dst: pointer to destination meter address
* @param src: pointer to source meter address
*/
static inline void iot_meter_addr_cpy(uint8_t* dst, uint8_t* src)
{
os_mem_cpy(dst, src, IOT_METER_ADDR_LEN);
}
/**
* @brief iot_mac_addr_cmp() - mac address compare
* @param dst: pointer to first mac address to compare
* @param src: pointer to second mac address to compare
*
* @return 1 -- if mac address is the same
* @return 0 -- otherwise
*/
static inline uint8_t iot_mac_addr_cmp(const uint8_t* dst, const uint8_t* src)
{
return os_mem_cmp(dst, src, IOT_MAC_ADDR_LEN) == 0 ? 1 : 0;
}
/**
* @brief iot_ip4_addr_cmp() - ip4 address compare
* @param dst: pointer to first ip4 address to compare
* @param src: pointer to second ip4 address to compare
*
* @return 1 -- if ip4 address is the same
* @return 0 -- otherwise
*/
static inline uint8_t iot_ip4_addr_cmp(const uint8_t* dst, const uint8_t* src)
{
return os_mem_cmp(dst, src, IOT_IP4_ADDR_LEN) == 0 ? 1 : 0;
}
/**
* @brief iot_meter_addr_cmp() - meter address compare
* @param dst: pointer to first meter address to compare
* @param src: pointer to second meter address to compare
*
* @return 1 -- if meter address is the same
* @return 0 -- otherwise
*/
static inline uint8_t iot_meter_addr_cmp(const uint8_t* dst,
const uint8_t* src)
{
return os_mem_cmp(dst, src, IOT_METER_ADDR_LEN) == 0 ? 1 : 0;
}
/**
* @brief iot_mac_is_bcast() - check if a mac is broadcast mac
* @param dst: the mac address to be checked
*
* @return 1 -- is broadcast mac
* @return 0 -- NOT a broadcast mac
*/
static inline uint8_t iot_mac_is_bcast(const uint8_t* dst)
{
return iot_mac_addr_cmp(dst, bcast_mac);
}
/**
* @brief iot_set_bcast_mac() - set the dest mac as bcast addr
* @param mac: the dest mac to be filled with bcast addr
*/
static inline void iot_set_bcast_mac(uint8_t *mac)
{
iot_mac_addr_cpy(mac, (uint8_t*)bcast_mac);
}
/**
* @brief iot_mac_addr_reverse() - reverse the mac address sequence
* @param addr: pointer to mac address to be reversed
*/
void iot_mac_addr_reverse(uint8_t* addr);
/**
* @brief iot_mac_addr_valid() - check if mac address is valid
* @param addr: pointer to mac address to be checked
*
* @return 1 -- if mac address is valid
* @return 0 -- otherwise
*/
uint8_t iot_mac_addr_valid(uint8_t* addr);
/**
* @brief iot_mac_addr_range_check() - check the addr in start address - end
address.
* @param addr: the address that need to check.
* @param start_addr: start address
* @param end_addr: end address
*
* @return 1 -- start_addr <= addr <= end_addr.
* @return 0 -- otherwise
*/
uint8_t iot_mac_addr_range_check(uint8_t *addr, uint8_t *start_addr,
uint8_t *end_addr);
/**
* @brief iot_meter_addr_valid() - check if meter address is valid
* @param addr: pointer to meter address to be checked
*
* @return 1 -- if meter address is valid
* @return 0 -- otherwise
*/
static inline uint8_t iot_meter_addr_valid(uint8_t* addr)
{
if (!addr) {
return 0;
}
return !!(addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5] ||
addr[6] || addr[7] || addr[8] || addr[9] || addr[10] || addr[11]);
}
/* iot_bytes_to_uint32() - parse byte stream to get a uint32_t value
* @data: data stream
* @flag_big_endian: flag of big endian. 1 mean data is big endian.
* return:
* the value from byte stream
*/
uint32_t iot_bytes_to_uint32(uint8_t* data, uint8_t flag_big_endian);
/* iot_bytes_to_uint16() - parse byte stream to get a uint32_t value
* @data: data stream
* @flag_big_endian: flag of big endian. 1 mean data is big endian.
* return:
* the value from byte stream
*/
static inline uint16_t iot_bytes_to_uint16(uint8_t* data,
uint8_t flag_big_endian)
{
uint16_t result = 0;
if (flag_big_endian) {
result = data[1] + (data[0] << 8);
} else {
result = data[0] + (data[1] << 8);
}
return result;
}
/* iot_uint32_to_bytes - convert uint32_t value to byte stream
* @value: the uint32_t value to be converted to byte stream
* @data: pointer to the buffer containing the output byte stream
* @flag_big_endian: flag of big endian. 1 mean data is big endian.
*/
void iot_uint32_to_bytes(uint32_t value, uint8_t *data,
uint8_t flag_big_endian);
/* iot_uint16_to_bytes - convert uint32_t value to byte stream
* @value: the uint16_t value to be converted to byte stream
* @data: pointer to the buffer containing the output byte stream
* @flag_big_endian: flag of big endian. 1 mean data is big endian.
*/
void iot_uint16_to_bytes(uint16_t value, uint8_t *data,
uint8_t flag_big_endian);
/* iot_bcd_to_byte - convert BCD code to byte
* @value: the BCD value to be converted to byte
* @return: the byte value
*/
static inline uint8_t iot_bcd_to_byte(uint8_t value)
{
return (value >> 4) * 10 + (value & 0x0F);
}
/* iot_byte_to_bcd - convert byte to BCD code
* @value: the byte to be converted to BCD code
* @return: the BCD code
*/
static inline uint8_t iot_byte_to_bcd(uint8_t value)
{
return ((value / 10) << 4) + (value % 10);
}
/*
* @brief iot_float_ceil() - float ceil.
* @param f: - float value.
* @return uint32_t: - float ceil uint32_t
*/
static inline uint32_t iot_float_ceil(float f)
{
if (f - (uint32_t)(f) > 0) {
return (uint32_t)f + 1;
} else {
return (uint32_t)f;
}
}
/**
* @brief iot_float_round_int32() - float round to int32_t.
* @param f: float value.
* @return int32_t: float round to int32_t
*/
static inline int32_t iot_float_round_int32(float f)
{
if (f < 0)
return (int32_t)(f - 0.5);
else
return (int32_t)(f + 0.5);
}
/**
* @brief: iot_uint32_to_bcd - convert a uint32 number to bcd buffer
* @param value: the value to be converted
* @param bcd_len: bcd buffer len
* @param bcd: bcd buffer to receive the result
* @return: the actual valid len in bcd buffer
*/
uint8_t iot_uint32_to_bcd(uint32_t value, uint8_t bcd_len,
uint8_t *bcd);
/**
* @brief: iot_bcd_to_uint32 - convert bcd buffer to a uint32 number
* @param bcd: bcd buffer to be converted
* @param bcd_len: bcd buffer len, max length is 4 byte.
* @param flag_big:flag of bcd buffer edition. 1 mean big edition.
* @param value: the value to receive the result
* @return: the actual valid len in bcd buffer
*/
uint8_t iot_bcd_to_uint32(uint8_t *bcd, uint8_t bcd_len,
uint8_t flag_big, uint32_t *value);
/**
* @brief: iot_byte_reverse - convert a byte between MSB to LSB
* @param value: the byte to be converted
* @return: the byte after converted
*/
uint8_t iot_byte_reverse(uint8_t value);
/**
* @brief iot_bcd_data_check() - check if bcd data is valid
* @param data: pointer to bcd data to be checked
* @param len: length of bcd data
* @return 1 -- if bcd data is valid
* @return 0 -- otherwise
*/
uint8_t iot_bcd_data_check(uint8_t *data, uint8_t len);
/**
* @brief iot_bcd_check() - whether bytes are BCD code
* @param v: value to be checked
* @return 1 -- bytes is BCD code
* @return 0 -- otherwise
*/
uint8_t iot_bcd_check(uint8_t v);
/**
* @brief: iot_data_reverse - convert data sequence
* @param data: the data to be converted
* @param data: the data length. unit is 1 byte
*/
void iot_data_reverse(uint8_t *data, uint32_t len);
/**
* @brief iot_atoi() - alphanumeric to integer.
* @s: The string to be convert.
* @return: convert integer value.
*/
int iot_atoi(const char *s);
/**
* @brief iot_atoi_to_uint8() - alphanumeric to uint8 data.
* @param s: The string to be convert.
* @param value: convert uint8 value.
* @retval ERR_OK: handle success.
* @retval ERR_FAIL: handle false.
*/
uint8_t iot_atoi_to_uint8(const char *s, uint8_t *value);
/**
* @brief iot_atoi_to_uint16() - alphanumeric to uint16 data.
* @param s: The string to be convert.
* @param value: convert uint16 value.
* @retval ERR_OK: handle success.
* @retval ERR_FAIL: handle false.
*/
uint8_t iot_atoi_to_uint16(const char *s, uint16_t *value);
/**
* @brief iot_atoi_to_uint32() - alphanumeric to uint32 data.
* @param s: The string to be convert.
* @param value: convert uint32 value.
* @retval ERR_OK: handle success.
* @retval ERR_FAIL: handle false.
*/
uint8_t iot_atoi_to_uint32(const char *s, uint32_t *value);
/**
* @brief iot_calc_week() - calculate weekday
* @param year: year of the date, like 2008, 2019 ...
* @param mon : month of the date
* @param mday: day of the date
* @return : weekday from 0 to 6. 0 - sunday, 6 - saturday.
*/
uint8_t iot_calc_week(uint16_t year, uint8_t mon, uint8_t mday);
/*
* @brief iot_bubble_sort_int32() - bubble sort of the array.
* @param data: continuous data array
* @param cnt: array size
* @param increase: 1 means sort from small to large, 0 means sort from large
* small.
*/
void iot_bubble_sort_int32(int32_t *data, uint32_t cnt, uint8_t increase);
/*
* @brief iot_bubble_sort_int8() - bubble sort of the array.
* @param data: continuous data array
* @param cnt: array size
* @param increase: 1 means sort from small to large, 0 means sort from large
* small.
*/
void iot_bubble_sort_int8(int8_t *data, uint32_t cnt, uint8_t increase);
/*
* @brief iot_math_sqrt() - square root.
* @param data: value to be calculated
* @return: result of square root
*/
int32_t iot_math_sqrt(int64_t x);
/*
* @brief iot_ascii_to_byte() - ascii to byte.
* @param value: ascii code value
* @return: byte value
*/
uint8_t iot_ascii_to_byte(const char value);
/*
* @brief iot_byte_to_ascii() - byte to ascii.
* @param value: byte value
* @param flag_uppercase: 1 means byte to uppercase ascii code value,
* 0 means byte to lowercase ascii code value.
* @return: ascii code value
*/
uint8_t iot_byte_to_ascii(const uint8_t value, uint8_t flag_uppercase);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* IOT_UTILS_API_H */