415 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			415 lines
		
	
	
		
			11 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.
 | |
| 
 | |
| ****************************************************************************/
 | |
| 
 | |
| #include "app_uart.h"
 | |
| #include "app_main_task.h"
 | |
| #include "app_common.h"
 | |
| #include "app_config.h"
 | |
| #include "app_cus_task.h"
 | |
| #include "iot_plc_led_api.h"
 | |
| #include "proto_645.h"
 | |
| #include "app_proto_dlt645.h"
 | |
| #include "app_cus_comm.h"
 | |
| 
 | |
| /* customer task handle. */
 | |
| static iot_cus_task_t g_cus_task;
 | |
| 
 | |
| /* handle for mismatch dlt645 frame. */
 | |
| static iot_cus_task_mismatch_dlt645_proc_fn g_mismatch_dlt645_handle = NULL;
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_645pkt_from_uart_handle() - handle 645pkt from uart.
 | |
|  * @param [in] pkt : pkt with dlt645 frame.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_645pkt_from_uart_handle(iot_pkt_t *pkt)
 | |
| {
 | |
|     uint32_t ret = ERR_FAIL;
 | |
|     iot_pkt_t *pkt_ack = NULL;
 | |
|     proto_645_header_t *frame = (proto_645_header_t *)iot_pkt_data(pkt);
 | |
|     uint16_t frame_len = iot_pkt_data_len(pkt);
 | |
| 
 | |
|     ret = app_dlt645_local_handle(APP_TASK_CUS, frame, frame_len, &pkt_ack);
 | |
|     if (ERR_OK == ret) {
 | |
|         /* ack frame, send back to uart. */
 | |
|         iot_cus_task_msg_post(E_CUS_MSG_FROM_CUSTASK, E_CUS_MSG_ID_BYTES_SEND,
 | |
|                 pkt_ack);
 | |
|         iot_pkt_free(pkt);
 | |
|     } else {
 | |
|         /* unhandled frame, send to main task. */
 | |
|         iot_main_task_msg_post(E_MAIN_MSG_FROM_CUSTASK,
 | |
|             E_MAIN_MSG_ID_645PKT_RECV, (void *)pkt);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_from_uart_handle() - handle message from uart.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_from_uart_handle(iot_cus_task_msg_t *msg)
 | |
| {
 | |
|     iot_pkt_t *pkt = (iot_pkt_t *)msg->data;
 | |
| 
 | |
|     switch (msg->msg.id)
 | |
|     {
 | |
|         /* customer task receive bytes from uart */
 | |
|         case E_CUS_MSG_ID_BYTES_RECV:
 | |
|         {
 | |
|             iot_cus_uart_recv_handle(iot_pkt_data(pkt), iot_pkt_data_len(pkt));
 | |
|             iot_pkt_free(pkt);
 | |
|             break;
 | |
|         }
 | |
|         /* customer task receive dlt645 frame from uart */
 | |
|         case E_CUS_MSG_ID_645PKT_RECV:
 | |
|         {
 | |
|             iot_cus_645pkt_from_uart_handle(pkt);
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         default:
 | |
|             iot_pkt_free(pkt);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_from_custask_handle() - handle message from customer task.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_from_custask_handle(iot_cus_task_msg_t *msg)
 | |
| {
 | |
|     iot_pkt_t *pkt = (iot_pkt_t *)msg->data;
 | |
| 
 | |
|     switch (msg->msg.id)
 | |
|     {
 | |
|         /* customer task send bytes to uart or other task */
 | |
|         case E_CUS_MSG_ID_BYTES_SEND:
 | |
|         {
 | |
|             iot_cus_bytes_send_handle(pkt);
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             iot_pkt_free(pkt);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_645pkt_from_maintask_handle() - handle 645pkt from main task.
 | |
|  * @param [in] pkt : pkt with dlt645 frame.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_645pkt_from_maintask_handle(iot_pkt_t *pkt)
 | |
| {
 | |
|     uint32_t ret = ERR_FAIL;
 | |
|     iot_pkt_t *pkt_ack = NULL;
 | |
|     proto_645_header_t *frame = (proto_645_header_t *)iot_pkt_data(pkt);
 | |
|     uint16_t frame_len = iot_pkt_data_len(pkt);
 | |
| 
 | |
|     ret = app_dlt645_local_handle(APP_TASK_CUS, frame, frame_len, &pkt_ack);
 | |
|     if (ERR_OK == ret) {
 | |
|         /* ack frame, send back to main task. */
 | |
|         iot_main_task_msg_post(E_MAIN_MSG_FROM_CUSTASK,
 | |
|             E_MAIN_MSG_ID_645PKT_RECV, (void *)pkt_ack);
 | |
|         iot_pkt_free(pkt);
 | |
|     } else {
 | |
|         if (g_mismatch_dlt645_handle) {
 | |
|             /* call mismatch handle firstly, if exists. */
 | |
|             g_mismatch_dlt645_handle(pkt);
 | |
|         } else {
 | |
|             /* unhandled frame, send to uart. */
 | |
|             iot_cus_task_msg_post(E_CUS_MSG_FROM_CUSTASK,
 | |
|                 E_CUS_MSG_ID_BYTES_SEND,pkt);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_from_maintask_handle() - handle message from main task.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_from_maintask_handle(iot_cus_task_msg_t *msg)
 | |
| {
 | |
|     iot_pkt_t *pkt = (iot_pkt_t *)msg->data;
 | |
| 
 | |
|     switch (msg->msg.id)
 | |
|     {
 | |
|         /* customer task receive on line or off line event from main task */
 | |
|         case E_CUS_MSG_ID_ONOFF_LINE:
 | |
|         {
 | |
|             iot_cus_onoff_line_event_from_maintask_handle(pkt);
 | |
|             break;
 | |
|         }
 | |
|         /* customer task receive dlt645 frame from main task */
 | |
|         case E_CUS_MSG_ID_645PKT_RECV:
 | |
|         {
 | |
|             iot_plc_led_request(IOT_PLC_LED_REQ_PLC_485_TX);
 | |
|             iot_cus_645pkt_from_maintask_handle(pkt);
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|             iot_pkt_free(pkt);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_from_timer_handle() - handle message from timer.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_from_timer_handle(iot_cus_task_msg_t *msg)
 | |
| {
 | |
|     switch(msg->msg.id)
 | |
|     {
 | |
|         /* period timer of customer task triggered */
 | |
|         case E_CUS_MSG_ID_TMR_TRIGGER:
 | |
|         {
 | |
|             // APP_PRINTF("PEROID TIMER FIRED\n");
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|         {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_handle() - handle message by type.
 | |
|  * @param [in] task_h : iot task handle, not used.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
 | |
| {
 | |
|     iot_cus_task_msg_t *dm_msg = (iot_cus_task_msg_t *)msg;
 | |
| 
 | |
|     (void)task_h;
 | |
| 
 | |
|     if ((NULL == dm_msg) || (!APP_CUS_MSG_VALID(dm_msg->msg.type))) {
 | |
|         /* Maybe this can cause memory overflow! */
 | |
|         APP_PRINTF("[ERR] %s Invalid MSG !!", __FUNCTION__);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     switch (dm_msg->msg.type)
 | |
|     {
 | |
|         case E_CUS_MSG_FROM_UART:
 | |
|         {
 | |
|             iot_cus_msg_from_uart_handle(dm_msg);
 | |
|             break;
 | |
|         }
 | |
|         case E_CUS_MSG_FROM_CUSTASK:
 | |
|         {
 | |
|             iot_cus_msg_from_custask_handle(dm_msg);
 | |
|             break;
 | |
|         }
 | |
|         case E_CUS_MSG_FROM_MAINTASK:
 | |
|         {
 | |
|             iot_cus_msg_from_maintask_handle(dm_msg);
 | |
|             break;
 | |
|         }
 | |
|         case E_CUS_MSG_FROM_TIMER:
 | |
|         {
 | |
|             iot_cus_msg_from_timer_handle(dm_msg);
 | |
|             break;
 | |
|         }
 | |
|         default:
 | |
|         {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* need free task message */
 | |
|     iot_task_free_msg(task_h, msg);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_msg_cancel() - handle message canceling.
 | |
|  * @param [in] task_h : iot task handle, not used.
 | |
|  * @param [in] msg : message.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
 | |
| {
 | |
|     iot_cus_task_msg_t *dm_msg = (iot_cus_task_msg_t *)msg;
 | |
| 
 | |
|     (void)task_h;
 | |
| 
 | |
|     if ((NULL == dm_msg) || (!APP_CUS_MSG_VALID(dm_msg->msg.type))) {
 | |
|         /* Maybe this can cause memory overflow! */
 | |
|         APP_PRINTF("[ERR] CANCEL AN INVALID MSG !!");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if ((E_CUS_MSG_FROM_UART == dm_msg->msg.type)
 | |
|         ||(E_CUS_MSG_FROM_CUSTASK == dm_msg->msg.type)
 | |
|         ||(E_CUS_MSG_FROM_MAINTASK == dm_msg->msg.type)
 | |
|         ||(E_CUS_MSG_FROM_TIMER == dm_msg->msg.type)) {
 | |
|             iot_pkt_t *pkt = (iot_pkt_t *)dm_msg->data;
 | |
|             if (pkt) {
 | |
|                 iot_pkt_free(pkt);
 | |
|             }
 | |
|     }
 | |
| 
 | |
|     iot_task_free_msg(task_h, &(dm_msg->msg));
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_event_handle() - handle task event.
 | |
|  * @param [in] task_h : iot task handle, not used.
 | |
|  * @param [in] event : task event.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_event_handle(iot_task_h task_h, uint32_t event)
 | |
| {
 | |
|     (void)task_h;
 | |
|     (void)event;
 | |
| 
 | |
|     APP_PRINTF("[INF] %s", __FUNCTION__);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief iot_cus_task_timer_callback() - task period timer callback.
 | |
|  * @param [in] timer_id : timer id.
 | |
|  * @param [in] arg : not used.
 | |
|  * @return None.
 | |
|  */
 | |
| static void iot_cus_task_timer_callback(timer_id_t timer_id, void *arg)
 | |
| {
 | |
|     (void)arg;
 | |
| 
 | |
|     if (timer_id == g_cus_task.peroid_timer) {
 | |
|         iot_cus_task_msg_post(E_CUS_MSG_FROM_TIMER, E_CUS_MSG_ID_TMR_TRIGGER,
 | |
|             NULL);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| uint32_t iot_cus_task_msg_post(uint16_t msg_type, uint16_t msg_id,
 | |
|     iot_pkt_t *data)
 | |
| {
 | |
|     iot_task_msg_t      *msg;
 | |
|     iot_cus_task_msg_t  *task_msg;
 | |
| 
 | |
|     msg = iot_task_alloc_msg_with_reserved(g_cus_task.task, 0);
 | |
|     if (NULL == msg) {
 | |
|         if (NULL != data) {
 | |
|             iot_pkt_free(data);
 | |
|         }
 | |
|         IOT_ASSERT(0);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     task_msg = (iot_cus_task_msg_t*)msg;
 | |
|     task_msg->msg.type = msg_type;
 | |
|     task_msg->msg.id = msg_id;
 | |
|     task_msg->data = data;
 | |
|     iot_task_queue_msg(g_cus_task.task, &task_msg->msg, 0);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| uint32_t iot_cus_task_onoffline_report(uint8_t *dev_mac, uint8_t status)
 | |
| {
 | |
|     iot_pkt_t *pkt = NULL;
 | |
|     uint8_t *buf = NULL;
 | |
| 
 | |
|     pkt = iot_pkt_alloc(IOT_MAC_ADDR_LEN + sizeof(status), IOT_APP_DL645_MID);
 | |
|     if (NULL == pkt) {
 | |
|         APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
|     buf = iot_pkt_put(pkt, IOT_MAC_ADDR_LEN + sizeof(status));
 | |
|     os_mem_cpy(buf, (void *)dev_mac, IOT_MAC_ADDR_LEN);
 | |
|     buf += IOT_MAC_ADDR_LEN;
 | |
|     os_mem_cpy(buf, (void *)&status, sizeof(status));
 | |
|     iot_cus_task_msg_post(E_CUS_MSG_FROM_MAINTASK, E_CUS_MSG_ID_ONOFF_LINE, pkt);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| void iot_cus_task_mismatch_dlt645_handle_set(
 | |
|     iot_cus_task_mismatch_dlt645_proc_fn handle)
 | |
| {
 | |
|     g_mismatch_dlt645_handle = handle;
 | |
| }
 | |
| 
 | |
| iot_uart_h iot_cus_task_get_uart_handle(void)
 | |
| {
 | |
|     return g_cus_task.uart_h;
 | |
| }
 | |
| 
 | |
| void iot_cus_task_set_uart_handle(iot_uart_h uart_h)
 | |
| {
 | |
|     g_cus_task.uart_h = uart_h;
 | |
| }
 | |
| 
 | |
| uint32_t iot_cus_task_init(void)
 | |
| {
 | |
|     iot_task_config_t t_cfg;
 | |
| 
 | |
|     os_mem_set(&g_cus_task, 0x0, sizeof(g_cus_task));
 | |
| 
 | |
|     os_mem_set(&t_cfg, 0x0, sizeof(t_cfg));
 | |
|     t_cfg.stack_size = 0;
 | |
|     /* task priority */
 | |
|     t_cfg.task_prio = APP_CUS_HANDLE_TASK_PRIO;
 | |
|     t_cfg.msg_size = sizeof(iot_cus_task_msg_t);
 | |
|     /* task message count */
 | |
|     t_cfg.msg_cnt = APP_CUS_PENDING_LIMIT;
 | |
|     /* task message queue count */
 | |
|     t_cfg.queue_cnt = APP_CUS_TASK_PRIO_QUE;
 | |
|     t_cfg.queue_cfg[0].quota = 0;
 | |
|     t_cfg.task_event_func = iot_cus_event_handle;
 | |
|     t_cfg.msg_exe_func = iot_cus_msg_handle;
 | |
|     t_cfg.msg_cancel_func = iot_cus_msg_cancel;
 | |
| 
 | |
|     /* create task */
 | |
|     g_cus_task.task = iot_task_create(IOT_APP_DL645_MID, &t_cfg);
 | |
|     if (NULL == g_cus_task.task) {
 | |
|         APP_PRINTF("[ERR] %s Create Task Failed !!", __FUNCTION__);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     /* register dlt645 local handlers */
 | |
|     iot_cus_task_local_handle_register();
 | |
| 
 | |
|     /* init hardware resource */
 | |
|     iot_cus_hw_init();
 | |
| 
 | |
|     /* create timer */
 | |
|     g_cus_task.peroid_timer = os_create_timer(IOT_APP_DL645_MID, true,
 | |
|         iot_cus_task_timer_callback, NULL);
 | |
| 
 | |
|     if (0 == g_cus_task.peroid_timer) {
 | |
|         iot_cus_printf("[cus_task]create cmd timer failed.\n");
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
|     /* start timer */
 | |
|     os_start_timer(g_cus_task.peroid_timer, APP_CUS_TASK_TIMER_PERIOD_MS);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 |