// // Created by xajhu on 2019/11/18 0018. // #include #include #include #include #ifdef MONITOR_ZTP_CFG_FILE #include #include #endif #include "common.h" #include "log.h" #include "err_code.h" #include "ztp_config.h" static char *g_ztpFilePath = NULL; static pthread_t g_monThreadId; static ZTP_CONFIG g_ztpInfo; static DEVICE_CONFIG g_devInfo; PZTP_CONFIG get_ztp_configure(void) { return &g_ztpInfo; } PDEVICE_CONFIG get_device_configure(void) { return &g_devInfo; } static void __init_dev_config(PDEVICE_CONFIG pCfg) { int i; memset(pCfg, 0, sizeof(DEVICE_CONFIG)); for(i = 0; i < DEV_MAX_PORT; i++) { pCfg->port_cfg[i].port_type = UNKNOWN_PORT; pCfg->port_cfg[i].port_protocol = UNKNOWN_PRO_TYPE; } pCfg->lan_config.ip_type = UNKNOWN_IP_TYPE; } static int __get_dev_port_config(config_t *pCfg, DEV_PORT_CONFIG pPortCfg[], int *pMaxItems) { int i, nItems; config_setting_t *pSetting; if(pPortCfg == NULL || pMaxItems == NULL || *pMaxItems <= 0) { return -ERR_INPUTERR; } pSetting = config_lookup(pCfg, "network.port"); if(pSetting == NULL) { return -ERR_NOTFOUND; } nItems = config_setting_length(pSetting); if(nItems <= 0) { return -ERR_NOTFOUND; } else if(nItems > *pMaxItems) { nItems = *pMaxItems; } *pMaxItems = nItems; for(i = 0; i < *pMaxItems; i++) { char *pString; int port_type, port_pro, iValue; config_setting_t *pSubVal; config_setting_t *pVal = config_setting_get_elem(pSetting, (unsigned int)i); if(config_setting_lookup_int(pVal, "port_type", &port_type) == CONFIG_TRUE) { pPortCfg[i].port_type = port_type; } // below this process WAN configures if(port_type == LAN_PORT) { continue; } if(config_setting_lookup_int(pVal, "protocol", &port_pro) == CONFIG_TRUE) { pPortCfg[i].port_protocol = port_pro; } switch(port_pro) { case STATIC_TYPE: pSubVal = config_setting_get_member(pVal, "static"); if(pSubVal == NULL) { break; } if(config_setting_lookup_int(pSubVal, "ip_type", &iValue) == CONFIG_TRUE) { pPortCfg[i].wan_conf.static_config.ip_type = iValue; } if(config_setting_lookup_string(pSubVal, "ip_addr", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.static_config.ip_addr, pString); } if(config_setting_lookup_string(pSubVal, "netmask", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.static_config.netmask, pString); } if(config_setting_lookup_string(pSubVal, "gateway", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.static_config.gateway, pString); } if(config_setting_lookup_string(pSubVal, "master_dns", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.static_config.master_dns, pString); } if(config_setting_lookup_string(pSubVal, "backup_dns", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.static_config.backup_dns, pString); } break; case PPPOE_TYPE: pSubVal = config_setting_get_member(pVal, "pppoe"); if(pSubVal == NULL) { break; } if(config_setting_lookup_string(pSubVal, "username", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.pppoe_config.username, pString); } if(config_setting_lookup_string(pSubVal, "password", (const char **)&pString) == CONFIG_TRUE) { strcpy(pPortCfg[i].wan_conf.pppoe_config.password, pString); } break; case DHCP_TYPE: break; default: break; } } return ERR_OK; } static int __load_dev_config(config_t* pCfg) { DEVICE_CONFIG devInfo; __init_dev_config(&devInfo); devInfo.total_ports = DEV_MAX_PORT; __get_dev_port_config(pCfg, devInfo.port_cfg, &devInfo.total_ports); devInfo.lan_config.ip_type = cfg_get_int_value(pCfg, "network.lan_network.ip_type", IPV4_TYPE); strncpy(devInfo.lan_config.ip_addr, cfg_get_string_value(pCfg, "network.lan_network.ip_addr", ""), MAX_IP_LEN - 1); strncpy(devInfo.lan_config.netmask, cfg_get_string_value(pCfg, "network.lan_network.netmask", ""), MAX_IP_LEN - 1); memcpy(&g_devInfo, &devInfo, sizeof(DEVICE_CONFIG)); return ERR_OK; } int load_ztp_config(const char *pPath) { config_t ztpCfg; ZTP_CONFIG ztpInfo; config_init(&ztpCfg); config_set_tab_width(&ztpCfg, 4); memset(&ztpInfo, 0, sizeof(ZTP_CONFIG)); if(config_read_file(&ztpCfg, pPath) != CONFIG_TRUE) { LOG_EX(LOG_Error, "Read ztp configre file %s error %s at %d\n", pPath, config_error_text(&ztpCfg), config_error_file(&ztpCfg)); config_destroy(&ztpCfg); return -ERR_READFILE; } ztpInfo.svr_cfg.port = cfg_get_int_value(&ztpCfg, "ztp.server.port", 10000); strncpy(ztpInfo.svr_cfg.server_url, cfg_get_string_value(&ztpCfg, "ztp.server.domain", ""), MAX_PATH * 2 - 1); if(g_ztpInfo.svr_cfg.port != ztpInfo.svr_cfg.port) { LOG_EX(LOG_Info, "Port Changed: [%d] --> [%d]\n", g_ztpInfo.svr_cfg.port, ztpInfo.svr_cfg.port); g_ztpInfo.svr_cfg.port = ztpInfo.svr_cfg.port; } if(strcmp(g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url) != 0) { LOG_EX(LOG_Info, "Url Changed: [%s] --> [%s]\n", g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url); memset(g_ztpInfo.svr_cfg.server_url, 0, MAX_PATH * 2); strncpy(g_ztpInfo.svr_cfg.server_url, ztpInfo.svr_cfg.server_url, MAX_PATH * 2 - 1); } __load_dev_config(&ztpCfg); config_destroy(&ztpCfg); return ERR_OK; } #ifdef MONITOR_ZTP_CFG_FILE static void *__cfg_file_monitor(void *p) { int wd; int fd = inotify_init(); UNUSED(p); if(fd == -1) { LOG_EX(LOG_Error, "Create file watch error: %s\n", strerror(errno)); return NULL; } wd = inotify_add_watch(fd, g_ztpFilePath, (IN_CREATE + IN_DELETE + IN_MODIFY + IN_MOVED_FROM + IN_MOVED_TO)); if(wd < 0) { LOG_EX(LOG_Error, "Watch %s error %s\n", g_ztpFilePath, strerror(errno)); close(fd); free(g_ztpFilePath); return NULL; } while(g_ztpFilePath && strlen(g_ztpFilePath) > 0) { unsigned char buf[MAX_PATH]; struct inotify_event *event = NULL; fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); memset(buf, 0, MAX_PATH); if(select(fd + 1, &fds, NULL, NULL, NULL) > 0) { ssize_t len; unsigned int index = 0; while(((len = read(fd, &buf, MAX_PATH)) < 0) && (errno == EINTR)); //没有读取到事件。 while(index < len) { event = (struct inotify_event *)(buf + index); //LOG_EX(LOG_Info, "event->mask: 0x%08x\n", event->mask); switch(event->mask) { case IN_MODIFY: case IN_MOVED_FROM: load_ztp_config(g_ztpFilePath); break; case IN_MOVED_TO: case IN_DELETE: case IN_CREATE: //config_destroy(&ztpCfg); break; default: break; } //获取事件。 index += sizeof(struct inotify_event) + event->len; //移动index指向下一个事件。 } } } inotify_rm_watch(fd, wd); free(g_ztpFilePath); pthread_detach(pthread_self()); return NULL; } #endif int init_configure(const char *pPath) { memset(&g_ztpInfo, 0, sizeof(ZTP_CONFIG)); __init_dev_config(&g_devInfo); if(!pPath || strlen(pPath) == 0) { LOG_EX(LOG_Error, "Load configure file %s error\n", pPath); return -ERR_NOTFOUND; } else { LOG_EX(LOG_Debug, "Load ztp configure file: %s\n", pPath); } if(access(pPath, F_OK) != 0) { LOG_EX(LOG_Error, "Configure file %s not exists\n", pPath); return -ERR_NOTFOUND; } load_ztp_config(pPath); #ifdef MONITOR_ZTP_CFG_FILE pthread_create(&g_monThreadId, NULL, __cfg_file_monitor, NULL); #endif return ERR_OK; } int cfg_get_array_int_value(config_t *pCfg, const char *pTags, int *pArray, int *pMaxItem) { int i, nItems; config_setting_t *pSetting; if(pTags == NULL || strlen(pTags) == 0 || pMaxItem == NULL || *pMaxItem <= 0 || pArray == NULL) { return -ERR_INPUTERR; } pSetting = config_lookup(pCfg, pTags); if(pSetting == NULL) { return -ERR_NOTFOUND; } nItems = config_setting_length(pSetting); if(nItems > *pMaxItem) { nItems = *pMaxItem; } *pMaxItem = nItems; for(i = 0; i < *pMaxItem; i++) { pArray[i] = config_setting_get_int_elem(pSetting, i); } return ERR_OK; } char *cfg_get_string_value(config_t *pCfg, const char *pTags, char *pDefValue) { char *pValue = pDefValue; if(pTags == NULL || strlen(pTags) == 0) { return pDefValue; } if(config_lookup_string(pCfg, pTags, (const char **)&pValue) != CONFIG_TRUE) { return pDefValue; } return pValue; } int cfg_get_int_value(config_t *pCfg, const char *pTags, int defValue) { int iValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_int(pCfg, pTags, &iValue) != CONFIG_TRUE) { return defValue; } return iValue; } double cfg_get_float_value(config_t *pCfg, const char *pTags, double defValue) { double dValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_float(pCfg, pTags, &dValue) != CONFIG_TRUE) { return defValue; } return dValue; } int cfg_get_bool_value(config_t *pCfg, const char *pTags, int defValue) { int iValue = defValue; if(pTags == NULL || strlen(pTags) == 0) { return defValue; } if(config_lookup_bool(pCfg, pTags, &iValue) != CONFIG_TRUE) { return defValue; } return iValue; }