/* os_shim header files */ #include "os_types_api.h" #include "os_utils_api.h" /* common includes */ #include "iot_dbglog_api.h" #include "iot_io_api.h" #include "iot_version_api.h" #include "iot_errno_api.h" #include "iot_system_api.h" #include "iot_oem_api.h" /* smart grid internal header files */ #include "iot_sg_fr.h" #include "iot_sg_cco_drv_api.h" #include "iot_sg_cco_cmd.h" #include "iot_cli_sg_api.h" #if (IOT_SMART_GRID_ENABLE && PLC_SUPPORT_CCO_ROLE) /* max count of mac address in a ul packet to CLI */ #define IOT_CLI_MAX_ADDR_COUNT (8) /* default secondary node registration duration, in minute */ #define IOT_CLI_DEFAULT_SEC_NODE_REG_DUR (30) /* defines secondary node registration time unit(1min), uint is 1s */ #define IOT_CLI_SEC_NODE_REG_TIME_UNIT_DUR (60) typedef struct _cli_drv_data { /* current meter reading power meter */ uint8_t cur_mr_pm[IOT_MAC_ADDR_LEN]; /* request sequence number */ uint8_t req_sn; } cli_drv_data_t; static cli_drv_data_t *cli_drv_data = NULL; uint32_t cli_drv_init() { if (cli_drv_data) { return 0; } cli_drv_data = os_mem_malloc(IOT_SMART_GRID_MID, sizeof(cli_drv_data_t)); if (!cli_drv_data) { return 1; } return 0; } void cli_drv_deinit() { if (cli_drv_data) { os_mem_free(cli_drv_data); cli_drv_data = NULL; } } /** * @brief iot_cli_drv_request_rt_mr_data() - request route meter reading data * @param ul_data: request meter reading data up link */ static void iot_cli_drv_request_rt_mr_data( const iot_cli_request_rt_mr_data_ul *ul_data) { iot_pkt_t *pkt = NULL; uint16_t pkt_len = 0; iot_cli_request_rt_mr_data_ul *des_data = NULL; pkt_len = iot_cli_sg_get_headroom_req() + sizeof(*ul_data); pkt = iot_pkt_alloc(pkt_len, IOT_SMART_GRID_MID); IOT_ASSERT(pkt); /* fill response info */ des_data = (iot_cli_request_rt_mr_data_ul*)iot_pkt_reserve(pkt, iot_cli_sg_get_headroom_req()); os_mem_cpy(des_data, ul_data, sizeof(*ul_data)); iot_cli_sg_send_data_to_cli_interface(pkt, IOT_CLI_SG_MSG_PRT_RT_REQ_MR_DATA, IOT_CLI_SG_REQ_ID_DEFAULT); } /** * @brief iot_cli_drv_run_rt_mr_data() - send packet about the route meter * reading data * @param req: cli request route meter reading data down link * @param pkt: iot_pkt_t containing the cli request pkt. * @param consumed: 0 - iot_pkt is not consumed. * otherwise - iot_pkt is consumed. * @return: ERR_OK: success. others: fail */ static uint32_t iot_cli_drv_run_rt_mr_data( iot_cli_sg_rpt_rt_mr_data_dl *req, iot_pkt_t *pkt, uint8_t *consumed) { iot_sg_wl_entry_info_t node_info = { 0 }; uint8_t cco_mac[IOT_MAC_ADDR_LEN] = {0}; uint32_t result = ERR_OK; *consumed = 0; if (iot_sg_cco_rt_mr_get_state() != IOT_SG_CCO_RT_AMR_STATE_RUN) { return ERR_NOT_READY; } if (cli_drv_data->req_sn != req->sn) { return ERR_INVAL; } switch (req->read_flag) { case SG_READ_PM_FAILED: { if (iot_mac_addr_cmp(cli_drv_data->cur_mr_pm, req->mac)) { os_mem_set(cli_drv_data->cur_mr_pm, 0, IOT_MAC_ADDR_LEN); if (0 == ++cli_drv_data->req_sn) { cli_drv_data->req_sn = 1; } iot_sg_route_control(IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_RT_CTRL_MR_FAILED); } break; } case SG_READ_PM_SUCCEED: { if (iot_mac_addr_cmp(cli_drv_data->cur_mr_pm, req->mac)) { os_mem_set(cli_drv_data->cur_mr_pm, 0, IOT_MAC_ADDR_LEN); if (0 == ++cli_drv_data->req_sn) { cli_drv_data->req_sn = 1; } iot_sg_route_control(IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_RT_CTRL_MR_SUCCESS); } break; } case SG_MAY_READ_PM: { if (!iot_mac_addr_cmp(cli_drv_data->cur_mr_pm, req->mac)) { return ERR_INVAL; } if (iot_sg_get_wl_entry_info_by_mac(req->mac, &node_info)) { /* failed to get meter info */ return ERR_NOT_EXIST; } if (0 == ++cli_drv_data->req_sn) { cli_drv_data->req_sn = 1; } iot_sg_get_cco_mac(cco_mac); /* update pkt to have meter reading data in its data block */ iot_pkt_set_data(pkt, req->data); iot_pkt_set_tail(pkt, req->data + req->data_len); result = (uint8_t)iot_sg_cco_cache_sg_mr_cmd(IOT_SG_RMT_ROUTER, req->sn, SG_AFN_RMT_ROUTER, req->proto_type, cco_mac, req->mac, pkt, IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_TASK_PRIO_3, iot_sg_cco_get_mr_timeout(IOT_SG_CALLER_TYPE_CLI, IOT_SG_RMT_ROUTER), 1, IOT_SG_INVALID_TASK_ID, 1, 0); if (ERR_OK == result) { *consumed = 1; iot_sg_cco_enable_mr(IOT_SG_CALLER_TYPE_CLI); } break; } default: result = ERR_INVAL; break; } return result; } /** * @brief iot_cli_drv_route_mr_data() - running route meter * reading data task * @param req: cli request route meter reading data cmd down link * @param pkt: iot_pkt_t containing the cli request pkt. * @return 0 - iot_pkt is not consumed. * otherwise - iot_pkt is consumed. */ static uint8_t iot_cli_drv_route_mr_data(iot_cli_sg_rpt_rt_mr_data_dl *req, iot_pkt_t *pkt) { iot_pkt_t *buf_pkt = NULL; iot_cli_sg_result_t *rsp = NULL; uint16_t rsp_len; uint8_t consumed = 0; /* allocate buffer for response */ rsp_len = iot_cli_sg_get_headroom_req() + sizeof(iot_cli_sg_result_t); buf_pkt = iot_pkt_alloc(rsp_len, IOT_SMART_GRID_MID); IOT_ASSERT(buf_pkt); /* fill response info */ rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt, iot_cli_sg_get_headroom_req()); if (!iot_sg_cco_is_ready()) { rsp->result = ERR_BUSY; goto end; } if (iot_sg_get_rt_mr_state() & IOT_SG_CALLER_TYPE_CCTT) { rsp->result = ERR_BUSY; goto end; } if (!iot_sg_cco_get_power_status()) { rsp->result = ERR_BUSY; goto end; } if (!iot_sg_cco_get_online_sta_count()) { rsp->result = ERR_BUSY; goto end; } rsp->result = ERR_OK; switch (req->action) { case IOT_CLI_SG_RT_START_MR_CMD: { /* restart : router shall restart meter reading*/ iot_sg_route_control(IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_RT_CTRL_RESTART); cli_drv_data->req_sn = 1; break; } case IOT_CLI_SG_RT_STOP_MR_CMD: { iot_sg_route_control(IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_RT_CTRL_MR_STOP); cli_drv_data->req_sn = 1; break; } case IOT_CLI_SG_RT_RUNNING_MR_CMD: { rsp->result = iot_cli_drv_run_rt_mr_data(req, pkt, &consumed); break; } default: rsp->result = ERR_INVAL; break; } end: iot_cli_sg_send_data_to_cli_interface(buf_pkt, IOT_CLI_SG_MSG_PRT_METER, 0); return consumed; } /** * @brief cli_drv_send_router_data_change - CCo to send router change msg * @param sn: sequence number. * @param mission_change: 1 - meter read finished * 2 - search meter finished * 3 - transformer detect finished * @param intf_type: see IOT_SG_CALLER_TYPE_XXX */ static void cli_drv_send_router_data_change(uint8_t sn, uint8_t mission_change, uint8_t intf_type) { (void)sn; (void)intf_type; if (IOT_SG_CCO_RT_CHG_STOP_SEARCH_METER == mission_change) { iot_sg_printf("%s stop search meter \n", __FUNCTION__); } else if (IOT_SG_CCO_RT_CHG_STOP_READ_METER == mission_change) { iot_sg_printf("%s stop meter reading \n", __FUNCTION__); } else if (IOT_SG_CCO_RT_CHG_STOP_TSFM_DETECT == mission_change) { iot_sg_printf("%s stop transformer detect \n", __FUNCTION__); } else { iot_sg_printf("%s get error mission change \n", __FUNCTION__); } } /** * @brief - report cctt meter data from CCO module. * @param data: report meter data * @param len: length of the data * @param afn: afn for meter reading * @param sn: concentrator cmd sn * @param proto_type: proto type of data * @param mac_field: address field of meter * @param mr_result: read meter result * @param plc_cost: time cost in PLC in 1ms * @param mr_type: meter read type, see IOT_SG_RMT_XXX * @param intf_type: see IOT_SG_CALLER_TYPE_XXX * @retval: 0 -- successful case * @retval: otherwise -- failure case */ static uint32_t cli_drv_rpt_meter_data_handler(uint8_t *data, uint16_t len, uint32_t afn, uint16_t sn, uint32_t proto_type, uint8_t *mac_field, uint8_t mr_result, uint32_t plc_cost, uint8_t mr_type, uint8_t intf_type) { (void)afn; (void)sn; (void)mac_field; (void)mr_result; (void)plc_cost; (void)mr_type; (void)intf_type; iot_cli_sg_rpt_mr_data_ul *rsp = NULL; iot_pkt_t *pkt = NULL; uint16_t pkt_len; if (NULL == data) { len = 0; } pkt_len = iot_cli_sg_get_headroom_req() + sizeof(*rsp) + len; pkt = iot_pkt_alloc(pkt_len, IOT_SMART_GRID_MID); IOT_ASSERT(pkt); /* fill response info */ rsp = (iot_cli_sg_rpt_mr_data_ul*)iot_pkt_reserve(pkt, iot_cli_sg_get_headroom_req()); rsp->result = ERR_OK; rsp->proto_type = (uint8_t)proto_type; rsp->sn = (uint8_t)sn; os_mem_cpy(rsp->mac, mac_field, IOT_MAC_ADDR_LEN); rsp->datalen = len; if (len) { os_mem_cpy(rsp->data, data, len); } iot_cli_sg_send_data_to_cli_interface(pkt, IOT_CLI_SG_MSG_PRT_METER_DATA, IOT_CLI_SG_REQ_ID_DEFAULT); return ERR_OK; } /** * @brief cli_drv_rt_req_read_meter - router request meter reading. * @param phase: power meter phase * @param mac: power meter mac address, little-endian * @param index: power meter index * @param obj_type: communication object type, see PROTO_3762_FJ_OBJ_XXX * @param intf_type: see IOT_SG_CALLER_TYPE_XXX */ void cli_drv_rt_req_read_meter(uint8_t phase, uint8_t *mac, uint16_t index, uint8_t obj_type, uint8_t intf_type) { (void)obj_type; (void)intf_type; iot_cli_request_rt_mr_data_ul dec_data = { 0 }; iot_mac_addr_cpy(dec_data.mac_addr, mac); dec_data.phase = phase; dec_data.node_index = index; dec_data.sn = cli_drv_data->req_sn; /* request read meter */ dec_data.opt_flag = IOT_SG_RT_MR_REQUEST; iot_cli_drv_request_rt_mr_data(&dec_data); iot_mac_addr_cpy(cli_drv_data->cur_mr_pm, mac); return; } static uint8_t iot_cli_drv_read_meter_data(iot_cli_sg_rpt_mr_data_dl *req, uint8_t req_id, iot_pkt_t *pkt) { iot_pkt_t *buf_pkt = NULL; iot_cli_sg_result_t *rsp =NULL; uint16_t rsp_len; uint8_t cco_mac[IOT_MAC_ADDR_LEN] = {0}; uint8_t consumed = 0; uint8_t afn = 0; uint8_t mr_result = 0; uint32_t mr_count = 0; /* allocate buffer for response */ rsp_len = iot_cli_sg_get_headroom_req() + sizeof(iot_cli_sg_result_t); buf_pkt = iot_pkt_alloc(rsp_len, IOT_SMART_GRID_MID); IOT_ASSERT(buf_pkt); /* fill response info */ rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt, iot_cli_sg_get_headroom_req()); if (!iot_sg_cco_is_ready()) { rsp->result = ERR_BUSY; goto end; } if (!iot_sg_cco_get_power_status()) { rsp->result = ERR_BUSY; goto end; } iot_mac_addr_reverse(req->mac); if (iot_sg_cco_get_wl_cnt() && (!iot_sg_cco_wl_entry_exist(req->mac))) { /* white list is not empty, */ /* meter to be read is not in white list. */ rsp->result = ERR_INVAL; iot_sg_printf("cli mr data inval, meter mac error \n"); goto end; } if (IOT_SG_RMT_CCTT_CON == req->mr_type) { mr_result = iot_sg_cco_check_exceed_con_cnt(req->mac); rsp->result = mr_result; if (ERR_OK != mr_result) { rsp->result = EXCEED_DEV_MAX_CONCURRENT_COUNT; goto end; } if ((req->proto_type == PROTO_TYPE_698_45 || req->proto_type == PROTO_TYPE_RAW_DATA) && req->data_len > IOT_SG_CON_MR_MAX_69845_LEN) { /* data type is 698.45, and length exceed max length, send NACK */ rsp->result = EXCEED_DEV_PKT_COUNT; goto end; } if (req->proto_type == PROTO_TYPE_645_1997 || req->proto_type == PROTO_TYPE_645_2007) { mr_count = iot_sg_cco_get_645_pkt_cnt(req->data, req->data_len); if (0 == mr_count) { rsp->result = ERR_INVAL; goto end; } if (mr_count > IOT_SG_CON_MR_MAX_645_CNT) { /* data type is 645, and packet exceed max count, send NACK */ rsp->result = EXCEED_DEV_PKT_COUNT; goto end; } } if (iot_sg_cco_cache_has_sg_mr_cmd(req->mac)) { rsp->result = ERR_EXIST; goto end; } afn = SG_AFN_RMT_CCTT_CON; } else if (IOT_SG_RMT_CCTT == req->mr_type) { if (iot_sg_cco_cache_has_sg_mr_cmd_ex(req->mac, req->sn)) { rsp->result = ERR_INVAL; goto end; } afn = SG_AFN_RMT_CCTT; } else { rsp->result = ERR_INVAL; goto end; } iot_sg_get_cco_mac(cco_mac); /* update pkt to have meter reading data in its data block */ iot_pkt_set_data(pkt, req->data); iot_pkt_set_tail(pkt, req->data + req->data_len); rsp->result = (uint8_t)iot_sg_cco_cache_sg_mr_cmd(req->mr_type, req->sn, afn, req->proto_type, cco_mac, req->mac, pkt, IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_TASK_PRIO_3, iot_sg_cco_get_mr_timeout(IOT_SG_CALLER_TYPE_CLI, req->mr_type), 1, IOT_SG_INVALID_TASK_ID, 1, 0); if (rsp->result == ERR_OK) { consumed = 1; iot_sg_cco_enable_mr(IOT_SG_CALLER_TYPE_CLI); } else { rsp->result = ERR_INVAL; if (IOT_SG_RMT_CCTT_CON == req->mr_type) { rsp->result = EXCEED_DEV_MAX_CONCURRENT_COUNT; } } end: iot_cli_sg_send_data_to_cli_interface(buf_pkt, IOT_CLI_SG_MSG_PRT_METER, req_id); return consumed; } static void iot_cli_start_get_meter_list( iot_cli_sg_start_sec_node_reg_dl_t *data, uint8_t req_id) { uint32_t dur_s = 0; iot_cli_sg_result_t *rsp; iot_pkt_t *buf_pkt; uint16_t rsp_len; /* allocate buffer for response */ rsp_len = iot_cli_sg_get_headroom_req() + sizeof(iot_cli_sg_result_t); buf_pkt = iot_pkt_alloc(rsp_len, IOT_SMART_GRID_MID); IOT_ASSERT(buf_pkt); /* fill response info */ rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt, iot_cli_sg_get_headroom_req()); if (!iot_sg_cco_get_router_sec_node_reg_allowed()) { rsp->result = ERR_NOSUPP; } else if (iot_sg_cco_get_tsfm_detect_status() != IOT_SG_CCO_TSFM_DETECT_DONE) { rsp->result = ERR_BUSY; } else { if (data->duration == 0) { data->duration = IOT_CLI_DEFAULT_SEC_NODE_REG_DUR; } dur_s = data->duration * IOT_CLI_SEC_NODE_REG_TIME_UNIT_DUR; rsp->result = (uint8_t)iot_sg_start_sec_node_reg( IOT_SG_CALLER_TYPE_CLI, dur_s, IOT_CLI_MAX_ADDR_COUNT, 1); } iot_cli_sg_send_data_to_cli_interface(buf_pkt, IOT_CLI_SG_MSG_RPT_START_METER_LIST, req_id); } /** * @brief: iot_cli_handle_report_ack - deal with ack data that from cli. * @param pkt: iot_pkt is ack data form cli * pkt is not consumed */ static void iot_cli_handle_report_ack(iot_pkt_t *pkt) { iot_cli_sg_rpt_ack_dl_t *report_ack = NULL; uint8_t pre_sn = cli_drv_data->req_sn; if (!pkt) { return; } report_ack = (iot_cli_sg_rpt_ack_dl_t *)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA); iot_printf("%s get cli ack type: %d \n", __FUNCTION__, report_ack->type); switch (report_ack->type) { case IOT_CLI_SG_MR_DATA_RSP: { if (iot_sg_get_rt_mr_state() & IOT_SG_CALLER_TYPE_CLI) { pre_sn = (0 == pre_sn ? 255 : (pre_sn - 1)); if (report_ack->sn == pre_sn) { iot_sg_cco_recv_ack_to_report(1, report_ack->sn); iot_sg_cco_rt_mr_result_ack(report_ack->sn); } } break; } case IOT_CLI_SG_SEC_NODE_REG_DATA_RSP: { iot_sg_cco_recv_ack_to_report(1, report_ack->sn); break; } default: break; } } /** * @brief: cli_drv_data_handler - handle data from CLI * @param channel: data sources. * @param pkt: iot_pkt containing data to be process * @retval: 0-iot_pkt is not consumed * @retval: otherwise iot_pkt is consumed */ static uint32_t cli_drv_data_handler(uint8_t channel, iot_pkt_t *pkt, uint32_t ntb) { uint32_t consumed = 0; iot_cli_sg_rpt_mr_data_dl *req; iot_cli_sg_rpt_rt_mr_data_dl *rt_req; iot_cli_sg_msg_header_t *hdr; iot_cli_sg_start_sec_node_reg_dl_t *start_reg_req; uint8_t* data_ptr = iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA); hdr = (iot_cli_sg_msg_header_t *)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD); (void)ntb; (void)channel; switch (hdr->msg_id) { case IOT_CLI_SG_MSG_GET_METER: { /* handle con mr/cctt active mr */ req = (iot_cli_sg_rpt_mr_data_dl *)data_ptr; consumed = iot_cli_drv_read_meter_data(req, hdr->req_id, pkt); break; } case IOT_CLI_SG_MSG_GET_RT_METER: { /* handle router meter reading. */ rt_req = (iot_cli_sg_rpt_rt_mr_data_dl *)data_ptr; consumed = iot_cli_drv_route_mr_data(rt_req, pkt); break; } case IOT_CLI_SG_MSG_START_METER_LIST: { start_reg_req = (iot_cli_sg_start_sec_node_reg_dl_t *)data_ptr; iot_cli_start_get_meter_list(start_reg_req, hdr->req_id); break; } case IOT_CLI_SG_MSG_STOP_METER_LIST: { iot_sg_stop_sec_node_reg(IOT_SG_CALLER_TYPE_CLI, IOT_SG_CCO_STOP_SEC_NODE_REG_CLI); break; } case IOT_CLI_SG_MSG_GET_REPORT_ACK: { iot_cli_handle_report_ack(pkt); break; } default: iot_sg_printf("%s unable to handle msg id: 0n%d\n", __FUNCTION__, hdr->msg_id); break; } return consumed; } static uint32_t cli_drv_sec_node_info_handler(uint8_t sn, uint16_t index, sec_node_query_t *sec_node_info) { iot_cli_sg_rpt_sec_node_info_ul_t *rsp = NULL; uint16_t pkt_len = 0; uint8_t cnt = 0, i = 0; iot_pkt_t *pkt; (void)index; cnt = sec_node_info->contain_sec_node_count; pkt_len = sizeof(*rsp) + sizeof(iot_cli_sg_sec_node_info_t) * cnt; pkt_len += iot_cli_sg_get_headroom_req(); pkt = iot_pkt_alloc(pkt_len, IOT_SMART_GRID_MID); if (pkt == NULL) { return ERR_NOMEM; } /* fill response info */ rsp = (iot_cli_sg_rpt_sec_node_info_ul_t*)iot_pkt_reserve(pkt, iot_cli_sg_get_headroom_req()); for (i = 0; i < sec_node_info->contain_sec_node_count; i++) { rsp->node_info[i].proto_type = sec_node_info->node_info[i].proto_type & 0x0F; rsp->node_info->dev_type = iot_sg_cco_get_node_cli_dev_type(sec_node_info->dev_type) & 0x0F; iot_mac_addr_cpy(rsp->node_info[i].sta_mac, sec_node_info->sta_addr); iot_mac_addr_cpy(rsp->node_info[i].meter_mac, sec_node_info->node_info[i].mac); } rsp->sn = sn; rsp->sec_node_count = 1; rsp->rsp_sec_node_count = i; iot_pkt_put(pkt, pkt_len - iot_cli_sg_get_headroom_req()); iot_cli_sg_send_data_to_cli_interface(pkt, IOT_CLI_SG_MSG_PRT_SEARCH_METER_LIST, IOT_CLI_SG_REQ_ID_DEFAULT); return ERR_OK; } static uint32_t cli_drv_rpt_event_data_handler(uint8_t sn, uint8_t *pm_addr, uint8_t dev_type, uint32_t proto_type, uint8_t evt_type, uint8_t *data, uint16_t len) { (void)sn; (void)pm_addr; (void)dev_type; (void)proto_type; (void)evt_type; (void)data; (void)len; return ERR_OK; } static uint32_t cli_drv_rpt_topo_handler( uint8_t req_id, iot_plc_nw_topo_rpt_t *rpt) { (void)rpt; (void)req_id; return ERR_OK; } static uint32_t cli_drv_rpt_neighbor_net_handler(uint8_t req_id, iot_sg_nb_nw_rpt_t *req) { (void)req_id; (void)req; return ERR_OK; } static uint32_t cli_drv_rpt_freq_band_handler(uint8_t req_id, iot_plc_freq_band_info_query_rpt_t *req) { (void)req_id; (void)req; return ERR_OK; } static uint32_t cli_drv_rpt_freq_band_set_result_handler(uint8_t req_id, uint8_t result) { (void)result; (void)req_id; return ERR_OK; } static uint32_t cli_drv_rpt_rf_channel_set_result_handler(uint8_t req_id, uint8_t result) { (void)result; (void)req_id; return ERR_OK; } static uint32_t cli_drv_rpt_tx_power_set_result_handler(uint8_t req_id, uint8_t result) { (void)result; (void)req_id; return ERR_OK; } static void cli_drv_rpt_nw_info_handler(uint8_t req_id, iot_plc_nw_info_query_rpt_t *rpt) { (void)req_id; (void)rpt; } static void cli_drv_timer_handler() { } static void cli_drv_log_to_flash_timer_handler() { } static uint8_t cli_drv_sta_state_chg_handler(uint8_t state, uint8_t *sta_mac) { (void)sta_mac; (void)state; return 0; } static void cli_drv_rpt_tsfm_detect_ret_handler(uint8_t *pm_mac, uint8_t *tsfm_addr, uint8_t tsfm_status, uint8_t dev_type) { (void)pm_mac; (void)tsfm_addr; (void)tsfm_status; (void)dev_type; } static uint8_t cli_drv_mr_data_valid_handler(uint8_t mr_type, uint8_t *pm_addr) { (void)pm_addr; (void)mr_type; return 1; } static void cli_drv_tsfm_detect_done_handler(uint8_t tsfm_is_timeout) { (void)tsfm_is_timeout; } static void cli_drv_rpt_reject_join_handler(iot_plc_sta_join_rejected_t *node) { (void)node; } static void cli_drv_cco_state_chg_handler(uint8_t curr_state, uint8_t next_state, uint8_t *cert_flag_chg) { (void)curr_state; (void)next_state; (void)cert_flag_chg; } static void cli_drv_rpt_node_info_handler(uint8_t req_id, iot_plc_node_info_rpt_t *rpt) { (void)req_id; (void)rpt; } static uint32_t cli_drv_data_to_cctt_handler(iot_pkt_t *pkt) { iot_pkt_free(pkt); return ERR_OK; } static void cli_drv_nw_fmt_done_handler(void) { } static void cli_drv_handle_node_state_chg_rpt(uint8_t sn, sec_node_state_chg_t *node_chg) { (void)sn; (void)node_chg; } static void cli_drv_neighbor_dev_rpt(uint8_t req_id, iot_plc_neighbor_dev_rpt_t *rpt) { (void)req_id; (void)rpt; } static void cli_drv_cco_info_rpt(uint8_t req_id, iot_sg_cco_info_rpt_t *rpt) { (void)req_id; (void)rpt; } static void cli_drv_bcast_result_rpt(uint8_t done) { (void)done; } iot_sg_cco_drv_t iot_sg_cli_drv = { .drv_id = IOT_SG_CCTT_DRV_ID_CLI, .init = cli_drv_init, .deinit = cli_drv_deinit, .data_type_mask = 0xFFFF, .headroom = 0, .meter_data_report_cb = cli_drv_rpt_meter_data_handler, .event_data_report_cb = cli_drv_rpt_event_data_handler, .sec_node_report_cb = cli_drv_sec_node_info_handler, .topo_report_cb = cli_drv_rpt_topo_handler, .neighbour_net_report_cb = cli_drv_rpt_neighbor_net_handler, .freq_band_report_cb = cli_drv_rpt_freq_band_handler, .freq_band_set_result_report_cb = cli_drv_rpt_freq_band_set_result_handler, .rf_channel_set_result_report_cb = cli_drv_rpt_rf_channel_set_result_handler, .tx_power_set_result_report_cb = cli_drv_rpt_tx_power_set_result_handler, .nw_info_rpt_cb = cli_drv_rpt_nw_info_handler, .report_router_status_change = cli_drv_send_router_data_change, .cctt_data_handler = cli_drv_data_handler, .timer1_func = cli_drv_timer_handler, .timer2_func = cli_drv_timer_handler, .timer3_func = cli_drv_timer_handler, .timer4_func = cli_drv_timer_handler, .timer5_func = cli_drv_timer_handler, .timer6_func = cli_drv_timer_handler, .log_to_flash_timer_func = cli_drv_log_to_flash_timer_handler, .sta_state_chg_cb = cli_drv_sta_state_chg_handler, .rpt_tsfm_detect_ret_cb = cli_drv_rpt_tsfm_detect_ret_handler, .cco_status_chg_cb = cli_drv_cco_state_chg_handler, .mr_data_valid_cb = cli_drv_mr_data_valid_handler, .node_info_rpt_cb = cli_drv_rpt_node_info_handler, .rt_request_mr_cb = cli_drv_rt_req_read_meter, .tsfm_detect_done_cb = cli_drv_tsfm_detect_done_handler, .reject_join_cb = cli_drv_rpt_reject_join_handler, .passthrough_to_cctt_cb = cli_drv_data_to_cctt_handler, .nw_fmt_done_cb = cli_drv_nw_fmt_done_handler, .node_state_chg_cb = cli_drv_handle_node_state_chg_rpt, .neighbor_dev_report_cb = cli_drv_neighbor_dev_rpt, .cco_info_report_cb = cli_drv_cco_info_rpt, .cco_rpt_bcast_result_cb = cli_drv_bcast_result_rpt, }; #endif /* IOT_SMART_GRID_ENABLE && PLC_SUPPORT_CCO_ROLE */