210 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			210 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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_task.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* common includes */
							 | 
						||
| 
								 | 
							
								#include "iot_mem_pool.h"
							 | 
						||
| 
								 | 
							
								#include "iot_module.h"
							 | 
						||
| 
								 | 
							
								#include "iot_task_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* mac module internal includes */
							 | 
						||
| 
								 | 
							
								#include "mac.h"
							 | 
						||
| 
								 | 
							
								#include "mac_msg.h"
							 | 
						||
| 
								 | 
							
								#include "mac_task.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* define MAC layer message pool size */
							 | 
						||
| 
								 | 
							
								#define MAC_MSG_POOL_SIZE           128
							 | 
						||
| 
								 | 
							
								/* define MAC layer message pool size */
							 | 
						||
| 
								 | 
							
								#define MAC_MSG_SYNC_POOL_SIZE      4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _mac_msg_check_param {
							 | 
						||
| 
								 | 
							
								    iot_msg_entry_t *head;
							 | 
						||
| 
								 | 
							
								    uint16_t type;
							 | 
						||
| 
								 | 
							
								    uint16_t id;
							 | 
						||
| 
								 | 
							
								} mac_msg_check_param_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_init_msg_pool()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i, j;
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    mac_msg_sync_t *msg[MAC_MSG_SYNC_POOL_SIZE];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* allocate messages pool */
							 | 
						||
| 
								 | 
							
								    ret = iot_mem_pool_new(PLC_MAC_COMMON_MID, MAC_MSG_POOL_SIZE,
							 | 
						||
| 
								 | 
							
								        sizeof(mac_msg_t), &p_mac_glb->msg_p, 1);
							 | 
						||
| 
								 | 
							
								    if (ret)
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* allocate sync messages pool */
							 | 
						||
| 
								 | 
							
								    ret = iot_mem_pool_new(PLC_MAC_COMMON_MID, MAC_MSG_SYNC_POOL_SIZE,
							 | 
						||
| 
								 | 
							
								        sizeof(mac_msg_sync_t), &p_mac_glb->msg_sync_p, 1);
							 | 
						||
| 
								 | 
							
								    if (ret)
							 | 
						||
| 
								 | 
							
								        goto err_sync;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* init sync messages event */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
							 | 
						||
| 
								 | 
							
								        msg[i] = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
							 | 
						||
| 
								 | 
							
								        msg[i]->event = os_create_event(PLC_MAC_COMMON_MID, false);
							 | 
						||
