/**************************************************************************** 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_utils_api.h" #include "iot_io.h" #include "iot_utils_api.h" #include "iot_mtd.h" #include "iot_pkt_api.h" #include "iot_cli_tx_rx.h" #include "iot_cli_host_interface.h" #include "iot_cli_flash_log.h" extern iot_cli_host_info_t *host_info; uint8_t preamble_code[] = "$$"; uint8_t backcode[] = "&&"; uint8_t buffer_in_use = 0; void download_log_to_flash(iot_pkt_t *pkt) { iot_share_task_post_msg(IOT_SHARE_TASK_QUEUE_LP, IOT_SHARE_TASK_MT_CLI, IOT_CLI_LOG_WRITE_FLASH, 0, pkt); } void cli_read_log_from_flash(uint8_t* data, uint32_t datalen, uint8_t *src_mac) { (void)data; (void)datalen; (void)src_mac; iot_share_task_post_msg(IOT_SHARE_TASK_QUEUE_LP, IOT_SHARE_TASK_MT_CLI, IOT_CLI_LOG_READ_FLASH, 0, NULL); } void cli_read_log_from_flash_ex(uint8_t* data, uint32_t datalen, uint8_t *src_mac) { if (!data || datalen < sizeof(cli_host_get_log_param_t)) IOT_ASSERT(0); cli_host_get_log_param_t* log_flash = (cli_host_get_log_param_t*)data; uint8_t is_local_read = (MAC_IS_EMPTY(log_flash->mac) || os_mem_cmp(log_flash->mac, host_info->mac_addr, CLI_MAC_ADDR_LEN) == 0); if (!is_local_read) { iot_cli_send_data(CLI_UNICAST_SEND_TYPE, 0, CLI_MODULEID_DEBUGLOG, CLI_MSGID_GET_LOG_FROM_FLASH_EX, src_mac, log_flash->mac, data, datalen); } else { iot_pkt_t *pkt = iot_pkt_alloc(sizeof(remote_log_param), IOT_DBGLOG_MID); if (data == NULL) { iot_printf("cli_read_log_from_flash_ex cannot alloc the buffer"); return; } iot_printf("cli_read_log_from_flash_ex\n"); remote_log_param *data_ptr; data_ptr = (remote_log_param*)iot_pkt_data(pkt); os_mem_set(data_ptr, 0, sizeof(remote_log_param)); os_mem_cpy(&(data_ptr->data), data, datalen); if (src_mac) os_mem_cpy(data_ptr->src_mac, src_mac, 6); iot_share_task_post_msg(IOT_SHARE_TASK_QUEUE_LP, IOT_SHARE_TASK_MT_CLI, IOT_CLI_LOG_READ_FLASH_EX, 0, pkt); } } void iot_cli_log_to_flash_msg_cancel_handle(iot_msg_entry_t *entry) { iot_share_task_msg_t *task_msg = (iot_share_task_msg_t*)entry; iot_pkt_t* data = (iot_pkt_t*)task_msg->data2; iot_printf("iot_cli_log_to_flash_msg_cancel_handle: msg.id = %d\n", task_msg->msg.id); switch (task_msg->msg.id) { case IOT_CLI_LOG_WRITE_FLASH: iot_pkt_free(data); break; case IOT_CLI_LOG_READ_FLASH: break; case IOT_CLI_LOG_READ_FLASH_EX: iot_pkt_free(data); break; default: IOT_ASSERT(0); break; } } void iot_cli_log_to_flash_msg_handle(iot_msg_entry_t *entry) { iot_share_task_msg_t *task_msg = (iot_share_task_msg_t*)entry; iot_pkt_t* data = NULL; uint32_t len = 0; if (!task_msg) { iot_printf("iot_cli_log_to_flash_msg_handle: no recv data\n"); buffer_in_use = 0; return; } iot_printf("iot_cli_log_to_flash_msg_handle: msg.id = %d\n", task_msg->msg.id); switch (task_msg->msg.id) { case IOT_CLI_LOG_WRITE_FLASH: data = (iot_pkt_t*)task_msg->data2; len = add_flashlog_tag(data); write_log(iot_pkt_data(data), len); restore_pkt(data); send_tx_msg_to_cli_task(data); break; case IOT_CLI_LOG_READ_FLASH: read_log(); break; case IOT_CLI_LOG_READ_FLASH_EX: IOT_ASSERT(task_msg->data2); read_remote_log((remote_log_param*)iot_pkt_data(task_msg->data2)); iot_pkt_free(task_msg->data2); break; default: IOT_ASSERT(0); break; } } uint32_t add_flashlog_tag(iot_pkt_t *data) { uint8_t * newdata = iot_pkt_push(data, MAX_FRAME_CODE_LEN); if (newdata) { os_mem_cpy(newdata, preamble_code, MAX_FRAME_CODE_LEN); } else { IOT_ASSERT(0); return 0; } newdata = iot_pkt_put(data, MAX_FRAME_CODE_LEN); if (newdata) { os_mem_cpy(newdata + (iot_pkt_data_len(data) - MAX_FRAME_CODE_LEN), backcode, MAX_FRAME_CODE_LEN); } else { IOT_ASSERT(0); return 0; } return iot_pkt_data_len(data); } uint32_t add_flashlog_tag_preamble(uint8_t* data) { os_mem_cpy(data, preamble_code, MAX_FRAME_CODE_LEN); return MAX_FRAME_CODE_LEN; } uint32_t add_flashlog_tag_backcode(uint8_t* data) { os_mem_cpy(data, backcode, MAX_FRAME_CODE_LEN); return MAX_FRAME_CODE_LEN; } void restore_pkt(iot_pkt_t *buf) { uint8_t *data, *data_new, *tail, *tail_new; data = iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_DATA); tail = iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_TAIL); data_new = data + MAX_FRAME_CODE_LEN; tail_new = tail - MAX_FRAME_CODE_LEN; iot_pkt_set_data(buf, data_new); iot_pkt_set_tail(buf, tail_new); } void read_remote_log(remote_log_param* param) { uint32_t read_len = 0; uint8_t is_local_read = 0; uint8_t* log_buf = NULL; cli_transfer_log_from_flash_ex *pkt = NULL; uint32_t size = IOT_CLI_LOG_DEFAULT_SIZE; #if HW_PLATFORM > HW_PLATFORM_SIMU int32_t fd = iot_log_dev_open(); if (fd == -1) { iot_printf("failed to open log dev\n"); goto err_exit; } size = (uint32_t)iot_log_dev_query_rw_size((uint8_t)fd); #endif IOT_ASSERT(param); is_local_read = (MAC_IS_EMPTY(param->src_mac) || iot_mac_addr_cmp(param->src_mac, host_info->mac_addr)); iot_printf("cli_read_log_from_flash %d, size %d, block_id %d\n", is_local_read, size, param->data.hdr.block_id); // get total size if ((param->data.hdr.block_id == 0) && (param->data.hdr.datalen == 0)) { cli_host_get_log_param_t get_log = { 0 }; iot_mac_addr_cpy(&get_log.mac[0], param->data.hdr.mac); get_log.size = size; if (is_local_read == 1) { cli_send_module_msg(CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFER_LOG_FROM_FLASH_START, (uint8_t*)&get_log, sizeof(cli_host_get_log_param_t)); } else { iot_cli_send_data(CLI_UNICAST_SEND_TYPE, 0, CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFER_LOG_FROM_FLASH_START, NULL, param->src_mac, (uint8_t*)&get_log, sizeof(cli_host_get_log_param_t)); } goto err_exit; } if ((size == 0) || (param->data.hdr.block_id >= size)) { goto err_exit; } if ((uint32_t)(param->data.hdr.block_id + param->data.hdr.datalen) > size) { read_len = size - param->data.hdr.block_id; } else { read_len = param->data.hdr.datalen; } if ((CLI_TRANSFER_LOG_HDR_LEN_EX + read_len) > MAX_BUF_SIZE_FOR_READ_FLASH) { iot_printf("%s, read_len too big %d\n", __FUNCTION__, read_len); read_len = MAX_BUF_SIZE_FOR_READ_FLASH - CLI_TRANSFER_LOG_HDR_LEN_EX; } log_buf = os_mem_malloc(IOT_CLI_MID, MAX_BUF_SIZE_FOR_READ_FLASH); if (!log_buf) { iot_printf("%s, no mem with size :%d avaliable\n", __FUNCTION__, log_buf); goto err_exit; } os_mem_set(log_buf, 0, MAX_BUF_SIZE_FOR_READ_FLASH); pkt = (cli_transfer_log_from_flash_ex *)log_buf; #if HW_PLATFORM > HW_PLATFORM_SIMU int32_t ret = 0; ret = iot_log_dev_seek(fd, param->data.hdr.block_id, DEV_SEEK_SET); if (ret == -1) { iot_printf("log seek fail\n"); goto err_exit; } ret = iot_log_dev_read(fd, (void*)&pkt->data[0], read_len); if (ret == -1) { iot_printf("log read fail\n"); goto err_exit; } #endif pkt->hdr.block_id = param->data.hdr.block_id; pkt->hdr.datalen = (uint16_t)read_len; iot_mac_addr_cpy(pkt->hdr.mac, param->data.hdr.mac); iot_printf("send log, block id:%d, datalen:%d\n", pkt->hdr.block_id, read_len); /*for (uint32_t i = 0; i < read_len; i++) { iot_printf(" %02x ", pkt->data[i]); } iot_printf("\n");*/ if (is_local_read == 1) { cli_send_module_msg(CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFERING_LOG_FROM_FLASH, (uint8_t*)&log_buf[0], CLI_TRANSFER_LOG_HDR_LEN_EX + read_len); } else { iot_cli_send_data(CLI_UNICAST_SEND_TYPE, 0, CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFERING_LOG_FROM_FLASH, NULL, param->src_mac, (uint8_t*)&log_buf[0], CLI_TRANSFER_LOG_HDR_LEN_EX + read_len); } err_exit: #if HW_PLATFORM > HW_PLATFORM_SIMU if (fd >= 0) { iot_log_dev_close(fd); } #endif if (log_buf) { os_mem_free(log_buf); log_buf = NULL; } } #if HW_PLATFORM > HW_PLATFORM_SIMU uint8_t required_to_write_to_flash() { uint8_t direction = 0; int32_t ret = iot_log_get_flow_direction(&direction); if (ret == -1) { return 0; } iot_printf("need write to flash=%d\n", direction == 0); return (direction == 0); } void write_log(uint8_t* data, uint32_t datalen) { int32_t fd = -1; uint32_t written_len = 0; //for (uint32_t i = 0; i < datalen; i++) //{ // iot_printf(" %02x ", data[i]); //} //iot_printf("\n"); fd = iot_log_dev_open(); if (fd == -1) { iot_printf("failed to open log dev\n"); goto err_exit; } written_len = iot_log_dev_write(fd, data, datalen); iot_printf("write_log:write len:%d, raw data len:%d\n", written_len, datalen); err_exit: if (fd >= 0) { iot_log_dev_close(fd); } } void write_log_nolock(uint8_t* data, uint32_t datalen) { int32_t fd = -1; //for (uint32_t i = 0; i < datalen; i++) //{ // iot_printf(" %02x ", data[i]); //} fd = iot_log_dev_open_no_lock(); if (fd == -1) { goto err_exit; } iot_log_dev_write_no_lock(fd, data, datalen); err_exit: if (fd >= 0) { iot_log_dev_close(fd); } } void read_log() { uint8_t* log_buf = NULL; int32_t ret = 0; int32_t fd = 0; uint32_t blockid = 0; uint32_t size = 0; uint32_t remain_len = 0; uint32_t read_len = 0; cli_transfer_log_from_flash* pkt = NULL; fd = iot_log_dev_open(); if (fd == -1) { iot_printf("failed to open log dev\n"); goto err_exit; } log_buf = os_mem_malloc(IOT_CLI_MID, MAX_BUF_SIZE_FOR_READ_FLASH); if (!log_buf) { iot_printf("%s, no mem with size :%d avaliable\n", __FUNCTION__, log_buf); goto err_exit; } else { os_mem_set(log_buf, 0, MAX_BUF_SIZE_FOR_READ_FLASH); } size = (uint32_t)iot_log_dev_query_rw_size(fd); iot_printf("read flash log total size:%d\n", size); // report flash size cli_send_module_msg( CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFER_LOG_FROM_FLASH_START, (uint8_t*)&size, sizeof(uint32_t)); if (size == 0) { goto err_exit; } remain_len = size; while (remain_len > 0) { read_len = min(remain_len, MAX_BUF_SIZE_FOR_READ_FLASH - CLI_TRANSFER_LOG_HDR_LEN); pkt = (cli_transfer_log_from_flash *)log_buf; ret = iot_log_dev_read(fd, (void*)&pkt->data[0], read_len); if (ret == -1) { iot_printf("log read fail\n"); goto err_exit; } pkt->hdr.block_id = blockid++; pkt->hdr.datalen = read_len; iot_printf("send log, block id:%d, datalen:%d\n", pkt->hdr.block_id, read_len); cli_send_module_msg(CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFERING_LOG_FROM_FLASH, log_buf, CLI_TRANSFER_LOG_HDR_LEN + read_len); remain_len -= read_len; iot_printf("remain %d to read\n", remain_len); os_delay(50); } err_exit: cli_send_module_msg(CLI_MODULEID_DEBUGLOG, CLI_MSGID_TRANSFER_LOG_FROM_FLASH_END, NULL, 0); if (fd >= 0) { iot_log_dev_close(fd); } if (log_buf) { os_mem_free(log_buf); log_buf = NULL; } } #else void write_log(uint8_t* data, uint32_t datalen) { (void)data; (void)datalen; } uint8_t required_to_write_to_flash() { return 0; } void read_log() { } void write_log_nolock(uint8_t* data, uint32_t datalen) { (void)data; (void)datalen; } #endif