448 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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;
 | 
						|
} |