#include "cm_common.h"

typedef struct
{
    char *topic_get;
    char *topic_set;
    char *cfg_file;
    char *version_name;
} cfg_manage_t;

const char *version_name[] =
    {
        "soft_ver",
        "hard_ver",
        "net_cfg_ver",
        "lora_cfg_ver",
        "rs485_cfg_ver",
        "nodes_cfg_ver",
        "rules_cfg_ver",
        "templates_cfg_ver",
        "objectmodel_cfg_ver",
        "platform_cfg_ver",
        "vport_cfg_ver",
        "can_cfg_ver",
        "logserver_cfg_ver",
        "wan_cfg_ver",
        "macipbind_cfg_ver",
        "common_socket_cfg_ver",
        "wifi_cfg_ver",
        "multi_mqtt_cld_ver",
};

cfg_manage_t cfg_manage[] =
    {
        {TOPIC_GET_MULTI_MQTT_CLD, TOPIC_SET_MULTI_MQTT_CLD, CLOUD_MQTT_CFG, "multi_mqtt_cld_ver"},
        {TOPIC_GET_SERVERREDIRECT, TOPIC_SET_SERVERREDIRECT, MQTT_SERVER_FILE, "mqtt_server_ver"},
        {TOPIC_GET_NODES_CFG, TOPIC_SET_NODES_CFG, NODES_CFG_PATH, "nodes_cfg_ver"},
        {TOPIC_GET_TEMPL_CFG, TOPIC_SET_TEMPL_CFG, TEMPLATES_CFG_PATH, "templates_cfg_ver"},
        {TOPIC_GET_OBJ_CFG, TOPIC_SET_OBJ_CFG, OBJECTS_CFG_PATH, "objectmodel_cfg_ver"},
        {TOPIC_GET_RS485_CFG, TOPIC_SET_RS485_CFG, RS485_PORT_CFG, "rs485_cfg_ver"},
        {TOPIC_GET_COMMON_SOCKET_CFG, TOPIC_SET_COMMON_SOCKET_CFG, COMMON_SOCKET_CFG, "common_socket_cfg_ver"},
        {TOPIC_GET_HUAYUN_CFG, TOPIC_SET_HUAYUN_CFG, HUAYUN_CFG, "huayun_cfg_ver"},
        {TOPIC_GET_LORAWANCFG, TOPIC_SET_LORAWANCFG, LORAWAN_MODULE_CFG, "lorawan_cfg_ver"},
        {TOPIC_GET_LORACFG, TOPIC_SET_LORACFG, LORA_MODULE_CFG, "lora_cfg_ver"},
        {TOPIC_GET_RULESENGINECFG, TOPIC_SET_RULESENGINECFG, RULES_CFG_LOCAL, "rules_cfg_ver"},
        {TOPIC_GET_GATEWAYWANCFG, TOPIC_SET_GATEWAYWANCFG, NETWORk_WAN_CFG, "wan_cfg_ver"},
        {TOPIC_GET_GATEWAYLANCFG, TOPIC_SET_GATEWAYLANCFG, NETWORk_LAN_CFG, "lan_cfg_ver"},
        {TOPIC_GET_MACIPBIND, TOPIC_SET_MACIPBIND, MAC_IP_BIND_CFG, "macipbind_cfg_ver"},
        {TOPIC_GET_RADIOCFG, TOPIC_SET_RADIOCFG, RADIO_CFG, "radio_cfg_ver"},
        {TOPIC_GET_GATEWAYVAPCFG, TOPIC_SET_GATEWAYVAPCFG, VAP_CFG, "vap_cfg_ver"},
        {TOPIC_GET_CANCFG, TOPIC_SET_CANCFG, CAN_MODULE_CFG, "can_cfg_ver"},
        {TOPIC_GET_LOGSERVERCFG, TOPIC_SET_LOGSERVERCFG, LOG_SRV_CFG, "logserver_cfg_ver"},
        {TOPIC_GET_VPORTCFG, TOPIC_SET_VPORTCFG, VIRTUAL_PORT_CFG, "vport_cfg_ver"},
        {TOPIC_GET_NTPSERVERCFG, TOPIC_SET_NTPSERVERCFG, NTP_CFG, "ntp_cfg_ver"},
        {NULL, TOPIC_SET_USERNAME_PASS, WEBUI_CFG, NULL},
        {TOPIC_GET_SUPOS_CFG, TOPIC_SET_SUPOS_CFG, LANZHUO_CFG, "supos_cfg_ver"},
};

static error_code_msg_t test_code_tab[] =
    {
        {TEST_OK, "successful"},
        {SYSTEM_RUN_ERR, "shell call error"},
        {NOT_WAN_PARAM_ERR, "can't find wan param"},
        {BROKER_CONN_ERR, "Can't connect the broker"},
        {CMD_PARSER_ERR, "json parser fail"},
        //shell exit status
        {1, "cmd run fail"},
        {2, "DNS invalid"},
        {3, "internet can't connect"},
        {4, "PPPoE call fail"},
};

static char *get_config_info(char *data)
{
    char url[256] = {0};

    if (json_pkt_json_url(data, url) == 0)
    {
        char *file = GetFileName(url);
        int ret;

        ret = download_file("/tmp", url, 10);
        if (ret != 0)
        {
            dy_syslog(LOG_INFO, "download file fail");
            return NULL;
        }

        char buff[256];
        char *url_v = NULL;
        sprintf(buff, "/tmp/%s", file);
        url_v = read_file_data(buff);
        if (url_v == NULL)
        {
            dy_syslog(LOG_INFO, "read file fail");
            return NULL;
        }
        unlink(buff);
        return url_v;
    }
    return NULL;
}

static void dev_script_del_all(cm_var_t *var)
{
    char cmd[64] = {0};

    snprintf(cmd, sizeof(cmd), "rm -rf %s/*", PARSE_SCRIPT_DIR);
    system(cmd);
}

static void lan_wan_cfg_free(lan_wan_cfg_t *cfg)
{
    free(cfg->pppoe_username);
    free(cfg->pppoe_password);
    free(cfg->ipaddr);
    free(cfg->netmask);
    free(cfg->gateway);
    free(cfg->dnss);
    free(cfg->dhcp);
}

static int lan_wan_cfg_parse(lan_wan_cfg_t *cfg, const char *str)
{
    if (!str || !cfg)
    {
        return -1;
    }
    cJSON *root = cJSON_Parse(str);
    if (!root)
    {
        return -1;
    }
    GET_JSON_VALUE_INT(root, "mi", cfg->mi);
    GET_JSON_VALUE_INT(root, "ip_type", cfg->ip_type);
    GET_JSON_VALUE_DY_STRING(root, "pppoe_username", cfg->pppoe_username);
    GET_JSON_VALUE_DY_STRING(root, "pppoe_password", cfg->pppoe_password);
    GET_JSON_VALUE_DY_STRING(root, "ipaddr", cfg->ipaddr);
    GET_JSON_VALUE_DY_STRING(root, "netmask", cfg->netmask);
    GET_JSON_VALUE_DY_STRING(root, "gateway", cfg->gateway);
    GET_JSON_VALUE_DY_STRING(root, "dnss", cfg->dnss);
    GET_JSON_VALUE_DY_STRING(root, "dhcp", cfg->dhcp);
    GET_JSON_VALUE_INT(root, "dhcp_server_enable", cfg->dhcp_server_enable);
    GET_JSON_VALUE_INT(root, "dhcp_start", cfg->shcp_start);
    GET_JSON_VALUE_INT(root, "dhcp_limit", cfg->dhcp_limit);
    GET_JSON_VALUE_INT(root, "dhcp_leasetime", cfg->dhcp_leasetime);
    GET_JSON_VALUE_INT(root, "bridge", cfg->bridge);
    cJSON_Delete(root);
    return 0;
}

static int run_wan_test_bash(lan_wan_cfg_t *cfg)
{
    pid_t status;
    char exec_cmd[256] = {0};
    memset(exec_cmd, 0, sizeof(exec_cmd));
    if (cfg->tpte == 0) //wan
    {
        char *dnss1, *dnss2, dnss[50] = {0};
        dnss1 = dnss2 = NULL;
        if (cfg->dnss)
        {
            dnss1 = malloc(strlen(cfg->dnss) + 1);
            memset(dnss1, 0, strlen(cfg->dnss));
            dnss2 = malloc(strlen(cfg->dnss) + 1);
            memset(dnss2, 0, strlen(cfg->dnss));
            int dns_cnt = sscanf(cfg->dnss, "%s %s", dnss1, dnss2);
            if (dns_cnt == 0)
            {
                memset(dnss, 0, sizeof(dnss));
            }
            else if (dns_cnt == 1)
            {
                sprintf(dnss, " -d %s", dnss1);
            }
            else if (dns_cnt == 2)
            {
                sprintf(dnss, " -d %s,%s", dnss1, dnss2);
            }
        }
        if (cfg->ip_type == 0)
        {
            sprintf(exec_cmd, "%s%s wan %s ", NET_BASH_PATH, "test_wan_dhcp.sh", dnss);
            status = system(exec_cmd);
            if (WIFEXITED(status))
            {
                return WEXITSTATUS(status);
            }
            else
            {
                return SYSTEM_RUN_ERR;
            }
        }
        else if (cfg->ip_type == 1)
        {
            sprintf(exec_cmd, "%s%s wan %s %s/%s %s,%s", NET_BASH_PATH, "test_wan_static_ip.sh", cfg->gateway, cfg->ipaddr, cfg->netmask, dnss1, dnss2);
            status = system(exec_cmd);
            free(dnss1);
            free(dnss2);
            if (WIFEXITED(status))
            {
                return WEXITSTATUS(status);
            }
            else
            {
                return SYSTEM_RUN_ERR;
            }
        }
        else if (cfg->ip_type == 2)
        {
            sprintf(exec_cmd, "%s%s wan %s %s -k %d %s", NET_BASH_PATH, "test_wan_pppoe.sh", cfg->pppoe_username, cfg->pppoe_password, 3, dnss);
            status = system(exec_cmd);
            if (WIFEXITED(status))
            {
                return WEXITSTATUS(status);
            }
            else
            {
                return SYSTEM_RUN_ERR;
            }
        }
    }
    else
    {
        return NOT_WAN_PARAM_ERR;
    }
    return 0;
}

