/**************************************************************************** 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_board.h" #include "iot_io_api.h" #include "iot_upgrade_api.h" #include "iot_cli.h" #include "iot_cli_host_interface.h" #include "iot_cli_plc_module.h" #include "iot_cli_common.h" #include "iot_cli_plc_tx_rx.h" #include "iot_cli_set_info.h" extern iot_plc_host_config_t *host_config; extern iot_cli_t cli; timer_id_t set_info_timer; uint8_t set_id; #if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA) static void cli_set_vendor_local_ack(uint8_t *src_mac) { cli_vendor_report report; report.set_id = set_id; iot_mac_addr_cpy(report.dst, host_config->mac_addr); iot_cli_send_to_host(CLI_MSGID_SET_VENDOR_ACK, (uint8_t*)&report, sizeof(cli_vendor_report), src_mac); } #endif /* cli set vendor handler */ void cli_set_vendor( uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac) { (void)src_mac; cli_vendor_info *vendor_info = (cli_vendor_info *)buffer; if ((!vendor_info) || (bufferlen < sizeof(*vendor_info))) { iot_printf("dev save vendor, invalid para\n"); return; } if (host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) { if (set_id != vendor_info->set_id) { iot_printf("sta set vendor %lu %lu\n", set_id, vendor_info->set_id); iot_board_save_user_vendor_id(vendor_info->vendor); set_id = vendor_info->set_id; } else { iot_printf("sta vendor already set\n"); } #if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA) cli_set_vendor_local_ack(src_mac); #else if (!os_is_timer_active(set_info_timer) && vendor_info->control) { if (vendor_info->report_window > CLI_SET_VENDOR_TIME_WINDOW) { vendor_info->report_window = CLI_SET_VENDOR_TIME_WINDOW; } os_start_timer(set_info_timer, os_rand() % vendor_info->report_window); } #endif } #if PLC_SUPPORT_CCO_ROLE else { cli_set_vendor_ack ack; ack.result = 0; iot_cli_send_to_host(CLI_MSGID_SET_VENDOR_ACK, (uint8_t *)&ack, sizeof(ack), src_mac); if (iot_mac_addr_cmp(host_config->mac_addr, vendor_info->dst)) { // set cco if (set_id != vendor_info->set_id) { iot_printf("cco set vendor %lu %lu\n", set_id, vendor_info->set_id); iot_board_save_user_vendor_id(vendor_info->vendor); set_id = vendor_info->set_id; } else { iot_printf("cco vendor already set\n"); } } else { // set sta uint8_t send_type = IOT_PLC_MSG_TYPE_UNICAST; // store requet id for vendor report host_config->cli_request_id = add_addr_to_mapping_table(src_mac); // check if broadcast if (iot_mac_is_bcast(vendor_info->dst)) { send_type = IOT_PLC_MSG_TYPE_BCAST; } iot_printf("cco forward set cmd stype %lu\n", send_type); iot_cli_host_send_data_plc( send_type, CLI_MSGID_SET_VENDOR, vendor_info->dst, buffer, bufferlen); } } #endif } /* dev save build info func */ static void cli_dev_save_build_info(cli_build_info *build_info) { iot_build_info_t iot_build_info; if (!build_info) { iot_printf("dev save build info, invalid para\n"); return; } iot_build_info.sw_ver = build_info->sw_ver; iot_build_info.year = build_info->year; iot_build_info.month = build_info->month; iot_build_info.day = build_info->day; iot_build_info.hour = build_info->hour; iot_build_info.min = build_info->min; iot_build_info.sec = build_info->sec; iot_board_save_user_build_info(&iot_build_info); } /* cli set build info handler */ void cli_set_build_info( uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac) { (void)src_mac; cli_build_info *build_info = (cli_build_info *)buffer; if ((!build_info) || (bufferlen < sizeof(*build_info))) { return; } if (host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) { if (set_id != build_info->set_id) { iot_printf("sta set build info %lu %lu %lu\n", set_id, build_info->set_id, build_info->sw_ver); cli_dev_save_build_info(build_info); set_id = build_info->set_id; } else { iot_printf("sta build info already set\n"); } if (!os_is_timer_active(set_info_timer) && build_info->control) { if (build_info->report_window > CLI_SET_VENDOR_TIME_WINDOW) { build_info->report_window = CLI_SET_VENDOR_TIME_WINDOW; } os_start_timer( set_info_timer, os_rand() % build_info->report_window); } } #if PLC_SUPPORT_CCO_ROLE else { cli_set_build_info_ack ack; ack.result = 0; iot_cli_send_to_host(CLI_MSGID_SET_BUILD_INFO_ACK, (uint8_t *)&ack, sizeof(ack), src_mac); if (iot_mac_addr_cmp(host_config->mac_addr, build_info->dst)) { // set cco if (set_id != build_info->set_id) { iot_printf("cco set build info %lu %lu\n", set_id, build_info->set_id); cli_dev_save_build_info(build_info); set_id = build_info->set_id; } else { iot_printf("cco build info already set\n"); } } else { // set sta uint8_t send_type = IOT_PLC_MSG_TYPE_UNICAST; // store requet id for vendor report host_config->cli_request_id = add_addr_to_mapping_table(src_mac); // check if broadcast if (iot_mac_is_bcast(build_info->dst)) { send_type = IOT_PLC_MSG_TYPE_BCAST; } iot_printf("cco forward set cmd stype %lu\n", send_type); iot_cli_host_send_data_plc(send_type, CLI_MSGID_SET_BUILD_INFO, build_info->dst, buffer, bufferlen); } } #endif } #if PLC_SUPPORT_CCO_ROLE /* cco handle venfor report from sta */ void cli_set_vendor_report( uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac) { (void)src_mac; uint8_t *addr = get_addr_from_mapping_table(host_config->cli_request_id); iot_cli_send_to_host(CLI_MSGID_VENDOR_REPORT, buffer, bufferlen, addr); } /* cco handle build info from sta */ void cli_set_build_info_report( uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac) { (void)src_mac; uint8_t *addr = get_addr_from_mapping_table(host_config->cli_request_id); iot_cli_send_to_host(CLI_MSGID_BUILD_INFO_REPORT, buffer, bufferlen, addr); } #endif /* timer for set info */ static void iot_cli_set_info_timer(timer_id_t timer_id, void *arg) { (void)timer_id; (void)arg; iot_task_msg_t *msg; msg = iot_cli_create_cli_msg(IOT_CLI_SET_TIMER, NULL); if (msg) { iot_task_queue_msg(cli.cli_task_h, msg, IOT_CLI_QUEUE_TIMER); } } /* check if set venfor */ static uint8_t iot_cli_is_set_vendor() { if (set_id <= CLI_SET_VENDOR_ID_MAX) { return 1; } return 0; } static void iot_cli_info_reset_report() { if (iot_cli_is_set_vendor()) { cli_vendor_report report; report.set_id = set_id; iot_mac_addr_cpy(report.dst, host_config->mac_addr); iot_cli_host_send_data_plc(IOT_PLC_MSG_TYPE_UNICAST, CLI_MSGID_VENDOR_REPORT, host_config->cco_mac, (uint8_t*)&report, sizeof(cli_vendor_report)); } else { cli_build_info_report report; report.set_id = set_id; iot_mac_addr_cpy(report.dst, host_config->mac_addr); iot_cli_host_send_data_plc(IOT_PLC_MSG_TYPE_UNICAST, CLI_MSGID_BUILD_INFO_REPORT, host_config->cco_mac, (uint8_t*)&report, sizeof(cli_build_info_report)); } } /* handle set timer msg */ void iot_cli_set_info_handle_timer_msg() { iot_cli_info_reset_report(); // stop timer os_stop_timer(set_info_timer); } /* init cli set info */ void iot_cli_set_info_init() { set_id = 0; if (host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) { set_info_timer = os_create_timer(IOT_CLI_MID, 1, iot_cli_set_info_timer, NULL); } } /* sta handle leave when ver change */ void iot_cli_user_ver_change_reset() { if (set_id > 0) { iot_upgrade_reset(); } }