| 
								 | 
							
								        if (msg[i]->event == NULL) {
							 | 
						||
| 
								 | 
							
								            for (j = 0; j < i; j++) {
							 | 
						||
| 
								 | 
							
								                os_delete_event(msg[j]->event);
							 | 
						||
| 
								 | 
							
								                msg[j]->event = NULL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            goto err_event;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_free(p_mac_glb->msg_sync_p, msg[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								err_event:
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_destroy(p_mac_glb->msg_sync_p);
							 | 
						||
| 
								 | 
							
								    p_mac_glb->msg_sync_p = NULL;
							 | 
						||
| 
								 | 
							
								err_sync:
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_destroy(p_mac_glb->msg_p);
							 | 
						||
| 
								 | 
							
								    p_mac_glb->msg_p = NULL;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_deinit_msg_pool()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i;
							 | 
						||
| 
								 | 
							
								    mac_msg_sync_t *msg[MAC_MSG_SYNC_POOL_SIZE];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_mac_glb->msg_p) {
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_destroy(p_mac_glb->msg_p);
							 | 
						||
| 
								 | 
							
								        p_mac_glb->msg_p = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_mac_glb->msg_sync_p) {
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
							 | 
						||
| 
								 | 
							
								            msg[i] = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
							 | 
						||
| 
								 | 
							
								            os_delete_event(msg[i]->event);
							 | 
						||
| 
								 | 
							
								            msg[i]->event = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
							 | 
						||
| 
								 | 
							
								            iot_mem_pool_free(p_mac_glb->msg_sync_p, msg[i]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_destroy(p_mac_glb->msg_sync_p);
							 | 
						||
| 
								 | 
							
								        p_mac_glb->msg_sync_p = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mac_msg_t *mac_alloc_msg()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_msg_t *msg = iot_mem_pool_alloc(p_mac_glb->msg_p);
							 | 
						||
| 
								 | 
							
								    if (msg) {
							 | 
						||
| 
								 | 
							
								        iot_msg_entry_init(&msg->link);
							 | 
						||
| 
								 | 
							
								        msg->sync = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return msg;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_free_msg(mac_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_free(p_mac_glb->msg_p, msg);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief :          check msg is matched with param type, if msg is matched, it
							 | 
						||
| 
								 | 
							
								 *                   will be pushed in param queue
							 | 
						||
| 
								 | 
							
								 * @param msg :      message entry to be checked
							 | 
						||
| 
								 | 
							
								 * @param param :    assigned message type and message id to match
							 | 
						||
| 
								 | 
							
								 * @return :         if check msg is macthed return true, else return false
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint32_t mac_msg_check(iot_msg_entry_t *msg, void* param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_msg_t *mac_msg;
							 | 
						||
| 
								 | 
							
								    mac_msg_check_param_t *check;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    check = (mac_msg_check_param_t *)param;
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(check);
							 | 
						||
| 
								 | 
							
								    mac_msg = container_of(msg, mac_msg_t, link);
							 | 
						||
| 
								 | 
							
								    if (mac_msg->type == check->type
							 | 
						||
| 
								 | 
							
								        && (check->id == MAC_MSG_ID_ALL || mac_msg->id == check->id)) {
							 | 
						||
| 
								 | 
							
								        msg->next = check->head;
							 | 
						||
| 
								 | 
							
								        check->head = msg;
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_clean_msg(uint8_t msg_type, uint16_t msg_id)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i;
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_t *pq;
							 | 
						||
| 
								 | 
							
								    iot_msg_entry_t *msg, *next_msg;
							 | 
						||
| 
								 | 
							
								    mac_msg_t *mac_msg;
							 | 
						||
| 
								 | 
							
								    mac_msg_check_param_t param;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    param.head = NULL;
							 | 
						||
| 
								 | 
							
								    param.type = msg_type;
							 | 
						||
| 
								 | 
							
								    param.id = msg_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* move out assigned message from the message queue */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++) {
							 | 
						||
| 
								 | 
							
								        pq = &p_mac_glb->msg_q[i].q;
							 | 
						||
| 
								 | 
							
								        iot_msg_queue_loop(pq, mac_msg_check, ¶m);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* clean the assigned message queue */
							 | 
						||
| 
								 | 
							
								    for (msg = param.head; msg != NULL; msg = next_msg) {
							 | 
						||
| 
								 | 
							
								        next_msg = msg->next;
							 | 
						||
| 
								 | 
							
								        mac_msg = container_of(msg, mac_msg_t, link);
							 | 
						||
| 
								 | 
							
								        mac_handle_msg_cancel(p_mac_glb, mac_msg);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_queue_msg(mac_msg_t *msg, uint8_t prio)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(prio < MAC_MSG_QUEUE_MAX_PRIO);
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_put(&p_mac_glb->msg_q[prio].q, &msg->link);
							 | 
						||
| 
								 | 
							
								    os_set_task_event(p_mac_glb->task_h);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mac_msg_sync_t *mac_alloc_msg_sync()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_msg_sync_t *msg = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (msg) {
							 | 
						||
| 
								 | 
							
								        iot_msg_entry_init(&msg->msg.link);
							 | 
						||
| 
								 | 
							
								        msg->msg.sync = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return msg;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_free_msg_sync(mac_msg_sync_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_free(p_mac_glb->msg_sync_p, msg);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_queue_msg_sync(mac_msg_sync_t *msg, uint8_t prio)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(prio < MAC_MSG_QUEUE_MAX_PRIO);
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_put(&p_mac_glb->msg_q[prio].q, &msg->msg.link);
							 | 
						||
| 
								 | 
							
								    os_set_task_event(p_mac_glb->task_h);
							 | 
						||
| 
								 | 
							
								    os_wait_event(msg->event, MAX_TIME);
							 | 
						||
| 
								 | 
							
								}
							 |