static int run_network_cfg_bash(lan_wan_cfg_t *cfg)
{

    pid_t status;
    char exec_cmd[256] = {0};
    memset(exec_cmd, 0, sizeof(exec_cmd));
    if (cfg->tpte == 0) //wan
    {
        char *dnss1, *dnss2, dnss[50] = {0}, dnss_no_d[50] = {0};
        if (cfg->dnss)
        {
            dnss1 = malloc(strlen(cfg->dnss) + 1);
            memset(dnss1, 0, strlen(cfg->dnss));
            dnss2 = malloc(strlen(cfg->dnss) + 1);
            memset(dnss2, 0, strlen(cfg->dnss));
            int dns_cnt = sscanf(cfg->dnss, "%s %s", dnss1, dnss2);
            if (dns_cnt == 0)
            {
                memset(dnss, 0, sizeof(dnss));
            }
            else if (dns_cnt == 1)
            {
                sprintf(dnss, " -d %s", dnss1);
                sprintf(dnss_no_d, "%s", dnss1);
            }
            else if (dns_cnt == 2)
            {
                sprintf(dnss, " -d %s,%s", dnss1, dnss2);
                sprintf(dnss_no_d, "%s,%s", dnss1, dnss2);
            }
            dy_syslog(LOG_INFO, "merge dns1:%s,dns2:%s >> dns:%s", dnss1, dnss2, dnss_no_d);
            free(dnss1);
            free(dnss2);
        }
        if (cfg->ip_type == 0)
        {
            sprintf(exec_cmd, "%s%s wan %s -S", NET_BASH_PATH, "set_wan_dhcp.sh", dnss);
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }
        }
        else if (cfg->ip_type == 1)
        {
            sprintf(exec_cmd, "%s%s wan %s %s/%s %s -S", NET_BASH_PATH, "set_wan_static_ip.sh", cfg->gateway, cfg->ipaddr, cfg->netmask, dnss_no_d);
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }
        }
        else if (cfg->ip_type == 2)
        {
            sprintf(exec_cmd, "%s%s wan %s %s -k %d %s -S", NET_BASH_PATH, "set_wan_pppoe.sh", cfg->pppoe_username, cfg->pppoe_password, 3, dnss);
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }
        }
    }
    else //lan
    {
        if (cfg->ip_type == 1)
        {
            sprintf(exec_cmd, "%s%s %s", NET_BASH_PATH, "set_bridge.sh", (cfg->bridge != 0) ? "set" : "del");
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }

            sprintf(exec_cmd, "%s%s set lan --ipaddr %s --netmask %s -S", NET_BASH_PATH, "set_vlan.sh", cfg->ipaddr, cfg->netmask);
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }

            sprintf(exec_cmd, "%s%s set lan --start %d --limit %d --lease %d %s", NET_BASH_PATH, "set_dhcp_server.sh", cfg->shcp_start, cfg->dhcp_limit, cfg->dhcp_leasetime, (cfg->dhcp_server_enable != 0) ? "" : "-D");
            status = system(exec_cmd);
            if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                dy_syslog(LOG_INFO, "system run:%s", exec_cmd);
            }
            else
            {
                goto system_run_err;
            }
        }
    }
    return ERR_CODE_NONE;
system_run_err:
    dy_syslog(LOG_WARNING, "system run:%s, error 0x%x", exec_cmd, status);
    return ERR_CODE_CMD_PARAM;
}

static void msg_test_result(cm_var_t *var, int mi, int code, char *t)
{
    char topic[256] = {0};
    cJSON *root = cJSON_CreateObject();
    if (root == NULL)
    {
        return;
    }
    cJSON_AddNumberToObject(root, "mi", mi);
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    cJSON_AddNumberToObject(root, "error_code", code);
    char *err_msg = NULL;
    int i;
    for (i = 0; i < sizeof(test_code_tab) / sizeof(test_code_tab[0]); i++)
    {
        if ((int)test_code_tab[i].code == code)
        {
            err_msg = test_code_tab[i].msg;
            break;
        }
    }
    cJSON_AddStringToObject(root, "error_msg", err_msg);
    char *str = (cJSON_Print(root));
    cJSON_Delete(root);

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, t);
    ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));
    free(str);
}

static int msg_test_gateway_net_wan(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = CMD_PARSER_ERR;
    lan_wan_cfg_t cfg;

    memset(&cfg, 0, sizeof(cfg));
    cfg.tpte = 0;

    if (lan_wan_cfg_parse(&cfg, mqtt_msg->payload) == 0)
    {
        ret = run_wan_test_bash(&cfg);
    }
    lan_wan_cfg_free(&cfg);
    msg_test_result(var, cfg.mi, ret, TOPIC_SET_GATEWAYWANTEST);
    return 0;
}

static int msg_test_mqtt_broker(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = CMD_PARSER_ERR;
    char host[64] = {0};
    int port = -1;
    char user[32] = {0};
    char pass[32] = {0};
    int mi = 0;
    char exec_cmd[256] = {0};
    int len = 0;
    pid_t status;

    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        ret = CMD_PARSER_ERR;
        goto out;
    }

    GET_JSON_VALUE_INT(root, "mi", mi);
    GET_JSON_VALUE_STRING(root, "host", host);
    GET_JSON_VALUE_INT(root, "port", port);
    GET_JSON_VALUE_STRING(root, "user", user);
    GET_JSON_VALUE_STRING(root, "pass", pass);

    len = sprintf(exec_cmd, "mosquitto_pub -h %s -p %d -n -t test", host, port);
    if (strlen(user) != 0 && strlen(pass) != 0)
    {
        sprintf(exec_cmd + len, " -u %s -P %s", user, pass);
    }

    status = system(exec_cmd);

    if (WIFEXITED(status))
    {
        if (WEXITSTATUS(status))
        {
            ret = BROKER_CONN_ERR;
        }
        else
        {
            ret = TEST_OK;
        }
    }
    else
    {
        return SYSTEM_RUN_ERR;
    }

out:
    msg_test_result(var, mi, ret, TOPIC_SET_MQTT_BROKER_TEST);
    return ret;
}

static int msg_set_gateway_net_wan_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = ERR_CODE_JSON_FORMAT;
    lan_wan_cfg_t cfg;

    memset(&cfg, 0, sizeof(cfg));
    cfg.tpte = 0;
    if (lan_wan_cfg_parse(&cfg, mqtt_msg->payload) == 0)
    {
        ret = run_network_cfg_bash(&cfg);
    }
    lan_wan_cfg_free(&cfg);

    pthread_mutex_lock(&var->restart_flag_lock);
    bit_set(var->restart_flag, BIT_NETWORK_RESTART, 1);
    pthread_mutex_unlock(&var->restart_flag_lock);
    return ret;
}

static int msg_set_gateway_net_lan_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = ERR_CODE_JSON_FORMAT;
    lan_wan_cfg_t cfg;

    memset(&cfg, 0, sizeof(cfg));
    cfg.tpte = 1;
    if (lan_wan_cfg_parse(&cfg, mqtt_msg->payload) == 0)
    {
        ret = run_network_cfg_bash(&cfg);
    }

    lan_wan_cfg_free(&cfg);

    pthread_mutex_lock(&var->restart_flag_lock);
    bit_set(var->restart_flag, BIT_NETWORK_RESTART, 1);
    pthread_mutex_unlock(&var->restart_flag_lock);

    return ret;
}

