diff --git a/include/jsprase.h b/include/jsprase.h index dce9bf6..07bae46 100644 --- a/include/jsprase.h +++ b/include/jsprase.h @@ -13,6 +13,7 @@ typedef enum JE_RSP_STATUS, JE_GLOBAL_CFG, JE_USER_CFG, + JE_GPIO, JE_MAX, } JSON_ENGINE_TYPE; diff --git a/include/protocol.h b/include/protocol.h index 8bbf104..07a523d 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -16,6 +16,7 @@ typedef enum CONFIG_AP = 2, EXIT_SOFTAP_MODE = 3, MSG_BYPASS = 1000, + GPIO_FUNC = 3000, } CLOUND_API_CMD; typedef enum @@ -31,6 +32,14 @@ typedef enum CRYPTO_DECODE = 1 } CRYPTO_OPT; +typedef enum +{ + GPIO_CMD_CFG = 0, + GPIO_CMD_OUTPUT, + GPIO_CMD_INPUT, + GPIO_CMD_MAX, +} GPIO_CFG_CMD; + typedef struct { char* cpuId; @@ -52,6 +61,21 @@ typedef struct char* gbkpasswd; } CFG_AP_INFO, *PCFG_AP_INFO; +typedef struct +{ + int id; + int cmd; + int cfgParams[4]; + int val; + int err; +} GPIO_VALUE, *PGPIO_VALUE; + +typedef struct +{ + int iSize; + PGPIO_VALUE pGpio; +} GPIO_INFO, *PGPIO_INFO; + typedef struct { int cmdId; diff --git a/jsprase/json_prase.c b/jsprase/json_prase.c index 9b7bcae..6f023fc 100644 --- a/jsprase/json_prase.c +++ b/jsprase/json_prase.c @@ -11,6 +11,7 @@ #include "user_main.h" #include "jsprase.h" #include "cfg.h" +#include "gpio_map.h" S2jHook s2jHook = { .malloc_fn = malloc, @@ -316,6 +317,21 @@ static int __getIntValue(cJSON *pRoot, const char* pKey, int defVal) } } +static int __getArrayIntValue(cJSON *pRoot, int idx, int defVal) +{ + cJSON* pRet = cJSON_GetArrayItem(pRoot, idx); + + if(pRet == NULL) + { + return defVal; + } + else + { + return pRet->valueint; + } +} + + static char* __getStringValue(cJSON *pRoot, const char* pKey, const char* defVal) { cJSON* pRet = cJSON_GetObjectItem(pRoot, pKey); @@ -334,7 +350,7 @@ static const char* __userCfg2Json(void* pData) { int i; const char* pJsonS; - cJSON *pSvrCfg, *pSoftApCfg, *pWifiApCfg, *pUartCfg, *pDhcpCfg; + cJSON *pSvrCfg, *pSoftApCfg, *pWifiApCfg, *pUartCfg, *pDhcpCfg, *pGPIOCfg; PUSER_CONFIG pCfg = (PUSER_CONFIG)pData; cJSON* pRoot = cJSON_CreateObject(); @@ -383,6 +399,18 @@ static const char* __userCfg2Json(void* pData) return NULL; } + pGPIOCfg = cJSON_CreateArray(); + if(pGPIOCfg == NULL) + { + LOG_EX(LOG_Error, "Create cJSON Error\n"); + cJSON_Delete(pRoot); + cJSON_Delete(pSvrCfg); + cJSON_Delete(pSoftApCfg); + cJSON_Delete(pWifiApCfg); + cJSON_Delete(pUartCfg); + return NULL; + } + pDhcpCfg = cJSON_CreateObject(); if(pDhcpCfg == NULL) { @@ -391,9 +419,12 @@ static const char* __userCfg2Json(void* pData) cJSON_Delete(pSvrCfg); cJSON_Delete(pSoftApCfg); cJSON_Delete(pUartCfg); + cJSON_Delete(pGPIOCfg); cJSON_Delete(pWifiApCfg); return NULL; } + + cJSON_AddItemToObject(pRoot, "UsedDefault", cJSON_CreateNumber(pCfg->UsedDefault)); cJSON_AddItemToObject(pRoot, "Version", cJSON_CreateNumber(pCfg->Version)); @@ -404,6 +435,7 @@ static const char* __userCfg2Json(void* pData) cJSON_AddItemToObject(pRoot, "WIFIApConfig", pWifiApCfg); cJSON_AddItemToObject(pRoot, "SoftAP", pSoftApCfg); cJSON_AddItemToObject(pRoot, "UART", pUartCfg); + cJSON_AddItemToObject(pRoot, "GPIO", pGPIOCfg); cJSON_AddItemToObject(pSvrCfg, "ProductKey", cJSON_CreateString(pCfg->ServerCfg.ProductKey)); cJSON_AddItemToObject(pSvrCfg, "ProductSecury", cJSON_CreateString(pCfg->ServerCfg.ProductSecury)); @@ -443,7 +475,26 @@ static const char* __userCfg2Json(void* pData) cJSON_AddItemToObject(pUartItem, "FlowCtrl", cJSON_CreateNumber(pCfg->UART[i].FlowCtrl)); cJSON_AddItemToArray(pUartCfg, pUartItem); } - + + for(i = 0; i < pCfg->GPIO.iSize && pCfg->GPIO.pGpioCfg; i++) + { + cJSON* pGpioItem = cJSON_CreateObject(); + + if(pGpioItem == NULL) + { + LOG_EX(LOG_Error, "Create cJSON Object Error\n"); + cJSON_Delete(pRoot); + return NULL; + } + + cJSON_AddItemToObject(pGpioItem, "Id", cJSON_CreateNumber(pCfg->GPIO.pGpioCfg[i].Id)); + cJSON_AddItemToObject(pGpioItem, "Func", cJSON_CreateNumber(pCfg->GPIO.pGpioCfg[i].Func)); + cJSON_AddItemToObject(pGpioItem, "Dir", cJSON_CreateNumber(pCfg->GPIO.pGpioCfg[i].Dir)); + cJSON_AddItemToObject(pGpioItem, "PullUp", cJSON_CreateNumber(pCfg->GPIO.pGpioCfg[i].PullUp)); + cJSON_AddItemToObject(pGpioItem, "Interrupt", cJSON_CreateNumber(pCfg->GPIO.pGpioCfg[i].Interrupt)); + cJSON_AddItemToArray(pGPIOCfg, pGpioItem); + } + pJsonS = cJSON_Print(pRoot); cJSON_Delete(pRoot); @@ -534,11 +585,202 @@ static void* __json2UserCfg(const char* pJsonS) pList = pList->next; } } + + pItem = cJSON_GetObjectItem(pRoot, "GPIO"); + + if(pItem) + { + int i = 0; + int arraySize = cJSON_GetArraySize(pItem); + cJSON *pList = pItem->child; + + if(arraySize > 0 && arraySize < USER_GPIO_MAX) + { + pCfg->GPIO.pGpioCfg = (PGPIO_ITEM)malloc(sizeof(GPIO_ITEM) * arraySize); + + if(pCfg->GPIO.pGpioCfg == NULL) + { + LOG_EX(LOG_Error, "Malloc Error Error: %d\n", arraySize); + } + } + + pCfg->GPIO.iSize = 0; + + for(i = 0; i < arraySize && pCfg->GPIO.pGpioCfg; i++) + { + LOG_EX(LOG_Debug, "i = %d, arraySize = %d, item = %d\n", i, arraySize, pCfg->GPIO.iSize); + pCfg->GPIO.pGpioCfg[i].Id = __getIntValue(pList, "Id", -1); + pCfg->GPIO.pGpioCfg[i].Func = __getIntValue(pList, "Func", -1); + pCfg->GPIO.pGpioCfg[i].Dir = __getIntValue(pList, "Dir", -1); + pCfg->GPIO.pGpioCfg[i].PullUp = __getIntValue(pList, "PullUp", -1); + pCfg->GPIO.pGpioCfg[i].Interrupt = __getIntValue(pList, "Interrupt", -1); + pCfg->GPIO.iSize++; + + pList = pList->next; + } + } cJSON_Delete(pRoot); return pCfg; } +static const char* __gpio2Json(void* pData) +{ + int i; + const char* pJsonS; + PGPIO_INFO pInfo = (PGPIO_INFO)pData; + cJSON* pGpio = NULL; + cJSON* pRoot = cJSON_CreateObject(); + + if(pRoot == NULL) + { + LOG_EX(LOG_Error, "Create cJSON Error\n"); + return NULL; + } + + pGpio = cJSON_CreateArray(); + + if(pGpio == NULL) + { + LOG_EX(LOG_Error, "Create cJSON Error\n"); + cJSON_Delete(pRoot); + return NULL; + } + + cJSON_AddItemToObject(pRoot, "gpio", pGpio); + + for(i = 0; i < pInfo->iSize && pInfo->pGpio; i++) + { + int id = pInfo->pGpio[i].id; + int cmd = pInfo->pGpio[i].cmd; + + cJSON* pGpioItem = cJSON_CreateObject(); + if(pGpioItem == NULL) + { + LOG_EX(LOG_Error, "Create cJSON Object Error\n"); + continue; + } + + if(id < USER_GPIO_4 || id >= USER_GPIO_MAX) + { + LOG_EX(LOG_Error, "Bad GPIO id [%d]\n", id); + continue; + } + + if(cmd < GPIO_CMD_CFG || cmd > GPIO_CMD_MAX) + { + LOG_EX(LOG_Error, "Bad GPIO cmd [%d --> %d]\n", id, cmd); + continue; + } + + cJSON_AddItemToObject(pGpioItem, "id", cJSON_CreateNumber(id)); + cJSON_AddItemToObject(pGpioItem, "cmd", cJSON_CreateNumber(cmd)); + cJSON_AddItemToObject(pGpioItem, "err", cJSON_CreateNumber(pInfo->pGpio[i].err)); + + if(cmd == GPIO_CMD_INPUT) + { + cJSON_AddItemToObject(pGpioItem, "val", cJSON_CreateNumber(pInfo->pGpio[i].val)); + } + } + + pJsonS = cJSON_Print(pRoot); + + cJSON_Delete(pRoot); + + return pJsonS; +} + +static void* __json2Gpio(const char* pJsonS) +{ + int i, arraySize = 0; + cJSON* pItem = NULL; + cJSON* pList = NULL; + PGPIO_INFO pInfo = NULL; + + cJSON *pRoot = cJSON_Parse(pJsonS); + + if(pRoot == NULL) + { + LOG_EX(LOG_Error, "Json Format Error: [%s]\n", pJsonS); + return NULL; + } + + pInfo = (PGPIO_INFO)malloc(sizeof(GPIO_INFO)); + + if(pInfo == NULL) + { + LOG_EX(LOG_Error, "Malloc GPIO_INFO Error\n"); + cJSON_Delete(pRoot); + return NULL; + } + + pItem = cJSON_GetObjectItem(pRoot, "gpio"); + + if(pItem == NULL) + { + LOG_EX(LOG_Error, "Items is empty:[%s]\n", pJsonS); + cJSON_Delete(pRoot); + return NULL; + } + + arraySize = cJSON_GetArraySize(pItem); + + if(arraySize <= 0) + { + LOG_EX(LOG_Error, "Items is empty(%d):[%s]\n", arraySize, pJsonS); + cJSON_Delete(pRoot); + return NULL; + } + + pInfo->pGpio = (PGPIO_VALUE)malloc(sizeof(GPIO_VALUE) * arraySize); + + if(pInfo->pGpio == NULL) + { + LOG_EX(LOG_Error, "Malloc GPIO_VALUE Error(%d)\n", arraySize); + cJSON_Delete(pRoot); + free(pInfo); + return NULL; + } + + pList = pItem->child; + + pInfo->iSize = arraySize; + + for(i = 0; i < arraySize; i++) + { + pInfo->pGpio[i].id = __getIntValue(pList, "id", USER_GPIO_MAX); + pInfo->pGpio[i].cmd = __getIntValue(pList, "cmd", -1); + + if(pInfo->pGpio[i].cmd == 0) + { + cJSON* pArray = cJSON_GetObjectItem(pList, "cfgParams"); + int nItem = cJSON_GetArraySize(pArray); + + if(nItem == 4 && pArray) + { + pInfo->pGpio[i].cfgParams[0] = __getArrayIntValue(pArray, 0, 0); + pInfo->pGpio[i].cfgParams[1] = __getArrayIntValue(pArray, 1, 0); + pInfo->pGpio[i].cfgParams[2] = __getArrayIntValue(pArray, 2, 0); + pInfo->pGpio[i].cfgParams[3] = __getArrayIntValue(pArray, 3, 0); + } + else + { + LOG_EX(LOG_Error, "Decode Array Error: nItem = %d, pArray = %p\n", nItem, pArray); + } + } + else if(pInfo->pGpio[i].cmd == 1) + { + pInfo->pGpio[i].val = __getIntValue(pList, "val", -1); + } + + pList = pList->next; + } + + cJSON_Delete(pRoot); + + return pInfo; +} + static JSON_ENGINE g_jSonEngine[] = { {JE_PROMAIN, __pro2Json, __json2pro, NULL}, @@ -549,6 +791,7 @@ static JSON_ENGINE g_jSonEngine[] = {JE_RSP_STATUS, __errno2Json, NULL, NULL}, {JE_GLOBAL_CFG, __gblCfg2Json, __json2GblCfg, NULL}, {JE_USER_CFG, __userCfg2Json, __json2UserCfg, NULL}, + {JE_USER_CFG, __gpio2Json, __json2Gpio, NULL}, }; void* Json2Struct(const char* pJsonStr, JSON_ENGINE_TYPE type, int cryptoType, int* pErr) diff --git a/protocol/protocol.c b/protocol/protocol.c index 238061c..ea5cd52 100644 --- a/protocol/protocol.c +++ b/protocol/protocol.c @@ -13,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#include "gpio_map.h" static xSemaphoreHandle g_MCUMutex = NULL; static PMCU_MSG_INFO g_pMCUMsg = NULL; @@ -330,6 +331,7 @@ int ProtocolOnMsg(PCLOUND_API pApi) { free(pInfo); } + break; } else if(pInfo->mcuCmd && strlen(pInfo->mcuCmd) > 0) { @@ -344,6 +346,92 @@ int ProtocolOnMsg(PCLOUND_API pApi) free(pInfo); break; } + case GPIO_FUNC: + { + PGPIO_INFO pInfo = (PGPIO_INFO)Json2Struct(pApi->msgContent, JE_GPIO, CRYPTO_NONE, &err); + isRspMsg = TRUE; + + 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); + } + + break; + } + else if(pInfo->iSize > 0 && pInfo->pGpio && pInfo->iSize < USER_GPIO_MAX) + { + int i; + char *pRsp, *pRspCtx = NULL; + for(i = 0; i < pInfo->iSize; i++) + { + PGPIO_VALUE pGpio = &pInfo->pGpio[i]; + + if(pGpio->cmd == GPIO_CMD_CFG) + { + pGpio->err = pin_cfg_gpio(pGpio->id, + pGpio->cfgParams[0], + pGpio->cfgParams[1], + pGpio->cfgParams[2], + pGpio->cfgParams[3]); + } + else if(pGpio->cmd == GPIO_CMD_OUTPUT) + { + pGpio->err = gpio_set_level(pGpio->id, pGpio->val); + } + else if(pGpio->cmd == GPIO_CMD_INPUT) + { + int ret = gpio_get_level(pGpio->id); + + if(ret < 0) + { + pGpio->err = ret; + } + else + { + pGpio->val = ret; + pGpio->err = 0; + } + } + else + { + pGpio->err = -ERR_GPIO_UNKNOWN_CMD; + } + //pInfo->pGpio[i].err = + } + + pSubMsg = (char*)Struct2Json(pInfo, JE_GPIO, CRYPTO_NONE, &err); + + if(err != ERR_OK) + { + LOG_EX(LOG_Error, "JE_GPIO Json Encode Error: %d\n", err); + } + if(pSubMsg == NULL || strlen(pSubMsg) <= 0) + { + LOG_EX(LOG_Error, "Create Rsponse Error Message Error %p: [%s]\n", pSubMsg, pSubMsg); + err = -ERR_JSON_STR_FORMAT; + } + else + { + err = 0; + } + } + else + { + err = -ERR_INPUT_PARAMS; + } + + if(pInfo->pGpio) + { + free(pInfo); + } + + free(pInfo); + break; + } } if(isRspMsg)