/**************************************************************************** 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 "os_task_api.h" #include "os_event_api.h" #include "os_timer_api.h" #include "os_utils_api.h" #include "os_lock_api.h" #include "iot_task_api.h" #include "iot_module_api.h" #include "iot_plc_sta_api.h" #include "iot_plc_cco_api.h" #include "iot_config_api.h" #include "iot_app_api.h" #include "iot_errno_api.h" #include "iot_io_api.h" #include "iot_flash_api.h" #include "iot_uart_api.h" #include "iot_utils_api.h" #include "iot_oem_api.h" #include "iot_board_api.h" #include "iot_gpio_api.h" #include "iot_plc_led_api.h" #include "iot_app_pib_api.h" #include "iot_bitmap_api.h" #include "iot_plc_sync_api.h" #include "iot_app_meta_api.h" #include "iot_plc_demo.h" #if IOT_PLCUART_APP_ENABLE /* demo app entity */ static app_dm_entity_t app_demo; /* demo app broadcast mac address for downlink proxy broadcast */ uint8_t app_demo_bcast_mac[IOT_MAC_ADDR_LEN] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF }; uint32_t app_demo_post_msg( uint16_t msg_type, uint16_t msg_id, void *data); uint32_t app_demo_post_event(uint32_t event_type); uint32_t app_demo_post_msg_cli(void *data); void app_demo_tmr_handle(timer_id_t tid, void *data); #if DEMO_APP_DEBUG_EN static char demo_app_log_buf[DEMO_APP_LOG_BUF_LEN] = { 0 }; void demo_app_data_print(const char* str, uint8_t* buf, uint16_t len) { uint32_t offset = 0; offset = iot_sprintf(demo_app_log_buf, "\r\n%s [len:%d]: ", str, len); for (uint32_t i = 0; i < len; ++i) { offset += iot_sprintf(demo_app_log_buf + offset, "%02X ", buf[i]); if (DEMO_APP_LOG_BUF_LEN <= offset + 4) { break; } } demo_app_log_buf[offset] = 0; iot_cus_printf("%s\r\n", demo_app_log_buf); return; } #else /* DEMO_APP_DEBUG_EN */ void demo_app_data_print(const char* str, uint8_t* buf, uint16_t len) { (void)str; (void)buf; (void)len; return; } #endif /* DEMO_APP_DEBUG_EN */ #if DEMO_APP_CTRL_LED #define DEMO_LED_LOCK() os_acquire_mutex(app_demo.led.sem_h) #define DEMO_LED_UNLOCK() os_release_mutex(app_demo.led.sem_h) /* Set the blinking time of led. */ static uint32_t inline app_demo_led_set_blink_time(dm_led_t *led, int time) { DEMO_LED_LOCK(); led->blink_time = time; DEMO_LED_UNLOCK(); return ERR_OK; } /* Rough control for led. */ void app_demo_led_ctrl(dm_led_t *led) { if(led->blink_time) { led->cur_perio -= ((led->cur_perio > DEMO_LED_TMR_PERIO) ? DEMO_LED_TMR_PERIO : led->cur_perio); if(0 == led->cur_perio) { led->status = (DEMO_LED_LIGHT_UP_FLAG == led->status) ? DEMO_LED_LIGHT_DOWN_FLAG : DEMO_LED_LIGHT_UP_FLAG; iot_gpio_value_set(((int)led->pin) & 0xFFFF, led->status); led->cur_perio = led->load_perio; if(DEMO_LED_TM_FOREVER != led->blink_time) { led->blink_time -= ((led->blink_time > led->load_perio) ? led->load_perio : led->blink_time); } } } else if(DEMO_LED_LIGHT_UP_FLAG == led->status) { led->status = DEMO_LED_LIGHT_DOWN_FLAG; iot_gpio_value_set(((int)led->pin) & 0xFFFF, led->status); } return; } /* use app control led */ static void app_demo_led_blink(void) { dm_led_t *led = NULL; DEMO_LED_LOCK(); led = &(app_demo.led.rx); app_demo_led_ctrl(led); led = &(app_demo.led.tx); app_demo_led_ctrl(led); DEMO_LED_UNLOCK(); return; } /* Initialize led. */ uint32_t app_demo_led_init(void) { dm_led_t *led = NULL; led = &(app_demo.led.rx); /* Configure rx led. */ led->load_perio = DEMO_LED_BLINK_RX_TM; led->cur_perio = 0; led->pin = iot_board_get_gpio(GPIO_RX_LED); led->status = DEMO_LED_LIGHT_UP_FLAG; led->blink_time = 0; if((ERR_OK != iot_gpio_open_as_output(led->pin)) ||(ERR_OK != iot_gpio_set_pull_mode(led->pin, GPIO_PULL_UP))) { DEMO_ERROR("OPEN GPIO#%d FAILED !!", led->pin, 2,3,4,5,6); return ERR_FAIL; } /* Configure tx led. */ led = &(app_demo.led.tx); led->load_perio = DEMO_LED_BLINK_TX_TM; led->cur_perio = 0; led->pin = iot_board_get_gpio(GPIO_TX_LED); led->status = DEMO_LED_LIGHT_UP_FLAG; led->blink_time = 0; if((ERR_OK != iot_gpio_open_as_output(led->pin)) ||(ERR_OK != iot_gpio_set_pull_mode(led->pin, GPIO_PULL_UP))) { DEMO_ERROR("OPEN GPIO#%d FAILED !!", led->pin, 2,3,4,5,6); return ERR_FAIL; } /* Create led mutex */ if(NULL == (app_demo.led.sem_h = os_create_mutex(IOT_APP_DEMO_MID))) { DEMO_ERROR("CREATE SEMAPHORE FAILED !!", 1, 2,3,4,5,6); return ERR_FAIL; } /* Tx led is always blinking. */ if(ERR_OK != app_demo_led_set_blink_time (&(app_demo.led.tx), DEMO_LED_TX_CONTINUE_TM)) { return ERR_FAIL; } /* Create a timer for repeatedly works. */ if((timer_id_t)NULL == (app_demo.led.tmr_id = os_create_timer (IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_tmr_handle, (void *)DEMO_LED_TMR_PERIO))) { DEMO_ERROR("CREATE TMR FAILED !!", 1, 2,3,4,5,6); return ERR_FAIL; } /* Start the timer. */ os_start_timer(app_demo.led.tmr_id, DEMO_LED_TMR_PERIO); return ERR_OK; } #endif /* DEMO_APP_CTRL_LED */ /* Set carrier communication frequency band. */ uint32_t app_demo_set_band(uint8_t band_id) { DEMO_INFO("SET BAND TO BAND %d", band_id, 2,3,4,5,6); iot_plc_set_freq_band(app_demo.app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, band_id); return ERR_OK; } /* plc set band bitmap */ void app_demo_set_sta_scan_band(uint8_t band_id) { uint8_t fb_bitmap[IOT_PLC_BAND_BITMAP_SIZE] = { 0 }; DEMO_INFO("SET SCAN BAND TO BAND %d", band_id, 2,3,4,5,6); fb_bitmap[band_id / 8] |= 1 << (band_id % 8); iot_plc_set_scan_band_bitmap(app_demo.app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE); return; } /* Get the OS running time. */ uint32_t app_demo_get_runing_time(void) { int fd; uint32_t tick; if(-1 == (fd = custom_dev_open())) { DEMO_ERROR("OPEN CUSTOMER FLASH FAILED !!", 1, 2,3,4,5,6); return 0; } if(-1 == custom_dev_read(fd, &tick, sizeof(tick))) { DEMO_ERROR("READ CUSTOMER FLASH FAILED !!", 1, 2,3,4,5,6); tick = 0; } (void)custom_dev_close(fd); return tick; } /* post the data from uart port to the message queue. */ uint32_t app_demo_uart_recv(uint8_t* buffer, uint32_t buffer_len, bool_t is_full_frame, uint32_t invalid_data_len) { iot_pkt_t *pkt; demo_app_data_print("uart recv", buffer, buffer_len); /* Apply for a pkt to store the data received by the serial port. Note: If you use the pak applied by iot_pkt_alloc, the last user will be responsible for free. */ if(NULL == (pkt = iot_pkt_alloc(buffer_len, IOT_APP_DEMO_MID))) { DEMO_ERROR("PACKET ALLOC FAILED !!", 1,2,3,4,5,6); return ERR_FAIL; } /* Put serial port data into pak. */ os_mem_cpy(iot_pkt_put(pkt, buffer_len), buffer, buffer_len); /* Publish data from uart port to message queue. */ if(ERR_OK != app_demo_post_msg (E_DEMO_MSG_PROCESS, E_CMD_ID_RCV_FROM_UART, (void*)pkt)) { DEMO_ERROR("POST MSG FAILED !!", 1,2,3,4,5,6); /* Failed to publish to message queue, release pkt. */ iot_pkt_free(pkt); return ERR_FAIL; } return ERR_OK; } /* Initialize serial port. */ uint32_t app_demo_uart_init(void) { uint8_t port; uint8_t port_name = UART_CUS_PORT_0; /* Get uart port for tranceiving data, not for printf() used. */ if((port = iot_board_get_uart(port_name)) >= iot_uart_get_max_port_num()) { DEMO_ERROR("INVALID UART %d !!", port, 2,3,4,5,6); return ERR_FAIL; } if(NULL == (app_demo.cmd_uart = iot_uart_open (port, (iot_uart_recv_func_t)app_demo_uart_recv, DEMO_UART_RCV_BUF_LEN, NULL))) { DEMO_ERROR("OPEN UART #%d FAILED !!", port, 2,3,4,5,6); return ERR_FAIL; } iot_uart_set_config(app_demo.cmd_uart, IOT_UART_BANDRATE_DEFAULT, IOT_UART_PARITY_NONE, IOT_UART_DLEN_8_BITS, IOT_UART_STOP_1_BITS); return ERR_OK; } /* Post the packet from plc-layer to message queue. */ void app_demo_plc_rcv(void *param, iot_pkt_t *pkt) { (void)param; if (false == sync_api_msg_from_mac_handle(pkt)) { app_demo_post_msg(E_DEMO_MSG_FROM_MAC, E_CMD_ID_RCV_FROM_PLC, (void*)pkt); } return; } /* Complex logic will not be handled in the timer-handle.So,just post out. */ void app_demo_tmr_handle(timer_id_t tid, void *data) { (void)tid; (void)data; app_demo_post_event(E_EVENT_TIMR); return; } /* Register an APP to PLC-layer,so we can transmit/receive packet from it. */ uint32_t app_demo_app_reg_init(void) { iot_plc_app_t app; app.app_id = IOT_PLC_APP_DEMO_ID; app.param = NULL; app.prio = DEMO_PLC_CMD_PRIO; app.recv = app_demo_plc_rcv; app_demo.app_hdl = iot_plc_register_app(&app); if(NULL == app_demo.app_hdl) { DEMO_ERROR("REGISTER APP FAILED !!", 1, 2,3,4,5,6); return ERR_FAIL; } iot_sync_api_init_app_hdl(app_demo.app_hdl, IOT_APP_DEMO_MID, app_demo_post_msg_cli); return ERR_OK; } uint8_t app_demo_send_plc_data(uint8_t *data, uint16_t len, uint8_t is_connless) { iot_pkt_t *msdu_pkt = NULL; uint8_t *ptr; uint16_t msdu_len; uint16_t meta_len = 0; //iot_plc_msdu_send_t *msdu; if (data == NULL || len == 0) { return ERR_FAIL; } msdu_len = iot_plc_calc_msdu_len_with_pad_info(len, is_connless, &meta_len); DEMO_INFO("%s: len %d, msdu_len %d, meta_len %d", __FUNCTION__, len, msdu_len, meta_len, 5,6); if (is_connless) { msdu_pkt = iot_plc_alloc_conn_less_msdu(app_demo.app_hdl, IOT_PLC_MSG_TYPE_CONN_LESS_DATA, app_demo_bcast_mac, app_demo.dev.mac_addr, app_demo.dev.link_id, msdu_len, DEMO_APP_CONNLESS_RETRY_CNT); } else { msdu_pkt = iot_plc_alloc_msdu(app_demo.app_hdl, IOT_PLC_MSG_TYPE_UNICAST, IOT_PLC_ACK_TYPE_NONE, app_demo.dev.rmt_addr, app_demo.dev.mac_addr, app_demo.dev.link_id, msdu_len, 0); } if (NULL == msdu_pkt) { DEMO_ERROR("ALLOC PACKET FAILED !!", 1,2,3,4,5,6); return ERR_FAIL; } ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL); os_mem_cpy(ptr, data, len); iot_pkt_put(msdu_pkt, len); iot_plc_add_meta_info(msdu_pkt, meta_len); DEMO_INFO("BINARY DATA FORWORD TO PLC:",1,2,3,4,5,6); demo_app_data_print("plc send", iot_pkt_data(msdu_pkt), iot_pkt_data_len(msdu_pkt)); /* Forword to PLC. */ iot_plc_send_msdu(app_demo.app_hdl, msdu_pkt); return ERR_OK; } /* This is the handle for messages from this module. */ void app_demo_msg_process_handle(uint16_t id, void *data) { iot_pkt_t *pkt = (iot_pkt_t*)data; if(NULL == pkt) { DEMO_ERROR("COMMOND HANDLE A 'NULL' PKT !!", 1, 2,3,4,5,6); return; } //iot_cus_printf("\n%s: id = %d\n", __FUNCTION__, id); DEMO_INFO("%s: id = %d", __FUNCTION__, id,3,4,5,6); if(E_CMD_ID_RCV_FROM_PLC == id) { iot_plc_msdu_recv_t *msdu; iot_pkt_t *uart_pkt; msdu = (iot_plc_msdu_recv_t*) (iot_pkt_data(pkt) + sizeof(iot_plc_msg_header_t)); #if DEMO_APP_CTRL_LED /* Blink RX-led. */ app_demo_led_set_blink_time (&(app_demo.led.rx), DEMO_LED_RX_CONTINUE_TM); #endif /* DEMO_APP_CTRL_LED */ if(NULL == (uart_pkt = iot_pkt_alloc(msdu->len, IOT_APP_DEMO_MID))) { DEMO_ERROR("PACKET ALLOC FAILED !!", 1,2,3,4,5,6); iot_pkt_free(pkt); return; } os_mem_cpy(iot_pkt_put(uart_pkt, msdu->len), msdu->data, msdu->len); iot_pkt_free(pkt); DEMO_INFO("BINARY DATA FORWORD TO UART:",1,2,3,4,5,6); //app_demo_main_bin_dmp(iot_pkt_data(uart_pkt), iot_pkt_data_len(uart_pkt)); demo_app_data_print("plc recv", iot_pkt_data(uart_pkt), iot_pkt_data_len(uart_pkt)); /* Forword to uart port. */ iot_uart_send(app_demo.cmd_uart, uart_pkt, NULL); } else if (E_CMD_ID_RCV_FROM_CLI == id) { iot_app_handle_cli_msg(pkt); } else if(E_CMD_ID_RCV_FROM_UART == id) { if ((!app_demo.dev.rmt_valid) || (!app_demo.dev.dev_ready)) { DEMO_INFO("REMOTE IS NOT READY, UART DATA DROPPED !!", 1,2,3,4,5,6); iot_pkt_free(pkt); return; } app_demo_send_plc_data(iot_pkt_data(pkt), iot_pkt_data_len(pkt), 0); iot_pkt_free(pkt); } else { iot_pkt_free(pkt); } return; } /* As all message data is a packet, so just free() it. */ void app_demo_msg_common_cancel(uint16_t id, void *data) { iot_pkt_t *pkt = (iot_pkt_t*)data; if(pkt) { iot_pkt_free(pkt); } (void)id; return; } /* Post messages for MSG queue. */ uint32_t app_demo_post_msg( uint16_t msg_type, uint16_t msg_id, void *data) { iot_task_msg_t *msg; dm_msg_t *task_msg; msg = iot_task_alloc_msg_with_reserved(app_demo.msg_task.handle, 0); if (NULL == msg) { DEMO_ERROR("ALLOC MSG-BUFFER FAILED !!", 1, 2,3,4,5,6); return ERR_FAIL; } task_msg = (dm_msg_t*)msg; task_msg->msg.type = msg_type; task_msg->msg.id = msg_id; task_msg->data = data; iot_task_queue_msg(app_demo.msg_task.handle, &task_msg->msg, DEMO_TASK_MSG_PRIO); return ERR_OK; } uint32_t app_demo_post_msg_cli(void *data) { return app_demo_post_msg(E_DEMO_MSG_PROCESS, E_CMD_ID_RCV_FROM_CLI, data); } /* If we donot need that kind of pending message anymore, just clean it. */ void app_demo_clean_msg(uint16_t msg_type, uint16_t msg_id) { DEMO_INFO("CLEAR MSG TYPE %d, ID %d.", msg_type, msg_id,3,4,5,6); iot_task_clean_msg(app_demo.msg_task.handle, msg_type, msg_id); return; } /* This posts the event to the task. */ uint32_t app_demo_post_event(uint32_t event_type) { if(!DEMO_EVENT_VALID(event_type)) { DEMO_ERROR("POST AN INVALID EVENT TYPE#%d !!", event_type,2,3,4,5,6); return ERR_FAIL; } os_set_task_event_with_v (iot_task_get_os_task_h(app_demo.msg_task.handle), EVENT_BIT(event_type)); return ERR_OK; } void app_demo_msg_from_mac_handle(iot_pkt_t *pkt) { iot_plc_msg_header_t *hdr = (iot_plc_msg_header_t*)iot_pkt_data(pkt); /* Check if this packet belongs to me. */ if ((IOT_PLC_APP_ID_BCAST != hdr->app_id) && (IOT_PLC_APP_DEMO_ID != hdr->app_id)) { DEMO_ERROR("INVALID PACKET FROM MAC,APP ID#%d.", hdr->app_id,2,3,4,5,6); iot_pkt_free(pkt); return; } /* Check if I'm registerd before handling msg. */ if ((!app_demo.app_reg) && (IOT_PLC_MSG_APP_REG_CONF != hdr->msg_id)) { DEMO_ERROR("INVALID PACKET FROM MAC,MSG ID#%d.", hdr->msg_id,2,3,4,5,6); iot_pkt_free(pkt); return; } switch (hdr->msg_id) { case IOT_PLC_MSG_APP_REG_CONF : { iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1); if ((IOT_PLC_SUCCESS == rpt->result) || (IOT_PLC_SUCCESS_MODIFIED == rpt->result)) { app_demo.app_reg = true; DEMO_INFO("APP REGISTERED SUCCESSFULLY.",1,2,3,4,5,6); if (MODULE_TYPE_STA_TEST == app_demo.dev.dev_type) { iot_plc_cfg_set_req_t cfg; os_mem_set(&cfg, 0, sizeof(cfg)); cfg.dev_type_valid = 1; cfg.dev_type = IOT_PLC_DEV_TYPE_REPEATER; cfg.reset = 1; iot_plc_set_cfg(app_demo.app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, &cfg); } } break; } case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT : { iot_plc_dev_state_change_rpt_t* rpt = (iot_plc_dev_state_change_rpt_t*)(hdr + 1); if(rpt->is_ready) { DEMO_INFO("STATE CHANGE REPORT MAC GET READY, MY ROLE TYPE#%d.", rpt->dev_role,2,3,4,5,6); DEMO_INFO("CCO MAC : %02x-%02x-%02x-%02x-%02x-%02x.", rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); DEMO_INFO("LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.", rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2], rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]); if(IOT_PLC_DEV_ROLE_STA == rpt->dev_role) { iot_mac_addr_cpy(app_demo.dev.rmt_addr, rpt->cco_mac); app_demo.dev.rmt_valid = true; } app_demo.dev.dev_ready = true; app_demo.dev.dev_role = rpt->dev_role; app_demo.dev.nid = rpt->nid; iot_mac_addr_cpy(app_demo.dev.mac_addr, rpt->local_mac); iot_mac_addr_cpy(app_demo.dev.cco_addr, rpt->cco_mac); } else { DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6); app_demo.dev.dev_ready = false; } break; } case IOT_PLC_MSG_DEV_INFO_RPT : { iot_plc_dev_info_rpt_t* rpt = (iot_plc_dev_info_rpt_t*)(hdr + 1); if(rpt->is_ready) { DEMO_INFO("DEVICE INFO REPORT MAC GET READY, MY ROLE TYPE#%d.", rpt->dev_role,2,3,4,5,6); DEMO_INFO("CCO MAC : %02x-%02x-%02x-%02x-%02x-%02x.", rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); DEMO_INFO("LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.", rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2], rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]); app_demo.dev.dev_ready = true; app_demo.dev.dev_role = rpt->dev_role; if(IOT_PLC_DEV_ROLE_STA == rpt->dev_role) { iot_mac_addr_cpy(app_demo.dev.rmt_addr, rpt->cco_mac); app_demo.dev.rmt_valid = true; } iot_mac_addr_cpy(app_demo.dev.mac_addr, rpt->local_mac); iot_mac_addr_cpy(app_demo.dev.cco_addr, rpt->cco_mac); } else { DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6); app_demo.dev.dev_ready = false; } break; } case IOT_PLC_MSG_STA_JOIN_INFO : { int16_t addr_index; iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1); DEMO_INFO("STA JOINED : MAC#%02x-%02x-%02x-%02x-%02x-%02x.", rpt->sta_info.addr[0], rpt->sta_info.addr[1], rpt->sta_info.addr[2], rpt->sta_info.addr[3], rpt->sta_info.addr[4], rpt->sta_info.addr[5]); if (IOT_PLC_DEV_ROLE_CCO == app_demo.dev.dev_role) { /* Keep the remote device as the last one we got. */ iot_mac_addr_cpy(app_demo.dev.rmt_addr, rpt->sta_info.addr); app_demo.dev.rmt_valid = true; addr_index = iot_app_get_addrs_index_in_wl(rpt->sta_info.addr); if (addr_index >= 0) { iot_bitmap_set(app_demo.addr_bitmap, DEMO_APP_BIT_MAP_SIZE, (uint16_t)addr_index); } if (0xFFFF != app_demo.periods_count) { if (app_demo.periods_count >= DEMO_APP_MED_ASSOC_PERIODS/2) { app_demo.assoc_timeout_period = DEMO_APP_MAX_ASSOC_PERIODS; } else if (app_demo.periods_count >= DEMO_APP_MIN_ASSOC_PERIODS/2) { app_demo.assoc_timeout_period = DEMO_APP_MED_ASSOC_PERIODS; } } app_demo.periods_count = 0; } break; } case IOT_PLC_MSG_STA_LEAVE_INFO : { uint32_t cnt; int16_t addr_index; iot_plc_sta_leave_info_t* rpt = (iot_plc_sta_leave_info_t*)(hdr + 1); for(cnt = 0; cnt < rpt->sta_count; cnt++) { DEMO_INFO("STA LEAVED : MAC %02x-%02x-%02x-%02x-%02x-%02x.", rpt->sta[cnt].mac_addr[0], rpt->sta[cnt].mac_addr[1], rpt->sta[cnt].mac_addr[2], rpt->sta[cnt].mac_addr[3], rpt->sta[cnt].mac_addr[4], rpt->sta[cnt].mac_addr[5]); if ((IOT_PLC_DEV_ROLE_STA == app_demo.dev.dev_role) &&(iot_mac_addr_cmp (app_demo.dev.rmt_addr, rpt->sta[cnt].mac_addr))) { app_demo.dev.rmt_valid = false; } else if (IOT_PLC_DEV_ROLE_CCO == app_demo.dev.dev_role) { addr_index = iot_app_get_addrs_index_in_wl (rpt->sta[cnt].mac_addr); if (addr_index >= 0) { iot_bitmap_clear(app_demo.addr_bitmap, DEMO_APP_BIT_MAP_SIZE, (uint16_t)addr_index); } } } break; } case IOT_PLC_MSG_MSDU_RECV : { iot_plc_msdu_recv_t *msdu = (iot_plc_msdu_recv_t*)(hdr + 1); DEMO_INFO("MSDU RECEIVED FROM MAC %02x-%02x-%02x-%02x-%02x-%02x.", msdu->src[0], msdu->src[1], msdu->src[2], msdu->src[3], msdu->src[4], msdu->src[5]); iot_check_meta_data(pkt); #if PLC_SUPPORT_STA_ROLE iot_meta_rcd_app_msdu_info(msdu, 1); #endif if(!app_demo.dev.dev_ready) { DEMO_INFO("DEVICE NOT READY.PACKET DROPPED.", 1,2,3,4,5,6); break; } app_demo_post_msg (E_DEMO_MSG_PROCESS, E_CMD_ID_RCV_FROM_PLC, (void*)pkt); /* Packet will not be freed here. */ pkt = NULL; } default : { break; } } if(pkt) { iot_pkt_free(pkt); } return; } /* CCO timing trigger check STA connection status. */ void app_demo_assoc_check_tmr_handle(timer_id_t tid, void *data) { (void)tid; (void)data; app_demo_post_msg(E_DEMO_MSG_TIMER, E_CMD_ID_TMR_ASSOC_CHECK, NULL); return; } /* Connection status check function. */ void app_demo_assoc_check_func(void) { uint16_t joined_cnt, wl_total_cnt; if (1 == iot_plc_cco_get_whiltlist_state_func()) { wl_total_cnt = iot_app_get_wl_cnt(); joined_cnt = iot_bitmap_cbs(app_demo.addr_bitmap, DEMO_APP_BIT_MAP_SIZE); if (wl_total_cnt == joined_cnt && 0 != wl_total_cnt) { if (!app_demo.assoc_done) { app_demo.assoc_done = 1; iot_plc_led_request(IOT_PLC_LED_ASSOCIATED); } } else { if (app_demo.assoc_done) { app_demo.assoc_done = 0; iot_plc_led_request(IOT_PLC_LED_DIS_ASSOCIATED); } } } else { if (app_demo.periods_count < 0xFFFF) { if (app_demo.periods_count < app_demo.assoc_timeout_period) { app_demo.periods_count++; if (app_demo.assoc_done) { app_demo.assoc_done = 0; iot_plc_led_request(IOT_PLC_LED_DIS_ASSOCIATED); } } else { app_demo.periods_count = 0xFFFF; app_demo.assoc_done = 1; iot_plc_led_request(IOT_PLC_LED_ASSOCIATED); } } } return; } /* Timed task processing function. */ void app_demo_msg_timer_handle(dm_msg_t *dm_msg) { switch (dm_msg->msg.id) { case E_CMD_ID_TMR_ASSOC_CHECK: { app_demo_assoc_check_func(); break; } default: { break; } } return; } void app_demo_device_query() { static uint32_t cnt = 1; if((cnt++) % (DEMO_APP_QUERY_TM / DEMO_TMR_PERIO)) { return; } if((!app_demo.dev.dev_ready) || (IOT_PLC_DEV_ROLE_INVALID != app_demo.dev.dev_role)) { return; } iot_plc_query_dev_info(app_demo.app_hdl, IOT_PLC_API_REQ_ID_DEFAULT); return; } /* Event handler * he current DEMO supports the following types of event processing: * E_EVENT_TIMR --Event from timer */ void app_demo_event_handle(iot_task_h task_h, uint32_t event) { (void)task_h; if(EVENT_BIT(E_EVENT_TIMR) & event) { #if DEMO_APP_CTRL_LED app_demo_led_blink(); #endif /* DEMO_APP_CTRL_LED */ app_demo_device_query(); } return; } /* Message processing function. * The current DEMO supports the following types of message processing: * E_DEMO_MSG_PROCESS --Messages from this module * E_DEMO_MSG_FROM_MAC --Messages from outside * E_DEMO_MSG_TIMER --Message from timer */ void app_demo_msg_handle(iot_task_h task_h, iot_task_msg_t *msg) { dm_msg_t *dm_msg = (dm_msg_t *)msg; (void)task_h; if((NULL == dm_msg) || (!DEMO_MSG_VALID(dm_msg->msg.type))) { /* Maybe this can cause memory overflow! */ DEMO_ERROR("HANDLE AN INVALID MSG !!", 1,2,3,4,5,6); return; } if(E_DEMO_MSG_PROCESS == dm_msg->msg.type) { app_demo_msg_process_handle(dm_msg->msg.id, dm_msg->data); } else if(E_DEMO_MSG_FROM_MAC == dm_msg->msg.type) { app_demo_msg_from_mac_handle((iot_pkt_t *)dm_msg->data); } else if(E_DEMO_MSG_TIMER == dm_msg->msg.type) { app_demo_msg_timer_handle(dm_msg); } /* need free task message */ iot_task_free_msg(task_h, &(dm_msg->msg)); return; } void app_demo_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg) { dm_msg_t *dm_msg = (dm_msg_t *)msg; (void)task_h; if((NULL == dm_msg) ||(!DEMO_MSG_VALID(dm_msg->msg.type))) { /* Maybe this can cause memory overflow! */ DEMO_ERROR("CANCEL AN INVALID MSG !!", 1,2,3,4,5,6); return; } if((E_DEMO_MSG_PROCESS == dm_msg->msg.type) || (E_DEMO_MSG_FROM_MAC == dm_msg->msg.type)) { app_demo_msg_common_cancel(dm_msg->msg.id, dm_msg->data); } iot_task_free_msg(task_h, &(dm_msg->msg)); return; } /* The initialization function of the message task, which is used to register * functions for processing messages and events. */ uint32_t app_demo_msg_task_init(void) { dm_msg_task_t *msg_task = &(app_demo.msg_task); iot_task_config_t *t_cfg = &(msg_task->cfg); t_cfg->stack_size = 0; t_cfg->task_prio = DEMO_MSG_HANDLE_TASK_PRIO; t_cfg->msg_size = sizeof(dm_msg_t); t_cfg->msg_cnt = DEMO_MSG_PENDING_LIMIT; t_cfg->queue_cnt = DEMO_MSG_TASK_PRIO_QUE; t_cfg->queue_cfg[0].quota = 0; t_cfg->task_event_func = app_demo_event_handle; /* event handler */ t_cfg->msg_exe_func = app_demo_msg_handle; /* message handler */ t_cfg->msg_cancel_func = app_demo_msg_cancel; msg_task->handle = iot_task_create(IOT_APP_DEMO_MID, t_cfg); if(NULL == msg_task->handle) { DEMO_ERROR("iot_task_create RETURNS NULL !!", 1,2,3,4,5,6); return ERR_FAIL; } return ERR_OK; } /* Report the basic information of this board. */ uint32_t app_demo_board_info_report(void) { uint32_t r_time, size; iot_oem_base_cfg_t * oem_cfg; size = custom_dev_query_rw_size(); (void)iot_oem_get_base_cfg(&oem_cfg); r_time = app_demo_get_runing_time(); iot_cus_printf("\r\n************************** INFORMATION ***********************"); iot_cus_printf("\r\n* This demo-application is designed by Aerospace C.Power"); iot_cus_printf("\r\n* And it's a guide to show how to use PLC-communication module"); iot_cus_printf("\r\n* and periphera devices."); iot_cus_printf("\r\n* MAC ADDRS : %02X-%02X-%02X-%02X-%02X-%02X.", oem_cfg->module_mac[0], oem_cfg->module_mac[1], oem_cfg->module_mac[2], oem_cfg->module_mac[3], oem_cfg->module_mac[4], oem_cfg->module_mac[5]); iot_cus_printf("\r\n* MODULE TYPE : %d ", oem_cfg->module_type); iot_cus_printf("\r\n* USER FLASH SIZE : %dbytes.(Size is optional.)", size); iot_cus_printf("\r\n* LAST POWERUP RUNNING TIME : %dH,%dM,%dS.", r_time / 3600, (r_time % 3600) / 60, ((r_time % 3600) % 60)); iot_cus_printf("\r\n**************************************************************"); app_demo.dev.dev_type = oem_cfg->module_type; return ERR_OK; } /* App initialization, creating task, timer, etc */ uint32_t app_demo_uart_module_init(void) { int ret = ERR_FAIL; dm_dev_t *dev; os_mem_set(&app_demo, 0x0, sizeof(app_demo)); app_demo_board_info_report(); DEMO_INFO("MODULE INITIALIZING...", 1,2,3,4,5,6); do { app_demo.app_hdl = NULL; app_demo.app_reg = false; dev = &(app_demo.dev); dev->link_id = DEMO_APP_LINK_ID; dev->nid = 1; dev->rmt_valid = false; dev->dev_role = IOT_PLC_DEV_ROLE_INVALID; dev->dev_ready = false; DEMO_INFO(" UART PORT INITIALIZING...", 1,2,3,4,5,6); if(ERR_OK != (ret = app_demo_uart_init())) { DEMO_ERROR("UART INIT FAILED !!", 1,2,3,4,5,6); break; } DEMO_INFO(" MESSAGE TASK INITIALIZING...", 1,2,3,4,5,6); if(ERR_OK != (ret = app_demo_msg_task_init())) { DEMO_ERROR("MSG TASK INIT FAILED !!", 1,2,3,4,5,6); break; } DEMO_INFO(" DEMO APP REGISTERING...", 1,2,3,4,5,6); if(ERR_OK != (ret = app_demo_app_reg_init())) { DEMO_ERROR("APP REGISTER FAILED !!", 1,2,3,4,5,6); break; } #if DEMO_APP_CTRL_LED DEMO_INFO(" LED & TIMER INITIALIZING...", 1,2,3,4,5,6); if(ERR_OK != (ret = app_demo_led_init())) { DEMO_ERROR("LED INIT FAILED !!", 1,2,3,4,5,6); break; } #endif /* DEMO_APP_CTRL_LED */ /* Only the code executed by the client. */ if (iot_plc_is_client_mode()) { /* default set sta only scan band 1, freq: 2.4M to 5.6M */ app_demo_set_sta_scan_band(PLC_LIB_FREQ_BAND_1); /* close watchdog */ iot_plc_wdg_set(app_demo.app_hdl, 0, 0); } if(ERR_OK !=(ret = app_demo_set_band(PLC_LIB_FREQ_BAND_1))) { DEMO_ERROR("SET BAND ID FAILED !!", 1,2,3,4,5,6); break; } /* code executed by non-client */ if (!(iot_plc_is_client_mode())) { /* Create a timer to check sta associated to network. */ app_demo.tmr_assoc_check = os_create_timer(IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_assoc_check_tmr_handle, NULL); if (0 == app_demo.tmr_assoc_check) { DEMO_ERROR("CREATE TMR FAILED !!", 1, 2,3,4,5,6); return ERR_FAIL; } os_start_timer(app_demo.tmr_assoc_check, DEMO_APP_ASSOC_CHECK_TMR_PERIOD); app_demo.assoc_timeout_period = DEMO_APP_MIN_ASSOC_PERIODS; app_demo.periods_count = 0xFFFF; app_demo.assoc_done = 0; os_mem_set(app_demo.addr_bitmap, 0, DEMO_APP_BIT_MAP_SIZE); } #if PLC_SUPPORT_STA_ROLE /* initialize meta information */ iot_meta_init(IOT_APP_DEF_3_DEMO, IOT_APP_DEMO_MID); #endif ret = ERR_OK; }while(0); DEMO_INFO("MODULE INITIALIZED %s.", (ERR_OK == ret) ? "SUCCESSFULLY" : "WITH ERROR",2,3,4,5,6); return ret; } extern void iot_print_config(bool_t enable); uint32_t app_plcuart_entry(void) { uint32_t ret = ERR_FAIL; /* turn on user printing function. */ iot_cus_print_config(true); /* turn off iot plc printing function. */ iot_print_config(false); DEMO_INFO("APP CUS TASK INIT...\n",1,2,3,4,5,6); /* initialize demo module. */ ret = app_demo_uart_module_init(); return ret; } #endif /* IOT_PLCUART_APP_ENABLE */