static int mac_ips_bind_info_parse(net_mac_ips_t *tab, const char *str)
{
    if (!str || !tab)
    {
        return -1;
    }
    int i;
    cJSON *root = cJSON_Parse(str);
    if (!root)
    {
        return -1;
    }
    cJSON *mac_ips = cJSON_GetObjectItem(root, "mac_ips");
    if (!mac_ips)
    {
        return -1;
    }
    tab->add_cnt = cJSON_GetArraySize(mac_ips);
    if (tab->add_cnt)
    {
        tab->add_list = calloc(tab->add_cnt, sizeof(int *));
    }
    if (tab->add_list == NULL)
    {
        dy_syslog(LOG_ERR, "mac ip add size %d,memaddr %p", tab->add_cnt, tab->add_list);
        return -1;
    }
    for (i = 0; i < tab->add_cnt; i++)
    {
        cJSON *mac_ip_add = cJSON_GetArrayItem(mac_ips, i);
        if (mac_ip_add)
        {
            tab->add_list[i] = malloc(sizeof(net_mac_ip_t));
            memset(tab->add_list[i], 0, sizeof(net_mac_ip_t));

            GET_JSON_VALUE_DY_STRING(mac_ip_add, "ip", tab->add_list[i]->ip);
            GET_JSON_VALUE_DY_STRING(mac_ip_add, "id", tab->add_list[i]->id);
            GET_JSON_VALUE_DY_STRING(mac_ip_add, "name", tab->add_list[i]->name);
            GET_JSON_VALUE_DY_STRING(mac_ip_add, "mac", tab->add_list[i]->mac);
        }
    }
    cJSON_Delete(root);
    return 0;
}

static int run_mac_ips_bind_bash(net_mac_ips_t *tab)
{
    pid_t status;
    char exec_cmd[256] = {0};
    memset(exec_cmd, 0, sizeof(exec_cmd));
    int i;
    sprintf(exec_cmd, "%s%s del", NET_BASH_PATH, "set_mac_ip.sh");
    status = system(exec_cmd);
    if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
    {
        dy_syslog(LOG_ERR, "clear mac ip bind table failed");
        return -1;
    }
    for (i = 0; i < tab->add_cnt; i++)
    {
        net_mac_ip_t *tmp = tab->add_list[i];
        if (tmp->name)
        {
            sprintf(exec_cmd, "%s%s set %s --mac %s --ip %s --name %s", NET_BASH_PATH, "set_mac_ip.sh", tmp->id, tmp->mac, tmp->ip, tmp->name);
        }
        else
        {
            sprintf(exec_cmd, "%s%s set %s --mac %s --ip %s", NET_BASH_PATH, "set_mac_ip.sh", tmp->id, tmp->mac, tmp->ip);
        }
        status = system(exec_cmd);
    }
    if (WIFEXITED(status))
    {
        return WEXITSTATUS(status);
    }
    return -1;
}

static int free_mac_ips_bind_table(net_mac_ips_t *tab)
{
    int i;
    for (i = 0; i < tab->add_cnt; i++)
    {
        net_mac_ip_t *tmp = tab->add_list[i];
        if (tmp->id)
        {
            free(tmp->id);
        }
        if (tmp->name)
        {
            free(tmp->name);
        }
        if (tmp->ip)
        {
            free(tmp->ip);
        }
        if (tmp->mac)
        {
            free(tmp->mac);
        }
        free(tab->add_list[i]);
    }
    if (i > 0)
    {
        free(tab->add_list);
    }
    return 0;
}

static int msg_set_mac_ip_bind_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    net_mac_ips_t tab = {0};

    mac_ips_bind_info_parse(&tab, mqtt_msg->payload);
    run_mac_ips_bind_bash(&tab);
    free_mac_ips_bind_table(&tab);

    return 0;
}

static int msg_get_lan_status(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char exec_cmd[256] = {0};
    char *buff = NULL;
    char topic[256] = {0};

    sprintf(exec_cmd, "%s%s status", NET_BASH_PATH, "fetch_dhcp_mac_status.sh");
    system_reply(exec_cmd, &buff);
    if (!buff)
    {
        dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
        return -1;
    }
    int msgid = json_pkt_json_mi(mqtt_msg->payload);
    char *json = json_pkt_add_mi2str(buff, msgid);
    free(buff);

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_RSP_LANDEVICESTATUS);
    ipc_session_publish(var->session, topic, (unsigned char *) json, strlen(json));
    free(json);

    return 0;
}

static int msg_set_radio_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    pid_t status;
    char exec_cmd[256] = {0};
    memset(exec_cmd, 0, sizeof(exec_cmd));
    int i;
    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        return -1;
    }
    cJSON *radio_list = cJSON_GetObjectItem(root, "radio_list");
    if (!radio_list)
    {
        return -1;
    }
    int radio_cnt = cJSON_GetArraySize(radio_list);
    for (i = 0; i < radio_cnt; i++)
    {
        cJSON *radio = cJSON_GetArrayItem(radio_list, i);
        if (radio)
        {
            cJSON *disabled = cJSON_GetObjectItem(radio, "disabled");
            char *alias = cJSON_GetItemString(radio, "alias");
            int radio_idx = -1;

            sscanf(alias, "radio%d", &radio_idx);
            if (radio_idx == -1)
            {
                dy_syslog(LOG_ERR, "wrong alias:%s", alias);
                continue;
            }

            if (disabled && disabled->valueint)
            {
                sprintf(exec_cmd, "%s%s stop -radio %d -S", NET_BASH_PATH, "set_radio.sh", radio_idx);
            }
            else
            {
                char *channel = cJSON_GetItemString(radio, "channel");
                char *hwmode = cJSON_GetItemString(radio, "hwmode");
                char *htmode = cJSON_GetItemString(radio, "htmode");
                char *txpower = cJSON_GetItemString(radio, "txpower");
                sprintf(exec_cmd, "%s%s set -radio %d -channel %s -hwmode %s -htmode %s -txpower %s -alias %s -S", NET_BASH_PATH, "set_radio.sh",
                        radio_idx, channel, hwmode, htmode, txpower, alias);
            }
            status = system(exec_cmd);
            dy_syslog(LOG_INFO, "System Cmd:%s", exec_cmd);
            if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
            {
                //TODO 应答码没有定义
                //                ret = EER_;
            }
        }
    }
    cJSON_Delete(root);

    pthread_mutex_lock(&var->restart_flag_lock);
    bit_set(var->restart_flag, BIT_NETWORK_RESTART, 1);
    pthread_mutex_unlock(&var->restart_flag_lock);

    return 0;
}

static int msg_set_vap_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    pid_t status;
    char exec_cmd[384] = {0};
    memset(exec_cmd, 0, sizeof(exec_cmd));
    int i;
    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        return -1;
    }
    cJSON *radio_list = cJSON_GetObjectItem(root, "vap_list");
    if (!radio_list)
    {
        return -1;
    }
    int radio_cnt = cJSON_GetArraySize(radio_list);
    for (i = 0; i < radio_cnt; i++)
    {
        cJSON *radio = cJSON_GetArrayItem(radio_list, i);
        if (radio)
        {
            cJSON *disabled = cJSON_GetObjectItem(radio, "disabled");
            char *name = NULL;
            char *mode = NULL;
            name = cJSON_GetItemString(radio, "vap_name");
            mode = cJSON_GetItemString(radio, "mode");
            if (mode == NULL || name == NULL)
            {
                dy_syslog(LOG_ERR, "mode or name is empty");
                continue;
            }
            if (access("/app/config/rtl_hostapd.conf", F_OK) == 0)
            {
                if (strcmp(name, "vap00") != 0 || strcmp(mode, "ap") != 0)
                {
                    dy_syslog(LOG_ERR, "vap_name(%s) or mode(%s) is not support", name, mode);
                    continue;
                }
                char *ssid = cJSON_GetItemString(radio, "ssid");
                char *key = cJSON_GetItemString(radio, "key");
                if (ssid == NULL || key == NULL)
                {
                    dy_syslog(LOG_ERR, "ssid or password is empty");
                    continue;
                }

                if (disabled && disabled->valueint)
                {
                    sprintf(exec_cmd, "/etc/init.d/rtlap stop");
                }
                else
                {
                    sprintf(exec_cmd, "sed -i 's/^ssid=.*$/ssid=%s/g' /app/config/rtl_hostapd.conf; sed -i 's/^wpa_passphrase=.*$/wpa_passphrase=%s/g' /app/config/rtl_hostapd.conf; /etc/init.d/rtlap restart;", ssid, key);
                }
            }
            else
            {
                if (disabled && disabled->valueint)
                {
                    sprintf(exec_cmd, "%s%s stop -name %s -S", NET_BASH_PATH, "set_vap.sh", name);
                }
                else
                {
                    uint8_t buff_ssid[200] = {0};
                    uint8_t buff_meshid[200] = {0};
                    char *ssid = cJSON_GetItemString(radio, "ssid");
                    if (ssid)
                    {
                        b64_encode(ssid, strlen(ssid), buff_ssid, sizeof(buff_ssid));
                    }
                    char *mesh_id = cJSON_GetItemString(radio, "mesh_id");
                    if (mesh_id)
                    {
                        b64_encode(mesh_id, strlen(mesh_id), buff_meshid, sizeof(buff_meshid));
                    }
                    char *key = cJSON_GetItemString(radio, "key");
                    if (strcmp(mode, "mesh") == 0)
                    {
                        cJSON *portal_ap = cJSON_GetObjectItem(radio, "portal_ap");
                        if (portal_ap && portal_ap->valueint)
                            sprintf(exec_cmd, "%s%s set %s -mesh_id %s -key %s -name %s -P -B -S", NET_BASH_PATH, "set_vap.sh",
                                    mode, buff_meshid, key, name);
                        else
                            sprintf(exec_cmd, "%s%s set %s  -mesh_id %s -key %s -name %s -B -S", NET_BASH_PATH, "set_vap.sh",
                                    mode, buff_meshid, key, name);
                    }
                    else
                    {
                        sprintf(exec_cmd, "%s%s set %s -ssid %s -key %s -name %s -B", NET_BASH_PATH, "set_vap.sh",
                                mode, buff_ssid, key, name);
                    }
                }
            }
            dy_syslog(LOG_INFO, "System Cmd:%s", exec_cmd);
            status = system(exec_cmd);
            if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
            {
                //TODO 应答码没有定义
                //                ret = EER_;
            }
        }
    }
    cJSON_Delete(root);

    pthread_mutex_lock(&var->restart_flag_lock);
    bit_set(var->restart_flag, BIT_NETWORK_RESTART, 1);
    pthread_mutex_unlock(&var->restart_flag_lock);

    return 0;
}

