#include #include #include #include "esp_common.h" #include "esp_wifi.h" #include "user_config.h" #include "cfg.h" #include "log.h" #include "jsprase.h" #include "user_main.h" #include "uart.h" #include "mbedtls/aes.h" #define GLOBAL_TAGS "NETEASEIOTGLOBALCONFIGURETAG" #define NE_PRODUCT_ID_LEN 4 #define DEBUG_USER_CFG (0) static PUSER_CONFIG g_pUserCfg = NULL; static GLOGAL_CONFIG g_globalCfg; static void __dumpGlobalCfg(void) { int err; char *pSerial; pSerial = (char *)Struct2Json(&g_globalCfg, JE_GLOBAL_CFG, CRYPTO_NONE, &err); if(err != ERR_OK || pSerial == NULL) { return; } LOG_EX(LOG_Debug, "Global Configure Information:\n%s\n", pSerial); free(pSerial); } PUSER_CONFIG ne_cfg_get_user_cfg(void) { return g_pUserCfg; } /****************************************************************************** * FunctionName : ne_cfg_get_init_type * Description : config function * Parameters : task param * Returns : none *******************************************************************************/ int32 ne_cfg_get_init_type(void) { uint32_t flash_sector = PARAM_SAVE_OTAINFO_TYPE; uint8_t data[4]; if (spi_flash_read(flash_sector*SECTOR_SIZE, (uint32 *)data, sizeof(data)) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "get type\r\n"); } if ((data[0] == 0x55) && (data[1] == 0xAA)) { return data[2]-1; } else { return -1; } } /****************************************************************************** * FunctionName : ne_cfg_set_init_type * Description : config function * Parameters : task param * Returns : none *******************************************************************************/ uint32_t ne_cfg_set_init_type(uint8_t type) { uint32_t flash_sector = PARAM_SAVE_OTAINFO_TYPE; uint8_t data[4]; data[0] = 0x55; data[1] = 0xAA; data[2] = type+1; data[3] = 0; /* write information to flash */ if (spi_flash_erase_sector(flash_sector) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "flash erase\r\n"); } else { if (spi_flash_write(flash_sector*SECTOR_SIZE, (uint32 *)data, sizeof(data)) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "flash write\r\n"); } } return TRUE; } int ne_cfg_get_product_id(uint8 *product_id, uint32 len) { uint32_t flash_sector = PARAM_SAVE_PRODUCTID; if(product_id == NULL || len < NE_PRODUCT_ID_LEN + 1){ LOG_EX(LOG_Error, "param error\r\n"); return ERR_FAIL; } if (spi_flash_read(flash_sector*SECTOR_SIZE, (uint32 *)product_id, sizeof(product_id)) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "read sector error\r\n"); return ERR_FAIL; } return ERR_OK; } int ne_cfg_save_product_id(uint8 *product_id, int32 len) { if(product_id == NULL || len < NE_PRODUCT_ID_LEN + 1){ LOG_EX(LOG_Error, "param error\n"); } if(spi_flash_erase_sector(PARAM_SAVE_PRODUCTID) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error\n"); return -ERR_ERASE_FLASH; } if(spi_flash_write(PARAM_SAVE_PRODUCTID * SECTOR_SIZE, (unsigned int*)product_id, len) != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error\n"); return -ERR_WRITE_FLASH; } return ERR_OK; } int CfgSaveToFlash(void) { SpiFlashOpResult ret = spi_flash_erase_sector(PARAM_SAVE_CONFIGURE); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error: %d\n", ret); return -ERR_ERASE_FLASH; } ret = spi_flash_write(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&g_globalCfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error: %d\n", ret); return -ERR_WRITE_FLASH; } return ERR_OK; } void ne_save_ssid_psk(uint8 *ssid, uint8 *psk) { GLOGAL_CONFIG cfg; SpiFlashOpResult ret; if(ssid == NULL) return; ret = spi_flash_read(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&cfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Read Sector error: %d\n", ret); } memset(cfg.staWifiCfg.pSSID, 0 , MAX_WIFI_SSID); memset(cfg.staWifiCfg.pPassword, 0 , MAX_WIFI_PASSWD); memcpy(cfg.staWifiCfg.pSSID, ssid, strlen(ssid)); memcpy(cfg.staWifiCfg.pPassword, psk, strlen(psk)); /* earse */ spi_flash_erase_sector(PARAM_SAVE_CONFIGURE); ret = spi_flash_write(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&cfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "write Sector error: %d\n", ret); } } void ne_clear_ssid_psk(void) { GLOGAL_CONFIG cfg; SpiFlashOpResult ret; ret = spi_flash_read(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&cfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Read Sector error: %d\n", ret); } memset(cfg.staWifiCfg.pSSID, 0, MAX_WIFI_SSID); memset(cfg.staWifiCfg.pPassword, 0, MAX_WIFI_PASSWD); ret = spi_flash_write(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&cfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "write Sector error: %d\n", ret); } } static void __dumpUserConfig(PUSER_CONFIG pCfg) { char* pStr; int i; #if 0 printf("FactoryMode: %d\n", pCfg->FactoryMode); printf("DeviceType: %d\n", pCfg->DeviceType); printf("ServerCfg:\n"); printf(" ProductKey: %s\n", pCfg->ServerCfg.ProductKey); printf(" ProductSecury: %s\n", pCfg->ServerCfg.ProductSecury); printf(" MQTTServer: %s\n", pCfg->ServerCfg.MQTTServer); printf(" MQTTPort: %d\n", pCfg->ServerCfg.MQTTPort); printf(" HTTPSServer: %s\n", pCfg->ServerCfg.HTTPSServer); printf("SoftAP:\n"); printf(" UDPSvrPort: %d\n", pCfg->SoftAP.UDPSvrPort); printf(" SoftAPFormat: %s\n", pCfg->SoftAP.SoftAPFormat); printf(" SoftAPDHCP:\n"); printf(" IPAddr: %s\n", pCfg->SoftAP.softAPDHCP.IPAddr); printf(" Netmask: %s\n", pCfg->SoftAP.softAPDHCP.Netmask); printf(" Gatway: %s\n", pCfg->SoftAP.softAPDHCP.Gatway); printf(" DHCPStartIP: %s\n", pCfg->SoftAP.softAPDHCP.DHCPStartIP); printf(" DHCPEndIP: %s\n", pCfg->SoftAP.softAPDHCP.DHCPEndIP); printf("UART:\n"); for(i = 0; i < 2; i++) { printf(" Baud[%d]: %d\n", i, pCfg->UART[i].Baud); printf(" DataBits[%d]: %d\n", i, pCfg->UART[i].DataBits); printf(" StopBits[%d]: %d\n", i, pCfg->UART[i].StopBits); printf(" FlowCtrl[%d]: %d\n", i, pCfg->UART[i].FlowCtrl); } #endif pStr = (char*)Struct2Json(pCfg, JE_USER_CFG, CRYPTO_NONE, &i); if(pStr == NULL || i != ERR_OK) { LOG_EX(LOG_Error, "Create JE_USER_CFG Error\n"); return; } LOG_EX(LOG_Debug, "User Configure Information:\n%s\n", pStr); free(pStr); } PUSER_CONFIG CreateDefaultUserCfg(void) { static USER_CONFIG usrCfg; memset(&usrCfg, 0, sizeof(USER_CONFIG)); usrCfg.Version = USER_CFG_VERSION; usrCfg.UsedDefault = TRUE; usrCfg.FactoryMode = 0; usrCfg.DeviceType = 0; usrCfg.ServerCfg.ProductKey = "46ab16f31749ac85076d50294efe2e03"; usrCfg.ServerCfg.ProductSecury = "eac46ba44c94"; usrCfg.ServerCfg.MQTTServer = "mqtt-dev.netease.im"; usrCfg.ServerCfg.MQTTPort = 8883; usrCfg.ServerCfg.HTTPSServer = "https://api-iot-dev.netease.im/RegisterDevice"; usrCfg.SoftAP.UDPSvrPort = 10086; usrCfg.SoftAP.SoftAPFormat = "NetEase_%02x%02x_Robovac"; usrCfg.WifiAP.pSSID = ""; usrCfg.WifiAP.pPassword = ""; usrCfg.SoftAP.softAPDHCP.IPAddr = "192.168.5.1"; usrCfg.SoftAP.softAPDHCP.Netmask = "255.255.255.0"; usrCfg.SoftAP.softAPDHCP.Gatway = "192.168.5.1"; usrCfg.SoftAP.softAPDHCP.DHCPStartIP = "192.168.5.100"; usrCfg.SoftAP.softAPDHCP.DHCPEndIP = "192.168.5.105"; usrCfg.UART[0].Baud = BIT_RATE_115200; usrCfg.UART[0].DataBits = UART_WordLength_8b; usrCfg.UART[0].StopBits = USART_StopBits_1; usrCfg.UART[0].Parity = USART_Parity_None; usrCfg.UART[0].FlowCtrl = USART_HardwareFlowControl_None; usrCfg.UART[1].Baud = BIT_RATE_115200; usrCfg.UART[1].DataBits = UART_WordLength_8b; usrCfg.UART[1].StopBits = USART_StopBits_1; usrCfg.UART[1].Parity = USART_Parity_None; usrCfg.UART[1].FlowCtrl = USART_HardwareFlowControl_None; usrCfg.UART[0].Baud = 115200; usrCfg.UART[0].DataBits = 3; usrCfg.UART[0].StopBits = 1; usrCfg.UART[0].Parity = 2; usrCfg.UART[0].FlowCtrl = 0; usrCfg.UART[1].Baud = 115200; usrCfg.UART[1].DataBits = 3; usrCfg.UART[1].StopBits = 1; usrCfg.UART[2].Parity = 2; usrCfg.UART[1].FlowCtrl = 0; usrCfg.GPIO.iSize = 0; usrCfg.GPIO.pGpioCfg = NULL; return &usrCfg; } int UserCfgSaveToFlash(void) { char* pStr; int err = ERR_OK; SpiFlashOpResult ret = spi_flash_erase_sector(PARAM_SAVE_USERCFG); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error: %d\n", ret); return -ERR_ERASE_FLASH; } pStr = (char *)Struct2Json(g_pUserCfg, JE_USER_CFG, CRYPTO_NONE, &err); if(pStr == NULL || err != ERR_OK) { LOG_EX(LOG_Error, "Create JE_USER_CFG Error: %d\n", err); return -ERR_JSON_STR_FORMAT; } ret = spi_flash_write(PARAM_SAVE_USERCFG * SECTOR_SIZE, (unsigned int *)pStr, strlen(pStr)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Erase Sector error: %d\n", ret); return -ERR_WRITE_FLASH; } free(pStr); return ERR_OK; } static int CfgDecrypto(unsigned char* pDest, unsigned char* pSrc, int iSlen) { int i = 0; unsigned char* pRet = pDest; mbedtls_aes_context aes_ctx; //密钥数值 const unsigned char key[16] = {'0', '1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; mbedtls_aes_init(&aes_ctx); //设置解密密钥 mbedtls_aes_setkey_dec(&aes_ctx, key, 128); //LOG_EX(LOG_Debug, "Input size: %d\n", iSlen); // AES ECB 解密 for(i = 0; i < iSlen / 16; i++) { mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, (const unsigned char*)pSrc, pDest); pSrc += 16; pDest += 16; } // 去除pad字符 for(i = 0; i < iSlen; i++) { if((isprint(pRet[i]) == 0) && (pRet[i] != 0x0A) && (pRet[i] != 0x0D)) { // LOG_EX(LOG_Debug, "pRet[%d] = %02X\n", i, pRet[i]); pRet[i] = 0; break; } } return i; } int CfgReadUserCfgFromFlash(void) { int i, slen; SpiFlashOpResult ret; PUSER_CONFIG pCfgInfo = NULL; unsigned char* pBase64Buf = NULL; char* pUserCfg = (char*)HAL_Malloc(SECTOR_SIZE); if(pUserCfg == NULL) { //LOG_EX(LOG_Error, "Malloc Memory Error\n"); return -ERR_MALLOC_MEMORY; } memset(pUserCfg, 0, SECTOR_SIZE); ret = spi_flash_read(PARAM_SAVE_USERCFG * SECTOR_SIZE, (unsigned int*)pUserCfg, SECTOR_SIZE); if(ret != SPI_FLASH_RESULT_OK) { //LOG_EX(LOG_Error, "Read Sector error: %d\n", ret); return -ERR_READ_FLASH; } slen = strlen(pUserCfg); pBase64Buf = (unsigned char *)HAL_Malloc(slen); if(pBase64Buf == NULL) { free(pUserCfg); return -ERR_MALLOC_MEMORY; } //LOG_EX(LOG_Debug, "Nand Read: \n%s\n\n", pUserCfg); ret = mbedtls_base64_decode(pBase64Buf, slen, &i, pUserCfg, slen); //IHW_LOG_BUF(LOG_Debug, "Json", (unsigned char*)pBase64Buf, i); //LOG_EX(LOG_Debug, "User Cfg(%d): \n%s\n\n", ret, pBase64Buf); memset(pUserCfg, 0, SECTOR_SIZE); ret = CfgDecrypto(pUserCfg, pBase64Buf, i); #if DEBUG_USER_CFG LOG_EX(LOG_Debug, "User Cfg Decode(%d): \n%s\n\n", ret, pUserCfg); #endif //IHW_LOG_BUF(LOG_Debug, "Json", (unsigned char*)pBase64Buf, strlen(pBase64Buf)); pCfgInfo = (PUSER_CONFIG)Json2Struct(pUserCfg, JE_USER_CFG, CRYPTO_NONE, &i); if(i != ERR_OK || pCfgInfo == NULL) { //LOG_EX(LOG_Error, "Decode User Configure Error: %d\n", i); if(pCfgInfo) { free(pCfgInfo); } if(pCfgInfo->GPIO.iSize > 0 && pCfgInfo->GPIO.pGpioCfg) { free(pCfgInfo->GPIO.pGpioCfg); } free(pUserCfg); free(pBase64Buf); return -ERR_JSON_STR_FORMAT; } pCfgInfo->UsedDefault = 0; //IHW_LOG_BUF(LOG_Debug, "UserCfg", (unsigned char*)pCfgInfo, sizeof(USER_CONFIG)); //__dumpUserConfig(pCfgInfo); g_pUserCfg = pCfgInfo; if(g_pUserCfg->Version != USER_CFG_VERSION) { UserCfgSaveToFlash(); } free(pUserCfg); free(pBase64Buf); return ERR_OK; } int CfgReadFromFlash(void) { GLOGAL_CONFIG cfg; SpiFlashOpResult ret; memset(&cfg, 0, sizeof(GLOGAL_CONFIG)); ret = spi_flash_read(PARAM_SAVE_CONFIGURE * SECTOR_SIZE, (unsigned int*)&cfg, sizeof(GLOGAL_CONFIG)); if(ret != SPI_FLASH_RESULT_OK) { LOG_EX(LOG_Error, "Read Sector error: %d\n", ret); return -ERR_READ_FLASH; } if(strcmp(cfg.pCfgTagsInfo, GLOBAL_TAGS) != 0) { LOG_EX(LOG_Warn, "Global Configure Uninit\n"); return -ERR_ITEM_UNINIT; } memcpy(&g_globalCfg, &cfg, sizeof(GLOGAL_CONFIG)); return ERR_OK; } GLOGAL_CONFIG * ne_get_cfg_data(void) { if(CfgReadFromFlash() == ERR_OK){ return &g_globalCfg; } else{ return NULL; } } void CfgInitEnv(void) { g_pUserCfg = CreateDefaultUserCfg(); #if !DEBUG_USER_CFG if(CfgReadUserCfgFromFlash() != ERR_OK) { UserCfgSaveToFlash(); } #endif if(CfgReadFromFlash() == ERR_OK) { return; } LOG_EX(LOG_Warn, "cfg read fail\n"); memset(&g_globalCfg, 0, sizeof(GLOGAL_CONFIG)); strcpy(g_globalCfg.pCfgTagsInfo, GLOBAL_TAGS); /* set soft ap config */ g_globalCfg.softapWifiCfg.authMode = AUTH_OPEN; g_globalCfg.softapWifiCfg.svrPort = SOFTAP_SERVER_PORT; strcpy(g_globalCfg.softapWifiCfg.pPassword, ""); CfgSaveToFlash(); } void ShowCfgConfigure(void) { LOG_EX(LOG_Debug, "Read user configure at Nand Flash address: 0x%04X000\n", PARAM_SAVE_USERCFG); #if DEBUG_USER_CFG CfgReadUserCfgFromFlash(); #endif __dumpUserConfig(g_pUserCfg); __dumpGlobalCfg(); }