inwudriver-weibo/app/mrs/cco/mrs_cco_queue.c

155 lines
3.7 KiB
C
Raw Permalink Normal View History

/*
* Copyright (c) CompanyNameMagicTag 2019-2020. All rights reserved.
* Description: MRS CCO queue.
*/
#include "mrs_cco_queue.h"
#include "mrs_msg.h"
#include "mrs_common_tools.h"
#include "mrs_common_uart.h"
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
mrs_cco_queue g_cco_queue;
td_void mrs_cco_queue_init(td_void)
{
mrs_queue_init(&g_cco_queue.queue);
}
mrs_cco_queue *mrs_get_cco_queue(td_void)
{
return &g_cco_queue;
}
td_u8 mrs_cco_queue_get_fsm(td_void)
{
mrs_cco_queue *q = mrs_get_cco_queue();
return q->fsm;
}
td_void mrs_cco_queue_set_fsm(td_u8 fsm)
{
mrs_cco_queue *q = mrs_get_cco_queue();
q->fsm = fsm;
}
td_void mrs_cco_queue_enqueue(mrs_cco_queue_item *item)
{
mrs_cco_queue *q = mrs_get_cco_queue();
mrs_queue_enqueue(&q->queue, &item->link);
q->num++;
}
td_void mrs_cco_queue_set_item_invalid(td_u8 afn, td_u8 fn)
{
mrs_cco_queue *q = mrs_get_cco_queue();
mrs_cco_queue_item *item = (mrs_cco_queue_item *)mrs_queue_top(&q->queue);
mrs_queue_node *it;
if (item == TD_NULL) {
mrs_unlock(q->lock);
return;
}
if ((item->afn == afn) && (item->fn == fn)) {
mrs_timer_stop(MRS_TIMER_ID_CCO_TO_HOST);
mrs_cco_queue_end(q);
}
for (it = q->queue.head; it != TD_NULL; it = it->next) {
item = (mrs_cco_queue_item *)it;
if ((item->afn == afn) && (item->fn == fn)) {
item->valid = TD_FALSE;
}
}
}
td_void mrs_cco_queue_end(mrs_cco_queue *q)
{
mrs_cco_queue_item *item = TD_NULL;
mrs_unlock(q->lock);
/* reset status of queue */
mrs_cco_queue_set_fsm(FSM_CCO_QUEUE_IDLE);
item = (mrs_cco_queue_item *)mrs_queue_dequeue(&q->queue);
mrs_free(item);
q->num--;
q->retry = 0;
mrs_cco_queue_active();
}
td_void mrs_msg_on_queue_notify(EXT_CONST mrs_queue_msg *msg)
{
mrs_cco_queue *q = mrs_get_cco_queue();
mrs_cco_queue_item *item = TD_NULL;
ext_unref_param(msg);
if (mrs_try_lock(q->lock) == 0) {
return;
}
item = (mrs_cco_queue_item *)mrs_queue_top(&q->queue);
if (item == TD_NULL) {
mrs_unlock(q->lock);
return;
}
if (item->valid != TD_TRUE) {
/* remove invalid element */
mrs_cco_queue_end(q);
return;
}
q->retry = 0;
mrs_uart_tx(item->data, item->data_len);
/* update status, wait for response */
mrs_cco_queue_set_fsm(FSM_CCO_QUEUE_WAIT_ACK);
mrs_timer_start(MRS_TIMER_ID_CCO_TO_HOST, item->timeout, EXT_TIMER_TYPE_ONCE);
}
td_void mrs_cco_queue_on_timer(td_void)
{
mrs_cco_queue *q = mrs_get_cco_queue();
mrs_cco_queue_item *item = TD_NULL;
mrs_cco_queue_item *temp = TD_NULL;
item = (mrs_cco_queue_item *)mrs_queue_top(&q->queue);
if (item == TD_NULL) {
mrs_unlock(q->lock);
return;
}
if (q->retry < item->retry_max) {
if (item->single_timeout != TD_NULL) {
if (item->single_timeout(item->param) != EXT_ERR_CONTINUE) {
mrs_cco_queue_end(q);
return;
}
}
q->retry++;
mrs_uart_tx(item->data, item->data_len);
mrs_cco_queue_set_fsm(FSM_CCO_QUEUE_WAIT_ACK);
mrs_timer_start(MRS_TIMER_ID_CCO_TO_HOST, item->timeout, EXT_TIMER_TYPE_ONCE);
return;
}
if (item->total_timeout != TD_NULL) {
item->total_timeout(item->param);
}
temp = (mrs_cco_queue_item *)mrs_queue_top(&q->queue);
if (temp == item) {
mrs_cco_queue_end(q);
}
}
#endif /* defined(PRODUCT_CFG_PRODUCT_TYPE_CCO) */