static void msg_get_wifi_status(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char exec_cmd[256] = {0};
    char topic[256] = {0};
    char *buff = NULL;
    int msgid = 0;

    msgid = json_pkt_json_mi(mqtt_msg->payload);

    sprintf(exec_cmd, "%s%s", NET_BASH_PATH, "fetch_wifi_status.sh");
    dy_syslog(LOG_INFO, "System Cmd:%s", exec_cmd);
    system_reply(exec_cmd, &buff);
    if (!buff)
    {
        dy_syslog(LOG_ERR, "exec \'%s\' fail !", exec_cmd);
        return;
    }
    cJSON *root = cJSON_Parse(buff);
    if (root)
    {
        cJSON_AddNumberToObject(root, "mi", msgid);
        char *str = cJSON_Print(root);

        snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_RSP_WIFISTATUS);
        ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));
        free(str);
        cJSON_Delete(root);
    }
    else
    {
        dy_syslog(LOG_ERR, "json praser \'%s\' fail!", buff);
    }
    free(buff);
}

static void msg_get_wireless_scan_status(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int i;
    char exec_cmd[256] = {0};
    char topic[256] = {0};
    char *buff = NULL;

    sprintf(exec_cmd, "%s%s", NET_BASH_PATH, "fetch_scan_2_4G.sh");
    dy_syslog(LOG_INFO, "System Cmd:%s", exec_cmd);
    system_reply(exec_cmd, &buff);
    if (!buff)
    {
        dy_syslog(LOG_ERR, "exec \'%s\' fail !", exec_cmd);
        return;
    }
    cJSON *root = cJSON_Parse(buff);
    if (!root)
    {
        dy_syslog(LOG_ERR, "json praser \'%s\' fail!", buff);
        return;
    }
    cJSON *ap_list = cJSON_GetObjectItem(root, "beacon_list");
    int count = cJSON_GetArraySize(ap_list);
    for (i = 0; i < count; i++)
    {
        cJSON *ap = cJSON_GetArrayItem(ap_list, i);
        char *ssid = cJSON_GetItemString(ap, "ssid");
        if (ssid)
        {
            char *tmp = strdup(ssid);
            cJSON_DeleteItemFromObject(ap, "ssid");
            b64_decode(tmp, exec_cmd, sizeof(exec_cmd));
            cJSON_AddStringToObject(ap, "ssid", exec_cmd);
            free(tmp);
        }
    }
    free(buff);

    char *str = cJSON_Print(root);
    cJSON_Delete(root);

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_GET_WIRELESSSCANRESULT);
    ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));
    free(str);
}

static int log_server_cfg_set(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *input = mqtt_msg->payload;
    int ret = -1;
    char * exec = NULL, *reply = NULL;
    if (!input)
    {
        return -1;
    }
    cJSON *root = cJSON_Parse(input);
    if (!root)
    {
        return -1;
    }
    char log_ip_default[256] = "log.lnxall.com";
    int log_port_default = 514;
    char log_proto_default[256] = "udp";
    int log_level_default = 5;
    cJSON *log_ip = cJSON_GetObjectItem(root, "log_ip");
    if (log_ip && log_ip->valuestring)
    {
        strcpy(log_ip_default, log_ip->valuestring);
    }
    cJSON *log_port = cJSON_GetObjectItem(root, "log_port");
    if (log_port)
    {
        log_port_default = log_port->valueint;
    }
    cJSON *log_proto = cJSON_GetObjectItem(root, "log_proto");
    if (log_proto && log_proto->valuestring)
    {
        strcpy(log_proto_default, log_proto->valuestring);
    }
    cJSON *log_level = cJSON_GetObjectItem(root, "log_level");
    if (log_level)
    {
        log_level_default = log_level->valueint;
    }

#define TEMP_MACRO_BUFSIZE 1024
    exec = (char *) calloc(0x1, TEMP_MACRO_BUFSIZE);
    if (exec != NULL) {
        snprintf(exec, TEMP_MACRO_BUFSIZE, "%s%s -ip %s -port %d -proto %s -loglevel %d", NET_BASH_PATH, "set_logserver.sh",
            log_ip_default, log_port_default, log_proto_default, log_level_default);
        ret = system_reply(exec, &reply);
        free(reply);
        free(exec);
    }

    cJSON_Delete(root);
    return ret;
}

static int msg_set_ntp_cfg(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *input = mqtt_msg->payload;
    int msgid;
    cJSON *root = NULL;
    char host[128] = {0};
    int port = 0;
    char exec_cmd[256] = {0};
    char timezone[32] = {0};
    int len = 0;

    if (!input)
    {
        return ERR_CODE_JSON_FORMAT;
        ;
    }
    root = cJSON_Parse(input);
    if (!root)
    {
        return ERR_CODE_JSON_FORMAT;
        ;
    }

    GET_JSON_VALUE_INT(root, "mi", msgid);
    GET_JSON_VALUE_STRING(root, "host", host);
    GET_JSON_VALUE_STRING(root, "timezone", timezone);
    GET_JSON_VALUE_INT(root, "port", port);

    len += sprintf(exec_cmd, "%s%s set -h %s -p %d", NET_BASH_PATH, "set_ntp_server.sh",
                   host, port);
    if (strlen(timezone) > 0)
    {
        len += sprintf(exec_cmd + len, " -z %s", timezone);
    }
    system(exec_cmd);
    cJSON_Delete(root);
    return 0;
}

static int msg_set_sim_card(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *input = mqtt_msg->payload;
    int ret = ERR_CODE_NONE;
    int msgid = 0;
    cJSON *root = NULL;
    char exec_cmd[256] = {0};
    char pin[32] = {0};
    char apn[32] = {0};
    int len = 0;

    if (!input)
    {
        return ERR_CODE_JSON_FORMAT;
        ;
    }
    root = cJSON_Parse(input);
    if (!root)
    {
        return ERR_CODE_JSON_FORMAT;
        ;
    }

    GET_JSON_VALUE_INT(root, "mi", msgid);
    GET_JSON_VALUE_STRING(root, "pin", pin);
    GET_JSON_VALUE_STRING(root, "apn", apn);

    len = sprintf(exec_cmd, "%s%s ", NET_BASH_PATH, "clear_sim_pin_set_apn.sh");
    if (strlen(pin) != 0)
    {
        len += sprintf(exec_cmd + len, " -p %s", pin);
    }
    if (strlen(apn) != 0)
    {
        len += sprintf(exec_cmd + len, " -a %s", apn);
    }
    ret = system(exec_cmd);

    cJSON_Delete(root);

    pthread_mutex_lock(&var->restart_flag_lock);
    bit_set(var->restart_flag, BIT_NETWORK_RESTART, 1);
    pthread_mutex_unlock(&var->restart_flag_lock);
    msg_test_result(var, msgid, ret, TOPIC_SET_SIM_CARD);
    return 0;
}

static int msg_update_dc_cfg(cJSON * json)
{
    cJSON *ser_cfg = NULL;
	cJSON * root = NULL;
	int time_limit = 0;
	char *data = NULL;
	char * data_tmp = NULL;

    if (!json)
    {
        return ERR_CODE_JSON_FORMAT;
    }
	
    data = read_file_data(DC_CONFIG_FILE_PATH);
    if (data == NULL)
    {
		root = cJSON_CreateObject();
    }
	else
	{
		root = cJSON_Parse(data);
		if (!root)
		{
			root = cJSON_CreateObject();
		}
	}

	if (cJSON_HasObjectItem(json,"time_limit"))
	{
		if (cJSON_HasObjectItem(root,"time_limit"))
		{
			cJSON_DeleteItemFromObject(root,"time_limit");
		}
    	GET_JSON_VALUE_INT(json, "time_limit", time_limit);
		cJSON_AddNumberToObject(root, "time_limit", time_limit);
	}
	else
	{
		if (cJSON_HasObjectItem(root,"identifier_list"))
		{
			cJSON_DeleteItemFromObject(root,"identifier_list");
		}
    	ser_cfg = cJSON_GetObjectItem(json, "identifier_list");
		cJSON_AddItemToObject(root, "identifier_list", ser_cfg);
	}

	data_tmp = cJSON_Print(root);
	
    write_file_data(DC_CONFIG_FILE_PATH, data_tmp, strlen(data_tmp));

	cJSON_Delete(root);
	
	return ERR_CODE_NONE;
}


