440 lines
11 KiB
C
440 lines
11 KiB
C
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include "esp_common.h"
|
|
#include "user_config.h"
|
|
#include "cfg.h"
|
|
#include "log.h"
|
|
#include "c_types.h"
|
|
#include "protocol.h"
|
|
#include "user_main.h"
|
|
#include "jsprase.h"
|
|
#include "uthash/libut.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/semphr.h"
|
|
|
|
static xSemaphoreHandle g_MCUMutex = NULL;
|
|
static PMCU_MSG_INFO g_pMCUMsg = NULL;
|
|
|
|
int ProCacheMCUMsg(unsigned char* pData, int msgSize, int msgType)
|
|
{
|
|
int codeSize, iCount = 0;
|
|
PMCU_MSG_INFO pMsg = NULL;
|
|
|
|
if(pData == NULL || msgSize <= 0)
|
|
{
|
|
return ERR_OK;
|
|
}
|
|
|
|
LL_COUNT(g_pMCUMsg, pMsg, iCount);
|
|
|
|
if(iCount >= MAX_MSG_CACHE)
|
|
{
|
|
LOG_EX(LOG_Error, "MCU Msg Full(%d)\n", iCount);
|
|
return -ERR_MSG_FULL;
|
|
}
|
|
|
|
pMsg = (PMCU_MSG_INFO)malloc(sizeof(struct MCU_MSG_INFO));
|
|
|
|
if(pMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Malloc Memory(%u) Error\n", sizeof(struct MCU_MSG_INFO));
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
|
|
memset(pMsg, 0, sizeof(struct MCU_MSG_INFO));
|
|
codeSize = ((msgSize + 3) / 3) * 4 + 4;
|
|
|
|
pMsg->pMessage = (char*)malloc(codeSize);
|
|
pMsg->msgType = msgType;
|
|
|
|
if(pMsg->pMessage == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Malloc Memory(%u) Error\n", sizeof(codeSize));
|
|
free(pMsg);
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
|
|
memset(pMsg->pMessage, 0, codeSize);
|
|
mbedtls_base64_encode(pMsg->pMessage, codeSize, &iCount, pData, msgSize);
|
|
|
|
xSemaphoreTake(g_MCUMutex, portMAX_DELAY);
|
|
LL_APPEND(g_pMCUMsg, pMsg);
|
|
xSemaphoreGive(g_MCUMutex);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
char* ProGetMCUMsg(int* pMsgType)
|
|
{
|
|
PMCU_MSG_INFO pMsg = NULL,
|
|
pTmp = NULL;
|
|
char* pMQTTMsg = NULL;
|
|
int ret = ERR_OK;
|
|
BYPASS_INFO bypassInfo;
|
|
char* pMsgContent = NULL;
|
|
int msgType;
|
|
|
|
xSemaphoreTake(g_MCUMutex, portMAX_DELAY);
|
|
LL_FOREACH_SAFE(g_pMCUMsg, pMsg, pTmp)
|
|
{
|
|
LL_DELETE(g_pMCUMsg, pMsg);
|
|
break;
|
|
}
|
|
xSemaphoreGive(g_MCUMutex);
|
|
|
|
if(pMsg == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
msgType = pMsg->msgType;
|
|
|
|
if(pMsgType)
|
|
{
|
|
*pMsgType = msgType;
|
|
}
|
|
|
|
memset(&bypassInfo, 0, sizeof(BYPASS_INFO));
|
|
bypassInfo.mcuCmd = pMsg->pMessage;
|
|
free(pMsg);
|
|
pMsg = NULL;
|
|
|
|
if(MSG_TYPE_BYPASS == msgType || MSG_TYPE_BIGDATA == msgType)
|
|
{
|
|
CLOUND_API api;
|
|
|
|
api.cmdId = MSG_BYPASS;
|
|
api.ver = PROTOCOL_VERSION;
|
|
api.cryptoType = 0;
|
|
api.timeStamp = 0;
|
|
|
|
api.msgContent = (char*)Struct2Json(&bypassInfo, JE_BYPASS, CRYPTO_NONE, &ret);
|
|
free(bypassInfo.mcuCmd);
|
|
|
|
if(ret != ERR_OK || api.msgContent == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Bypass Message Error %p: %d\n", api.msgContent, ret);
|
|
if(api.msgContent)
|
|
{
|
|
free(api.msgContent);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
pMQTTMsg = (char *)Struct2Json(&api, JE_PROMAIN, CRYPTO_NONE, &ret);
|
|
|
|
if(api.msgContent)
|
|
{
|
|
free(api.msgContent);
|
|
}
|
|
|
|
if(ret != ERR_OK || pMQTTMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Protocol Message Error %p: %d\n", pMQTTMsg, ret);
|
|
|
|
if(pMQTTMsg)
|
|
{
|
|
free(pMQTTMsg);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
else if(MSG_TYPE_SHADOW == msgType)
|
|
{
|
|
SHADOW_UPDATE shadow;
|
|
|
|
memset(&shadow, 0, sizeof(SHADOW_UPDATE));
|
|
shadow.method = "update";
|
|
shadow.version = 1;
|
|
shadow.state.reported.mcuCmd = bypassInfo.mcuCmd;
|
|
pMQTTMsg = (char *)Struct2Json(&shadow, JE_SHADOWUP, CRYPTO_NONE, &ret);
|
|
free(bypassInfo.mcuCmd);
|
|
|
|
if(ret != ERR_OK || pMQTTMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Bypass Message Error %p: %d\n", pMQTTMsg, ret);
|
|
if(pMQTTMsg)
|
|
{
|
|
free(pMQTTMsg);
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free(bypassInfo.mcuCmd);
|
|
}
|
|
|
|
return pMQTTMsg;
|
|
}
|
|
|
|
int ProCacheMQTTMsg(char* pData)
|
|
{
|
|
int codeSize, iCount = 0;
|
|
MQTT_MSG msg;
|
|
|
|
if(pData == NULL)
|
|
{
|
|
return ERR_OK;
|
|
}
|
|
|
|
memset(&msg, 0, sizeof(MQTT_MSG));
|
|
|
|
codeSize = ((strlen(pData) + 4) / 4) * 3;
|
|
msg.pMessage = (unsigned char *)malloc(codeSize);
|
|
|
|
if(msg.pMessage == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Malloc Memory(%u) Error\n", sizeof(codeSize));
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
|
|
memset(msg.pMessage, 0, codeSize);
|
|
mbedtls_base64_decode(msg.pMessage, codeSize, &iCount, pData, strlen(pData));
|
|
msg.msgSize = iCount;
|
|
#if 0
|
|
char buf[512];
|
|
|
|
SysBin2HexStr(buf, pMsg->pMQTTMsg->pMessage, iCount);
|
|
LOG_EX(LOG_Debug, "Cache:\n%s\n", buf);
|
|
#endif
|
|
if(iCount > codeSize)
|
|
{
|
|
LOG_EX(LOG_Error, "Memory overlay: iCount = %d, malloc = %d\n", iCount, codeSize);
|
|
}
|
|
|
|
ne_device_send_queue(msg.pMessage, msg.msgSize, MSG_DIRECTION_CLOUD_DOWN);
|
|
|
|
free(msg.pMessage);
|
|
return ERR_OK;
|
|
}
|
|
|
|
void ProDumpCloundApi(PCLOUND_API pApi)
|
|
{
|
|
LOG_EX(LOG_Debug, "Dump CLOUND API Info:\n");
|
|
LOG_RAW(LOG_Debug, "-----------------------------------------------------\n");
|
|
LOG_RAW(LOG_Debug, "CmdId : %s(%d)\n", ProName2Str(pApi->cmdId), pApi->cmdId);
|
|
LOG_RAW(LOG_Debug, "Crypto : %s(%d)\n", ProCryptoName2Str(pApi->cryptoType), pApi->cryptoType);
|
|
LOG_RAW(LOG_Debug, "Timestamp : %d\n", pApi->timeStamp);
|
|
LOG_RAW(LOG_Debug, "Message : %s\n", pApi->msgContent ? pApi->msgContent : "");
|
|
}
|
|
|
|
int ProtocolOnMsg(PCLOUND_API pApi)
|
|
{
|
|
int isRspMsg = FALSE;
|
|
int err = ERR_OK;
|
|
void* pObject = NULL;
|
|
char* pSubMsg = NULL;
|
|
CLOUND_API api;
|
|
|
|
switch(pApi->cmdId)
|
|
{
|
|
default: return -ERR_UNKNOWN_CMD_ID;
|
|
case GET_DEV_ID:
|
|
{
|
|
RSP_GET_DEVID_PRO devId;
|
|
uint8 product_id[5];
|
|
|
|
memset(product_id, 0, sizeof(product_id));
|
|
memset(&devId, 0, sizeof(RSP_GET_DEVID_PRO));
|
|
devId.cpuId = (char*)GetPlatformDevId();
|
|
devId.macAddr = (char *)GetSTAMacAddr();
|
|
if(ne_cfg_get_product_id(product_id, sizeof(product_id)) == ERR_OK){
|
|
devId.productSign = product_id;
|
|
}
|
|
pSubMsg = (char*)Struct2Json(&devId, JE_GETID, CRYPTO_NONE, &err);
|
|
|
|
if(err != ERR_OK || pSubMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create %s Message Error %p: %d\n", ProName2Str(pApi->cmdId), pSubMsg, err);
|
|
|
|
if(pSubMsg)
|
|
{
|
|
free(pSubMsg);
|
|
}
|
|
|
|
pSubMsg = NULL;
|
|
}
|
|
|
|
isRspMsg = TRUE;
|
|
break;
|
|
}
|
|
case CONFIG_AP:
|
|
{
|
|
PCFG_AP_INFO pApInfo = (PCFG_AP_INFO)Json2Struct(pApi->msgContent, JE_CFG_AP, CRYPTO_NONE, &err);
|
|
|
|
if(err != ERR_OK || pApInfo == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Process %s Message Error %p: %d\n", ProName2Str(pApi->cmdId), pSubMsg, err);
|
|
|
|
if(pApInfo)
|
|
{
|
|
free(pApInfo);
|
|
}
|
|
|
|
break;
|
|
}
|
|
#if 0
|
|
pApInfo->gbkpasswd = strdup(pApInfo->passwd);
|
|
pApInfo->gbkssid = strdup("zt7P31dpRmnExLzSx7+wocC2z+g=");
|
|
#endif
|
|
soft_ap_start_test(pApInfo);
|
|
|
|
if(pApInfo->bssid)
|
|
{
|
|
free(pApInfo->bssid);
|
|
}
|
|
|
|
if(pApInfo->passwd)
|
|
{
|
|
free(pApInfo->passwd);
|
|
}
|
|
|
|
if(pApInfo->ssid)
|
|
{
|
|
free(pApInfo->ssid);
|
|
}
|
|
|
|
if(pApInfo->gbkssid)
|
|
{
|
|
free(pApInfo->gbkssid);
|
|
}
|
|
|
|
if(pApInfo->gbkpasswd)
|
|
{
|
|
free(pApInfo->gbkpasswd);
|
|
}
|
|
|
|
free(pApInfo);
|
|
|
|
break;
|
|
}
|
|
case EXIT_SOFTAP_MODE:
|
|
{
|
|
isRspMsg = TRUE;
|
|
SoftAPExitCfgMode(1);
|
|
break;
|
|
}
|
|
case MSG_BYPASS:
|
|
{
|
|
PBYPASS_INFO pInfo = (PBYPASS_INFO)Json2Struct(pApi->msgContent, JE_BYPASS, CRYPTO_NONE, &err);
|
|
|
|
if(err != ERR_OK || pInfo == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Process %s Message Error %p: %d\n", ProName2Str(pApi->cmdId), pInfo, err);
|
|
|
|
if(pInfo)
|
|
{
|
|
free(pInfo);
|
|
}
|
|
}
|
|
else if(pInfo->mcuCmd && strlen(pInfo->mcuCmd) > 0)
|
|
{
|
|
ProCacheMQTTMsg(pInfo->mcuCmd);
|
|
}
|
|
|
|
if(pInfo->mcuCmd)
|
|
{
|
|
free(pInfo->mcuCmd);
|
|
}
|
|
|
|
free(pInfo);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(isRspMsg)
|
|
{
|
|
char *pRspMsg = NULL;
|
|
|
|
api.msgContent = NULL;
|
|
api.ver = PROTOCOL_VERSION;
|
|
api.cmdId = CLOUND_API_CMD_RSP_BASE + pApi->cmdId;
|
|
api.cryptoType = 0;
|
|
api.timeStamp = 0;
|
|
|
|
if(err != ERR_OK)
|
|
{
|
|
CLOUND_API_RSP_ERR rspErr;
|
|
|
|
rspErr.errNo = err < 0 ? -err : err;
|
|
rspErr.errMsg = (char*)SysGetErrName(rspErr.errNo);
|
|
|
|
pSubMsg = (char*)Struct2Json(&rspErr, JE_RSP_STATUS, CRYPTO_NONE, &err);
|
|
|
|
if(err != ERR_OK || pRspMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Rsponse Error Message Error %p: %d\n", pRspMsg, err);
|
|
}
|
|
}
|
|
|
|
if(pSubMsg)
|
|
{
|
|
api.msgContent = pSubMsg;
|
|
}
|
|
|
|
pRspMsg = (char*)Struct2Json(&api, JE_PROMAIN, CRYPTO_NONE, &err);
|
|
|
|
if(err != ERR_OK || pRspMsg == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Rsponse Error %p: %d\n", pRspMsg, err);
|
|
}
|
|
|
|
if(pApi->cmdId == GET_DEV_ID
|
|
|| pApi->cmdId == CONFIG_AP
|
|
|| pApi->cmdId == EXIT_SOFTAP_MODE)
|
|
{
|
|
SoftAPSendRspMsg(pRspMsg);
|
|
}
|
|
|
|
if(pRspMsg)
|
|
{
|
|
free(pRspMsg);
|
|
}
|
|
}
|
|
|
|
if(pSubMsg)
|
|
{
|
|
free(pSubMsg);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int ProtocolProcess(char* pStrJson)
|
|
{
|
|
int err = ERR_OK;
|
|
PCLOUND_API pApi = (PCLOUND_API)Json2Struct(pStrJson, JE_PROMAIN, CRYPTO_NONE, &err);
|
|
|
|
if(pApi == NULL || err != ERR_OK)
|
|
{
|
|
LOG_EX(LOG_Error, "Protocol %p: %d\n", pApi, err);
|
|
return err;
|
|
}
|
|
|
|
ProDumpCloundApi(pApi);
|
|
|
|
err = ProtocolOnMsg(pApi);
|
|
|
|
if(pApi->msgContent)
|
|
{
|
|
free(pApi->msgContent);
|
|
}
|
|
free(pApi);
|
|
return err;
|
|
}
|
|
|
|
int ProtocolInitEnv(void)
|
|
{
|
|
g_MCUMutex = xSemaphoreCreateMutex();
|
|
|
|
if(g_MCUMutex == NULL)
|
|
{
|
|
LOG_EX(LOG_Error, "Create Mutex Error\n");
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
}
|