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

734 lines
20 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.
****************************************************************************/
#include "iot_module_api.h"
#include "iot_plc_cco_api.h"
#include "iot_errno_api.h"
#include "iot_io_api.h"
#include "iot_pkt_api.h"
#include "iot_utils_api.h"
#include "iot_app_api.h"
#include "iot_app_pib_api.h"
#include "iot_uart_api.h"
#define APP_PIB_DEBUG_ENABLE (0)
static app_pib_rw_t *pib_rw;
/* for record whitelist count */
static uint16_t wl_set_cnt = 0;
/* sync whilelist address count everytime */
#define APP_WL_PIB_SYNC_CNT 100
/* query whilelist address max count everytime */
#define APP_WL_PIB_MAX_CNT 80
app_pib_rw_t *iot_get_rw_pib_info(void)
{
return pib_rw;
}
uint32_t iot_app_whitelist_pib_enable_qr(iot_plc_app_h app_handle,
uint8_t *value)
{
if (pib_rw == NULL || app_handle == NULL) {
return ERR_FAIL;
}
*value = pib_rw->wl_state;
return ERR_OK;
}
void iot_app_whitelist_pib_enable_set(iot_plc_app_h app_handle, uint8_t value)
{
uint16_t ticket;
uint8_t ref;
if (pib_rw == NULL || app_handle == NULL) {
return;
}
if (pib_rw->wl_state == value) {
return;
}
iot_pib_acquire_app_commit_ref(&ref);
pib_rw->wl_state = value;
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
#if PLC_SUPPORT_CCO_ROLE
/**
* @function_name: iot_calc_wl_mac_and_sort.
* @brief : calc the whitelist and sort, remove invalid hole.
**/
static void iot_calc_wl_mac_and_sort(void)
{
uint16_t i;
uint8_t *pib_addr;
uint8_t *mac_addr;
if (pib_rw == NULL) {
return;
}
pib_addr = pib_rw->white_list;
mac_addr = pib_rw->white_list;
/* find invalid mac and move */
for (wl_set_cnt = 0, i = 0; i < IOT_APP_WL_PIB_ADDR_CNT; i++) {
/* find valid mac */
if (iot_mac_addr_valid(mac_addr)) {
if (i != wl_set_cnt) {
iot_mac_addr_cpy(pib_addr, mac_addr);
os_mem_set(mac_addr, 0, IOT_MAC_ADDR_LEN);
}
wl_set_cnt++;
pib_addr += IOT_MAC_ADDR_LEN;
}
mac_addr += IOT_MAC_ADDR_LEN;
}
iot_cus_printf("%s wl_cnt:%d\n", __FUNCTION__, wl_set_cnt);
return;
}
/**
* @function_name: iot_wl_mac_remove.
* @brief : find mac list in whitelist and remove.
* @param[in] mac_addr_array: will be remove mac list
* @param[in] count: remove mac count
* @return failed: -1, success:0.
**/
static int8_t iot_wl_mac_remove(uint8_t *mac_addr_array, uint8_t count)
{
int8_t phase;
uint16_t i, wl_cnt;
uint8_t *pib_addr;
if (pib_rw == NULL || mac_addr_array == NULL) {
return -1;
}
while(count) {
pib_addr = pib_rw->white_list;
wl_cnt = wl_set_cnt;
for (i = 0; i < wl_cnt; i++) {
/* find exist mac */
if (iot_mac_addr_cmp(pib_addr, mac_addr_array)) {
if (i + 1 < wl_cnt) {
os_mem_move(pib_addr, pib_addr + IOT_MAC_ADDR_LEN,
(wl_cnt - i - 1) * IOT_MAC_ADDR_LEN);
}
/* clear last mac */
os_mem_set(pib_rw->white_list + (wl_cnt - 1) * IOT_MAC_ADDR_LEN,
0x00, IOT_MAC_ADDR_LEN);
wl_set_cnt--;
#if APP_PIB_DEBUG_ENABLE
iot_cus_printf("mac_remove i=%d bef_offset(%d %d %d)\n", i,
pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2]);
#endif
for (phase = 0; phase < IOT_APP_CCO_PHASE_OFFSET_CNT; phase++) {
if (i < pib_rw->phase_offset[phase]) {
pib_rw->phase_offset[phase]--;
}
}
#if APP_PIB_DEBUG_ENABLE
iot_cus_printf("mac_remove i=%d aft_offset(%d %d %d)\n", i,
pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2]);
#endif
break;
}
pib_addr += IOT_MAC_ADDR_LEN;
}
count--;
mac_addr_array += IOT_MAC_ADDR_LEN;
}
return 0;
}
void iot_app_whitelist_pib_add(iot_plc_app_h app_handle, uint16_t count,
uint8_t *mac_addr_array, uint8_t phase)
{
uint16_t ticket;
uint8_t ref;
int16_t i;
uint16_t total_cnt = 0;
uint16_t start = 0;
uint16_t mov_cnt;
if (pib_rw == NULL || app_handle == NULL ||
mac_addr_array == NULL || phase > IOT_PLC_PHASE_CNT) {
return;
}
iot_cus_printf("total:%d(%d %d %d) add:%d phase:%d\n",
wl_set_cnt, pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2], count, phase);
iot_pib_acquire_app_commit_ref(&ref);
iot_wl_mac_remove(mac_addr_array, count);
total_cnt = wl_set_cnt;
if (wl_set_cnt + count > IOT_APP_WL_PIB_ADDR_CNT) {
/* calc real add count */
count = IOT_APP_WL_PIB_ADDR_CNT - wl_set_cnt;
iot_cus_printf("add count:%d\n", count);
if (count == 0) {
goto out;
}
}
if (phase == IOT_PLC_PHASE_C) {
start = total_cnt;
} else {
start = pib_rw->phase_offset[phase];
}
mov_cnt = total_cnt - start;
iot_cus_printf("total:%d(%d %d %d) start:%d move:%d cnt:%d\n",
total_cnt, pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2], start, mov_cnt, count);
/* new add */
if (mov_cnt) {
os_mem_move(pib_rw->white_list + (start + count) * IOT_MAC_ADDR_LEN,
pib_rw->white_list + start * IOT_MAC_ADDR_LEN,
mov_cnt * IOT_MAC_ADDR_LEN);
}
os_mem_cpy(pib_rw->white_list + start * IOT_MAC_ADDR_LEN, mac_addr_array,
count * IOT_MAC_ADDR_LEN);
wl_set_cnt += count;
/* update offset value */
for (i = 0; i < IOT_APP_CCO_PHASE_OFFSET_CNT; i++) {
if (i >= phase) {
pib_rw->phase_offset[i] += count;
}
}
iot_cus_printf("%s total:%d(%d %d %d)\n", __FUNCTION__,
wl_set_cnt, pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2]);
out:
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
void iot_app_whitelist_pib_rm(iot_plc_app_h app_handle, uint16_t count,
uint8_t *mac_addr_array)
{
uint16_t ticket;
uint8_t ref;
if (pib_rw == NULL || app_handle == NULL) {
return;
}
iot_pib_acquire_app_commit_ref(&ref);
iot_wl_mac_remove(mac_addr_array, count);
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
uint32_t iot_app_whitelist_pib_sync(iot_plc_app_h app_handle)
{
uint8_t ref;
uint8_t *pib_addr;
uint8_t *rw = NULL;
uint8_t action;
uint16_t cnt = 0;
uint32_t ret = ERR_FAIL;
iot_pib_type_t pibtype = MAX_PIB_TYPE + 1;
uint8_t phase;
uint16_t add_cnt;
BUILD_BUG_ON(sizeof(app_pib_rw_t) <= IOT_PIB_APP_WRITE_SECTION_SIZE);
if (app_handle == NULL) {
return ERR_FAIL;
}
ret = iot_pib_get_app_section(&rw, &pibtype, IOT_PIB_APP_GET_WRITE_SECTION);
if (ret != ERR_OK || pibtype > MAX_PIB_TYPE) {
pib_rw = NULL;
iot_cus_printf("[err]app load pib rw error\n");
IOT_ASSERT(0);
return ERR_FAIL;
}
pib_rw = (app_pib_rw_t *)rw;
if (pib_rw->mark_magic != APP_PIB_RW_MARK_MAGIC) {
iot_cus_printf("app_pib magic err(%X, %X)\n", pib_rw->mark_magic,
APP_PIB_RW_MARK_MAGIC);
iot_pib_acquire_app_commit_ref(&ref);
/* clean pib info include whitelist array, phase offset, band, uart */
os_mem_set(pib_rw, 0, sizeof(app_pib_rw_t));
pib_rw->mark_magic = APP_PIB_RW_MARK_MAGIC;
iot_pib_release_app_commit_ref(&ref);
return ERR_OK;
}
iot_calc_wl_mac_and_sort();
if (wl_set_cnt == 0) {
/* no whitelist mac need set */
goto out;
}
pib_addr = pib_rw->white_list;
iot_cus_printf("total:%d(%d %d %d)\n",
wl_set_cnt, pib_rw->phase_offset[0], pib_rw->phase_offset[1],
pib_rw->phase_offset[2]);
for (phase = 0; phase <= IOT_PLC_PHASE_CNT; phase++) {
switch (phase) {
case 3:
action = IOT_PLC_WL_ADD_PC;
add_cnt = wl_set_cnt - pib_rw->phase_offset[2];
if (pib_rw->phase_offset[2] == 0 && add_cnt > 0) {
/* for adapt old fw */
action = IOT_PLC_WL_ADD;
pib_rw->phase_offset[0] = add_cnt;
pib_rw->phase_offset[1] = add_cnt;
pib_rw->phase_offset[2] = add_cnt;
}
break;
case 2:
action = IOT_PLC_WL_ADD_PB;
add_cnt = pib_rw->phase_offset[2] - pib_rw->phase_offset[1];
break;
case 1:
action = IOT_PLC_WL_ADD_PA;
add_cnt = pib_rw->phase_offset[1] - pib_rw->phase_offset[0];
break;
case 0:
default:
action = IOT_PLC_WL_ADD;
add_cnt = pib_rw->phase_offset[0];
break;
}
iot_cus_printf("%s act:%02X cnt:%d\n", __FUNCTION__, action, add_cnt);
while (add_cnt) {
if (add_cnt >= APP_WL_PIB_SYNC_CNT) {
cnt = APP_WL_PIB_SYNC_CNT;
add_cnt -= APP_WL_PIB_SYNC_CNT;
} else {
cnt = add_cnt;
add_cnt = 0;
}
iot_plc_set_whitelist_ex(app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
action, cnt, pib_addr, 0);
pib_addr += cnt * IOT_MAC_ADDR_LEN;
}
}
out:
if (pib_rw->wl_state) {
iot_plc_set_whitelist_ex(app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ENABLE, 0, NULL, 0);
}
return ERR_OK;
}
#else /* else PLC_SUPPORT_CCO_ROLE */
void iot_app_whitelist_pib_add(iot_plc_app_h app_handle, uint16_t count,
uint8_t *mac_addr_array, uint8_t phase)
{
uint16_t ticket;
uint8_t ref;
uint16_t i, j;
uint8_t *pib_addr, *valid_addr;
if (pib_rw == NULL || app_handle == NULL) {
return;
}
(void)phase;
iot_pib_acquire_app_commit_ref(&ref);
for (i = 0; i < count; i++) {
pib_addr = pib_rw->white_list;
valid_addr = NULL;
for (j = 0; j < IOT_APP_WL_PIB_ADDR_CNT; j++) {
if (iot_mac_addr_valid(mac_addr_array)) {
if (iot_mac_addr_valid(pib_addr)) {
if (iot_mac_addr_cmp(mac_addr_array, pib_addr)) {
valid_addr = NULL;
break;
}
} else {
if (valid_addr == NULL) {
valid_addr = pib_addr;
}
}
} else {
valid_addr = NULL;
break;
}
pib_addr += IOT_MAC_ADDR_LEN;
}
if (valid_addr) {
wl_set_cnt++;
iot_mac_addr_cpy(valid_addr, mac_addr_array);
}
mac_addr_array += IOT_MAC_ADDR_LEN;
}
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
void iot_app_whitelist_pib_rm(iot_plc_app_h app_handle, uint16_t count,
uint8_t *mac_addr_array)
{
uint16_t ticket;
uint8_t ref;
uint16_t i, j;
uint8_t *pib_addr;
if (pib_rw == NULL || app_handle == NULL) {
return;
}
iot_pib_acquire_app_commit_ref(&ref);
for (i = 0; i < count; i++) {
pib_addr = pib_rw->white_list;
for (j = 0; j < IOT_APP_WL_PIB_ADDR_CNT; j++) {
if (iot_mac_addr_cmp(pib_addr, mac_addr_array)) {
os_mem_set(pib_addr, 0x00, IOT_MAC_ADDR_LEN);
wl_set_cnt--;
break;
}
pib_addr += IOT_MAC_ADDR_LEN;
}
mac_addr_array += IOT_MAC_ADDR_LEN;
}
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
uint32_t iot_app_whitelist_pib_sync(iot_plc_app_h app_handle)
{
uint8_t ref;
uint8_t *addr_ptr, *pib_addr;
uint8_t *tmp_buf;
uint8_t *rw = NULL;
uint16_t i, cnt = 0;
uint32_t ret = ERR_FAIL;
iot_pib_type_t pibtype = MAX_PIB_TYPE + 1;
iot_pkt_t *pkt;
BUILD_BUG_ON(sizeof(app_pib_rw_t) <= IOT_PIB_APP_WRITE_SECTION_SIZE);
if (app_handle == NULL) {
return ERR_FAIL;
}
ret = iot_pib_get_app_section(&rw, &pibtype, IOT_PIB_APP_GET_WRITE_SECTION);
if (ret != ERR_OK || pibtype > MAX_PIB_TYPE) {
pib_rw = NULL;
iot_cus_printf("[err]app load pib rw error\n");
IOT_ASSERT(0);
return ERR_FAIL;
}
pib_rw = (app_pib_rw_t *)rw;
if (pib_rw->mark_magic != APP_PIB_RW_MARK_MAGIC) {
iot_cus_printf("app_pib magic err(%X, %X)\n", pib_rw->mark_magic,
APP_PIB_RW_MARK_MAGIC);
iot_pib_acquire_app_commit_ref(&ref);
os_mem_set(pib_rw, 0, sizeof(app_pib_rw_t));
pib_rw->mark_magic = APP_PIB_RW_MARK_MAGIC;
iot_pib_release_app_commit_ref(&ref);
return ERR_OK;
}
pkt = iot_pkt_alloc(APP_WL_PIB_SYNC_CNT * IOT_MAC_ADDR_LEN, IOT_PIB_MID);
IOT_ASSERT(pkt);
tmp_buf = iot_pkt_data(pkt);
addr_ptr = tmp_buf;
pib_addr = pib_rw->white_list;
for (i = 0; i < IOT_APP_WL_PIB_ADDR_CNT; i++) {
if (iot_mac_addr_valid(pib_addr)) {
wl_set_cnt++;
iot_mac_addr_cpy(addr_ptr, pib_addr);
cnt++;
addr_ptr += IOT_MAC_ADDR_LEN;
if (cnt == APP_WL_PIB_SYNC_CNT) {
iot_plc_set_whitelist_ex(app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ADD, cnt, tmp_buf, 0);
cnt = 0;
addr_ptr = tmp_buf;
}
}
pib_addr += IOT_MAC_ADDR_LEN;
}
if (cnt) {
iot_plc_set_whitelist_ex(app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ADD, cnt, tmp_buf, 0);
}
iot_pkt_free(pkt);
if (pib_rw->wl_state) {
iot_plc_set_whitelist_ex(app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ENABLE, 0, NULL, 0);
}
return ERR_OK;
}
#endif /* end PLC_SUPPORT_CCO_ROLE */
void iot_app_whitelist_pib_rm_all(iot_plc_app_h app_handle)
{
uint16_t ticket;
uint8_t ref;
if (pib_rw == NULL || app_handle == NULL) {
return;
}
iot_pib_acquire_app_commit_ref(&ref);
os_mem_set(pib_rw->white_list, 0x00, IOT_APP_WL_ADDR_LEN);
wl_set_cnt = 0;
#if PLC_SUPPORT_CCO_ROLE
os_mem_set(pib_rw->phase_offset, 0,
sizeof(uint16_t) * IOT_APP_CCO_PHASE_OFFSET_CNT);
#endif
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
}
uint16_t iot_app_get_wl_cnt()
{
return wl_set_cnt;
}
static uint16_t iot_app_get_real_wl_by_index(uint16_t index)
{
uint16_t i = 0, j = 0;
uint8_t *addr_ptr;
if (pib_rw == NULL) {
return IOT_APP_WL_PIB_ADDR_CNT + 1;
}
for (i = 1; i <= IOT_APP_WL_PIB_ADDR_CNT; i++) {
addr_ptr = pib_rw->white_list + (i - 1) * IOT_MAC_ADDR_LEN;
if (iot_mac_addr_valid(addr_ptr)) {
j++;
if (j == index) {
return i;
}
}
}
return IOT_APP_WL_PIB_ADDR_CNT + 1;
}
iot_pkt_t *iot_app_get_wl_entry_info(uint32_t start_index, uint32_t count,
uint16_t ex_len)
{
uint32_t buf_len = 0;
iot_pkt_t *pkt = NULL;
iot_app_wl_entry_info_transfer_t *p_node_info;
uint16_t index = 0;
uint16_t wl_cnt = wl_set_cnt;
uint8_t *addr_ptr = NULL;
uint16_t i, real_start;
if (pib_rw == NULL) {
count = 0;
start_index = 1;
}
count = min(count, min(wl_cnt , APP_WL_PIB_MAX_CNT));
if (count + start_index > IOT_APP_WL_PIB_ADDR_CNT) {
count = IOT_APP_WL_PIB_ADDR_CNT - start_index + 1;
}
if (start_index > IOT_APP_WL_PIB_ADDR_CNT) {
count = 0;
}
buf_len = sizeof(iot_app_wl_entry_info_transfer_t);
buf_len += sizeof(iot_app_wl_entry_info_t) * count;
buf_len += ex_len;
pkt = iot_pkt_alloc(buf_len, IOT_PIB_MID);
IOT_ASSERT(pkt);
p_node_info = (iot_app_wl_entry_info_transfer_t*)iot_pkt_reserve(pkt,
ex_len);
p_node_info->total_count = wl_cnt;
p_node_info->count = 0;
iot_pkt_put(pkt, sizeof(iot_app_wl_entry_info_transfer_t));
if (count == 0) {
goto out;
}
real_start = iot_app_get_real_wl_by_index(start_index);
for (i = real_start; (i <= IOT_APP_WL_PIB_ADDR_CNT) && (count != 0); i++) {
addr_ptr = pib_rw->white_list + (i - 1) * IOT_MAC_ADDR_LEN;
if (!iot_mac_addr_valid(addr_ptr)) {
continue;
}
count--;
iot_mac_addr_cpy(p_node_info->info[index].mac_addr, addr_ptr);
index++;
iot_pkt_put(pkt, sizeof(iot_app_wl_entry_info_t));
}
p_node_info->count = index;
out:
return pkt;
}
int16_t iot_app_get_addrs_index_in_wl(uint8_t *mac)
{
uint16_t i = 0;
uint8_t *addr_ptr = NULL;
if (pib_rw == NULL) {
return -1;
}
addr_ptr = pib_rw->white_list;
for (i = 0; i < IOT_APP_WL_PIB_ADDR_CNT; i++) {
if (iot_mac_addr_cmp(mac, addr_ptr)) {
return i;
}
addr_ptr += IOT_MAC_ADDR_LEN;
}
return -1;
}
uint8_t iot_app_get_mac_in_pib(uint8_t *mac)
{
if (pib_rw == NULL || mac == NULL) {
return ERR_FAIL;
}
iot_mac_addr_cpy(mac, pib_rw->local_mac);
return ERR_OK;
}
uint8_t iot_app_save_mac_to_pib(uint8_t *mac)
{
uint16_t ticket;
uint8_t ref;
if (pib_rw == NULL || mac == NULL) {
return ERR_FAIL;
}
if (!iot_mac_addr_valid(mac)) {
return ERR_FAIL;
}
iot_pib_acquire_app_commit_ref(&ref);
iot_mac_addr_cpy(pib_rw->local_mac, mac);
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
return ERR_OK;
}
uint8_t iot_app_get_uart_cfg_in_pib(uart_cfg_t *uart_param)
{
if (pib_rw == NULL || uart_param == NULL) {
return ERR_FAIL;
}
os_mem_cpy(uart_param, &pib_rw->uart_param, sizeof(uart_cfg_t));
return ERR_OK;
}
uint8_t iot_app_save_uart_cfg_to_pib(uart_cfg_t *uart_param)
{
uint16_t ticket;
uint8_t ref;
if (pib_rw == NULL || uart_param->baud_rate == 0) {
return ERR_FAIL;
}
/* check parity valid */
switch (uart_param->parity) {
case IOT_UART_PARITY_NONE:
case IOT_UART_PARITY_ODD:
case IOT_UART_PARITY_EVEN:
case IOT_UART_PARITY_MARK:
case IOT_UART_PARITY_SPACE:
break;
default:
return ERR_FAIL;
}
/* check data bits valid */
switch (uart_param->data_bits) {
case IOT_UART_DLEN_5_BITS:
case IOT_UART_DLEN_6_BITS:
case IOT_UART_DLEN_7_BITS:
case IOT_UART_DLEN_8_BITS:
break;
default:
return ERR_FAIL;
}
/* check stop bits valid */
switch (uart_param->stop_bits) {
case IOT_UART_STOP_1_BITS:
case IOT_UART_STOP_1_5_BITS:
case IOT_UART_STOP_2_BITS:
break;
default:
return ERR_FAIL;
}
if(uart_param->threshold_value < IOT_UART_DEFAULT_THDVALUE){
uart_param->threshold_value = IOT_UART_DEFAULT_THDVALUE;
}
if(uart_param->threshold_value > IOT_UART_MAX_THDVALUE){
uart_param->threshold_value = IOT_UART_MAX_THDVALUE;
}
iot_pib_acquire_app_commit_ref(&ref);
os_mem_cpy(&pib_rw->uart_param, uart_param, sizeof(uart_cfg_t));
pib_rw->uart_param.uart_conf_vaild = 1;
iot_pib_release_app_commit_ref(&ref);
iot_pib_app_commit(&ticket);
return ERR_OK;
}