static int msg_trouble_shooting_4G(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = CMD_PARSER_ERR;
    int mi = 0;
    char exec_cmd[256] = {0};
    char topic[256] = {0};
    char *buff = NULL;
    cJSON *reply = NULL;
    cJSON *root = NULL;
    char *str = NULL;

    root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        ret = CMD_PARSER_ERR;
        goto out;
    }

    GET_JSON_VALUE_INT(root, "mi", mi);
    sprintf(exec_cmd, "%s%s", NET_BASH_PATH, "troubleshooting.sh");

    system_reply(exec_cmd, &buff);
    if (!buff)
    {
        dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
        ret = -1;
        goto out;
    }

    reply = cJSON_CreateObject();
    if (reply == NULL)
    {
        ret = -1;
        goto out;
    }
    cJSON_AddNumberToObject(reply, "mi", mi);
    cJSON_AddStringToObject(reply, "test_result", buff);
    str = (cJSON_Print(reply));

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_TROUBLESHOOOTING_4G);
    ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));

    ret = 0;

out:
    cJSON_Delete(reply);
    cJSON_Delete(root);
    free(buff);
    free(str);
    return ret;
}

static int gateway_versions_get(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *str = NULL;
    char topic[256] = {0};
    int i;
    char version[32] = {0};
    cJSON *root = cJSON_CreateObject();
    if (root == NULL)
    {
        return -1;
    }

    for (i = 0; i < ARRAY_SIZE(cfg_manage); i++)
    {
        char *cfg_data = NULL;
        if (cfg_manage[i].version_name == NULL)
        {
            continue;
        }

        if (strcmp(cfg_manage[i].cfg_file, MQTT_SERVER_FILE) == 0)
        {
            cfg_data = lnxall_read_encrypted_file(cfg_manage[i].cfg_file, NULL);
        }
        else
        {
            cfg_data = read_file_data(cfg_manage[i].cfg_file);
        }

        if (cfg_data != NULL)
        {
            cJSON *cfg_json = cJSON_Parse(cfg_data);
            if (cfg_json == NULL)
            {
                free(cfg_data);
                continue;
            }
            GET_JSON_VALUE_STRING(cfg_json, "version", version);
            cJSON_Delete(cfg_json);
            free(cfg_data);

            cJSON_AddStringToObject(root, cfg_manage[i].version_name, version);
        }
    }

    get_hardware_ver(version);
    cJSON_AddStringToObject(root, "hard_ver", version);
    get_software_ver(version);
    cJSON_AddStringToObject(root, "soft_ver", version);
    cJSON_AddNumberToObject(root, "mi", json_pkt_json_mi(mqtt_msg->payload));
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    str = (cJSON_Print(root));
    cJSON_Delete(root);

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_GET_VERSION_ALL);
    ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));
    free(str);
    return 0;
}

static int msg_exe_run_cmd(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char topic[256] = {0};
    char *exe_result = NULL;

    system_reply(mqtt_msg->payload, &exe_result);

    if (exe_result != NULL)
    {
        snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_RSP_RUN);
        ipc_session_publish(var->session, topic, (unsigned char *) exe_result, strlen(exe_result));
        free(exe_result);
    }
    return 0;
}

static void debug_info_exit(void)
{
    char cmd[128] = {0};
    char result[1024] = {0};

    sprintf(cmd, "ps | grep \"debug_info.sh\"");
    if (get_exec_info(cmd, result, sizeof(result)) == 0)
    {
        int debug_info_pid = 0;

        /* dy_syslog(LOG_DEBUG, "result:%s", result); */
        sscanf(result, "%d", &debug_info_pid);
        if (debug_info_pid)
        {
            sprintf(cmd, "kill -9 %d;rm /tmp/fifofile", debug_info_pid);
            system(cmd);
            dy_syslog(LOG_DEBUG, "cmd:%s", cmd);
        }
    }
}

static void *debug_info_thread_loop(void *param)
{
    cm_var_t *var = (cm_var_t *)param;
    char str[1024];
    char topic[256] = {0};
    char cmd[256] = {0};
    int readfifo;

    sprintf(cmd, "/lib/dyiot/bin/debug_info.sh &");
    system(cmd);
    sleep(1);

    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_REPORT_DEBUG_INFO);
    readfifo = open("/tmp/fifofile", O_RDONLY, 0);
    dy_syslog(LOG_DEBUG, "topic %s open %d readfifo %d", topic, var->debug_info.open, readfifo);
    while (var->debug_info.open)
    {
        int ret = read(readfifo, str, 1024);
        if (ret > 0)
        {
            ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));
        }
        memset(str, 0, sizeof(str));
        sleep(1);
    }
    close(readfifo);
    debug_info_exit();
    var->debug_info.start_debug_info = 0;
    return NULL;
}

static int msg_set_debug_info(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char topic[256] = {0};
    char *exe_result = NULL;
    int mi = 0;
    int code = 0;
    char error_msg[64] = {0};

    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (root)
    {
        GET_JSON_VALUE_INT(root, "mi", mi);
        GET_JSON_VALUE_INT(root, "open", var->debug_info.open);
        strcpy(error_msg, "successful");
        dy_syslog(LOG_DEBUG, "debug_info.open %d,start_debug_info %d", var->debug_info.open, var->debug_info.start_debug_info);
        if (var->debug_info.start_debug_info == 0)
        {
            var->debug_info.start_debug_info = 1;
            pthread_t thread_debug;
            pthread_create(&thread_debug, NULL, debug_info_thread_loop, (void *)var);
        }
    }
    else
    {
        code = ERR_CODE_JSON_FORMAT;
        strcpy(error_msg, "json parser fail");
    }
    cJSON *result = cJSON_CreateObject();
    cJSON_AddNumberToObject(result, "mi", mi);
    cJSON_AddNumberToObject(result, "timestamp", time(NULL));
    cJSON_AddNumberToObject(result, "error_code", code);
    cJSON_AddStringToObject(result, "error_msg", error_msg);

    exe_result = cJSON_PrintUnformatted(result);
    if (exe_result != NULL)
    {
        snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_SET_DEBUG_INFO);
        ipc_session_publish(var->session, topic, (unsigned char *) exe_result, strlen(exe_result));
        free(exe_result);
    }

    cJSON_Delete(root);
    cJSON_Delete(result);
    return 0;
}

static int get_firmware_upgrade_info(lnxall_firmware_t * lft,
    const cJSON * lft_info)
{
    size_t md5l = 0;
    const cJSON * jdat;

    jdat = cJSON_GetObjectItem(lft_info, "firmware_url");
    if (cJSON_IsString(jdat) == 0)
        return -1;
    lft->firmware_url = jdat->valuestring;
    if (lft->firmware_url == NULL || lft->firmware_url[0] == '\0')
        return -2;

    jdat = cJSON_GetObjectItem(lft_info, "md5");
    if (cJSON_IsString(jdat) == 0)
        return -3;
    lft->firmware_md5 = jdat->valuestring;
    if (lft->firmware_md5)
        md5l = strlen(lft->firmware_md5);
    if (md5l != 32)
        return -4;

    jdat = cJSON_GetObjectItem(lft_info, "upgrade");
    if (cJSON_IsString(jdat))
        lft->upgraded = jdat->valuestring;
    else
        lft->upgraded = NULL;
    return 0;
}

