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;
 | |
| } |