summaryrefslogtreecommitdiff
path: root/network/wlan/WDI/COMMON/P2P_Util.c
diff options
context:
space:
mode:
Diffstat (limited to 'network/wlan/WDI/COMMON/P2P_Util.c')
-rw-r--r--network/wlan/WDI/COMMON/P2P_Util.c219
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