#define FIRMWARE_INFO_BUFSIZ  4096
static void msg_firmware_upgrade(cm_var_t * var, const ipc_msg_t * imsg)
{
    int fd, ret, nowrite;
    char * updat = NULL;
    cJSON * upinfo = NULL;
    cJSON * curinfo = NULL;
    lnxall_firmware_t newfirm;
    lnxall_firmware_t oldfirm;
    const char * firminfo = "/app/config/firmware_upgrade.json";
    const char * reload_cmd = "/etc/init.d/firmware_upgrade reload";

    updat = (char *) malloc(FIRMWARE_INFO_BUFSIZ);
    if (updat == NULL) {
        dy_syslog(LOG_ERR, "System out of memory!");
        return;
    }

    if (imsg->payload && imsg->payloadLen > 0)
        upinfo = cJSON_Parse(imsg->payload);
    if (upinfo == NULL) {
        dy_syslog(LOG_ERR, "Invalid payload for firmware upgrade");
        goto mfu_exit;
    }

    memset(&newfirm, 0, sizeof(newfirm));
    ret = get_firmware_upgrade_info(&newfirm, upinfo);
    if (ret < 0) {
        dy_syslog(LOG_ERR, "invalid firmware upgrade info: %d, cancelling\n", ret);
        /* clear existing scheduled firmware upgrade: */
        unlink(firminfo);
        system(reload_cmd);
        goto mfu_exit;
    }

    fd = open(firminfo, O_RDONLY);
    if (fd != -1) {
        ssize_t rval;
        rval = read(fd, updat, FIRMWARE_INFO_BUFSIZ - 1);
        close(fd); fd = -1;
        if (rval > 0) {
            updat[rval] = '\0';
            curinfo = cJSON_Parse(updat);
        }
    }

    nowrite = 0;
    if (curinfo != NULL) {
        memset(&oldfirm, 0, sizeof(oldfirm));
        ret = get_firmware_upgrade_info(&oldfirm, curinfo);
        if (ret == 0 && strcasecmp(oldfirm.firmware_md5, newfirm.firmware_md5) == 0) {
            if (oldfirm.upgraded && oldfirm.upgraded[0] == '1') {
                dy_syslog(LOG_INFO, "No need to upgrade firmware, already done");
                goto mfu_exit;
            }
            /*
             * do not write the firmware upgrade info file,
             * because MD5 already matches:
             */
            if (strcmp(oldfirm.firmware_url, newfirm.firmware_url) == 0)
                nowrite = 1;
        }
    }

    if (!nowrite) {
        ret = snprintf(updat, FIRMWARE_INFO_BUFSIZ,
            "{\n"
            "\t\"firmware_url\":\"%s\",\n"
            "\t\"md5\":\"%s\",\n"
            "\t\"upgrade\":\"0\"\n}",
            newfirm.firmware_url, newfirm.firmware_md5);
        if (ret > 0) {
            fd = open(firminfo, O_CREAT | O_TRUNC | O_WRONLY, 0644);
            if (fd != -1 && write(fd, updat, (size_t) ret) != (ssize_t) ret) {
                dy_syslog(LOG_ERR, "Error, failed to write: %s", firminfo);
            }
            if (fd != -1)
            close(fd);
        }
    }

    /* invoke external application to upgrade */
    system(reload_cmd);

mfu_exit:
    free(updat);
    if (upinfo != NULL)
        cJSON_Delete(upinfo);
    if (curinfo != NULL)
        cJSON_Delete(curinfo);
}

static void msg_get_gateway_net_port_info(cm_var_t *var)
{
    char *buff = NULL;
    char topic[256] = {0};
    char exec_cmd[256] = {0};

    sprintf(exec_cmd, "%s/%s", NET_BASH_PATH, "fetch_port_status.sh");
    system_reply(exec_cmd, &buff);
    if (!buff)
    {
        dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
        return;
    }
    snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_EVT_NETWORKINFO);
    ipc_session_publish(var->session, topic, (unsigned char *) buff, strlen(buff));
    free(buff);
}

#define WEBUI_DEF_USER "admin"
#define wEBUI_DEF_PASS "admin"

static int msg_login(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    int ret = ERR_CODE_NONE;
    char *data = NULL;
    int msgid = 0;
    char username[32] = {0};
    char password[32] = {0};
    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }
    GET_JSON_VALUE_INT(root, "mi", msgid);

    GET_JSON_VALUE_STRING(root, "username", username);
    GET_JSON_VALUE_STRING(root, "password", password);

    data = read_file_data(WEBUI_CFG);
    if (data != NULL)
    {
        char user_store[32];
        char pass_store[32];

        cJSON *user_pass = cJSON_Parse(data);
        GET_JSON_VALUE_STRING(user_pass, "username", user_store);
        GET_JSON_VALUE_STRING(user_pass, "password", pass_store);

        if (strcmp(username, user_store) == 0 &&
            strcmp(password, pass_store) == 0)
        {
            ret = ERR_CODE_NONE;
        }
        else
        {
            ret = ERR_CODE_LOGIN_FAILED;
        }
        cJSON_Delete(user_pass);
        free(data);
    }
    else
    {
        if (strcmp(username, WEBUI_DEF_USER) == 0 &&
            strcmp(password, wEBUI_DEF_PASS) == 0)
        {
            ret = ERR_CODE_NONE;
        }
        else
        {
            ret = ERR_CODE_LOGIN_FAILED;
        }
    }

    gw_common_result(var->session, msgid, ret, TOPIC_WEBUI_LOGIN);

out:
    cJSON_Delete(root);

    return 0;
}

static int msg_get_template_list(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    cJSON *root = NULL;
    cJSON *templates = NULL;
    cJSON *template = NULL;
    cJSON *template_list = NULL;
    int cnt = 0;
    char *data = NULL;
    char *data_tmp = NULL;
    char topic[256] = {0};

    template_list = cJSON_CreateObject();

    if (template_list != NULL)
    {
        cJSON_AddNumberToObject(template_list, "mi", json_pkt_json_mi(mqtt_msg->payload));
        data = read_file_data(TEMPLATES_CFG_PATH);
        if (data != NULL)
        {
            root = cJSON_Parse(data);
            if (root != NULL)
            {
                templates = cJSON_GetObjectItem(root, "template_cfg");
                if (templates != NULL)
                {
                    char template_id[32] = {0};
                    char name[32] = {0};
                    cJSON *item = NULL;
                    cJSON *items = NULL;
                    int i = 0;

                    cnt = cJSON_GetArraySize(templates);
                    items = cJSON_CreateArray();
                    for (i = 0; i < cnt; i++)
                    {
                        template = cJSON_GetArrayItem(templates, i);
                        if (template)
                        {
                            item = cJSON_CreateObject();
                            GET_JSON_VALUE_STRING(template, "template_id", template_id);
                            GET_JSON_VALUE_STRING(template, "template_name", name);

                            cJSON_AddStringToObject(item, "template_id", template_id);
                            cJSON_AddStringToObject(item, "template_name", name);

                            cJSON_AddItemToArray(items, item);
                        }
                    }
                    cJSON_AddItemToObject(template_list, "template_list", items);
                }
                cJSON_Delete(root);
            }
            free(data);
        }
        else
        {
            cJSON_AddNullToObject(template_list, "template_list");
        }
        data_tmp = (cJSON_Print(template_list));
        cJSON_Delete(template_list);

        snprintf(topic, sizeof(topic), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, TOPIC_GET_TEMPLATE_LIST);
        ipc_session_publish(var->session, topic, (unsigned char *) data_tmp, strlen(data_tmp));
        free(data_tmp);
    }
    return 0;
}

static int msg_get_gateway_info(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *str = NULL;
    char topic[TOPIC_MAX_LEN] = {0};
    char version[32] = {0};
    cJSON *root = cJSON_CreateObject();
    if (root == NULL)
    {
        return -1;
    }

    get_hardware_ver(version);
    cJSON_AddStringToObject(root, "hard_ver", version);
    get_software_ver(version);
    cJSON_AddStringToObject(root, "soft_ver", version);
    cJSON_AddNumberToObject(root, "mi", json_pkt_json_mi(mqtt_msg->payload));
    cJSON_AddNumberToObject(root, "timestamp", time(NULL));
    cJSON_AddStringToObject(root, "sn", var->sn_str);
    str = (cJSON_Print(root));
    cJSON_Delete(root);

    snprintf(topic, TOPIC_MAX_LEN, "G/%s", TOPIC_GET_GWINFO);
    ipc_session_publish(var->session, topic, (unsigned char *) str, strlen(str));

    free(str);
    return 0;
}

static int msg_add_update_node(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *data = NULL;
    cJSON *root = NULL;
    cJSON *nodes = NULL;
    cJSON *node = NULL;
    int node_cnt = 0;
    int i = 0, ret = 0;
    int mi = 0;
    char SN[SN_MAX_LEN] = {0};
    char SN_tmp[SN_MAX_LEN] = {0};
    int find = 0;
    char *data_new = NULL;

    cJSON *new = cJSON_Parse(mqtt_msg->payload);
    if (new == NULL)
    {
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }

    GET_JSON_VALUE_INT(new, "mi", mi);
    GET_JSON_VALUE_STRING(new, "sn", SN);

    if (strlen(SN) == 0)
    {
        cJSON_Delete(new);
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }

    data = read_file_data(NODES_CFG_PATH);
    if (data == NULL)
    {
        dy_syslog(LOG_ERR, "read cfg file %s error", NODES_CFG_PATH);
        ret = -1;
        cJSON_Delete(new);
        goto out;
    }

    root = cJSON_Parse(data);
    if (!root)
    {
        dy_syslog(LOG_ERR, "parse cfg file %s error", NODES_CFG_PATH);
        ret = -1;
        cJSON_Delete(new);
        goto out;
    }
    nodes = cJSON_GetObjectItem(root, "nodes_cfg");
    if (!nodes)
    {
        dy_syslog(LOG_ERR, "get nodes_cfg failed");
        ret = -1;
        cJSON_Delete(new);
        goto out;
    }

    node_cnt = cJSON_GetArraySize(nodes);

    for (i = 0; i < node_cnt; i++)
    {

        node = cJSON_GetArrayItem(nodes, i);
        GET_JSON_VALUE_STRING(node, "sn", SN_tmp);

        if (strcmp(SN_tmp, SN) == 0)
        {
            // update existing node
            find = 1;
            cJSON_ReplaceItemInArray(nodes, i, new);
        }
    }

    if (find == 0)
    {
        // add new node
        cJSON_AddItemToArray(nodes, new);
    }

    data_new = cJSON_Print(root);
    write_file_data(NODES_CFG_PATH, data_new, strlen(data_new));

out:
    gw_common_result(var->session, mi, ret, TOPIC_ADD_UPDATE_NODE);
    cJSON_Delete(root);
    free(data);
    free(data_new);
    return ret;
}

