blob: b4f4d742d4123cde22ae0b2c81e598a98ea47f66 [file] [log] [blame]
/****************************************************************************
* (c) Copyright 2007 Wi-Fi Alliance. All Rights Reserved
*
*
* LICENSE
*
* License is granted only to Wi-Fi Alliance members and designated
* contractors (“Authorized Licensees”).  Authorized Licensees are granted
* the non-exclusive, worldwide, limited right to use, copy, import, export
* and distribute this software:
* (i) solely for noncommercial applications and solely for testing Wi-Fi
* equipment; and
* (ii) solely for the purpose of embedding the software into Authorized
* Licensee’s proprietary equipment and software products for distribution to
* its customers under a license with at least the same restrictions as
* contained in this License, including, without limitation, the disclaimer of
* warranty and limitation of liability, below.  The distribution rights
* granted in clause
* (ii), above, include distribution to third party companies who will
* redistribute the Authorized Licensee’s product to their customers with or
* without such third party’s private label. Other than expressly granted
* herein, this License is not transferable or sublicensable, and it does not
* extend to and may not be used with non-Wi-Fi applications.  Wi-Fi Alliance
* reserves all rights not expressly granted herein. 
* Except as specifically set forth above, commercial derivative works of
* this software or applications that use the Wi-Fi scripts generated by this
* software are NOT AUTHORIZED without specific prior written permission from
* Wi-Fi Alliance.
* Non-Commercial derivative works of this software for internal use are
* authorized and are limited by the same restrictions; provided, however,
* that the Authorized Licensee shall provide Wi-Fi Alliance with a copy of
* such derivative works under a perpetual, payment-free license to use,
* modify, and distribute such derivative works for purposes of testing Wi-Fi
* equipment.
* Neither the name of the author nor "Wi-Fi Alliance" may be used to endorse
* or promote products that are derived from or that use this software without
* specific prior written permission from Wi-Fi Alliance.
*
* THIS SOFTWARE IS PROVIDED BY WI-FI ALLIANCE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE,
* ARE DISCLAIMED. IN NO EVENT SHALL WI-FI ALLIANCE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, THE COST OF PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
/* Revision History:
* 2007/07/25 -- Initial created by qhu
* 2007/08/15 -- 02.10 WMM-Power Save Released by qhu
* 2007/10/10 -- 02.20 Voice SOHO beta -- qhu
* 2007/11/07 -- 02.30 Voice HSO -- qhu
* 2007/12/10 -- 02.32 no change
* 2008/02/07 -- 02.40 Upgrade the new WMM-PS method.
* 2008/03/20 -- 02.41 [Bug #18] In some devices, "num_hello" reaches its
* upper limit, causing other tests to reset. The
* counter now resets at the completion of each test.
* Affected Function(s): wfaRcvProc()
*
* [None] Print message too long and frequent. Remove
* trace messages for L1.
*
*/
#ifdef WFA_WMM_EXT
#ifdef WFA_WMM_PS_EXT
#ifndef WIN32
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#endif /* !WIN32 */
#include "wfa_debug.h"
#include "wfa_sock.h"
#include "wfa_types.h"
#include "wfa_tg.h"
#include "wfa_ca.h"
#include "wfa_wmmps.h"
#include "wfa_miscs.h"
#include "wfa_main.h"
extern int psSockfd;
extern int num_hello;
extern tgWMM_t wmm_thr[];
extern unsigned int psTxMsg[512];
extern unsigned int psRxMsg[512];
extern int msgsize;
int resetsnd=0;
int reset_recd=0;
int resetrcv=0;
int num_retry=0;
int gtgPsPktRecvd = 0; // need to reset
extern wfaWmmPS_t wmmps_info;
extern void *g_wl_handle;
extern int wfaTGSetPrio(int sockfd, int tgClass);
void wmmps_wait_state_proc();
void wfaSetDUTPwrMgmt(int mode);
/* APTS messages*/
struct apts_msg apts_msgs[] ={
{0, -1},
{"B.D", B_D},
{"B.H", B_H},
{"B.B", B_B},
{"B.M", B_M},
{"M.D", M_D},
{"B.Z", B_Z},
{"M.Y", M_Y},
{"L.1", L_1},
{"A.Y", A_Y},
{"B.W", B_W},
{"A.J", A_J},
{"M.V", M_V},
{"M.U", M_U},
{"A.U", A_U},
{"M.L", M_L},
{"B.K", B_K},
{"M.B", M_B},
{"M.K", M_K},
{"M.W", M_W},
#ifdef WFA_WMM_AC
{"ATC1", ATC1},
{"ATC2", ATC2},
{"ATC3", ATC3},
{"ATC4", ATC4},
{"ATC5", ATC5},
{"ATC6", ATC6},
{"ATC7", ATC7},
{"ATC8", ATC8},
{"ATC9", ATC9},
{"ATC10", ATC10},
{"ATC11", ATC11},
{"STC1", STC1},
{"STC2", STC2},
{"STC3", STC3},
#endif
{"APTS TX ", APTS_DEFAULT },
{"APTS Hello ", APTS_HELLO },
{"APTS Broadcast ", APTS_BCST },
{"APTS Confirm ", APTS_CONFIRM},
{"APTS STOP ", APTS_STOP},
{"APTS CK BE ", APTS_CK_BE },
{"APTS CK BK ", APTS_CK_BK },
{"APTS CK VI ", APTS_CK_VI },
{"APTS CK VO ", APTS_CK_VO },
{"APTS RESET ", APTS_RESET },
{"APTS RESET RESP ", APTS_RESET_RESP },
{"APTS RESET STOP ", APTS_RESET_STOP },
{0, 0 } // APTS_LAST
};
/* The DUT recv table for each of the test cases*/
StationRecvProcStatetbl_t stationRecvProcStatetbl[LAST_TEST+1][6] =
{
{WfaRcvStop,0,0,0,0,0},
/*B.D*/ {WfaRcvProc,WfaRcvVO,WfaRcvStop,0,0,0},
/*B.H*/ {WfaRcvProc,WfaRcvVO,WfaRcvVO,WfaRcvStop,0,0},
/*B.B*/ {WfaRcvProc,WfaRcvStop,0,0,0,0},
/*B.M*/ {WfaRcvProc,WfaRcvStop,0,0,0,0},
/*M.D*/ {WfaRcvProc,WfaRcvBE,WfaRcvBK,WfaRcvVI,WfaRcvVO,WfaRcvStop},
/*B.Z*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvStop,0,0},
/*M.Y*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvBE,WfaRcvStop,0},
/*L.1*/ {WfaRcvProc,WfaRcvVOCyclic,0,0,0,0},
/*A.Y*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvBE,WfaRcvStop,0},
/*B.W*/ {WfaRcvProc,WfaRcvBE,WfaRcvVI,WfaRcvBE,WfaRcvVI,WfaRcvStop},
/*A.J*/ {WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvBE,WfaRcvBK,WfaRcvStop},
/*M.V*/ {WfaRcvProc,WfaRcvBE,WfaRcvVI,WfaRcvStop,0,0},
/*M.U*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvVO,WfaRcvVO,WfaRcvStop},
/*A.U*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvVO,WfaRcvStop,0},
/*M.L*/ {WfaRcvProc,WfaRcvBE,WfaRcvStop,0,0,0},
/*B.K*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvStop,0,0},
/*M.B*/ {WfaRcvProc,WfaRcvStop,0,0,0,0},
/*M.K*/ {WfaRcvProc,WfaRcvBE,WfaRcvVI,WfaRcvStop,0,0},
/*M.W*/ {WfaRcvProc,WfaRcvBE,WfaRcvBE,WfaRcvBE,WfaRcvVI,WfaRcvStop}
#ifdef WFA_WMM_AC
/*ATC1*/ ,{WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvStop},
/*ATC2*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvBE,WfaRcvStop},
/*ATC3*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvBE,WfaRcvStop},
/*ATC4*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvVO,WfaRcvVO,WfaRcvStop},
/*ATC5*/ {WfaRcvProc,WfaRcvVI,WfaRcvVO,WfaRcvStop},
/*ATC6*/ {WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvVI,WfaRcvStop},
/*ATC7*/ {WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvBE,WfaRcvBK,WfaRcvStop},
/*ATC8*/ {WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvStop},
/*ATC9*/ {WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvBE,WfaRcvBK,WfaRcvStop},
/*ATC10*/{WfaRcvProc,WfaRcvVO,WfaRcvVI,WfaRcvBE,WfaRcvBK,WfaRcvStop},
/*ATC11*/{WfaRcvProc,WfaRcvVO,WfaRcvVO,WfaRcvVI,WfaRcvVO,WfaRcvStop},
/*STC1*/ {WfaRcvProc,WfaRcvVI,WfaRcvBE,WfaRcvStop},
/*STC2*/ {WfaRcvProc,WfaRcvBE,WfaRcvVI,WfaRcvStop},
/*STC3*/ {WfaRcvProc,WfaRcvBE,WfaRcvBK,WfaRcvVI,WfaRcvVO,WfaRcvStop}
#endif
};
/* The DUT send table for each of the test cases*/
StationProcStatetbl_t stationProcStatetbl[LAST_TEST+1][11] = {
/* Dummy*/{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}},
/* B.D*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* B.H*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* B.B*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndBK,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0}},
/* B.M*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,30000000},{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.D*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0}},
/* B.Z*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2 } ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.Y*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0}},
/* L.1*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVOCyclic,P_ON,20000},{WfaStaWaitStop,P_ON,LII / 2 }},
/* A.Y*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndBE,P_OFF,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2},{0,0,0},{0,0,0}},
/* B.W*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* A.J*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVO,P_OFF,LII / 2},{WfaStaWaitStop ,P_ON,LII / 2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.V*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop ,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.U*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSnd2VO,P_ON,LII / 2} ,{WfaStaWaitStop ,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* A.U*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_OFF,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndBE,P_OFF,LII / 2} ,{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVO,P_OFF,LII / 2} ,{WfaStaWaitStop ,P_ON,LII / 2},{0,0,0}},
/* M.L*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* B.K*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.B*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndBK,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* M.K*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* M.W*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaSndBE,P_ON,LII / 2} ,{WfaStaSndVI,P_ON,LII / 2} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
#ifdef WFA_WMM_AC
/* ATC1*/ ,{{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,1000000} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* ATC2*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,1000000} ,{WfaStaSndVO,P_ON,1000000} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC3*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVO,P_ON,1000000} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC4*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,lis_int} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaSndVO,P_ON,1000000} ,{WfaStaSndVO,P_ON,1} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC5*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, 1},
{WfaStaSndVI,P_ON,lis_int} ,{WfaStaSndVO,P_ON,lis_int+2*becon_int} ,{WfaStaSndVO,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* ATC6*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVO,P_ON,lis_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVO,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC7*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVO,P_ON,lis_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVO,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC8*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVO,P_ON,lis_int} ,{WfaStaSndVI,P_ON,lis_int+2*becon_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* ATC9*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndBE,P_ON,becon_int} ,{WfaStaSndVO,P_ON,lis_int} ,{WfaStaSndBE,P_ON,becon_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC10*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndBE,P_ON,lis_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndBE,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* ATC11*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndBE,P_ON,becon_int} ,{WfaStaSndVI,P_ON,lis_int} ,{WfaStaSndBE,P_ON,becon_int} ,{WfaStaSndVO,P_ON,lis_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0}},
/* STC1*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaSndVI,P_ON,1000000} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* STC2*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndBE,P_ON,1000000} ,{WfaStaSndVO,P_ON,1000000} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
/* STC3*/ {{WfaStaSndHello,P_OFF, 1000000},{WfaStaSndConfirm,P_ON, LII / 2},
{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaSndVI,P_ON,becon_int} ,{WfaStaWaitStop,P_ON,LII / 2} ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
#endif
};
int ac_seq[APTS_LAST][6] ={
{0, 0, 0, 0, 0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0}, // APTS_TESTS
{0}, // B.D
{0}, // B.2
{0}, // B.H
{0}, // B.4
{0}, // B_5
{0, 0, 0, 0, 0}, // B_6
{TG_WMM_AC_VO, TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_BK, 0}, // B.B B_B - 4 exchanges: 1 uplink, 0 downlink
{0}, // B.E
{0}, // B.G
{0}, // B.I
{0}, // M.D
{0}, // M.G
{0}, // M.I
{0}, // B.Z 1, 1, 1, 0}, // 1 special exchange for Broadcast testing
{TG_WMM_AC_VI, TG_WMM_AC_VO, TG_WMM_AC_BE, TG_WMM_AC_BE, 0}, // M.Y M_Y 2 special exchange for Broadcast testing
{0}, // L.1
{0}, // DLOAD
{0}, // ULOAD
{0}, // "APTS PASS"
{0}, // "APTS FAIL"
//{TOS_VI, TOS_VO, TOS_BE, TOS_BE, 0}, // A.Y A_Y special exchange for Broadcast testing
{TG_WMM_AC_VI, TG_WMM_AC_VO, TG_WMM_AC_BE, TG_WMM_AC_BE, TG_WMM_AC_BE}, // A.Y A_Y special exchange for Broadcast testing
{0}, // B.W 2 special exchange for Broadcast testing
{0}, // A.J
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_VI, TG_WMM_AC_VI, TG_WMM_AC_VI}, // M.V M_V
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_VO, TG_WMM_AC_VO, TG_WMM_AC_VO}, // M.U M_U
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_BE, TG_WMM_AC_BE, TG_WMM_AC_VO, TG_WMM_AC_VO}, // A.U A_U
{0}, // M.L M_L
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_VI, TG_WMM_AC_VI, 0}, // B.K B_K
{TG_WMM_AC_VO, TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_BK, 0}, // M.B M_B - 4 exchanges: 1 uplink, 0 downlink
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_VI, TG_WMM_AC_VI, 0}, // M.K M_K
{TG_WMM_AC_VI, TG_WMM_AC_BE, TG_WMM_AC_VI, TG_WMM_AC_VI, 0} // M.W M_W special exchange for Broadcast testing
};
/* Generic function to create a meassage, it also fills in the AC as part of
** the payload
** */
void create_apts_msg(int msg, unsigned int txbuf[],int id)
{
struct apts_msg *t;
t = &apts_msgs[msg];
txbuf[ 0] = wmmps_info.my_cookie;
txbuf[ 1] = wmmps_info.dscp;
txbuf[ 2] = 0;
txbuf[ 3] = 0;
txbuf[ 4] = 0;
txbuf[ 5] = 0;
//txbuf[ 6] = t->param0;
//txbuf[ 7] = t->param1;
//txbuf[ 8] = t->param2;
txbuf[ 9] = id;
txbuf[ 10] = t->cmd;
strcpy((char *)&txbuf[11], t->name);
PRINTF("create_apts_msg (%s) %d\n", t->name,t->cmd);
}
void print_hex_string(char* buf, int len)
{
int i;
if (len==0) { printf("<empty string>"); return; }
for (i = 0; i < len; i++) {
printf("%02x ", *((unsigned char *)buf + i));
if ((i&0xf)==15) printf("\n ");
}
if ((i&0xf))
printf("\n");
}
/* trace print*/
void mpx(char *m, void *buf_v, int len)
{
char *buf = buf_v;
printf("%s MSG: %s\n ", m, &buf[44] );
print_hex_string(buf, len);
}
/* function to validate the AC of the payload recd to ensure the correct
** message sequence*/
int receiver(unsigned int *rmsg,int length,int tos,unsigned int type)
{
int r=1;
int new_dscp=rmsg[1];
if((new_dscp != tos)||(rmsg[10] != type)) {
PRINTF("\r\n dscp recd is %d msg type is %d\n",new_dscp,rmsg[10]);
r=-6;
}
return r;
}
/* WfaRcvProc: This function receives the test case name
** after sending the initial hello packet, on receiving a
** valid test case it advances onto the next receive state
*/
int WfaRcvProc(unsigned int *rmsg,int length,int *state)
{
int sta_test;
int usedThread = wmmps_info.ps_thread;
num_hello=0;
sta_test = wmmps_info.sta_test = rmsg[10];
mpx("STA recv\n", rmsg, 64);
if(!((sta_test >=B_D)&&(sta_test <= LAST_TEST)))
return -1;
wmmps_info.my_sta_id = rmsg[9];
/* Pthread mutex Lock & Unlock mechanisms are only used in case of Linux
* since Linux uses six threads for WMM to 3 RX and 3 TX. This is as per the
* original design of Wifi. The same threads are used for WMMPS recv.
* In case of Win CE for WMMPS we create a single thread that does wmmps recv.
* For WMM the threads are created dynamically based on the no of streams.
*/
#ifndef WIN32
pthread_mutex_lock(&wmm_thr[usedThread].thr_flag_mutex);
#endif /*!WIN32 */
wmm_thr[usedThread].thr_flag = wmmps_info.streamid;
#ifndef WIN32
pthread_mutex_unlock(&wmm_thr[usedThread].thr_flag_mutex);
#endif /*!WIN32 */
(*state)++;
return 0;
}
/* WfaStaResetAll: This function resets the whole communication with
** the console (in the event of a wrong message received for the test case)
** resulting into resending of all the packets from the scratch, there is an
** upper bound for the resets a max of three*/
void WfaStaResetAll()
{
int r;
PRINTF("Entering Reset\n");
num_retry++;
if(num_retry > MAXRETRY)
{
create_apts_msg(APTS_RESET_STOP, psTxMsg,wmmps_info.my_sta_id);
wfaTGSetPrio(psSockfd, TG_WMM_AC_BE);
r = wfaTrafficSendTo(psSockfd, (char *)psTxMsg, msgsize, (struct sockaddr *)&wmmps_info.psToAddr);
mpx("STA msg",psTxMsg,64);
printf("Too many retries\n");
exit(-8);
}
if(!reset_recd)
{
create_apts_msg(APTS_RESET, psTxMsg,wmmps_info.my_sta_id);
wfaTGSetPrio(psSockfd, TG_WMM_AC_BE);
psTxMsg[1] = TOS_BE;
r = wfaTrafficSendTo(psSockfd, (char *)psTxMsg, msgsize, (struct sockaddr *)&wmmps_info.psToAddr);
mpx("STA msg",psTxMsg,64);
}
else
{
create_apts_msg(APTS_RESET_RESP, psTxMsg,wmmps_info.my_sta_id);
wfaTGSetPrio(psSockfd, TG_WMM_AC_BE);
r = wfaTrafficSendTo(psSockfd, (char *)psTxMsg, msgsize, (struct sockaddr *)&wmmps_info.psToAddr);
mpx("STA msg",psTxMsg,64);
reset_recd=0;
}
resetsnd=1;
resetrcv=1;
}
/* WfaRcvVO: A function expected to receive a AC_VO packet from
** the console, if it does not reeive a valid VO, it prints out
** an error message*/
int WfaRcvVO(unsigned int *rmsg,int length,int *state)
{
int r;
if ((r=receiver(rmsg,length,TOS_VO,APTS_DEFAULT))>=0)
(*state)++;
else
{
PRINTF("\nBAD REC in VO%d\n",r);
//WfaStaResetAll();
}
return 0;
}
/* WfaRcvVI: A function expected to receive a AC_VI packet from
** the console, if does not reeive a valid VI it prints out
** an error message.
*/
int WfaRcvVI(unsigned int *rmsg,int length,int *state)
{
int r;
if ((r=receiver(rmsg,length,TOS_VI,APTS_DEFAULT))>=0)
(*state)++;
else
PRINTF("\nBAD REC in VI%d\n",r);
return 0;
}
/* WfaRcvBE: A function expected to receive a AC_BE packet from
** the console, if does not reeive a valid BE it prints out
** an error message
*/
int WfaRcvBE(unsigned int *rmsg,int length,int *state)
{
int r;
if ((r=receiver(rmsg,length,TOS_BE,APTS_DEFAULT))>=0)
(*state)++;
else
{
PRINTF("\nBAD REC in BE%d\n",r);
}
return 0;
}
/* WfaRcvBK: A function expected to receive a AC_BK packet from
** the console, if does not reeive a valid BK it prints out
** an error message
*/
int WfaRcvBK(unsigned int *rmsg,int length,int *state)
{
int r;
if ((r=receiver(rmsg,length,TOS_BK,APTS_DEFAULT))>=0)
(*state)++;
else
PRINTF("\nBAD REC in BK%d\n",r);
return 0;
}
void BUILD_APTS_MSG(int msg, unsigned long *txbuf)
{
struct apts_msg *t;
t = &apts_msgs[msg];
txbuf[0] = wmmps_info.msgno++;
txbuf[1] = 0;
txbuf[2] = 0;
txbuf[3] = 0;
txbuf[4] = 0;
txbuf[5] = 0;
txbuf[6] = t->param0;
txbuf[7] = t->param1;
txbuf[8] = t->param2;
txbuf[9] = t->param3;
txbuf[10] = t->cmd;
strcpy((char *)&txbuf[11], t->name);
}
void send_txmsg(int new_prio_class)
{
int r;
int new_dscp = 0;
if(new_prio_class > -1)
new_dscp = wfaTGSetPrio(psSockfd, new_prio_class);
psTxMsg[0] = wmmps_info.msgno++;
psTxMsg[1] = new_dscp;
psTxMsg[2] = wmmps_info.my_group_cookie;
psTxMsg[3] = wmmps_info.my_cookie;
psTxMsg[4] = wmmps_info.my_sta_id;
if(psTxMsg[10] == APTS_DEFAULT)
{
psTxMsg[13] = (wmmps_info.msgno%10) + 0x20202030;
}
r = wfaTrafficSendTo(psSockfd, (char *)psTxMsg, 200+(wmmps_info.msgno%200), (struct sockaddr *) &wmmps_info.psToAddr);
wmmps_info.nsent++;
}
/*
* This needs to adopt to the specific platform you port to.
*/
void wfaSetDUTPwrMgmt(int mode)
{
static int curr_mode;
if(curr_mode == mode)
{
return;
}
wl_set (g_wl_handle,WLC_SET_PM,&mode,sizeof(int));
curr_mode = mode;
}
int wfaWmmPowerSaveProcess(int sockfd)
{
int rbytes = 0;
int sta_test;
struct sockaddr from;
int len;
StationRecvProcStatetbl_t *rcvstatarray;
StationRecvProcStatetbl_t func;
int *rcv_state;
len=sizeof(from);
rbytes = WmmpsTrafficRecv(sockfd,(char *)psRxMsg, (struct sockaddr *)&from);
if(rbytes < 0)
{
p_error("receive error");
return rbytes;
}
sta_test = wmmps_info.sta_test;
if(sta_test != L_1)
mpx("RX msg",psRxMsg,64);
if(psRxMsg[10] == APTS_STOP)
PRINTF("\r\n stop recd\n");
if(psRxMsg[10] == APTS_RESET)
{
reset_recd=1;
//wmmps_info.ps_thread = 1;
WfaStaResetAll();
return 0;
}
//If reset signal is there for the receiving thread and station has sent the
//reset message (i.e. !reset_recd) then ignore all the messages till an
//APTS_RESET_RESP has been received.
if(resetrcv)
{
wmmps_info.rcv_state = 0;
if((!reset_recd)&&(psRxMsg[10] != APTS_RESET_RESP))
return 0;
else
{
resetrcv = 0;
reset_recd = 0;
}
}
sta_test = wmmps_info.sta_test;
wmmps_info.my_cookie = psRxMsg[0];
rcv_state = &(wmmps_info.rcv_state);
rcvstatarray = stationRecvProcStatetbl[sta_test];
func = rcvstatarray[*(rcv_state)];
func.statefunc(psRxMsg,rbytes,rcv_state);
return TRUE;
}
void wmmps_wait_state_proc()
{
int ttypes[4], i, rbytes;
for(i = 0; i<4; i++)
{
ttypes[i] = 0xFF;
}
switch(wmmps_info.wait_state)
{
case WFA_WAIT_NEXT_CODEC:
ttypes[0] = -1;
wmmps_info.wait_state = WFA_WAIT_NEXT_CODEC;
break;
case WFA_WAIT_FOR_AP_RESPONSE:
wmmps_info.wait_state = WFA_WAIT_NEXT_CODEC;
break;
case WFA_WAIT_STAUT_00:
rbytes = wfaTrafficSendTo(psSockfd, (char *)psTxMsg, 200+(wmmps_info.msgno%200), (struct sockaddr *)&wmmps_info.psToAddr);
wmmps_info.nextsleep = 1000000; /* one second */
break;
case WFA_WAIT_STAUT_02:
ttypes[0] = TOS_VO;
wmmps_info.nextsleep = 1000000; // 1 sec
return;
break;
case WFA_WAIT_STAUT_04:
ttypes[0] = TOS_BE;
ttypes[1] = TOS_VO;
break;
case WFA_WAIT_STAUT_0E:
ttypes[0] = TOS_VO;
ttypes[1] = TOS_VO;
break;
case WFA_WAIT_STAUT_VOLOAD:
ttypes[0] = TOS_VO;
break;
case WFA_WAIT_STAUT_SEQ:
if( wmmps_info.nsent < 0 || wmmps_info.nsent > sizeof(ac_seq[wmmps_info.sta_test]) )
wmmps_info.nsent = 0;
if(( wmmps_info.sta_test == A_Y && wmmps_info.nsent == 3)
|| (wmmps_info.sta_test == A_U && wmmps_info.nsent == 1)
|| (wmmps_info.sta_test == A_U && wmmps_info.nsent == 3)
|| (wmmps_info.sta_test == A_U && wmmps_info.nsent == 5))
{
wfaSetDUTPwrMgmt(PS_OFF);
wmmps_info.nextsleep = 100000; // 100 ms
}
if((wmmps_info.sta_test == A_Y && wmmps_info.nsent == 4)
|| (wmmps_info.sta_test == A_U && wmmps_info.nsent == 2)
|| (wmmps_info.sta_test == A_U && wmmps_info.nsent == 4))
{
wfaSetDUTPwrMgmt(PS_ON);
wmmps_info.nextsleep = 100000; // 100 ms
}
ttypes[0] = ac_seq[wmmps_info.sta_test][wmmps_info.nsent];
printf("ttypes 0x%x\n", ttypes[0]);
// do we need sample time for one sec?
wmmps_info.nextsleep = 1000000;
break;
default:
printf("unknown wait state\n");
}
i=0;
while(ttypes[i] != 0xFF)
send_txmsg(ttypes[i++]);
}
#endif /* WFA_WMM_PS_EXT */
#endif /* WFA_WMM_EXT */