173 lines
4.6 KiB
C
173 lines
4.6 KiB
C
/*
|
|
* Copyright (c) CompanyNameMagicTag 2019-2020. All rights reserved.
|
|
* Description: MRS meter-reading manage.
|
|
*/
|
|
|
|
#include "mrs_cco_mr_manage.h"
|
|
#include "mrs_common_tools.h"
|
|
#include "mrs_cco_srv.h"
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
|
|
mrs_mr_pool *mrs_cco_mr_pool(td_void);
|
|
|
|
td_void mrs_cco_mr_pool_init(mrs_mr_pool *pool)
|
|
{
|
|
pool->num = 0;
|
|
uapi_list_init(&pool->list);
|
|
}
|
|
|
|
mrs_mr_pool *mrs_cco_mr_pool(td_void)
|
|
{
|
|
mrs_cco_srv_ctx *cco = (mrs_cco_srv_ctx *)mrs_cco_get_srv_ctx();
|
|
if (cco != TD_NULL) {
|
|
return &cco->mr_pool;
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
td_u32 mrs_cco_mr_add_pool_item(mr_task_node *node)
|
|
{
|
|
EXT_LIST *link = TD_NULL;
|
|
mrs_mr_item *item = TD_NULL;
|
|
mrs_mr_pool *pool = mrs_cco_mr_pool();
|
|
if (pool == TD_NULL) {
|
|
return EXT_ERR_NO_INITILIZATION;
|
|
}
|
|
|
|
if (pool->num >= MRS_CFG_PARALLEL_MAX) {
|
|
return EXT_ERR_FULL;
|
|
}
|
|
|
|
link = pool->list.next;
|
|
while (link != &pool->list) {
|
|
mrs_mr_item *temp = (mrs_mr_item *)link;
|
|
if (memcmp(node->dst_addr, temp->node->dst_addr, sizeof(node->dst_addr)) == 0) {
|
|
return EXT_ERR_BUSY;
|
|
}
|
|
|
|
link = link->next;
|
|
}
|
|
|
|
item = (mrs_mr_item *)mrs_malloc(sizeof(mrs_mr_item));
|
|
if (item == TD_NULL) {
|
|
return EXT_ERR_MALLOC_FAILUE;
|
|
}
|
|
|
|
(td_void) memset_s(item, sizeof(mrs_mr_item), 0, sizeof(mrs_mr_item));
|
|
item->node = node;
|
|
item->wait_tx = TD_TRUE;
|
|
uapi_list_tail_insert(&pool->list, &item->link);
|
|
pool->num++;
|
|
|
|
if (pool->num == 1) {
|
|
mrs_timer_start(MRS_TIMER_ID_PARALLEL_CHECK, MRS_PARALLEL_CHECK_INTERVAL, EXT_TIMER_TYPE_PERIOD);
|
|
}
|
|
|
|
return EXT_ERR_SUCCESS;
|
|
}
|
|
|
|
td_void mrs_cco_mr_remove_pool_item(const mr_task_node *node)
|
|
{
|
|
EXT_LIST *link = TD_NULL;
|
|
mrs_mr_pool *pool = mrs_cco_mr_pool();
|
|
if (pool == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
link = pool->list.next;
|
|
while (link != &pool->list) {
|
|
mrs_mr_item *item = (mrs_mr_item *)link;
|
|
link = link->next;
|
|
|
|
if (node != item->node) {
|
|
continue;
|
|
}
|
|
|
|
uapi_list_delete(&item->link);
|
|
pool->num--;
|
|
mrs_free(item);
|
|
return;
|
|
}
|
|
}
|
|
|
|
mrs_mr_item *mrs_cco_mr_find_pool_item(const td_pbyte mac, td_u16 seq, td_u8 type)
|
|
{
|
|
EXT_LIST *link = TD_NULL;
|
|
mrs_mr_pool *pool = mrs_cco_mr_pool();
|
|
if (pool == TD_NULL) {
|
|
return TD_NULL;
|
|
}
|
|
|
|
link = pool->list.next;
|
|
while (link != &pool->list) {
|
|
mrs_mr_item *item = (mrs_mr_item *)link;
|
|
mr_task_node *node = item->node;
|
|
|
|
link = link->next;
|
|
|
|
if ((node->type == type) && (node->plc_seq == seq) &&
|
|
(memcmp(node->plc_frame->addr, mac, EXT_PLC_MAC_ADDR_LEN) == 0)) {
|
|
return item;
|
|
}
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
td_void mrs_parallel_check_on_timer(td_void)
|
|
{
|
|
td_u32 ret = EXT_ERR_SUCCESS;
|
|
mrs_mr_pool *pool = mrs_cco_mr_pool();
|
|
if (pool == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
EXT_LIST *link = pool->list.next;
|
|
while (link != &pool->list) {
|
|
mrs_mr_item *item = (mrs_mr_item *)link;
|
|
link = link->next;
|
|
|
|
if (item->wait_tx == TD_TRUE) {
|
|
item->wait_tx = TD_FALSE;
|
|
if (mrs_plc_frame_send(item->node->plc_frame) != EXT_ERR_SUCCESS) {
|
|
mrs_printf("mrs_parallel_check_on_timer(): send plc frame failed. ret = %d\n", ret);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
item->run_time += MRS_PARALLEL_CHECK_INTERVAL;
|
|
|
|
if (item->run_time < (td_u32)(item->node->timeout) * 100) { /* unit : 100ms */
|
|
continue;
|
|
}
|
|
item->try_times++;
|
|
item->run_time = 0;
|
|
if (item->try_times >= item->node->tx_max) {
|
|
td_pbyte out_buf = TD_NULL;
|
|
td_u16 out_len = 0;
|
|
ret = item->node->create_uart_frame(&out_buf, &out_len, item->node, TD_NULL, 0);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
item->node->send_uart_frame(out_buf, out_len);
|
|
}
|
|
mrs_free(out_buf);
|
|
|
|
mrs_cco_mr_list_remove(item->node);
|
|
uapi_list_delete(&item->link);
|
|
pool->num--;
|
|
mrs_free(item);
|
|
} else if (mrs_plc_frame_send(item->node->plc_frame) != EXT_ERR_SUCCESS) {
|
|
mrs_printf("mrs_parallel_check_on_timer(): send plc frame failed. ret = %d\n", ret);
|
|
}
|
|
}
|
|
|
|
if (pool->num < MRS_CFG_PARALLEL_MAX) {
|
|
mrs_cco_mr_notify();
|
|
}
|
|
|
|
if (pool->num == 0) {
|
|
mrs_timer_stop(MRS_TIMER_ID_PARALLEL_CHECK);
|
|
}
|
|
}
|
|
#endif /* defined(PRODUCT_CFG_PRODUCT_TYPE_CCO) */
|