static int msg_delete_node(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char *data = NULL;
    cJSON *root = NULL;
    cJSON *nodes = NULL;
    cJSON *node = NULL;
    int node_cnt = 0;
    int i = 0, ret = 0;
    int mi = 0;
    char SN[SN_MAX_LEN] = {0};
    char SN_tmp[SN_MAX_LEN] = {0};
    int find = 0;
    char *data_new = NULL;

    cJSON *new = cJSON_Parse(mqtt_msg->payload);
    if (new == NULL)
    {
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }

    GET_JSON_VALUE_INT(new, "mi", mi);
    GET_JSON_VALUE_STRING(new, "sn", SN);

    if (strlen(SN) == 0)
    {
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }

    data = read_file_data(NODES_CFG_PATH);
    if (data == NULL)
    {
        dy_syslog(LOG_ERR, "read cfg file %s error", NODES_CFG_PATH);
        ret = -1;
        goto out;
    }

    root = cJSON_Parse(data);
    if (!root)
    {
        dy_syslog(LOG_ERR, "parse cfg file %s error", NODES_CFG_PATH);
        ret = -1;
        goto out;
    }
    nodes = cJSON_GetObjectItem(root, "nodes_cfg");
    if (!nodes)
    {
        dy_syslog(LOG_ERR, "get nodes_cfg failed");
        ret = -1;
        goto out;
    }

    node_cnt = cJSON_GetArraySize(nodes);

    for (i = 0; i < node_cnt; i++)
    {

        node = cJSON_GetArrayItem(nodes, i);
        GET_JSON_VALUE_STRING(node, "sn", SN_tmp);

        if (strcmp(SN_tmp, SN) == 0)
        {
            // update existing node
            find = 1;
            cJSON_DeleteItemFromArray(nodes, i);
        }
    }

    if (find == 0)
    {
        // add new node
        ret = ERR_CODE_NODE_NOT_EXIST;
    }

    data_new = cJSON_Print(root);
    write_file_data(NODES_CFG_PATH, data_new, strlen(data_new));

out:
    gw_common_result(var->session, mi, ret, TOPIC_DELETE_NODE);
    cJSON_Delete(root);
    cJSON_Delete(new);
    free(data);
    free(data_new);
    return ret;
}

static int cm_get_cfg(cm_var_t *var, char *topic, char *cfg_file, ipc_msg_t *mqtt_msg)
{
    char *data = NULL;
    cJSON *root = NULL;
    int msgid = 0;
    char *data_tmp = NULL;
    char t[384] = {0};

    msgid = json_pkt_json_mi(mqtt_msg->payload);
    if (strcmp(topic, TOPIC_GET_SERVERREDIRECT) == 0)
    {
        data = lnxall_read_encrypted_file(cfg_file, NULL);
    }
    else
    {
        data = read_file_data(cfg_file);
    }
    if (data == NULL)
    {
        if (strcmp(topic, TOPIC_GET_GATEWAYWANCFG) == 0)
        {
            char exec_cmd[256] = {0};
            sprintf(exec_cmd, "%s/%s", NET_BASH_PATH, "fetch_wan_config.sh");
            char *buff = NULL;
            system_reply(exec_cmd, &buff);
            if (!buff)
            {
                dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
            }
            data = buff;
        }
        else if (strcmp(topic, TOPIC_GET_GATEWAYLANCFG) == 0)
        {
            char exec_cmd[256] = {0};
            sprintf(exec_cmd, "%s/%s", NET_BASH_PATH, "fetch_lan_config.sh");
            char *buff = NULL;
            system_reply(exec_cmd, &buff);
            if (!buff)
            {
                dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
            }
            data = buff;
        }
        else if (strcmp(topic, TOPIC_GET_GATEWAYVAPCFG) == 0)
        {
            char exec_cmd[256] = {0};
            sprintf(exec_cmd, "%s/%s", NET_BASH_PATH, "fetch_vap_config.sh");
            char *buff = NULL;
            system_reply(exec_cmd, &buff);
            if (!buff)
            {
                dy_syslog(LOG_ERR, "system run \'%s\' fail !", exec_cmd);
            }
            data = buff;
        }
    }

    if (data != NULL)
    {
        root = cJSON_Parse(data);
        if (!root)
        {
            dy_syslog(LOG_ERR, "parse cfg file %s error, load default", cfg_file);
            goto out;
        }
        cJSON_AddNumberToObject(root, "mi", msgid);
    }
    else
    {
        root = cJSON_CreateObject();
        if (!root)
        {
            dy_syslog(LOG_ERR, "create json failed");
            goto out;
        }
        cJSON_AddNumberToObject(root, "mi", msgid);
    }
    data_tmp = cJSON_Print(root);

    snprintf(t, sizeof(t), "G/%s/gateway/device/%s/service/%s", var->sn_str, var->sn_str, topic);
    ipc_session_publish(var->session, t, (unsigned char *) data_tmp, strlen(data_tmp));

out:
    if (data != NULL)
        free(data);
    if (data_tmp != NULL)
        free(data_tmp);
    if (root != NULL)
        cJSON_Delete(root);
    return 0;
}

static int cm_write_cfg(cm_var_t *var, char *topic, char *cfg_file, ipc_msg_t *mqtt_msg)
{
    int ret = ERR_CODE_NONE;
    char *data_tmp = NULL;
    char *json = NULL;
    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (!root)
    {
        ret = ERR_CODE_JSON_FORMAT;
        goto out;
    }

    json = get_config_info(mqtt_msg->payload);
    if (json)
    {
        cJSON *tmp = cJSON_Parse(json);
        if (tmp == NULL)
        {
            ret = ERR_CODE_JSON_FORMAT;
            goto out;
        }
        cJSON_Delete(tmp);
        data_tmp = json;
    }
    else
    {
        cJSON_DeleteItemFromObject(root, "mi");
        data_tmp = cJSON_Print(root);
    }

    write_file_data(cfg_file, data_tmp, strlen(data_tmp));
out:
    free(data_tmp);
    cJSON_Delete(root);

    return ret;
}

