diff options
| author | Daiqian Hu <[email protected]> | 2016-11-21 08:54:24 +0800 |
|---|---|---|
| committer | Daiqian Hu <[email protected]> | 2016-11-21 08:54:24 +0800 |
| commit | a95eaad088f61aa55da9d73015cf1ed86e64a67e (patch) | |
| tree | 15b498a08a4aee4b7f8b1627d39c965b3aa3ba98 /network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c | |
| parent | 1aa0338ec5418345ea0c383e92b4fa19f7c98425 (diff) | |
Re-submit for WDI sample driver to GitHub
Submit WDI sample driver to GitHub for RS1.
Diffstat (limited to 'network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c')
| -rw-r--r-- | network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c | 502 |
1 files changed, 502 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c b/network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c new file mode 100644 index 00000000..4f13a420 --- /dev/null +++ b/network/wlan/WDI/COMMON/P2PSvc_ParamSpec.c @@ -0,0 +1,502 @@ +#include "Mp_Precomp.h" + +#include "P2PSvc_Internal.h" + +#if (P2P_SUPPORT == 1) +#if (P2PSVC_SUPPORT == 1) + +// +// Description: +// This table defines the parameters of the supported actions. +// The table is used for validating action request from upper layer. +// +P2PSVC_ACTION_SPEC_ENTRY lP2PSvcActionSpecTab[] = +{ + { + P2PSVC_OBJ_HDR_ID_ACT_ENABLE, + { + P2PSVC_OBJ_HDR_ID_DATA_BENABLE, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_SEEK, + { + P2PSVC_OBJ_HDR_ID_DATA_SEARCH_ID, + P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME, + P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH, + P2PSVC_OBJ_HDR_ID_DATA_DEV_ADDR, + P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO_REQ, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_CANCEL_SEEK, + { + P2PSVC_OBJ_HDR_ID_DATA_SEARCH_ID, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_ADVERTISE, + { + P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME, + P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH, + P2PSVC_OBJ_HDR_ID_DATA_SVC_AUTO_ACCEPT, + P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO, + P2PSVC_OBJ_HDR_ID_DATA_SVC_STATUS, + P2PSVC_OBJ_HDR_ID_DATA_NETWORK_CONFIG, + P2PSVC_OBJ_HDR_ID_DATA_ADV_ID, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_CANCEL_ADVERTISE, + { + P2PSVC_OBJ_HDR_ID_DATA_ADV_ID, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_SVC_STATUS, + { + P2PSVC_OBJ_HDR_ID_DATA_ADV_ID, + P2PSVC_OBJ_HDR_ID_DATA_SVC_STATUS, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_PD_REQ, + { + P2PSVC_OBJ_HDR_ID_DATA_SESSION_ID, + P2PSVC_OBJ_HDR_ID_DATA_DEV_ADDR, + P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH, + P2PSVC_OBJ_HDR_ID_DATA_ADV_ID, + P2PSVC_OBJ_HDR_ID_DATA_SESSION_INFO, + P2PSVC_OBJ_HDR_ID_DATA_NETWORK_ROLE, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_FOPD_REQ, + { + P2PSVC_OBJ_HDR_ID_DATA_USER_ACCEPTED, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + { + P2PSVC_OBJ_HDR_ID_ACT_CONN_CAP, + { + P2PSVC_OBJ_HDR_ID_DATA_CONN_CAP, + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, + + //---------------------------------------------- + { + P2PSVC_OBJ_HDR_ID_ACT_UNKNOWN, + { + //----------------------------------- + P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN // sentinel + } + }, +}; + +P2PSVC_PARAM_SPEC_ENTRY lP2PSvcParamSpecTab[] = +{ + {P2PSVC_OBJ_HDR_ID_DATA_BENABLE, sizeof(BOOLEAN), sizeof(BOOLEAN)}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME, 1, 255}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH, 6, 6}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO_REQ, 0, 65535}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO, 0, 65535}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_AUTO_ACCEPT, sizeof(BOOLEAN), sizeof(BOOLEAN)}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_STATUS, sizeof(u1Byte), sizeof(u1Byte)}, + {P2PSVC_OBJ_HDR_ID_DATA_ADV_ID, sizeof(u4Byte), sizeof(u4Byte)}, + {P2PSVC_OBJ_HDR_ID_DATA_DEV_ADDR, 6, 6}, + {P2PSVC_OBJ_HDR_ID_DATA_SEARCH_ID, 1, 1}, + {P2PSVC_OBJ_HDR_ID_DATA_DEV_NAME, 1, 32}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_DESC_LIST, 1, 65535}, + {P2PSVC_OBJ_HDR_ID_DATA_SESSION_INFO, 1, 144}, + {P2PSVC_OBJ_HDR_ID_DATA_NETWORK_ROLE, sizeof(u1Byte), sizeof(u1Byte)}, + {P2PSVC_OBJ_HDR_ID_DATA_CONN_CAP, sizeof(u1Byte), sizeof(u1Byte)}, + {P2PSVC_OBJ_HDR_ID_DATA_SESSION_ID, sizeof(u4Byte), sizeof(u4Byte)}, + {P2PSVC_OBJ_HDR_ID_DATA_USER_ACCEPTED, sizeof(BOOLEAN), sizeof(BOOLEAN)}, + {P2PSVC_OBJ_HDR_ID_DATA_SVC_COUNT, sizeof(u1Byte), sizeof(u1Byte)}, + //-------------------------------------------------------------------------- + {P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN, 0, 0} +}; + +//----------------------------------------------------------------------------- +// Local +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Exported +//----------------------------------------------------------------------------- + + +PP2PSVC_PARAM_SPEC_ENTRY +P2PSvc_GetParamSpec( + IN u4Byte actId + ) +{ + u4Byte paramSpecIdx = 0; + PP2PSVC_PARAM_SPEC_ENTRY pParamSpec = NULL; + + for(paramSpecIdx = 0; P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN != lP2PSvcParamSpecTab[paramSpecIdx].paramId; paramSpecIdx++) + { + if(actId == lP2PSvcParamSpecTab[paramSpecIdx].paramId) + { + pParamSpec = &(lP2PSvcParamSpecTab[paramSpecIdx]); + break; + } + } + + return pParamSpec; + +} + +// +// Description: +// Validate if the input buffer contains an object with obj list as its payload +// +RT_STATUS +P2PSvc_ValidateReqInfo( + IN PVOID infoBuf, + IN u4Byte inBufLen, + OUT pu4Byte pBytesNeeded + ) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + u4Byte bytesNeeded = 0; + + + P2PSVC_FUNC_IN(DBG_LOUD); + + do + { + PRT_OBJECT_HEADER pObjHdr = NULL; + PP2PSVC_OBJ_LIST pObjList = NULL; + u4Byte objIter = 0; + + // Check if we can read the obj hdr + bytesNeeded = RT_OBJECT_HEADER_SIZE; + + if(inBufLen < bytesNeeded) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] Buffer (%d) too short for required (%d)!\n", inBufLen, bytesNeeded)); + rtStatus = RT_STATUS_INVALID_LENGTH; + break; + } + + // Check if the in buf is large enough to hold the data whose length is declared in the obj header + pObjHdr = (PRT_OBJECT_HEADER)(infoBuf); + + if(inBufLen < bytesNeeded + pObjHdr->Length) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] in buf is not large enough to hold the value, value len: %u, inbuf len: %u!\n", pObjHdr->Length, inBufLen)); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + // Check if the payload is a valid obj list + pObjList = (PP2PSVC_OBJ_LIST)(pObjHdr->Value); + bytesNeeded += FIELD_OFFSET(P2PSVC_OBJ_LIST, varStart); + if(inBufLen < bytesNeeded) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] in buf is not large enough to hold an obj list, inbuf len: %u!\n", inBufLen)); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + // Validate the obj hdr of the info list + if(P2PSVC_OBJ_HDR_ID_DATA_OBJ_LIST != pObjList->hdr.Id) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] payload is not an obj list, its id is: %u\n", pObjList->hdr.Id)); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + // Check if the objs in the obj list has valid length + for(objIter = 0; objIter < pObjList->nObjs; objIter++) + { + PRT_OBJECT_HEADER pCurObj = NULL; + + // Check we can read the obj hdr of the current obj + if(inBufLen < bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE) + { + bytesNeeded = bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE; + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] obj with index %u is not valid\n", objIter)); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + // Get the obj + pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter); + + // Check the hdr of the cur obj + if(inBufLen < bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE + pCurObj->Length) + { + bytesNeeded = bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE + pCurObj->Length; + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] inbuf (len: %u) is not large enough to hold the obj (index: %u, len: %u)\n", inBufLen, objIter, pCurObj->Length)); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + } + + if(RT_STATUS_SUCCESS != rtStatus) + { + break; + } + }while(FALSE); + + *pBytesNeeded = bytesNeeded; + + // Dump raw data if invalid + if(RT_STATUS_SUCCESS != rtStatus) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] info req invalid, bytesNeeded: %u\n", *pBytesNeeded)); + RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "InBuf:\n", infoBuf, inBufLen); + } + + P2PSVC_FUNC_OUT(DBG_LOUD, rtStatus); + + return rtStatus; +} + + + +// +// Description: +// Validate the object list contains all the required parameters of the id. +// E.g., for P2PSVC_OBJ_HDR_ID_ACT_SEEK, the obj list shall contain list of +// [svc-name, svc-hash, svc-info-req]. +// Each required obj shall appear just once. +// Order is not important. +// +RT_STATUS +P2PSvc_ValidateActionParam( + IN u4Byte id, + IN PP2PSVC_OBJ_LIST pObjList + ) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + + + int actSpecIdx = 0; + int nParams = 0; + int paramIdx = 0; + PP2PSVC_ACTION_SPEC_ENTRY pActSpec = NULL; + + do + { + // Search table + for(actSpecIdx = 0; P2PSVC_OBJ_HDR_ID_ACT_UNKNOWN != lP2PSvcActionSpecTab[actSpecIdx].actId; actSpecIdx++) + { + if(id == lP2PSvcActionSpecTab[actSpecIdx].actId) + { + pActSpec = &(lP2PSvcActionSpecTab[actSpecIdx]); + break; + } + } + + RT_ASSERT(pActSpec, ("p2psvc_AddSeekInfo(): Spec of P2PSVC_OBJ_HDR_ID_ACT_SEEK not specified in the action spec table\n")); + + // Count # of parameters + if (pActSpec != NULL) + { + for (nParams = 0; P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN != pActSpec->paramList[nParams]; nParams++) {} + } + + // Shall have exactly 1 set of parameters + for(paramIdx = 0; paramIdx < nParams; paramIdx++) + {// foreach required parameter + u4Byte objIter = 0; + PRT_OBJECT_HEADER pCurObj = NULL; + u4Byte nOccurrence = 0; + + for(objIter = 0; objIter < pObjList->nObjs; objIter++) + { + pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter); + if(pCurObj->Id == pActSpec->paramList[paramIdx]) nOccurrence++; + } + + if(0 == nOccurrence) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("param (0x%08X) not found\n", pActSpec->paramList[paramIdx])); + rtStatus = RT_STATUS_INVALID_PARAMETER; + break; + } + else if(1 < nOccurrence + && P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN != pActSpec->paramList[paramIdx] + ) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("id of cur obj (%u) occur more than once: %u\n", pCurObj->Id, nOccurrence)); + rtStatus = RT_STATUS_INVALID_PARAMETER; + break; + } + } + + if(RT_STATUS_SUCCESS != rtStatus) + { + break; + } + }while(FALSE); + + // Dump raw data if invalid + if(RT_STATUS_SUCCESS != rtStatus) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] info action param\n")); + RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "ObjList:\n", pObjList, P2PSVC_OBJ_LIST_LEN(pObjList)); + } + + return rtStatus; +} + +// +// Description: +// Validate all params specified by the objcts in the obj list. +// +RT_STATUS +P2PSvc_ValidateParamContent( + IN PP2PSVC_OBJ_LIST pObjList + ) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + PRT_OBJECT_HEADER pCurObj = NULL; + u4Byte objIter = 0; + u4Byte paramSpecIdx = 0; + PP2PSVC_PARAM_SPEC_ENTRY pParamSpec = NULL; + + do + { + u4Byte valLen = 0; + + for(objIter = 0, pParamSpec = NULL; NULL != (pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter)); objIter++) + { + valLen = pCurObj->Length; + + if(NULL == (pParamSpec = P2PSvc_GetParamSpec(pCurObj->Id))) + { + //RT_TRACE(COMP_P2P, DBG_LOUD, ("%s(): param id (0x%08X) can't be found in the param spec tab\n", __FUNCTION__, pCurObj->Id)); + //rtStatus = RT_STATUS_INVALID_PARAMETER; + //break; + continue; + } + + if(!(pParamSpec->minLen <= valLen && valLen <= pParamSpec->maxLen)) + { + RT_TRACE(COMP_P2P, DBG_LOUD, ("%s(): param id (0x%08X) with invalid len: %u, shall between %u and %u\n", __FUNCTION__, pCurObj->Id, valLen, pParamSpec->minLen, pParamSpec->maxLen)); + rtStatus = RT_STATUS_INVALID_LENGTH; + break; + } + } + + if(RT_STATUS_SUCCESS != rtStatus) + { + break; + } + }while(FALSE); + + if(RT_STATUS_SUCCESS != rtStatus) + { + RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "ObjList:\n", pObjList, P2PSVC_OBJ_LIST_LEN(pObjList)); + } + + return rtStatus; +} + +PRT_OBJECT_HEADER +P2PSvc_GetParam( + IN PP2PSVC_OBJ_LIST pObjList, + IN u4Byte paramId, + IN u4Byte fromIdx + ) +{ + PRT_OBJECT_HEADER pParamObj = NULL; + PRT_OBJECT_HEADER pCurObj = NULL; + u4Byte objIter = 0; + + P2PSVC_CHECK_NULL(pObjList); + + do + { + // Index out of range + if(!(fromIdx < pObjList->nObjs)) break; + + // Search next appearence of the 1st param of the action + for(objIter = fromIdx; NULL != (pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter)); objIter++) + { + if(pCurObj->Id == paramId) + { + pParamObj = pCurObj; + break; + } + } + + if(NULL == pParamObj) + {// not found + break; + } + + }while(FALSE); + + return pParamObj; +} + +RT_STATUS +P2PSvc_UpdateParam( + IN PP2PSVC_OBJ_LIST pObjList, + IN u4Byte paramId, + IN u4Byte fromIdx, + IN u4Byte bufLen, + IN PVOID pBuf + ) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + PRT_OBJECT_HEADER pObj = NULL; + + P2PSVC_CHECK_NULL(pObjList); + + do + { + if(NULL == (pObj = P2PSvc_GetParam(pObjList, paramId, fromIdx))) + { + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + if(pObj->Length != bufLen) + { + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + PlatformMoveMemory(pObj->Value, pBuf, bufLen); + + }while(FALSE); + + return rtStatus; +} + + +#endif // #if (P2PSVC_SUPPORT == 1) +#endif // #if (P2P_SUPPORT == 1) |
