diff options
Diffstat (limited to 'network/wlan/WDI/COMMON/P2P_Util.c')
| -rw-r--r-- | network/wlan/WDI/COMMON/P2P_Util.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/P2P_Util.c b/network/wlan/WDI/COMMON/P2P_Util.c new file mode 100644 index 00000000..a1f3666c --- /dev/null +++ b/network/wlan/WDI/COMMON/P2P_Util.c @@ -0,0 +1,219 @@ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "P2P_Util.tmh" +#endif + +#include "P2P_Internal.h" + +#if (P2P_SUPPORT == 1) + +//----------------------------------------------------------------------------- +// Local +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Exported +//----------------------------------------------------------------------------- + +VOID +p2p_MoveMemory( + IN VOID *dest, + IN const VOID *src, + IN u4Byte len + ) +{ + u4Byte it = 0; + + for(it = 0; it < len; it++) + *(((u1Byte *)dest) + it) = *(((u1Byte *)src) + it); +} + +int +p2p_go_det( + IN u1Byte selfVal, + IN u1Byte peerVal + ) +{ + u1Byte selfIntent = selfVal >> 1; + u1Byte peerIntent = peerVal >> 1; + + RT_TRACE_F(COMP_P2P, DBG_LOUD, ("self intent: %u, tie: %u, peer intent: %u, tie: %u\n", + selfVal >> 1, selfVal & 0x01, peerVal >> 1, peerVal & 0x01)); + + if(selfIntent == peerIntent) + { + if (P2P_MAX_GO_INTENT == selfIntent) + return -1; /* both devices want to become GO */ + + /* Use tie breaker bit to determine GO */ + return (peerVal & 0x01) ? 0 : 1; + } + + return selfIntent > peerIntent; +} + + +BOOLEAN +p2p_ActingAs_Go( + IN P2P_INFO *pP2PInfo + ) +{ + BOOLEAN bGo = FALSE; + ADAPTER *pExtAdapter = P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter) + ? pP2PInfo->pAdapter + : GetFirstGOPort(pP2PInfo->pAdapter); + + bGo = (P2P_GO == pP2PInfo->Role && ACTING_AS_AP(pExtAdapter)); // copied from P2PMakeP2PCapability + + if(bGo) + { + SET_FLAG(pP2PInfo->GroupCapability, P2P_GROUP_CAP_GROUP_OWNER); + } + else + { + CLEAR_FLAG(pP2PInfo->GroupCapability, P2P_GROUP_CAP_GROUP_OWNER); + } + + return bGo; +} + +BOOLEAN +p2p_Doing_Provisioning( + IN const P2P_INFO *pP2PInfo + ) +{ + PMGNT_INFO pDefaultMgntInfo = &(GetDefaultAdapter(pP2PInfo->pAdapter)->MgntInfo); + + if(0 < GET_SIMPLE_CONFIG_IE_LEN(pDefaultMgntInfo) && GET_SIMPLE_CONFIG_ENABLED(pDefaultMgntInfo)) + { + return TRUE; + } + + return FALSE; +} + +BOOLEAN +p2p_Check_GroupLimitReached( + IN P2P_INFO *pP2PInfo + ) +{ + if(p2p_ActingAs_Go(pP2PInfo)) + { + if(P2P_MAX_P2P_CLIENT <= P2PClientInfoGetCount(pP2PInfo)) + {// no further P2P connections are supported + SET_FLAG(pP2PInfo->GroupCapability, P2P_GROUP_CAP_GROUP_LIMIT); + return TRUE; + } + } + + return FALSE; +} + +P2P_DEV_TYPE +p2p_MessageSrcType( + IN const P2P_MESSAGE *msg, + IN P2P_FRAME_TYPE frameType + ) +{ + if(frameType < P2P_FID_ACTION_START + && !FrameBuf_Length(&msg->p2pAttributes) + ) + { + return P2P_DEV_TYPE_LEGACY; + } + + if(msg->_dialogToken) + {// action frame + if(msg->_capability) + { + if(TEST_FLAG(msg->grpCap, P2P_GROUP_CAP_GROUP_OWNER)) + { + if(P2P_FID_GO_NEG_REQ == frameType + || P2P_FID_GO_NEG_RSP == frameType + || P2P_FID_GO_NEG_CONF == frameType + ) + { + return P2P_DEV_TYPE_DEV; // Actiontec ScreenBeam sends GO Neg Rsp with GO bit set + } + return P2P_DEV_TYPE_GO; + } + else + return P2P_DEV_TYPE_DEV; + } + + return P2P_DEV_TYPE_DEV; + } + else + { + if(!FrameBuf_Length(&msg->p2pAttributes)) + return P2P_DEV_TYPE_LEGACY; + + if(msg->_capability) + { + if(TEST_FLAG(msg->grpCap, P2P_GROUP_CAP_GROUP_OWNER)) + return P2P_DEV_TYPE_GO; + else + return P2P_DEV_TYPE_DEV; + } + } + + return P2P_DEV_TYPE_LEGACY; +} + +BOOLEAN +p2p_FindClientInfoByDevAddr( + IN const u1Byte *devAddr, + IN const P2P_MESSAGE *msg, + OUT const u1Byte **ppCliInfo + ) +{ + BOOLEAN bFound = FALSE; + + if(msg->_grpInfo && TEST_FLAG(msg->grpCap, P2P_GROUP_CAP_GROUP_OWNER)) + { + const u1Byte *pos = msg->cliInfoDescList; + const u1Byte *end = msg->cliInfoDescList + msg->cliInfoDescListLen; + + while(pos < end) + { + u1Byte len = 0; + const u1Byte *infostart = NULL; + const u1Byte *infoend = NULL; + + infostart = pos; + + len = pos[0]; + pos += 1; + + infoend = pos + len; + if(end < infoend) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("client info length field overflow: %u\n", len)); + break; + } + + if(len < 6 + 6 + 1 + 2 + 8 + 1) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("invalid client info length field: %u\n", len)); + break; + } + + if(eqMacAddr(pos, devAddr)) + { + bFound = TRUE; + if(ppCliInfo) + *ppCliInfo = infostart; + break; + } + else + { + pos = infoend; + } + } + } + + return bFound; +} + +#endif
\ No newline at end of file |