static int cm_config_take_effect(cm_var_t *var, char *topic, char *cfg_file, ipc_msg_t *mqtt_msg)
{
    int ret = 0;
    char cmd[64] = {0};

    if (strcmp(topic, TOPIC_SET_MULTI_MQTT_CLD) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_CLOUD_MQTT_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
        snprintf(cmd, sizeof(cmd), "rm -rf %s/*", CLOUD_MQTT_TLS_FILE_PATH);
        system(cmd);
    }
    else if (strcmp(topic, TOPIC_SET_SERVERREDIRECT) == 0)
    {
        lnxall_encrypt_file(MQTT_SERVER_FILE);
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_IOT_CLD_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
        snprintf(cmd, sizeof(cmd), "rm -rf %s/*", CONFIG_MQTT_TLS_FILE_PATH);
        system(cmd);
    }
    else if (strcmp(topic, TOPIC_SET_NODES_CFG) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_VINT_RESTART, 1);
        bit_set(var->restart_flag, BIT_RS485_RESTART, 1);
        bit_set(var->restart_flag, BIT_UPGRADE_RESTART, 1);
        bit_set(var->restart_flag, BIT_PP_RESTART, 1);
        bit_set(var->restart_flag, BIT_DR_RESTART, 1);
        bit_set(var->restart_flag, BIT_RULE_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORA_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORAWAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_VDEV_RESTART, 1);
        bit_set(var->restart_flag, BIT_HUAYUN_RESTART, 1);
        bit_set(var->restart_flag, BIT_LINKKIT_GATEWAY_RESTART, 1);
        bit_set(var->restart_flag, BIT_COMMON_SOCKET_RESTART, 1);
        bit_set(var->restart_flag, BIT_CAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_CLOUD_MQTT_RESTART, 1);
        bit_set(var->restart_flag, BIT_SHANGHAI_S5_RESTART, 1);
        bit_set(var->restart_flag, BIT_LANZHUO_RESTART, 1);
        bit_set(var->restart_flag, BIT_S7_PLC_RESTART, 1);
        bit_set(var->restart_flag, BIT_IPDEV_MANAGER_RESTART, 1);
        bit_set(var->restart_flag, BIT_BLE_RESTART, 1);
        bit_set(var->restart_flag, BIT_SCADA_IEC104_RESTART, 1);
        bit_set(var->restart_flag, BIT_ENTRANCE_GUARD_RESTART, 1);
        bit_set(var->restart_flag, BIT_NETSNIFFER_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
    }
    else if (strcmp(topic, TOPIC_SET_TEMPL_CFG) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_VINT_RESTART, 1);
        bit_set(var->restart_flag, BIT_RS485_RESTART, 1);
        bit_set(var->restart_flag, BIT_UPGRADE_RESTART, 1);
        bit_set(var->restart_flag, BIT_PP_RESTART, 1);
        bit_set(var->restart_flag, BIT_DR_RESTART, 1);
        bit_set(var->restart_flag, BIT_RULE_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORA_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORAWAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_VDEV_RESTART, 1);
        bit_set(var->restart_flag, BIT_HUAYUN_RESTART, 1);
        bit_set(var->restart_flag, BIT_LINKKIT_GATEWAY_RESTART, 1);
        bit_set(var->restart_flag, BIT_COMMON_SOCKET_RESTART, 1);
        bit_set(var->restart_flag, BIT_CAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_CLOUD_MQTT_RESTART, 1);
        bit_set(var->restart_flag, BIT_SHANGHAI_S5_RESTART, 1);
        bit_set(var->restart_flag, BIT_LANZHUO_RESTART, 1);
        bit_set(var->restart_flag, BIT_S7_PLC_RESTART, 1);
        bit_set(var->restart_flag, BIT_SCADA_IEC104_RESTART, 1);
        bit_set(var->restart_flag, BIT_NETSNIFFER_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
        dev_script_del_all(var);
    }
    else if (strcmp(topic, TOPIC_SET_OBJ_CFG) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_VINT_RESTART, 1);
        bit_set(var->restart_flag, BIT_RS485_RESTART, 1);
        bit_set(var->restart_flag, BIT_RS485_SLAVE_RESTART, 1);
        bit_set(var->restart_flag, BIT_UPGRADE_RESTART, 1);
        bit_set(var->restart_flag, BIT_PP_RESTART, 1);
        bit_set(var->restart_flag, BIT_DR_RESTART, 1);
        bit_set(var->restart_flag, BIT_RULE_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORA_RESTART, 1);
        bit_set(var->restart_flag, BIT_LORAWAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_VDEV_RESTART, 1);
        bit_set(var->restart_flag, BIT_HUAYUN_RESTART, 1);
        bit_set(var->restart_flag, BIT_LINKKIT_GATEWAY_RESTART, 1);
        bit_set(var->restart_flag, BIT_COMMON_SOCKET_RESTART, 1);
        bit_set(var->restart_flag, BIT_CAN_RESTART, 1);
        bit_set(var->restart_flag, BIT_CLOUD_MQTT_RESTART, 1);
        bit_set(var->restart_flag, BIT_SHANGHAI_S5_RESTART, 1);
        bit_set(var->restart_flag, BIT_LANZHUO_RESTART, 1);
        bit_set(var->restart_flag, BIT_S7_PLC_RESTART, 1);
        bit_set(var->restart_flag, BIT_SCADA_IEC104_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
    }
    else if (strcmp(topic, TOPIC_SET_RS485_CFG) == 0)
    {
        bit_set(var->restart_flag, BIT_RS485_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_COMMON_SOCKET_CFG) == 0)
    {
        bit_set(var->restart_flag, BIT_COMMON_SOCKET_RESTART, 1);
        snprintf(cmd, sizeof(cmd), "rm -rf %s/*", COMMON_SOCKET_TLS_FILE_PATH);
        system(cmd);
    }
    else if (strcmp(topic, TOPIC_SET_HUAYUN_CFG) == 0)
    {
        bit_set(var->restart_flag, BIT_HUAYUN_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_LORAWANCFG) == 0)
    {
        bit_set(var->restart_flag, BIT_LORAWAN_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_LORACFG) == 0)
    {
        bit_set(var->restart_flag, BIT_LORA_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_RULESENGINECFG) == 0)
    {
        bit_set(var->restart_flag, BIT_RULE_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_GATEWAYWANCFG) == 0)
    {
        ret = msg_set_gateway_net_wan_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_GATEWAYLANCFG) == 0)
    {
        ret = msg_set_gateway_net_lan_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_MACIPBIND) == 0)
    {
        ret = msg_set_mac_ip_bind_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_RADIOCFG) == 0)
    {
        ret = msg_set_radio_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_GATEWAYVAPCFG) == 0)
    {
        ret = msg_set_vap_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_CANCFG) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_CAN_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
    }
    else if (strcmp(topic, TOPIC_SET_LOGSERVERCFG) == 0)
    {
        ret = log_server_cfg_set(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_VPORTCFG) == 0)
    {
        pthread_mutex_lock(&var->restart_flag_lock);
        bit_set(var->restart_flag, BIT_VINT_RESTART, 1);
        pthread_mutex_unlock(&var->restart_flag_lock);
    }
    else if (strcmp(topic, TOPIC_SET_NTPSERVERCFG) == 0)
    {
        ret = msg_set_ntp_cfg(var, mqtt_msg);
    }
    else if (strcmp(topic, TOPIC_SET_SUPOS_CFG) == 0)
    {
        bit_set(var->restart_flag, BIT_HUAYUN_RESTART, 1);
    }
    else if (strcmp(topic, TOPIC_SET_DC_TIME_LIMIT) == 0)
    {
        bit_set(var->restart_flag, BIT_DR_RESTART, 1);
    }

    return ret;
}

int cm_handle_mqtt_data(cm_var_t *var, ipc_msg_t *mqtt_msg)
{
    char topic[TOPIC_MAX_LEN] = {0};
    int i = 0;
    int find = 0;
    int ret = 0;

    if (strstr(mqtt_msg->topic, TOPIC_GET_GWINFO))
    {
        strcpy(topic, TOPIC_GET_GWINFO);
    }
    else
    {
        sscanf(mqtt_msg->topic, "M/%*[^/]/gateway/device/%*[^/]/service/%" STR(TOPIC_MAX_LEN) "s", topic);
    }

    for (i = 0; i < ARRAY_SIZE(cfg_manage); i++)
    {
        if (cfg_manage[i].topic_get != NULL && strcmp(topic, cfg_manage[i].topic_get) == 0)
        {
            cm_get_cfg(var, topic, cfg_manage[i].cfg_file, mqtt_msg);
            find = 1;
            break;
        }
        else if (cfg_manage[i].topic_set != NULL && strcmp(topic, cfg_manage[i].topic_set) == 0)
        {
            ret = cm_write_cfg(var, topic, cfg_manage[i].cfg_file, mqtt_msg);
            if (ret == 0)
            {
                ret = cm_config_take_effect(var, topic, cfg_manage[i].cfg_file, mqtt_msg);
            }
            find = 2;
            break;
        }
    }

    if (find == 0)
    {
        // 未查询到配置相关topic，匹配其他topic
        if (strcmp(topic, TOPIC_SET_GATEWAYWANTEST) == 0)
        {
            msg_test_gateway_net_wan(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_SET_MQTT_BROKER_TEST) == 0)
        {
            msg_test_mqtt_broker(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_LANDEVICESTATUS) == 0)
        {
            msg_get_lan_status(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_WIRELESSSCANRESULT) == 0)
        {
            msg_get_wireless_scan_status(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_WIFISTATUS) == 0)
        {
            msg_get_wifi_status(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_VERSION_ALL) == 0)
        {
            gateway_versions_get(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_EXE_RUN) == 0)
        {
            msg_exe_run_cmd(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_TEMPLATE_LIST) == 0)
        {
            msg_get_template_list(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_WEBUI_LOGIN) == 0)
        {
            msg_login(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_ADD_UPDATE_NODE) == 0)
        {
            msg_add_update_node(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_DELETE_NODE) == 0)
        {
            msg_delete_node(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_GET_GWINFO) == 0)
        {
            msg_get_gateway_info(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_SET_SIM_CARD) == 0)
        {
            msg_set_sim_card(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_TROUBLESHOOOTING_4G) == 0)
        {
            msg_trouble_shooting_4G(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_SET_DEBUG_INFO) == 0)
        {
            msg_set_debug_info(var, mqtt_msg);
        }
        else if (strcmp(topic, TOPIC_EVT_NETWORKINFO) == 0)
        {
            msg_get_gateway_net_port_info(var);
        }
        else if (strcmp(topic, TOPIC_FIRMWARE_UPGRADE) == 0)
        {
            msg_firmware_upgrade(var, mqtt_msg);
        }
	    else if (strcmp(topic, TOPIC_SET_DC_TIME_LIMIT) == 0)
        {
            msg_update_dc_cfg(cJSON_Parse(mqtt_msg->payload));
        }
	
    }
    else if (find == 2)
    {
        int msgid = 0;
        reply_msg_t *msg = calloc(1, sizeof(reply_msg_t));
        if (msg != NULL)
        {
            msgid = json_pkt_json_mi(mqtt_msg->payload);
            msg->mi = msgid;
            msg->ret = ret;
            strcpy(msg->topic, topic);
            list_add_tail(&msg->list, &var->reply_list);
        }
        else
        {
            dy_syslog(LOG_ERR, "malloc failed");
        }
    }

    return 0;
}
