| /* |
| * trafficAdmControl.c |
| * |
| * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name Texas Instruments nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, 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 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| |
| /***************************************************************************/ |
| /* */ |
| /* MODULE: admCtrlQos.c */ |
| /* PURPOSE: WSM/WME admission Control */ |
| /* */ |
| /***************************************************************************/ |
| |
| #define __FILE_ID__ FILE_ID_89 |
| #include "osApi.h" |
| |
| #include "paramOut.h" |
| |
| #include "timer.h" |
| #include "fsm.h" |
| #include "report.h" |
| |
| #include "DataCtrl_Api.h" |
| |
| #include "trafficAdmControl.h" |
| #include "qosMngr_API.h" |
| #include "TWDriver.h" |
| #ifdef XCC_MODULE_INCLUDED |
| #include "XCCMngr.h" |
| #endif |
| /* Constants */ |
| |
| /** number of states in the state machine */ |
| #define TRAFFIC_ADM_CTRL_SM_NUM_STATES 2 |
| |
| /** number of events in the state machine */ |
| #define TRAFFIC_ADM_CTRL_SM_NUM_EVENTS 5 |
| |
| extern int WMEQosTagToACTable[MAX_NUM_OF_802_1d_TAGS]; |
| |
| typedef struct |
| { |
| TI_HANDLE hTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| TI_UINT8 acID; |
| |
| }fsmTSpecInfo_t; |
| |
| |
| /* Timer functions */ |
| void trafficAdmCtrl_timeoutAcBE(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured); |
| void trafficAdmCtrl_timeoutAcBK(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured); |
| void trafficAdmCtrl_timeoutAcVI(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured); |
| void trafficAdmCtrl_timeoutAcVO(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured); |
| |
| |
| /* SM Functions */ |
| TI_STATUS trafficAdmCtrl_smEvent(trafficAdmCtrl_t *pAdmCtrlQos, TI_UINT8 event, void *pData); |
| |
| TI_STATUS trafficAdmCtrl_smActionUnexpectedTspecResponse(fsmTSpecInfo_t *fsmTSpecInfo); /*unxcepted*/ |
| TI_STATUS trafficAdmCtrl_smActionUnexpected(fsmTSpecInfo_t *fsmTSpecInfo); /*unxcepted*/ |
| TI_STATUS trafficAdmCtrl_smActionNop(fsmTSpecInfo_t *fsmTSpecInfo); /*NOP*/ |
| TI_STATUS trafficAdmCtrl_smStart(fsmTSpecInfo_t *fsmTSpecInfo); /*EVENT_START*/ |
| TI_STATUS trafficAdmCtrl_smWaitStop(fsmTSpecInfo_t *fsmTSpecInfo); /*EVENT_STOP*/ |
| TI_STATUS trafficAdmCtrl_smWaitAccept(fsmTSpecInfo_t *fsmTSpecInfo); /*EVENT_ACCEPT*/ |
| TI_STATUS trafficAdmCtrl_smWaitReject(fsmTSpecInfo_t *fsmTSpecInfo); /*EVENT_REJECT*/ |
| TI_STATUS trafficAdmCtrl_smWaitTimeout(fsmTSpecInfo_t *fsmTSpecInfo); /*EVENT_TIMEOUT*/ |
| |
| |
| |
| TI_STATUS trafficAdmCtrl_sendAdmissionReq(TI_HANDLE hTrafficAdmCtrl, tspecInfo_t *pTSpecInfo); |
| TI_STATUS trafficAdmCtrl_startTimer(trafficAdmCtrl_t* pTrafficAdmCtrl, TI_UINT8 acID); |
| TI_STATUS trafficAdmCtrl_stopTimer(trafficAdmCtrl_t* pTrafficAdmCtrl, TI_UINT8 acID); |
| |
| |
| TI_STATUS trafficAdmCtrl_buildFrameHeader(trafficAdmCtrl_t *pTrafficAdmCtrl, TTxCtrlBlk *pPktCtrlBlk); |
| |
| static TI_STATUS trafficAdmCtrl_tokenToAc (TI_HANDLE hTrafficAdmCtrl, TI_UINT8 token, TI_UINT8 *acID); |
| |
| /******************************************************************************** |
| * trafficAdmCtrl_create * |
| ******************************************************************************** |
| DESCRIPTION: trafficAdmCtrl module creation function |
| |
| INPUT: hOs - Handle to OS |
| |
| |
| OUTPUT: |
| |
| RETURN: Handle to the trafficAdmCtrl module on success, NULL otherwise |
| |
| ************************************************************************/ |
| |
| TI_HANDLE trafficAdmCtrl_create(TI_HANDLE hOs) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| TI_STATUS status; |
| |
| /* allocate admission control context memory */ |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)os_memoryAlloc(hOs, sizeof(trafficAdmCtrl_t)); |
| if (pTrafficAdmCtrl == NULL) |
| { |
| return NULL; |
| } |
| |
| os_memoryZero(hOs, pTrafficAdmCtrl, sizeof(trafficAdmCtrl_t)); |
| |
| pTrafficAdmCtrl->hOs = hOs; |
| |
| /* allocate memory for admCtrlQos state machine */ |
| status = fsm_Create(hOs, &pTrafficAdmCtrl->pTrafficAdmCtrlSm, TRAFFIC_ADM_CTRL_SM_NUM_STATES, TRAFFIC_ADM_CTRL_SM_NUM_EVENTS); |
| if (status != TI_OK) |
| { |
| os_memoryFree(hOs, pTrafficAdmCtrl, sizeof(trafficAdmCtrl_t)); |
| return NULL; |
| } |
| |
| return pTrafficAdmCtrl; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_unload * |
| ************************************************************************ |
| DESCRIPTION: trafficAdmCtrl module destroy function, |
| - Free all memory alocated by the module |
| |
| INPUT: hTrafficAdmCtrl - trafficAdmCtrl handle. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_unload(TI_HANDLE hTrafficAdmCtrl) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| TI_UINT32 uAcId; |
| |
| if (pTrafficAdmCtrl->pTrafficAdmCtrlSm) |
| { |
| fsm_Unload (pTrafficAdmCtrl->hOs, pTrafficAdmCtrl->pTrafficAdmCtrlSm); |
| } |
| |
| /* free timers */ |
| for (uAcId = 0; uAcId < MAX_NUM_OF_AC; uAcId++) |
| { |
| if (pTrafficAdmCtrl->hAdmCtrlTimer[uAcId]) |
| { |
| tmr_DestroyTimer (pTrafficAdmCtrl->hAdmCtrlTimer[uAcId]); |
| } |
| } |
| |
| os_memoryFree(pTrafficAdmCtrl->hOs, pTrafficAdmCtrl, sizeof(trafficAdmCtrl_t)); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * trafficAdmCtrl_config * |
| ************************************************************************ |
| DESCRIPTION: trafficAdmCtrl module configuration function, |
| performs the following: |
| - Reset & initiailzes local variables |
| - Init the handles to be used by the module |
| |
| INPUT: hTrafficAdmCtrl - trafficAdmCtrl handle. |
| List of handles to be used by the module |
| pTrafficAdmCtrlInitParams - init parameters. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_config (TI_HANDLE hTrafficAdmCtrl, |
| TI_HANDLE hTxMgmtQ, |
| TI_HANDLE hReport, |
| TI_HANDLE hOs, |
| TI_HANDLE hQosMngr, |
| TI_HANDLE hCtrlData, |
| TI_HANDLE hXCCMgr, |
| TI_HANDLE hTimer, |
| TI_HANDLE hTWD, |
| TI_HANDLE hTxCtrl, |
| trafficAdmCtrlInitParams_t *pTrafficAdmCtrlInitParams) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| TI_STATUS status; |
| TI_UINT32 uAcId; |
| |
| fsm_actionCell_t trafficAdmCtrl_smMatrix[TRAFFIC_ADM_CTRL_SM_NUM_STATES][TRAFFIC_ADM_CTRL_SM_NUM_EVENTS] = |
| { |
| /* next state and actions for IDLE state */ |
| {{TRAFFIC_ADM_CTRL_SM_STATE_WAIT, (fsm_Action_t)trafficAdmCtrl_smStart}, /*EVENT_START*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smActionNop}, /*EVENT_STOP*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smActionUnexpectedTspecResponse}, /*EVENT_ACCEPT*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smActionUnexpectedTspecResponse}, /*EVENT_REJECT*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smActionUnexpected}, /*EVENT_TIMEOUT*/ |
| }, |
| /* next state and actions for WAIT state */ |
| {{TRAFFIC_ADM_CTRL_SM_STATE_WAIT, (fsm_Action_t)trafficAdmCtrl_smActionUnexpected}, /*EVENT_START*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smWaitStop}, /*EVENT_STOP*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smWaitAccept}, /*EVENT_ACCEPT*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smWaitReject}, /*EVENT_REJECT*/ |
| {TRAFFIC_ADM_CTRL_SM_STATE_IDLE, (fsm_Action_t)trafficAdmCtrl_smWaitTimeout}, /*EVENT_TIMEOUT*/ |
| }, |
| }; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| pTrafficAdmCtrl->hTxMgmtQ = hTxMgmtQ; |
| pTrafficAdmCtrl->hReport = hReport; |
| pTrafficAdmCtrl->hOs = hOs; |
| pTrafficAdmCtrl->hQosMngr = hQosMngr; |
| pTrafficAdmCtrl->hCtrlData = hCtrlData; |
| pTrafficAdmCtrl->hXCCMgr = hXCCMgr; |
| pTrafficAdmCtrl->hTimer = hTimer; |
| pTrafficAdmCtrl->hTWD = hTWD; |
| pTrafficAdmCtrl->hTxCtrl = hTxCtrl; |
| |
| for (uAcId = 0; uAcId < MAX_NUM_OF_AC; uAcId++) |
| { |
| pTrafficAdmCtrl->dialogToken[uAcId] = 0; |
| |
| /* Create per AC timers */ |
| pTrafficAdmCtrl->hAdmCtrlTimer[uAcId] = tmr_CreateTimer (pTrafficAdmCtrl->hTimer); |
| if (pTrafficAdmCtrl->hAdmCtrlTimer[uAcId] == NULL) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "trafficAdmCtrl_config(): Failed to create hAssocSmTimer!\n"); |
| return TI_NOK; |
| } |
| } |
| |
| /* configure state machine */ |
| status = fsm_Config(pTrafficAdmCtrl->pTrafficAdmCtrlSm, &trafficAdmCtrl_smMatrix[0][0], |
| TRAFFIC_ADM_CTRL_SM_NUM_STATES, TRAFFIC_ADM_CTRL_SM_NUM_EVENTS, NULL, hOs); |
| if (status != TI_OK) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "TRAFFIC_ADM_CTRL_SM: fsm_Config - Error \n"); |
| |
| return TI_NOK; |
| } |
| |
| pTrafficAdmCtrl->timeout = pTrafficAdmCtrlInitParams->trafficAdmCtrlResponseTimeout; |
| pTrafficAdmCtrl->useFixedMsduSize = pTrafficAdmCtrlInitParams->trafficAdmCtrlUseFixedMsduSize; |
| |
| pTrafficAdmCtrl->dialogTokenCounter = INITIAL_DIALOG_TOKEN; |
| |
| |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "TRAFFIC ADM CTRL - configuration completed ..... \n"); |
| |
| return TI_OK; |
| } |
| |
| |
| /************************************************************************ |
| * trafficAdmCtrl_smEvent * |
| ************************************************************************ |
| DESCRIPTION: trafficAdmCtrl SM general function |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| event - the event to the SM. |
| pData - handle to passing parameter |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smEvent(trafficAdmCtrl_t *pTrafficAdmCtrl, TI_UINT8 event, void *pData) |
| { |
| TI_STATUS status; |
| TI_UINT8 nextState; |
| fsmTSpecInfo_t *fsmTSpecInfo = (fsmTSpecInfo_t*)pData; |
| TI_UINT8 acID = fsmTSpecInfo->acID; |
| |
| /* It looks like it never happens. Anyway decided to check */ |
| if ( acID >= MAX_NUM_OF_AC ) |
| { |
| TRACE2( pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, |
| "trafficAdmCtrl_smEvent. fsmTSpecInfo->acID=%d exceeds the limit %d\n", |
| acID, MAX_NUM_OF_AC-1); |
| handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); |
| return TI_NOK; |
| } |
| |
| status = fsm_GetNextState(pTrafficAdmCtrl->pTrafficAdmCtrlSm, pTrafficAdmCtrl->currentState[acID], event, &nextState); |
| if (status != TI_OK) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "ADM_CTRL: ERROR - failed getting next state \n"); |
| |
| return(TI_NOK); |
| } |
| |
| TRACE3(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "trafficAdmCtrl_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", pTrafficAdmCtrl->currentState[acID], event, nextState); |
| |
| status = fsm_Event(pTrafficAdmCtrl->pTrafficAdmCtrlSm, &pTrafficAdmCtrl->currentState[acID], event, pData); |
| |
| return(status); |
| } |
| |
| |
| /************************************************************************ |
| * state machine functions * |
| ************************************************************************/ |
| /************************************************************************ |
| * trafficAdmCtrl_smStart * |
| ************************************************************************ |
| DESCRIPTION: the action function when event start ocuured on idle state |
| performs the following: |
| - send admision requestReset |
| - start timer for the response. |
| |
| INPUT: fsmTSpecInfo - parameters for the request |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smStart(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| TI_STATUS status; |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| /* send adm request frame */ |
| status = trafficAdmCtrl_sendAdmissionReq(pTrafficAdmCtrl, pTSpecInfo); |
| if(status != TI_OK) |
| return status; |
| |
| /* init timer */ |
| trafficAdmCtrl_startTimer(pTrafficAdmCtrl, pTSpecInfo->AC); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_smWaitStop * |
| ************************************************************************ |
| DESCRIPTION: the action function when event stop ocuured on wait state |
| performs the following: |
| - stop timer. |
| |
| INPUT: fsmTSpecInfo - parameters of the request |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smWaitStop(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| /* stop timer */ |
| trafficAdmCtrl_stopTimer(pTrafficAdmCtrl,fsmTSpecInfo->pTSpecInfo->AC); |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "TRAFFIC ADM CTRL - AC = %d, Stoped ..... \n", pTSpecInfo->AC); |
| |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_smWaitAccept * |
| ************************************************************************ |
| DESCRIPTION: the action function when event accept ocuured on wait state |
| performs the following: |
| - update the Qos Mngr of the status and the parameters |
| |
| INPUT: fsmTSpecInfo - parameters of the response |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smWaitAccept(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| /* update the QosMngr */ |
| qosMngr_setAdmissionInfo(pTrafficAdmCtrl->hQosMngr, pTSpecInfo->AC, pTSpecInfo, STATUS_TRAFFIC_ADM_REQUEST_ACCEPT); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_smWaitReject * |
| ************************************************************************ |
| DESCRIPTION: the action function when event reject ocuured on wait state |
| performs the following: |
| - update the Qos Mngr of the status and the parameters |
| |
| INPUT: fsmTSpecInfo - parameters of the response |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_smWaitReject(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| /* update the QosMngr */ |
| qosMngr_setAdmissionInfo(pTrafficAdmCtrl->hQosMngr, pTSpecInfo->AC, pTSpecInfo, STATUS_TRAFFIC_ADM_REQUEST_REJECT); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_smWaitTimeout * |
| ************************************************************************ |
| DESCRIPTION: the action function when event timeout ocuured on wait state |
| performs the following: |
| - update the Qos Mngr of the status and the parameters |
| |
| INPUT: fsmTSpecInfo - parameters of the request |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smWaitTimeout(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| |
| /* update the QosMngr */ |
| qosMngr_setAdmissionInfo(pTrafficAdmCtrl->hQosMngr, fsmTSpecInfo->acID, NULL, STATUS_TRAFFIC_ADM_REQUEST_TIMEOUT); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_smActionUnexpected * |
| ************************************************************************ |
| DESCRIPTION: |
| INPUT: fsmTSpecInfo - tspec parameters |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smActionUnexpected(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "TRAFFIC ADM CTRL - AC = %d, ActionUnexpected ..... \n", fsmTSpecInfo->acID); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * trafficAdmCtrl_smActionUnexpectedTspecResponse * |
| ************************************************************************ |
| DESCRIPTION: |
| INPUT: fsmTSpecInfo - tspec parameters |
| OUTPUT: |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smActionUnexpectedTspecResponse(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| /* Send event to user application - how come TSPEC response arrives without request ? */ |
| qosMngr_sendUnexpectedTSPECResponseEvent (pTrafficAdmCtrl->hQosMngr,pTSpecInfo); |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_WARNING, "TRAFFIC ADM CTRL - AC = %d, ActionUnexpected ..... \n", fsmTSpecInfo->acID); |
| |
| return TI_OK; |
| } |
| |
| |
| /************************************************************************ |
| * trafficAdmCtrl_smActionNop * |
| ************************************************************************ |
| DESCRIPTION: |
| INPUT: fsmTSpecInfo - tspec parameters |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_smActionNop(fsmTSpecInfo_t *fsmTSpecInfo) |
| { |
| trafficAdmCtrl_t *pTrafficAdmCtrl; |
| tspecInfo_t *pTSpecInfo; |
| |
| pTrafficAdmCtrl = (trafficAdmCtrl_t*)(fsmTSpecInfo->hTrafficAdmCtrl); |
| pTSpecInfo = fsmTSpecInfo->pTSpecInfo; |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "TRAFFIC ADM CTRL - AC = %d, Action NOP..... \n", pTSpecInfo->AC); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * API FUNCTIONS * |
| ************************************************************************ |
| ************************************************************************/ |
| |
| /************************************************************************ |
| * trafficAdmCtrl_startAdmRequest * |
| ************************************************************************ |
| DESCRIPTION: start TSPEC signaling |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| pTSpecInfo - the TSPEC parameters |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_startAdmRequest(TI_HANDLE hTrafficAdmCtrl, tspecInfo_t *pTSpecInfo) |
| { |
| TI_STATUS status; |
| fsmTSpecInfo_t fsmTSpecInfo; |
| |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| if (pTrafficAdmCtrl == NULL) |
| return TI_NOK; |
| |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = pTSpecInfo; |
| fsmTSpecInfo.acID = pTSpecInfo->AC; |
| |
| /* send event START to SM */ |
| status = trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_START, &fsmTSpecInfo); |
| |
| return status; |
| |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_stopAdmRequest * |
| ************************************************************************ |
| DESCRIPTION: stop specific tspec signaling |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| acID - the AC of the tspec to stop |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_stopAdmRequest(TI_HANDLE hTrafficAdmCtrl, TI_UINT8 acID) |
| { |
| TI_STATUS status; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| tspecInfo_t pTSpecInfo; |
| fsmTSpecInfo_t fsmTSpecInfo; |
| |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = &pTSpecInfo; |
| |
| fsmTSpecInfo.pTSpecInfo->AC = (EAcTrfcType)acID; |
| fsmTSpecInfo.acID = acID; |
| |
| /* send event STOP to SM */ |
| status = trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_STOP, &fsmTSpecInfo); |
| |
| return status; |
| |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_stop * |
| ************************************************************************ |
| DESCRIPTION: stop all tspecs and reset SM |
| called on disconnect |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_stop(TI_HANDLE hTrafficAdmCtrl) |
| { |
| TI_UINT32 uAcId; |
| |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| tspecInfo_t pTSpecInfo; |
| fsmTSpecInfo_t fsmTSpecInfo; |
| |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = &pTSpecInfo; |
| |
| /* clean all AC SM */ |
| for (uAcId = 0; uAcId < MAX_NUM_OF_AC; uAcId++) |
| { |
| fsmTSpecInfo.pTSpecInfo->AC = (EAcTrfcType)uAcId; |
| fsmTSpecInfo.acID = uAcId; |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_STOP, &fsmTSpecInfo); |
| |
| pTrafficAdmCtrl->dialogToken[uAcId] = 0; |
| } |
| |
| pTrafficAdmCtrl->dialogTokenCounter = INITIAL_DIALOG_TOKEN; |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * trafficAdmCtrl_recv * |
| ************************************************************************ |
| DESCRIPTION: |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_recv(TI_HANDLE hTrafficAdmCtrl, TI_UINT8* pData, TI_UINT8 action) |
| { |
| TI_STATUS status = TI_OK; |
| TI_UINT8 statusCode; |
| TI_UINT8 dialogToken; |
| TI_UINT8 tacID; |
| tspecInfo_t tspecInfo; |
| fsmTSpecInfo_t fsmTSpecInfo; |
| |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| if (action == ADDTS_RESPONSE_ACTION) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "action = 1 - ADDTS RESPONSE ACTION........!! \n"); |
| |
| /* parsing the dialog token */ |
| dialogToken = *pData; |
| pData++; |
| |
| /* in WME status code is 1 byte, in WSM is 2 bytes */ |
| statusCode = *pData; |
| pData++; |
| |
| tspecInfo.statusCode = statusCode; |
| |
| TRACE2(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "dialogToken = %d , statusCode = %d \n",dialogToken, statusCode); |
| |
| trafficAdmCtrl_parseTspecIE(&tspecInfo, pData); |
| |
| if (trafficAdmCtrl_tokenToAc (pTrafficAdmCtrl, dialogToken, &tacID) == TI_NOK) |
| { |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_WARNING, "dialog token Not found, dialogToken = %d , \n",dialogToken); |
| |
| qosMngr_sendUnexpectedTSPECResponseEvent(pTrafficAdmCtrl->hQosMngr, &tspecInfo); |
| |
| return TI_NOK; |
| } |
| |
| /* validate dialog token matching */ |
| if(pTrafficAdmCtrl->dialogToken[tspecInfo.AC] != dialogToken) |
| { |
| TRACE2(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_WARNING, "dialog token mismatch, dialogToken = %d , acID = %d \n",dialogToken, tspecInfo.AC); |
| |
| qosMngr_sendUnexpectedTSPECResponseEvent(pTrafficAdmCtrl->hQosMngr, &tspecInfo); |
| |
| return TI_NOK; |
| } |
| |
| /* Stop the relevant Timer */ |
| trafficAdmCtrl_stopTimer(pTrafficAdmCtrl, tspecInfo.AC); |
| |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = &tspecInfo; |
| |
| fsmTSpecInfo.acID = tspecInfo.AC; |
| |
| if(statusCode != ADDTS_STATUS_CODE_SUCCESS) |
| { |
| /* admission reject */ |
| /********************/ |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "***** admCtrlQos_recv: admission reject [ statusCode = %d ]\n",statusCode); |
| |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "ADDTS Response (reject) userPriority = %d , \n", tspecInfo.userPriority); |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_REJECT, &fsmTSpecInfo); |
| |
| } |
| else |
| { |
| /* admission accept */ |
| /********************/ |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "***** admCtrlQos_recv: admission accept [ statusCode = %d ]\n",statusCode); |
| |
| |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "ADDTS Response (accepted) userPriority = %d , \n", tspecInfo.userPriority); |
| |
| TRACE2(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "mediumTime = %d , surplusBandwidthAllowance = %d \n", tspecInfo.mediumTime, tspecInfo.surplausBwAllowance); |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_ACCEPT, &fsmTSpecInfo); |
| } |
| } |
| else |
| { |
| status = TI_NOK; |
| TRACE1(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "trafficAdmCtrl_recv: unknown action code = %d , \n",action); |
| |
| } |
| return status; |
| } |
| |
| |
| /************************************************************************ |
| * trafficAdmCtrl_sendDeltsFrame * |
| ************************************************************************ |
| DESCRIPTION: |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_sendDeltsFrame(TI_HANDLE hTrafficAdmCtrl, tspecInfo_t *pTSpecInfo, TI_UINT8 reasonCode) |
| { |
| TI_STATUS status = TI_OK; |
| TTxCtrlBlk *pPktCtrlBlk; |
| TI_UINT8 *pPktBuffer; |
| TI_UINT32 totalLen = 0; |
| tsInfo_t tsInfo; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t *)hTrafficAdmCtrl; |
| |
| |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlQos_sendDeltsFrame: Enter....!! \n"); |
| |
| /* Allocate a TxCtrlBlk and data buffer (large enough for the max packet) */ |
| pPktCtrlBlk = TWD_txCtrlBlk_Alloc (pTrafficAdmCtrl->hTWD); |
| pPktBuffer = txCtrl_AllocPacketBuffer (pTrafficAdmCtrl->hTxCtrl, pPktCtrlBlk, 2000); |
| if (pPktBuffer == NULL) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR , ": No memory\n"); |
| TWD_txCtrlBlk_Free (pTrafficAdmCtrl->hTWD, pPktCtrlBlk); |
| return TI_NOK; |
| } |
| |
| status = trafficAdmCtrl_buildFrameHeader (pTrafficAdmCtrl, pPktCtrlBlk); |
| if (status != TI_OK) |
| { |
| TWD_txCtrlBlk_Free (pTrafficAdmCtrl->hTWD, pPktCtrlBlk); |
| return TI_NOK; |
| } |
| |
| *(pPktBuffer + totalLen) = WME_CATAGORY_QOS; /* CATEGORY_QOS in WME = 17*/ |
| totalLen++; |
| *(pPktBuffer + totalLen) = DELTS_ACTION; /* DELTS ACTION */ |
| totalLen++; |
| *(pPktBuffer + totalLen) = 0; /* DIALOG_TOKEN is 0 in DELTS */ |
| totalLen++; |
| *(pPktBuffer + totalLen) = 0; /* STATUS CODE is 0 in DELTS */ |
| totalLen++; |
| |
| /* |
| * Build tsInfo fields |
| */ |
| |
| tsInfo.tsInfoArr[0] = 0; |
| tsInfo.tsInfoArr[1] = 0; |
| tsInfo.tsInfoArr[2] = 0; |
| |
| tsInfo.tsInfoArr[0] |= ( (pTSpecInfo->userPriority) << TSID_SHIFT); |
| |
| tsInfo.tsInfoArr[0] |= (BI_DIRECTIONAL << DIRECTION_SHIFT); /* bidirectional */ |
| tsInfo.tsInfoArr[0] |= (TS_INFO_0_ACCESS_POLICY_EDCA << ACCESS_POLICY_SHIFT); /* EDCA */ |
| |
| tsInfo.tsInfoArr[1] |= (0 << AGGREGATION_SHIFT); |
| |
| tsInfo.tsInfoArr[1] |= (pTSpecInfo->UPSDFlag << APSD_SHIFT); |
| |
| tsInfo.tsInfoArr[1] |= (pTSpecInfo->userPriority << USER_PRIORITY_SHIFT); |
| tsInfo.tsInfoArr[1] |= (NORMAL_ACKNOWLEDGEMENT << TSINFO_ACK_POLICY_SHIFT); |
| |
| tsInfo.tsInfoArr[2] |= (NO_SCHEDULE << SCHEDULE_SHIFT); |
| |
| /* |
| * Build TSpec IE for DELTS |
| */ |
| |
| *(pPktBuffer + totalLen ) = WME_TSPEC_IE_ID; |
| *(pPktBuffer + totalLen + 1) = WME_TSPEC_IE_TSINFO_LEN; |
| |
| *(pPktBuffer + totalLen + 2) = 0x00; |
| *(pPktBuffer + totalLen + 3) = 0x50; |
| *(pPktBuffer + totalLen + 4) = 0xf2; |
| *(pPktBuffer + totalLen + 5) = WME_TSPEC_IE_OUI_TYPE; |
| *(pPktBuffer + totalLen + 6) = WME_TSPEC_IE_OUI_SUB_TYPE; |
| *(pPktBuffer + totalLen + 7) = WME_TSPEC_IE_VERSION; |
| |
| *(pPktBuffer + totalLen + 8) = tsInfo.tsInfoArr[0]; |
| *(pPktBuffer + totalLen + 9) = tsInfo.tsInfoArr[1]; |
| *(pPktBuffer + totalLen +10) = tsInfo.tsInfoArr[2]; |
| |
| totalLen += WME_TSPEC_IE_TSINFO_LEN + 2; |
| |
| /* Update packet parameters (start-time, pkt-type and BDL) */ |
| pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (pTrafficAdmCtrl->hOs); |
| pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_MGMT; |
| BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk, pPktCtrlBlk->aPktHdr, WLAN_HDR_LEN, pPktBuffer, totalLen) |
| |
| /* Enqueue packet in the mgmt-queues and run the scheduler. */ |
| status = txMgmtQ_Xmit (pTrafficAdmCtrl->hTxMgmtQ, pPktCtrlBlk, TI_FALSE); |
| |
| return TI_OK; |
| } |
| |
| |
| /************************************************************************ |
| * INTERNAL FUNCTIONS * |
| ************************************************************************/ |
| /************************************************************************ |
| * trafficAdmCtrl_startTimer * |
| ************************************************************************ |
| DESCRIPTION: start a specific ac timer |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| acID - the AC of the timer |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_startTimer(trafficAdmCtrl_t* pTrafficAdmCtrl, TI_UINT8 acID) |
| { |
| TTimerCbFunc fTimerExpiryFunc = NULL; |
| |
| if (pTrafficAdmCtrl == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| switch (acID) |
| { |
| case QOS_AC_BE: fTimerExpiryFunc = trafficAdmCtrl_timeoutAcBE; break; |
| case QOS_AC_BK: fTimerExpiryFunc = trafficAdmCtrl_timeoutAcBK; break; |
| case QOS_AC_VI: fTimerExpiryFunc = trafficAdmCtrl_timeoutAcVI; break; |
| case QOS_AC_VO: fTimerExpiryFunc = trafficAdmCtrl_timeoutAcVO; break; |
| } |
| |
| tmr_StartTimer (pTrafficAdmCtrl->hAdmCtrlTimer[acID], |
| fTimerExpiryFunc, |
| (TI_HANDLE)pTrafficAdmCtrl, |
| pTrafficAdmCtrl->timeout, |
| TI_FALSE); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_stopTimer * |
| ************************************************************************ |
| DESCRIPTION: stop a specific ac timer |
| |
| INPUT: pTrafficAdmCtrl - trafficAdmCtr handle. |
| acID - the AC of the timer |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_stopTimer(trafficAdmCtrl_t* pTrafficAdmCtrl, TI_UINT8 acID) |
| { |
| if (pTrafficAdmCtrl == NULL) |
| return TI_NOK; |
| |
| tmr_StopTimer (pTrafficAdmCtrl->hAdmCtrlTimer[acID]); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * AC timers functionc * |
| ************************************************************************/ |
| |
| /* QOS_AC_BE */ |
| /*********/ |
| void trafficAdmCtrl_timeoutAcBE (TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured) |
| { |
| fsmTSpecInfo_t fsmTSpecInfo; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| |
| /* FSM Tspec Info Structure */ |
| fsmTSpecInfo.acID = QOS_AC_BE; |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = NULL; |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_TIMEOUT, &fsmTSpecInfo); |
| } |
| |
| /* QOS_AC_BK */ |
| /*********/ |
| void trafficAdmCtrl_timeoutAcBK(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured) |
| { |
| fsmTSpecInfo_t fsmTSpecInfo; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| |
| /* FSM Tspec Info Structure */ |
| fsmTSpecInfo.acID = QOS_AC_BK; |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = NULL; |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_TIMEOUT, &fsmTSpecInfo); |
| |
| } |
| /* QOS_AC_VI */ |
| /*********/ |
| void trafficAdmCtrl_timeoutAcVI(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured) |
| { |
| fsmTSpecInfo_t fsmTSpecInfo; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| |
| /* FSM Tspec Info Structure */ |
| fsmTSpecInfo.acID = QOS_AC_VI; |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = NULL; |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_TIMEOUT, &fsmTSpecInfo); |
| |
| } |
| /* QOS_AC_VO */ |
| /*********/ |
| void trafficAdmCtrl_timeoutAcVO(TI_HANDLE hTrafficAdmCtrl, TI_BOOL bTwdInitOccured) |
| { |
| fsmTSpecInfo_t fsmTSpecInfo; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| |
| /* FSM Tspec Info Structure */ |
| fsmTSpecInfo.acID = QOS_AC_VO; |
| fsmTSpecInfo.hTrafficAdmCtrl = hTrafficAdmCtrl; |
| fsmTSpecInfo.pTSpecInfo = NULL; |
| |
| trafficAdmCtrl_smEvent(pTrafficAdmCtrl, TRAFFIC_ADM_CTRL_SM_EVENT_TIMEOUT, &fsmTSpecInfo); |
| |
| } |
| |
| |
| static TI_STATUS trafficAdmCtrl_tokenToAc (TI_HANDLE hTrafficAdmCtrl, TI_UINT8 token, TI_UINT8 *acID) |
| { |
| TI_UINT8 idx; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| for (idx=0; idx<MAX_NUM_OF_AC; idx++) |
| { |
| if (pTrafficAdmCtrl->dialogToken[idx] == token) |
| { |
| *acID = idx; |
| return (TI_OK); |
| } |
| } |
| |
| return (TI_NOK); |
| |
| } |
| |
| |
| |
| /************************************************************************ |
| * trafficAdmCtrl_buildFrameHeader * |
| ************************************************************************ |
| DESCRIPTION: build frame header |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| TI_STATUS trafficAdmCtrl_buildFrameHeader(trafficAdmCtrl_t *pTrafficAdmCtrl, TTxCtrlBlk *pPktCtrlBlk) |
| { |
| TI_STATUS status; |
| TMacAddr daBssid, saBssid; |
| dot11_mgmtHeader_t *pdot11Header; |
| ScanBssType_e currBssType; |
| TMacAddr currBssId; |
| |
| pdot11Header = (dot11_mgmtHeader_t *)(pPktCtrlBlk->aPktHdr); |
| |
| /* Get the Destination MAC address */ |
| status = ctrlData_getParamBssid(pTrafficAdmCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid); |
| if (status != TI_OK) |
| { |
| return TI_NOK; |
| } |
| |
| /* Get the Source MAC address */ |
| status = ctrlData_getParamBssid(pTrafficAdmCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, saBssid); |
| if (status != TI_OK) |
| { |
| return TI_NOK; |
| } |
| |
| /* receive BssId and Bss Type from control module */ |
| ctrlData_getCurrBssTypeAndCurrBssId(pTrafficAdmCtrl->hCtrlData, &currBssId, &currBssType); |
| if (currBssType != BSS_INFRASTRUCTURE) |
| { |
| /* report failure but don't stop... */ |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR, "trafficAdmCtrl_buildFrameHeader: Error !! currBssType = BSS_INFRASTRUCTURE \n"); |
| |
| return TI_NOK; |
| } |
| /* infrastructure BSS */ |
| |
| /* copy BSSID */ |
| MAC_COPY (pdot11Header->BSSID, currBssId); |
| /* copy source mac address */ |
| MAC_COPY (pdot11Header->SA, saBssid); |
| /* copy destination mac address */ |
| MAC_COPY (pdot11Header->DA, daBssid); |
| |
| /* set frame ctrl to mgmt action frame an to DS */ |
| pdot11Header->fc = ENDIAN_HANDLE_WORD(DOT11_FC_ACTION | DOT11_FC_TO_DS); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * trafficAdmCtrl_sendAdmissionReq * |
| ************************************************************************ |
| DESCRIPTION: send admision request frame |
| |
| INPUT: hTrafficAdmCtrl - Qos Manager handle. |
| pTSpecInfo - tspec parameters |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| TI_STATUS trafficAdmCtrl_sendAdmissionReq(TI_HANDLE hTrafficAdmCtrl, tspecInfo_t *pTSpecInfo) |
| { |
| TI_STATUS status = TI_OK; |
| TTxCtrlBlk *pPktCtrlBlk; |
| TI_UINT8 *pPktBuffer; |
| TI_UINT32 len; |
| TI_UINT32 totalLen = 0; |
| trafficAdmCtrl_t *pTrafficAdmCtrl = (trafficAdmCtrl_t*)hTrafficAdmCtrl; |
| |
| |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_INFORMATION, "admCtrlQos_smAdmissionReq: Enter....!! \n"); |
| |
| /* Allocate a TxCtrlBlk and data buffer (large enough for the max packet) */ |
| pPktCtrlBlk = TWD_txCtrlBlk_Alloc (pTrafficAdmCtrl->hTWD); |
| pPktBuffer = txCtrl_AllocPacketBuffer (pTrafficAdmCtrl->hTxCtrl, pPktCtrlBlk, 2000); |
| if (pPktBuffer == NULL) |
| { |
| TRACE0(pTrafficAdmCtrl->hReport, REPORT_SEVERITY_ERROR , ": No memory\n"); |
| TWD_txCtrlBlk_Free (pTrafficAdmCtrl->hTWD, pPktCtrlBlk); |
| return TI_NOK; |
| } |
| |
| status = trafficAdmCtrl_buildFrameHeader (pTrafficAdmCtrl, pPktCtrlBlk); |
| if (status != TI_OK) |
| { |
| TWD_txCtrlBlk_Free (pTrafficAdmCtrl->hTWD, pPktCtrlBlk); |
| return TI_NOK; |
| } |
| |
| *(pPktBuffer + totalLen) = WME_CATAGORY_QOS; /* CATEGORY_QOS WME = 17*/ |
| totalLen++; |
| *(pPktBuffer + totalLen) = ADDTS_REQUEST_ACTION; /* ADDTS request ACTION */ |
| totalLen++; |
| |
| /* storing the dialog token for response validation */ |
| pTrafficAdmCtrl->dialogToken[pTSpecInfo->AC] = pTrafficAdmCtrl->dialogTokenCounter++; /* DIALOG_TOKEN */ |
| *(pPktBuffer + totalLen) = pTrafficAdmCtrl->dialogToken[pTSpecInfo->AC]; |
| totalLen++; |
| |
| *(pPktBuffer + totalLen) = 0; /* STATUS CODE is 0 for ADDTS */ |
| totalLen++; |
| |
| trafficAdmCtrl_buildTSPec (pTrafficAdmCtrl, pTSpecInfo, pPktBuffer + totalLen, (TI_UINT32*)&len); |
| totalLen += len; |
| |
| /* Update packet parameters (start-time, length, pkt-type) */ |
| pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (pTrafficAdmCtrl->hOs); |
| pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_MGMT; |
| BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk, pPktCtrlBlk->aPktHdr, WLAN_HDR_LEN, pPktBuffer, totalLen) |
| |
| /* Enqueue packet in the mgmt-queues and run the scheduler. */ |
| status = txMgmtQ_Xmit (pTrafficAdmCtrl->hTxMgmtQ, pPktCtrlBlk, TI_FALSE); |
| |
| return TI_OK; |
| } |
| /************************************************************************ |
| * trafficAdmCtrl_buildTSPec * |
| ************************************************************************ |
| DESCRIPTION: build a tspec according to the tspec parameters |
| |
| INPUT: hTrafficAdmCtrl - Qos Manager handle. |
| pTSpecInfo - tspec parameters |
| |
| OUTPUT: pPktBuffer - the Tspec IE to send |
| len - the tspec frame len |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| |
| void trafficAdmCtrl_buildTSPec(trafficAdmCtrl_t *pTrafficAdmCtrl, |
| tspecInfo_t *pTSpecInfo, |
| TI_UINT8 *pDataBuf, |
| TI_UINT32 *len) |
| { |
| tsInfo_t tsInfo; |
| TI_UINT16 nominalMSDUSize, maxMSDUSize; |
| TI_UINT32 suspensionInterval = 0; /* disable */ |
| |
| |
| os_memoryZero(pTrafficAdmCtrl->hOs, (void *)pDataBuf, WME_TSPEC_IE_LEN + 2); |
| |
| *pDataBuf = WME_TSPEC_IE_ID; |
| *(pDataBuf + 1) = WME_TSPEC_IE_LEN; |
| |
| *(pDataBuf + 2) = 0x00; |
| *(pDataBuf + 3) = 0x50; |
| *(pDataBuf + 4) = 0xf2; |
| *(pDataBuf + 5) = WME_TSPEC_IE_OUI_TYPE; |
| *(pDataBuf + 6) = WME_TSPEC_IE_OUI_SUB_TYPE; |
| *(pDataBuf + 7) = WME_TSPEC_IE_VERSION; |
| |
| /* |
| * Build tsInfo fields |
| */ |
| |
| tsInfo.tsInfoArr[0] = 0; |
| tsInfo.tsInfoArr[1] = 0; |
| tsInfo.tsInfoArr[2] = 0; |
| |
| tsInfo.tsInfoArr[0] |= ( (pTSpecInfo->userPriority) << TSID_SHIFT); |
| tsInfo.tsInfoArr[0] |= (pTSpecInfo->streamDirection << DIRECTION_SHIFT); /* bidirectional */ |
| |
| tsInfo.tsInfoArr[0] |= (TS_INFO_0_ACCESS_POLICY_EDCA << ACCESS_POLICY_SHIFT); /* EDCA */ |
| |
| tsInfo.tsInfoArr[1] |= (0 << AGGREGATION_SHIFT); |
| |
| tsInfo.tsInfoArr[1] |= (pTSpecInfo->UPSDFlag << APSD_SHIFT); |
| |
| tsInfo.tsInfoArr[1] |= (pTSpecInfo->userPriority << USER_PRIORITY_SHIFT); |
| tsInfo.tsInfoArr[1] |= (NORMAL_ACKNOWLEDGEMENT << TSINFO_ACK_POLICY_SHIFT); |
| |
| tsInfo.tsInfoArr[2] |= (NO_SCHEDULE << SCHEDULE_SHIFT); |
| |
| *(pDataBuf + 8) = tsInfo.tsInfoArr[0]; |
| *(pDataBuf + 9) = tsInfo.tsInfoArr[1]; |
| *(pDataBuf +10) = tsInfo.tsInfoArr[2]; |
| |
| pDataBuf += 11; /* Progress the data pointer to the next IE parameters. */ |
| |
| /* |
| * Set all remained parameters |
| */ |
| |
| nominalMSDUSize = pTSpecInfo->nominalMsduSize; |
| if (pTrafficAdmCtrl->useFixedMsduSize) |
| nominalMSDUSize |= FIX_MSDU_SIZE; |
| |
| maxMSDUSize = (nominalMSDUSize & (~FIX_MSDU_SIZE)); |
| |
| COPY_WLAN_WORD(pDataBuf, &nominalMSDUSize); /* Nominal-MSDU-size. */ |
| COPY_WLAN_WORD(pDataBuf + 2, &maxMSDUSize); /* Maximum-MSDU-size. */ |
| COPY_WLAN_LONG(pDataBuf + 4, &pTSpecInfo->uMinimumServiceInterval); /* Minimum service interval */ |
| COPY_WLAN_LONG(pDataBuf + 8, &pTSpecInfo->uMaximumServiceInterval); /* Maximum service interval */ |
| COPY_WLAN_LONG(pDataBuf + 16, &suspensionInterval); |
| COPY_WLAN_LONG(pDataBuf + 24, &pTSpecInfo->meanDataRate); /* Minimum-data-rate. */ |
| COPY_WLAN_LONG(pDataBuf + 28, &pTSpecInfo->meanDataRate); /* Mean-data-rate. */ |
| COPY_WLAN_LONG(pDataBuf + 32, &pTSpecInfo->meanDataRate); /* Peak-data-rate. */ |
| COPY_WLAN_LONG(pDataBuf + 44, &pTSpecInfo->minimumPHYRate); |
| COPY_WLAN_WORD(pDataBuf + 48, &pTSpecInfo->surplausBwAllowance); |
| |
| *len = WME_TSPEC_IE_LEN + 2; |
| } |
| |
| |
| |
| /************************************************************************ |
| * trafficAdmCtrl_parseTspecIE * |
| ************************************************************************ |
| DESCRIPTION: parses a tspec IE according to the tspec parameters |
| |
| INPUT: pData - tspec IE from received frame |
| |
| OUTPUT: pTSpecInfo - parsed tspec parameters |
| |
| RETURN: None |
| ************************************************************************/ |
| void trafficAdmCtrl_parseTspecIE(tspecInfo_t *pTSpecInfo, TI_UINT8 *pData) |
| { |
| tsInfo_t tsInfo; |
| TI_UINT8 userPriority; |
| TI_UINT8 acID; |
| TI_UINT8 tid; |
| TI_UINT8 direction; |
| TI_UINT8 APSDbit; |
| |
| pData += 8; /* Skip the WME_TSPEC_IE header */ |
| |
| /* Get the TS-Info (3 bytes) and parse its fields */ |
| tsInfo.tsInfoArr[0] = *pData; |
| tsInfo.tsInfoArr[1] = *(pData + 1); |
| tsInfo.tsInfoArr[2] = *(pData + 2); |
| pData += 3; |
| |
| userPriority = (((tsInfo.tsInfoArr[1]) & TS_INFO_1_USER_PRIORITY_MASK) >> USER_PRIORITY_SHIFT); |
| |
| acID = WMEQosTagToACTable[userPriority]; |
| |
| tid = (((tsInfo.tsInfoArr[0]) & TS_INFO_0_TSID_MASK) >> TSID_SHIFT); |
| APSDbit = (((tsInfo.tsInfoArr[1]) & TS_INFO_1_APSD_MASK) >> APSD_SHIFT); |
| direction = (((tsInfo.tsInfoArr[0]) & TS_INFO_0_DIRECTION_MASK) >> DIRECTION_SHIFT); |
| |
| |
| pTSpecInfo->AC = (EAcTrfcType)acID; |
| pTSpecInfo->userPriority = userPriority; |
| pTSpecInfo->UPSDFlag = APSDbit; |
| pTSpecInfo->streamDirection = (EStreamDirection)direction; |
| pTSpecInfo->tid = tid; |
| |
| /* Get the other Tspec IE parameters (handle WLAN fram endianess if required) */ |
| COPY_WLAN_WORD(&pTSpecInfo->nominalMsduSize, pData); |
| COPY_WLAN_LONG(&pTSpecInfo->uMinimumServiceInterval, pData + 4); |
| COPY_WLAN_LONG(&pTSpecInfo->uMaximumServiceInterval, pData + 8); |
| COPY_WLAN_LONG(&pTSpecInfo->meanDataRate, pData + 28); |
| COPY_WLAN_LONG(&pTSpecInfo->minimumPHYRate, pData + 44); |
| COPY_WLAN_WORD(&pTSpecInfo->surplausBwAllowance, pData + 48); |
| pTSpecInfo->surplausBwAllowance >>= SURPLUS_BANDWIDTH_ALLOW; /* Surplus is in 3 MSBits of TI_UINT16 */ |
| COPY_WLAN_WORD(&pTSpecInfo->mediumTime, pData + 50); |
| } |
| |
| |
| |
| /************************************************************************* |
| * * |
| * DEBUG FUNCTIONS * |
| * * |
| *************************************************************************/ |
| void trafficAdmCtrl_print(trafficAdmCtrl_t *pTrafficAdmCtr) |
| { |
| TI_UINT32 acID; |
| |
| WLAN_OS_REPORT((" traffic Adm Ctrl \n")); |
| WLAN_OS_REPORT(("-----------------------------------\n\n")); |
| WLAN_OS_REPORT(("timeout = %d\n",pTrafficAdmCtr->timeout)); |
| WLAN_OS_REPORT(("dialogTokenCounter = %d\n",pTrafficAdmCtr->dialogTokenCounter)); |
| |
| for (acID = 0 ; acID < MAX_NUM_OF_AC ; acID++) |
| { |
| WLAN_OS_REPORT((" AC = %d \n",acID)); |
| WLAN_OS_REPORT(("----------------------\n")); |
| WLAN_OS_REPORT(("currentState = %d \n",pTrafficAdmCtr->currentState[acID])); |
| WLAN_OS_REPORT(("dialogToken = %d \n",pTrafficAdmCtr->dialogToken[acID])); |
| } |
| } |
| |