esp8266-std/protocol/protocol.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;
}
}