Files
kunlun/common/utils/iot_utils.c
2024-09-28 14:24:04 +08:00

448 lines
10 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.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_mem.h"
#include "os_utils_api.h"
/* common includes */
#include "iot_utils.h"
#include "iot_errno.h"
#include "iot_utils_api.h"
/* define length of BCD length */
#define IOT_BCD_LEN_MAX 4
uint8_t iot_bcd_data_check(uint8_t *data, uint8_t len)
{
uint8_t i;
for (i = 0; i < len; i++) {
if ((data[i] & 0xF) > 9)
return 0;
if (((data[i] >> 4) & 0xF) > 9)
return 0;
}
return 1;
}
uint8_t iot_bcd_check(uint8_t v)
{
if ((v & 0xF) > 9)
return 0;
if (((v >> 4) & 0xF) > 9)
return 0;
return 1;
}
uint8_t iot_wait_timeout_fun(iot_timeout_func obj_func, \
int arg, int target_value, uint32_t wait_time_ms)
{
uint32_t start_time = 0, end_time = 0;
uint64_t time_span = 0;
int flag;
IOT_ASSERT(obj_func);
start_time = os_boot_time32();
do {
end_time = os_boot_time32();
time_span = end_time - start_time;
/* time out */
if (time_span > wait_time_ms) {
return ERR_TIMEOVER;
}
flag = obj_func(arg);
} while (flag != target_value);
return ERR_OK;
}
uint8_t iot_uint32_to_bcd(uint32_t value, uint8_t bcd_len,
uint8_t *bcd)
{
uint8_t len = 0, i;
uint32_t v_max = 0;
uint32_t mul, div = 0;
for (i = 0, mul = 1; i < bcd_len; i++) {
v_max += 99 * mul;
div = mul;
mul *= 100;
}
if (value > v_max) {
return 0;
}
while (div) {
bcd[len++] = iot_byte_to_bcd((uint8_t)(value / div));
value %= div;
div /= 100;
}
IOT_ASSERT(bcd_len == len);
iot_data_reverse(bcd, len);
return len;
}
uint8_t iot_bcd_to_uint32(uint8_t *bcd, uint8_t bcd_len,
uint8_t flag_big, uint32_t *value)
{
uint8_t len = 0, i;
uint32_t v = 0;
if (bcd_len > IOT_BCD_LEN_MAX || !bcd_len || !bcd) {
goto out;
}
if (flag_big) {
for (i = 0; i < bcd_len; i++) {
if (!iot_bcd_check(bcd[i])) {
goto out;
}
v += iot_bcd_to_byte(bcd[i]);
if (i != (bcd_len - 1)) {
v *= 100;
}
}
} else {
for (i = bcd_len; i != 0; i--) {
if (!iot_bcd_check(bcd[i - 1])) {
goto out;
}
v += iot_bcd_to_byte(bcd[i - 1]);
if ((i - 1) != 0) {
v *= 100;
}
}
}
len = bcd_len;
*value = v;
out:
return len;
}
uint8_t iot_byte_reverse(uint8_t value)
{
static const uint8_t array[16] ={0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06,
0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F};
uint8_t ret = 0;
ret |= (array[value & 0xF]) << 4;
ret |= array[value >> 4];
return ret;
}
void iot_data_reverse(uint8_t *data, uint32_t len)
{
uint32_t i = 0;
uint8_t tmp;
for (; i < (uint32_t)(len / 2); i++) {
tmp = data[i];
data[i] = data[len - 1 - i];
data[len - 1 - i] = tmp;
}
}
uint8_t iot_wait_timeout_fun2(iot_timeout_func2 obj_func, \
void *arg, int target_value, uint32_t wait_time_ms)
{
uint32_t start_time = 0, end_time = 0;
uint64_t time_span = 0;
int flag;
IOT_ASSERT(obj_func);
start_time = os_boot_time32();
do {
end_time = os_boot_time32();
time_span = end_time - start_time;
/* time out */
if (time_span > wait_time_ms) {
return ERR_TIMEOVER;
}
flag = obj_func(arg);
} while (flag != target_value);
return ERR_OK;
}
int iot_atoi(const char *s)
{
uint32_t ret = 0;
uint32_t d;
int neg = 0;
int tmp = 0;
if (*s == '-') {
neg = 1;
s++;
}
while (1) {
d = (*s++) - '0';
if (d > 9) {
break;
}
ret *= 10;
ret += d;
}
tmp = (int)ret;
return neg ? -tmp : tmp;
}
uint8_t iot_atoi_to_uint8(const char *s, uint8_t *value)
{
uint32_t tmp = 0;
if (iot_atoi_to_uint32(s, &tmp) || tmp > 0xff) {
*value = 0;
return ERR_FAIL;
} else {
*value = (uint8_t)tmp;
return ERR_OK;
}
}
uint8_t iot_atoi_to_uint16(const char *s, uint16_t *value)
{
uint32_t tmp = 0;
if (iot_atoi_to_uint32(s, &tmp) || tmp > 0xffff) {
*value = 0;
return ERR_FAIL;
} else {
*value = (uint16_t)tmp;
return ERR_OK;
}
}
uint8_t iot_atoi_to_uint32(const char *s, uint32_t *value)
{
uint8_t flag_valid = 0;
uint32_t ret = 0;
uint32_t d;
while (1) {
if (*s < '0' || *s > '9') {
break;
}
d = *s - '0';
ret *= 10;
ret += d;
s++;
flag_valid = 1;
}
if (flag_valid) {
*value = ret;
return ERR_OK;
} else {
*value = 0;
return ERR_FAIL;
}
}
uint8_t iot_calc_week(uint16_t year, uint8_t mon, uint8_t mday)
{
if (mon < 3) {
year -= 1;
mon += 12;
}
int32_t c = year / 100;
int32_t y = year % 100;
int32_t ans = (c / 4 - 2 * c + y + y / 4 + (26 * (mon + 1)) \
/ 10 + mday - 1) % 7;
if (ans < 0)
ans += 7;
return (uint8_t)ans;
}
void iot_bubble_sort_int32(int32_t *data, uint32_t cnt, uint8_t increase)
{
uint32_t i, j;
int32_t tmp;
uint8_t sw;
/* bubble sort */
for (i = 0; i < cnt - 1; i++) {
for (j = 0; j < cnt - 1 - i; j++) {
sw = 0;
if (increase) {
if (data[j] > data[j + 1]) {
sw = 1;
}
} else {
if (data[j] < data[j + 1]) {
sw = 1;
}
}
if (sw) {
tmp = data[j];
data[j] = data[j + 1];
data[j + 1] = tmp;
}
}
}
}
void iot_bubble_sort_int8(int8_t *data, uint32_t cnt, uint8_t increase)
{
uint32_t i, j;
int8_t tmp;
uint8_t sw;
/* bubble sort */
for (i = 0; i < cnt - 1; i++) {
for (j = 0; j < cnt - 1 - i; j++) {
sw = 0;
if (increase) {
if (data[j] > data[j + 1]) {
sw = 1;
}
} else {
if (data[j] < data[j + 1]) {
sw = 1;
}
}
if (sw) {
tmp = data[j];
data[j] = data[j + 1];
data[j + 1] = tmp;
}
}
}
}
int32_t iot_math_sqrt(int64_t x)
{
int64_t s1, s2;
/* check valid */
if (x < 0) {
return 0;
} else {
s1 = 16000;
}
do {
s2 = s1;
s1 = (s1 + x / s1) >> 1;
} while (IOT_ABS(s1 - s2) > 5);
return (int)s1;
}
void iot_mac_addr_reverse(uint8_t* addr)
{
uint8_t tmp;
tmp = addr[0];
addr[0] = addr[5];
addr[5] = tmp;
tmp = addr[1];
addr[1] = addr[4];
addr[4] = tmp;
tmp = addr[2];
addr[2] = addr[3];
addr[3] = tmp;
}
uint8_t iot_mac_addr_valid(uint8_t* addr)
{
if (!addr) {
return 0;
}
return !!(addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5]);
}
uint8_t iot_mac_addr_range_check(uint8_t *addr, uint8_t *start_addr,
uint8_t *end_addr)
{
uint64_t start_value = iot_mac_addr_uint8_array_to_long_int(start_addr);
uint64_t end_value = iot_mac_addr_uint8_array_to_long_int(end_addr);
uint64_t value = iot_mac_addr_uint8_array_to_long_int(addr);
return (uint8_t)((start_value <= value) && (end_value >= value));
}
uint32_t iot_bytes_to_uint32(uint8_t* data, uint8_t flag_big_endian)
{
uint32_t result = 0;
if (flag_big_endian) {
result = data[3] + (data[2] << 8) + (data[1] << 16) + (data[0] << 24);
} else {
result = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
}
return result;
}
void iot_uint32_to_bytes(uint32_t value, uint8_t *data, uint8_t flag_big_endian)
{
if (flag_big_endian) {
data[3] = value & 0xFF;
data[2] = (value >> 8) & 0xFF;
data[1] = (value >> 16) & 0xFF;
data[0] = (value >> 24) & 0xFF;
} else {
data[0] = value & 0xFF;
data[1] = (value >> 8) & 0xFF;
data[2] = (value >> 16) & 0xFF;
data[3] = (value >> 24) & 0xFF;
}
}
void iot_uint16_to_bytes(uint16_t value, uint8_t *data, uint8_t flag_big_endian)
{
if (flag_big_endian) {
data[1] = value & 0xFF;
data[0] = (value >> 8) & 0xFF;
} else {
data[0] = value & 0xFF;
data[1] = (value >> 8) & 0xFF;
}
}
uint8_t iot_ascii_to_byte(const char value)
{
uint8_t ret = 0;
if(value >= '0' && value <= '9') {
ret = value - '0';
}else if(value >= 'A' && value <= 'F') {
ret = value - 'A' + 0x0A;
}else if(value >= 'a' && value <= 'f') {
ret = value - 'a' + 0x0A;
}
return ret;
}
uint8_t iot_byte_to_ascii(const uint8_t value, uint8_t flag_uppercase)
{
uint8_t ret = 0;
if (value >= 0 && value <= 9) {
ret = value + '0';
} else if (value >= 0x0A && value <= 0x0F) {
if (flag_uppercase) {
ret = value - 0x0A + 'A';
} else {
ret = value - 0x0A + 'a';
}
}
return ret;
}