diff options
| author | Adam Shapiro <[email protected]> | 2016-02-04 13:02:45 -0800 |
|---|---|---|
| committer | Adam Shapiro <[email protected]> | 2016-02-04 13:02:45 -0800 |
| commit | 3c8ac8624f815e66b370ef412bbf13cbd2c732e2 (patch) | |
| tree | 9e1e9654be00272763677a6fe6891f7cb5fb4995 /network/wlan/WDI/COMMON/P2P_Build_PublicAction.c | |
| parent | 921231effe018f3939f5b67fc7e44560aa6f3998 (diff) | |
WDI Sample
Adding WDI sample from partner enablement-China
Diffstat (limited to 'network/wlan/WDI/COMMON/P2P_Build_PublicAction.c')
| -rw-r--r-- | network/wlan/WDI/COMMON/P2P_Build_PublicAction.c | 1060 |
1 files changed, 1060 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/P2P_Build_PublicAction.c b/network/wlan/WDI/COMMON/P2P_Build_PublicAction.c new file mode 100644 index 00000000..a048e74d --- /dev/null +++ b/network/wlan/WDI/COMMON/P2P_Build_PublicAction.c @@ -0,0 +1,1060 @@ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "P2P_Build_PublicAction.tmh" +#endif + +#include "P2P_Internal.h" + +#if (P2P_SUPPORT == 1) + +//----------------------------------------------------------------------------- +// Local +//----------------------------------------------------------------------------- + +static +VOID +p2p_build_GoNegReqIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo + ) +{ + pu1Byte pLen = NULL; + u1Byte grpCap = 0; + P2P_WPS_ATTRIBUTES *pWps = &pP2PInfo->WpsAttributes; + + u1Byte intent = 0; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + if(p2p_ActingAs_Go(pP2PInfo)) + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("Invalid role\n")); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + grpCap = (u1Byte)pP2PInfo->NegotiationRequestGroupCapability; + } + else + grpCap = pP2PInfo->GroupCapability; + + P2PAttr_Make_Capability(pBuf, + pP2PInfo->DeviceCapability & ~P2P_DEV_CAP_CLIENT_DISCOVERABILITY, // this cap valid only in P2P Group Info and AssocReq + grpCap); + + if(pP2PInfo->ConnectionContext.bProbePeerChannelList) + intent = 0; // make sure that peer will become the GO, note that the tie breaker bit is 0 + else + intent = pP2PInfo->GOIntent; + P2PAttr_Make_GoIntent(pBuf, intent); + + P2PAttr_Make_ConfigTimeout(pBuf, pP2PInfo->GOConfigurationTimeout, pP2PInfo->ClientConfigurationTimeout); + P2PAttr_Make_ListenChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, pP2PInfo->ListenChannel); + P2PAttr_Make_ExtListenTiming(pBuf, pP2PInfo->ExtListenTimingDuration, pP2PInfo->ExtListenTimingPeriod); + P2PAttr_Make_IntendedIntfAddr(pBuf, pP2PInfo->InterfaceAddress); + + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pP2PInfo->ChannelEntryList); + + P2PAttr_Make_DevInfo(pBuf, + pP2PInfo->DeviceAddress, + pWps->ConfigMethod, + &pWps->PrimaryDeviceType, + pWps->SecondaryDeviceTypeLength, pWps->SecondaryDeviceTypeList, + pWps->DeviceNameLength, pWps->DeviceName); + + P2PAttr_Make_OperatingChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, pP2PInfo->OperatingChannel); + //RT_TRACE_F(COMP_P2P, DBG_LOUD, ("Op Chnl: %d\n", pP2PInfo->OperatingChannel)); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_GoNegRspIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN const u1Byte *da + ) +{ + pu1Byte pLen = NULL; + u1Byte grpCap = 0; + PP2P_WPS_ATTRIBUTES pWps = &pP2PInfo->WpsAttributes; + + u1Byte status = 0; + u1Byte intent = 0; + pu1Byte pGrpDevAddr = NULL; + pu1Byte pGrpSsidBuf = NULL; + u1Byte grpSsidLen = 0; + + const P2P_DEV_LIST_ENTRY *pDev = NULL; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + pDev = p2p_DevList_Find(&pP2PInfo->devList, da, P2P_DEV_TYPE_DEV); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + status = pP2PInfo->NegotiationResponseStatus; + else + status = pP2PInfo->Status; + P2PAttr_Make_Status(pBuf, status); + + if(p2p_ActingAs_Go(pP2PInfo)) + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("Invalid role\n")); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + grpCap = (u1Byte)pP2PInfo->NegotiationResponseGroupCapability; + } + else + grpCap = pP2PInfo->GroupCapability; + + P2PAttr_Make_Capability(pBuf, + pP2PInfo->DeviceCapability & ~P2P_DEV_CAP_CLIENT_DISCOVERABILITY, // this cap valid only in P2P Group Info and AssocReq + grpCap); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + intent = pP2PInfo->GOIntent; + } + else + { + // TODO: this is bad doing jobs other than making IE here!!! + // The tie breaker bit in a GONRsp shall be toggled from the corresponding GONReq + // + pP2PInfo->GOIntent = (pP2PInfo->GOIntent | !(pP2PInfo->ConnectionContext.ConnectingDevice.GOIntent & 0x01)); + + intent = pP2PInfo->GOIntent; + } + + P2PAttr_Make_GoIntent(pBuf, intent); + + P2PAttr_Make_ConfigTimeout(pBuf, pP2PInfo->GOConfigurationTimeout, pP2PInfo->ClientConfigurationTimeout); + P2PAttr_Make_IntendedIntfAddr(pBuf, pP2PInfo->InterfaceAddress); + + if(pP2PInfo->ConnectionContext.bGoingToBeGO) + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pDev->p2p->commonChannels); + else + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pP2PInfo->ChannelEntryList); + + P2PAttr_Make_DevInfo(pBuf, + pP2PInfo->DeviceAddress, + pWps->ConfigMethod, + &pWps->PrimaryDeviceType, + pWps->SecondaryDeviceTypeLength, pWps->SecondaryDeviceTypeList, + pWps->DeviceNameLength, pWps->DeviceName); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + if(pP2PInfo->bNegotiationResponseUseGroupID) + { + pGrpDevAddr = pP2PInfo->NegotiationResponseGroupIDDeviceAddress; + pGrpSsidBuf = pP2PInfo->NegotiationResponseGroupIDSSID; + grpSsidLen = pP2PInfo->uNegotiationResponseGroupIDSSIDLength; + } + } + else + { + if(pP2PInfo->ConnectionContext.bGoingToBeGO && + P2P_STATUS_SUCCESS == pP2PInfo->ConnectionContext.Status) + { + pGrpDevAddr = pP2PInfo->DeviceAddress; + pGrpSsidBuf = pP2PInfo->SSIDBuf; + grpSsidLen = pP2PInfo->SSIDLen; + } + } + + if(pGrpDevAddr) + P2PAttr_Make_GroupId(pBuf, pGrpDevAddr, pGrpSsidBuf, grpSsidLen); + + // + // Going to be GO: + // The Operating Channel attribute shall indicate the intended Operating Channel + // of the P2P Group. The channel indicated in the Operating Channel attribute shall + // be one of the channels in the Channel List attribute in the GO Negotiation Response + // frame. + // + // Going to be Client: + // The Operating Channel attribute may indicate a preferred Operating Channel of the + // P2P Group, or may be omitted. Any channel indicated in the Operating Channel attribute + // shall be one of the channels in the Channel List attribute in the GO Negotiation Response frame. + // + P2PAttr_Make_OperatingChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, pP2PInfo->OperatingChannel); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_GoNegConfIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN const u1Byte *da + ) +{ + pu1Byte pLen = NULL; + u1Byte grpCap = 0; + + u1Byte status = 0; + pu1Byte pGrpDevAddr = NULL; + pu1Byte pGrpSsidBuf = NULL; + u1Byte grpSsidLen = 0; + u1Byte opChannel = 0; + + const P2P_DEV_LIST_ENTRY *pDev = NULL; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + pDev = p2p_DevList_Find(&pP2PInfo->devList, da, P2P_DEV_TYPE_DEV); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + status = pP2PInfo->NegotiationConfirmStatus; + else + status = pP2PInfo->Status; + P2PAttr_Make_Status(pBuf, pP2PInfo->Status); + + if(p2p_ActingAs_Go(pP2PInfo)) + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("Invalid role\n")); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + grpCap = (u1Byte)pP2PInfo->NegotiationConfirmGroupCapability; + } + else + grpCap = pP2PInfo->GroupCapability; + + P2PAttr_Make_Capability(pBuf, + pP2PInfo->DeviceCapability & ~P2P_DEV_CAP_CLIENT_DISCOVERABILITY, // this cap valid only in P2P Group Info and AssocReq + grpCap); + + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pDev->p2p->commonChannels); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + if(pP2PInfo->bNegotiationConfirmUseGroupID) + { + pGrpDevAddr = pP2PInfo->NegotiationConfirmGroupIDDeviceAddress; + pGrpSsidBuf = pP2PInfo->NegotiationConfirmGroupIDSSID; + grpSsidLen = pP2PInfo->uNegotiationConfirmGroupIDSSIDLength; + } + } + else + { + if(pP2PInfo->ConnectionContext.bGoingToBeGO && + P2P_STATUS_SUCCESS == pP2PInfo->ConnectionContext.Status) + { + pGrpDevAddr = pP2PInfo->DeviceAddress; + pGrpSsidBuf = pP2PInfo->SSIDBuf; + grpSsidLen = pP2PInfo->SSIDLen; + } + } + + if(pGrpDevAddr) + P2PAttr_Make_GroupId(pBuf, pGrpDevAddr, pGrpSsidBuf, grpSsidLen); + + // + // Going to be GO: + // The Operating Channel attribute shall indicate the intended Operating Channel of the + // P2P Group. The channel indicated in the Operating Channel attribute shall be one of the + // channels in the Channel List attribute in the GO Negotiation Confirmation frame. + // + // Going to be Client: + // The Operating Channel attribute in the GO Negotiation Confirmation frame shall be the + // Operating Channel attribute from the GO Negotiation Response frame. + // + if(pP2PInfo->ConnectionContext.bGoingToBeGO) + { + opChannel = pP2PInfo->OperatingChannel; + } + else + {//Chnl from the GONRsp + opChannel = pP2PInfo->ConnectionContext.ConnectingDevice.OperatingChannel; + } + + P2PAttr_Make_OperatingChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, opChannel); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_InvitationReqIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN const u1Byte *da + ) +{ + pu1Byte pLen = NULL; + PP2P_WPS_ATTRIBUTES pWps = &pP2PInfo->WpsAttributes; + + u1Byte goTimeout = 0; + u1Byte cliTimeout = 0; + u1Byte opChannel = 0; + u1Byte invitFlag = 0; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + if(pP2PInfo->InvitationContext.bPersistentInvitation) + {// in persistent case, we have to tell the peer our conf time + // No matter GO or client, we fill them with the max value + goTimeout = pP2PInfo->GOConfigurationTimeout; + cliTimeout = pP2PInfo->ClientConfigurationTimeout; + } + else + {// otherwise, we're either a GO or client in operating phase, wo we don't have to fill the conf time + // Ref Clause 3.1.5.1, a normal invitation always have them to be 0 + goTimeout = 0; + cliTimeout = 0; + } + P2PAttr_Make_ConfigTimeout(pBuf, goTimeout, cliTimeout); + + P2PAttr_Make_GroupBssid(pBuf, pP2PInfo->InvitationContext.GroupBssid); + + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pP2PInfo->ChannelEntryList); + + P2PAttr_Make_DevInfo(pBuf, + pP2PInfo->DeviceAddress, + pWps->ConfigMethod, + &pWps->PrimaryDeviceType, + pWps->SecondaryDeviceTypeLength, + pWps->SecondaryDeviceTypeList, + pWps->DeviceNameLength, + pWps->DeviceName); + + P2PAttr_Make_GroupId(pBuf, + pP2PInfo->InvitationContext.GODeviceAddress, + pP2PInfo->InvitationContext.SsidBuf, + pP2PInfo->InvitationContext.SsidLen); + + // + // GO: + // the Operating Channel attribute indicates the Operating Channel of the P2P Group + // + // Peristent GO: + // the Operating Channel attribute indicates the intended Operating Channel of the P2P Group + // + // Client: + // an Operating Channel attribute shall also be present, indicating the Operating Channel of the P2P Group + // + // Persistent Client: + // an Operating Channel attribute may be present to indicate a preferred Operating Channel + // + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter) + && 0 != pP2PInfo->uInvitationRequestOperatingChannelNumber + ) + { + opChannel = (u1Byte)pP2PInfo->uInvitationRequestOperatingChannelNumber; + } + else + { + if(pP2PInfo->InvitationContext.bPersistentInvitation) + { + if(0 == pP2PInfo->InvitationContext.OpChannel) + {// follow op ch + opChannel = pP2PInfo->OperatingChannel; + } + else + {// forced op ch + opChannel = pP2PInfo->InvitationContext.OpChannel; + } + } + else + { + opChannel = pP2PInfo->InvitationContext.OpChannel; + } + } + + P2PAttr_Make_OperatingChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, opChannel); + + if(pP2PInfo->InvitationContext.bPersistentInvitation) + SET_FLAG(invitFlag, P2P_INVITATION_FLAGS_TYPE); + + P2PAttr_Make_InvitationFlags(pBuf, invitFlag); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_InvitationRspIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN const u1Byte *da + ) +{ + pu1Byte pLen = NULL; + + u1Byte status = 0; + u1Byte goTimeout = 0; + u1Byte cliTimeout = 0; + u1Byte opChannel = 0; + + const P2P_DEV_LIST_ENTRY *pDev = NULL; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + pDev = p2p_DevList_Find(&pP2PInfo->devList, da, P2P_DEV_TYPE_DEV); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + status = pP2PInfo->InvitationResponseStatus; + else + status = pP2PInfo->Status; + + P2PAttr_Make_Status(pBuf, status); + + if(pP2PInfo->InvitationContext.bPersistentInvitation) + {// in persistent case, we have to tell the peer our conf time + // No matter GO or client, we fill them with the max value + goTimeout = pP2PInfo->GOConfigurationTimeout; + cliTimeout = pP2PInfo->ClientConfigurationTimeout; + } + else + {// non persistent case + goTimeout = 0; + cliTimeout = 0; + } + P2PAttr_Make_ConfigTimeout(pBuf, goTimeout, cliTimeout); + + P2PAttr_Make_GroupBssid(pBuf, pP2PInfo->InvitationContext.GroupBssid); + + P2PAttr_Make_ChannelList(pBuf, pP2PInfo, &pDev->p2p->commonChannels); + + // + // GO or Persisstent GO: + // intended Operating Channel + // + // Client or Persistent Client (optional): + // not specified in the spec + // + if(pP2PInfo->InvitationContext.bPersistentInvitation) + { + // + // if GO => intended op chnl, shall be one of the channels in the channel list in the InvitationReq + // if Client => intended op chnl. + // + if(P2P_CLIENT == pP2PInfo->InvitationContext.InvitorRole // peer is Cli + && pP2PInfo->InvitationContext.bPersistentInvitation // persistent + ) + {// I'm persistent GO + opChannel = pP2PInfo->InvitationContext.OpChannel; + } + else + { + opChannel = pP2PInfo->InvitationContext.InvitedDevice.OperatingChannel; + } + } + else + {// we are invited + // + // Not defined in the spec. + // Follow the op channel of the peer. + // + opChannel = pP2PInfo->InvitationContext.InvitedDevice.OperatingChannel; + } + + P2PAttr_Make_OperatingChannel(pBuf, pP2PInfo->CountryString, pP2PInfo->RegulatoryClass, opChannel); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_DevDiscReqIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo + ) +{ + pu1Byte pLen = NULL; + + PP2P_DEVICE_DISCOVERABILITY_CONTEXT pDevDiscContext = &pP2PInfo->DeviceDiscoverabilityContext; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + P2PAttr_Make_DevId(pBuf, pP2PInfo->DeviceDiscoverabilityContext.ClientDeviceAddress); + P2PAttr_Make_GroupId(pBuf, pDevDiscContext->GODeviceAddr, pP2PInfo->SSIDBuf, pP2PInfo->SSIDLen); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_DevDiscRspIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN u1Byte status + ) +{ + pu1Byte pLen = NULL; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + P2PAttr_Make_Status(pBuf, status); + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_PdReqIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo + ) +{ + pu1Byte pLen = NULL; + PP2P_WPS_ATTRIBUTES pWps = &pP2PInfo->WpsAttributes; + u1Byte grpCap = 0; + + pu1Byte pGrpDevAddr = NULL; + pu1Byte pGrpSsidBuf = NULL; + u1Byte grpSsidLen = 0; + + if(NULL == (pLen = p2p_add_IEHdr(pBuf))) return; + + if(p2p_ActingAs_Go(pP2PInfo)) + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("Invalid role\n")); + + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + grpCap = (u1Byte)pP2PInfo->ProvisionRequestGroupCapability; + } + else + grpCap = pP2PInfo->GroupCapability; + + P2PAttr_Make_Capability(pBuf, + pP2PInfo->DeviceCapability & ~P2P_DEV_CAP_CLIENT_DISCOVERABILITY, // this cap valid only in P2P Group Info and AssocReq + grpCap); + + P2PAttr_Make_DevInfo(pBuf, + pP2PInfo->DeviceAddress, + pWps->ConfigMethod, + &pWps->PrimaryDeviceType, + pWps->SecondaryDeviceTypeLength, + pWps->SecondaryDeviceTypeList, + pWps->DeviceNameLength, + pWps->DeviceName); + + if(pP2PInfo->ProvisionDiscoveryContext.go) + {// connecting to GO + if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) + { + if(pP2PInfo->bProvisionRequestUseGroupID) + { + pGrpDevAddr = pP2PInfo->ProvisionRequestGroupIDDeviceAddress; + pGrpSsidBuf = pP2PInfo->ProvisionRequestGroupIDSSID; + grpSsidLen = pP2PInfo->uProvisionRequestGroupIDSSIDLength; + } + } + else + { + pGrpDevAddr = pP2PInfo->ProvisionDiscoveryContext.devAddr; + pGrpSsidBuf = pP2PInfo->ProvisionDiscoveryContext.SsidBuf; + grpSsidLen = pP2PInfo->ProvisionDiscoveryContext.SsidLen; + } + + if(pGrpDevAddr) + P2PAttr_Make_GroupId(pBuf, pGrpDevAddr, pGrpSsidBuf, grpSsidLen); + } + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +static +VOID +p2p_build_PdRspIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo + ) +{ + /* Nothing to Append */ + return; +} + +static +VOID +p2p_add_WpsIeConfigMethods( + IN FRAME_BUF *pBuf, + IN u2Byte configMethods + ) +{ + pu1Byte pLen = NULL; + + FrameBuf_Add_u1(pBuf, (u1Byte)EID_Vendor); + + pLen = FrameBuf_Add(pBuf, 1); + + FrameBuf_Add_be_u4(pBuf, 0x0050F204); + + // Version + FrameBuf_Add_be_u2(pBuf, P2P_WPS_ATTR_TAG_VERSION); + FrameBuf_Add_be_u2(pBuf, 1); + FrameBuf_Add_u1(pBuf, 0x10); + + // Config Method + FrameBuf_Add_be_u2(pBuf, P2P_WPS_ATTR_TAG_CONFIG_METHODS); + FrameBuf_Add_be_u2(pBuf, 2); + FrameBuf_Add_be_u2(pBuf, configMethods); + + p2p_update_IeHdrLen(pBuf, pLen); + + return; +} + +//----------------------------------------------------------------------------- +// Exported +//----------------------------------------------------------------------------- + +VOID +p2p_add_P2PPublicActionHdr( + IN FRAME_BUF *pBuf, + IN u1Byte subtype, + IN u1Byte dialogToken + ) +{ + RT_TRACE_F(COMP_P2P, pBuf->dbgLevel, ("token: %u\n", dialogToken)); + + FrameBuf_Add_u1(pBuf, WLAN_ACTION_PUBLIC); + FrameBuf_Add_u1(pBuf, WLAN_PA_VENDOR_SPECIFIC); + FrameBuf_Add_be_u4(pBuf, P2P_IE_VENDOR_TYPE); + FrameBuf_Add_u1(pBuf, subtype); + FrameBuf_Add_u1(pBuf, dialogToken); + + return; +} + +VOID +p2p_Construct_GoNegReq( + IN P2P_INFO *pP2PInfo, + IN FRAME_BUF *pBuf, + IN const u1Byte *da, + IN u1Byte dialogToken + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, da); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_GO_NEG_REQ, dialogToken); + + // P2P IE + p2p_build_GoNegReqIe(pBuf, pP2PInfo); + + // Additional IE + P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_GO_NEGOTIATION_REQUEST, pBuf); + + // WPS IE + WPS_AppendElement(pP2PInfo->pAdapter, &pBuf->os, TRUE, WPS_INFO_PROBEREQ_IE); + + // WFD IE + WFD_AppendP2pGoNegReqIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + RT_TRACE(COMP_P2P, DBG_LOUD, + ("%s(): intent = %u, tie breaker: %u, dialog token: %u\n", + __FUNCTION__, + pP2PInfo->GOIntent >> 1, + pP2PInfo->GOIntent & 0x01, + dialogToken)); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_GoNegRsp( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN FRAME_BUF *pBuf, + IN const u1Byte *da + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, pP2PInfo->DeviceAddress); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_GO_NEG_RSP, dialogToken); + + // P2P IE + p2p_build_GoNegRspIe(pBuf, pP2PInfo, da); + + // Additional IE + P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_GO_NEGOTIATION_RESPONSE, pBuf); + + // WPS IE + WPS_AppendElement(pP2PInfo->pAdapter, &pBuf->os, TRUE, WPS_INFO_PROBERSP_IE); + + // WFD IE + WFD_AppendP2pGoNegRspIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + RT_TRACE(COMP_P2P, DBG_LOUD, + ("%s(): intent = %u, tie breaker: %u, dialog token: %u\n", + __FUNCTION__, + pP2PInfo->GOIntent >> 1, + pP2PInfo->GOIntent & 0x01, + dialogToken)); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_GoNegConf( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN FRAME_BUF *pBuf, + IN const u1Byte *da + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, da); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_GO_NEG_CONF, dialogToken); + + // P2P IE + p2p_build_GoNegConfIe(pBuf, pP2PInfo, da); + + // Additional IE + P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_GO_NEGOTIATION_CONFIRM, pBuf); + + // WFD IE + WFD_AppendP2pGoNegConfirmIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_InvitationReq( + IN P2P_INFO *pP2PInfo, + IN FRAME_BUF *pBuf, + IN const u1Byte *da, + IN u1Byte dialogToken + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, da); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_INVITATION_REQ, dialogToken); + + // P2P IE + p2p_build_InvitationReqIe(pBuf, pP2PInfo, da); + + // Additional IE + P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_INVITATION_REQUEST, pBuf); + + /* Below use octet string ONLY */ + { + WFD_AppendP2pInvitationReqIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + } + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_InvitationRsp( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN FRAME_BUF *pBuf, + IN const u1Byte *da + ) +{ + // + // Assume that pP2PInfo->Status has been set. + // + + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, pP2PInfo->DeviceAddress); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_INVITATION_RSP, dialogToken); + + // P2P IE + p2p_build_InvitationRspIe(pBuf, pP2PInfo, da); + + // Additional IE + P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_INVITATION_RESPONSE, pBuf); + + // WFD IE + WFD_AppendP2pInvitationRspIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_DevDiscReq( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN FRAME_BUF *pBuf, + IN const u1Byte *da, + IN const u1Byte *bssid + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, bssid, pP2PInfo->DeviceAddress, bssid); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_DEV_DISC_REQ, dialogToken); + + // P2P IE + p2p_build_DevDiscReqIe(pBuf, pP2PInfo); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_DevDiscRsp( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN FRAME_BUF *pBuf, + IN const u1Byte *da, + IN u1Byte status + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, pP2PInfo->DeviceAddress); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_DEV_DISC_RSP, dialogToken); + + // P2P IE + p2p_build_DevDiscRspIe(pBuf, pP2PInfo, status); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_PDReq( + IN P2P_INFO *pP2PInfo, + IN FRAME_BUF *pBuf, + IN const u1Byte *da, + IN u1Byte dialogToken, + IN u2Byte configMethod + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, da); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_PROV_DISC_REQ, dialogToken); + + // P2P IE + p2p_build_PdReqIe(pBuf, pP2PInfo); + + // Additional IE + if(0 == P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_PROVISION_DISCOVERY_REQUEST, pBuf)) + { + p2p_add_WpsIeConfigMethods(pBuf, configMethod); + } + + // WFDS IE + P2PSvc_MakePDReqIE(pP2PInfo->pP2PSvcInfo, pBuf); + + // WFD IE + WFD_AppendP2pProvDiscoveryReqIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_Construct_PDRsp( + IN P2P_INFO *pP2PInfo, + IN u1Byte dialogToken, + IN OCTET_STRING *posP2PAttrs, + IN u2Byte configMethod, + IN FRAME_BUF *pBuf, + IN const u1Byte *da + ) +{ + FunctionIn(COMP_P2P); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pP2PInfo->DeviceAddress, pP2PInfo->DeviceAddress); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_PROV_DISC_RSP, dialogToken); + + // P2P IE + p2p_build_PdRspIe(pBuf, pP2PInfo); + + // Additional IE + if(0 == P2P_AddIe_Append(&pP2PInfo->AdditionalIEs, P2P_ADD_IE_PROVISION_DISCOVERY_RESPONSE, pBuf)) + { + // TODO: we temporarilly accept all confing method in ProvisionDiscoveryReq + p2p_add_WpsIeConfigMethods(pBuf, configMethod); + } + + // WFDS IE + P2PSvc_MakePDRspIE(pP2PInfo->pP2PSvcInfo, posP2PAttrs, pBuf); + + // WFD IE + WFD_AppendP2pProvDiscoveryRspIEs(pP2PInfo->pAdapter, FrameBuf_Cap(pBuf), &pBuf->os); + + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + + FunctionOut(COMP_P2P); + + return; +} + +VOID +p2p_build_FakeInvitationRspIe( + IN FRAME_BUF *pBuf, + IN P2P_INFO *pP2PInfo, + IN const u1Byte *da + ) +{ + p2p_build_InvitationRspIe(pBuf, pP2PInfo, da); + + return; +} + +// +// Description: +// Construct fake provision discovery response frame by the device which is considered as the +// respondor and fill the content by the previous received information. +// Arguments: +// [in] pP2PInfo - +// P2P information context. +// [in] pRspDev - +// The device which sends the provision discovery response frame. +// [in] da - +// The destination which the response frame is sent to. +// [out] -pBuf +// The context of FRAME_BUF to put the frame. +// Return: +// Return RT_STATUS_SUCCESS if the construction of this response frame succeeds. +// By Bruce, 2015-02-17. +// +RT_STATUS +p2p_Construct_FakePDRsp( + IN P2P_INFO *pP2PInfo, + IN P2P_DEV_LIST_ENTRY *pRspDev, + IN const u1Byte *da, + OUT FRAME_BUF *pBuf + ) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + pu1Byte pPdReqFrame = NULL; + OCTET_STRING osPdReq, osTmpIe; + pu1Byte pPdRspTa = NULL;; + + FunctionIn(COMP_P2P); + + do + { + if(!pRspDev) + { + RT_ASSERT(FALSE, ("pRspDev = NULL\n")); + rtStatus = RT_STATUS_INVALID_PARAMETER; + break; + } + + if(!pRspDev->txFrames[P2P_FID_PD_REQ]) + { + RT_ASSERT(FALSE, ("pRspDev->txFrames[P2P_FID_PD_REQ] = NULL\n")); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + if(0 == pRspDev->txFrames[P2P_FID_PD_REQ]->frameLen) + { + RT_TRACE_F(COMP_P2P, DBG_WARNING, ("pRspDev->txFrames[P2P_FID_PD_REQ].frameLen = 0\n")); + rtStatus = RT_STATUS_INVALID_DATA; + break; + } + + FillOctetString(osPdReq, pRspDev->txFrames[P2P_FID_PD_REQ]->frame, pRspDev->txFrames[P2P_FID_PD_REQ]->frameLen); + + pPdReqFrame = pRspDev->txFrames[P2P_FID_PD_REQ]->frame; + pPdRspTa = Frame_pDaddr(osPdReq); + + // MAC Header + p2p_add_ActionFrameMacHdr(pBuf, da, pPdRspTa, pPdRspTa); + + // Action Header + p2p_add_P2PPublicActionHdr(pBuf, P2P_PROV_DISC_RSP, pRspDev->txFrames[P2P_FID_PD_REQ]->token); + + // WPS IE, getting from the original PD request + osTmpIe = PacketGetElement(osPdReq, EID_Vendor, OUI_SUB_SimpleConfig, OUI_SUB_DONT_CARE); + if(osTmpIe.Length > 0) + { + PacketMakeElement(&(pBuf->os), EID_Vendor, osTmpIe); + } + + // WFD IE + if(pRspDev->rxFrames[P2P_FID_PROBE_RSP]->frameLen > 0) + { + osTmpIe = PacketGetElement(osPdReq, EID_Vendor, OUI_SUB_WIFI_DISPLAY, OUI_SUB_DONT_CARE); + if(osTmpIe.Length > 0) + { + PacketMakeElement(&(pBuf->os), EID_Vendor, osTmpIe); + } + } + FrameBuf_Dump(pBuf, 0, DBG_LOUD, __FUNCTION__); + }while(FALSE); + + FunctionOut(COMP_P2P); + + return rtStatus; +} + +#endif + |
