/**
 * Called when we finished processing a request and want to request the SCR.
 *
 * @date 05-Jan-2006
 */
static TI_STATUS measurementMgrSM_acRequestSCR(void * pData)
{
	measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData;
	EScrClientRequestStatus scrStatus;
	EScePendReason scrPendReason;

	/* Request the channel */
	scrStatus = scr_clientRequest(pMeasurementMgr->hScr, SCR_CID_XCC_MEASURE,
	                              SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason);

	if (scrStatus == SCR_CRS_RUN) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received RUN response from SCR\n");

		/* The channel is allocated for the measurement */
		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_SCR_RUN, pMeasurementMgr);
	} else if ((scrStatus == SCR_CRS_PEND) && (scrPendReason == SCR_PR_DIFFERENT_GROUP_RUNNING)) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received PEND/DIFFGROUP response from SCR\n");

		/* No need to wait for the channel allocation */
		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Going to wait for SCR callback...\n");

	/* In all other cases wait for the callback function to be called */
	return TI_OK;
}
/**
 * Disables the Measurement Manager module.
 * 
 * @date 10-Jan-2006
 */
TI_STATUS measurementMgr_disable(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                                MEASUREMENTMGR_EVENT_DISABLE, pMeasurementMgr);
}
/**
 * Signals the Measurement Manager that the STA is disconnected.
 *
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_disconnected(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                                MEASUREMENTMGR_EVENT_DISCONNECTED, pMeasurementMgr);
}
/**
 * Disables the Measurement Manager module.
 * 
 * @date 10-Jan-2006
 */
TI_STATUS measurementMgr_disable(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to disabled.\n");

    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                                MEASUREMENTMGR_EVENT_DISABLE, pMeasurementMgr);
}
/**
 * Called when a frame with type measurement request is received.
 * 
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * @param frameType The frame type.
 * @param dataLen The length of the frame.
 * @param pData A pointer to the frame's content.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_receiveFrameRequest(TI_HANDLE hMeasurementMgr,
                                             EMeasurementFrameType frameType,
                                             TI_INT32 dataLen,
                                             TI_UINT8 * pData)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    TMeasurementFrameRequest * frame = &(pMeasurementMgr->newFrameRequest);    
    TI_UINT16 currentFrameToken;
    
    /* checking if measurement is enabled */
    if (pMeasurementMgr->Mode == MSR_MODE_NONE)
        return TI_NOK;

    /* ignore broadcast/multicast request if unicast request is active */
    if (frameType != MSR_FRAME_TYPE_UNICAST && pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST)
    {
        TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Broadcast/Multicast measurement frame has been ignored\n");

        return TI_NOK;
    }

    /* ignore broadcast request if multicast request is active */
    if (frameType == MSR_FRAME_TYPE_BROADCAST && pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_MULTICAST)
    {
        TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Broadcast measurement frame has been ignored\n");
        
        return TI_NOK;
    }

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame received\n");

    /* Parsing the Frame Request Header */
    pMeasurementMgr->parserFrameReq(hMeasurementMgr, pData, dataLen, 
                                        frame);

    frame->frameType = frameType;

    /* checking if the received token frame is the same as the one that is being processed */
    if ((requestHandler_getFrameToken(pMeasurementMgr->hRequestH, &currentFrameToken) == TI_OK)
        && (currentFrameToken == frame->hdr->dialogToken))
    {
        os_memoryZero(pMeasurementMgr->hOs, &pMeasurementMgr->newFrameRequest, 
                      sizeof(TMeasurementFrameRequest));

        TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame token %d is identical to current frame token - ignoring frame\n", currentFrameToken);

        return TI_NOK;
    }

    TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame token is %d\n", frame->hdr->dialogToken);

    /* Frame is Received for processing */
    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_FRAME_RECV, pMeasurementMgr);
}
/**
 * The callback called when the SCR responds to the SCR request.
 * 
 * @param hClient A handle to the Measurement Manager module.
 * @param requestStatus The request's status
 * @param eResource The resource for which the CB is issued
 * @param pendReason The reason of a PEND status.
 * 
 * @date 01-Jan-2006
 */
void measurementMgr_scrResponseCB(TI_HANDLE hClient, EScrClientRequestStatus requestStatus,
                                  EScrResourceId eResource, EScePendReason pendReason )
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hClient;
    measurementMgrSM_Events event;

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": SCR callback entered\n");

    /* If the SM is in a state where it waits for the CB, status of RUN */
    /* results in the SM asking the measurementSRV to start measurement; */
    /* otherwise we got an ABORT or a PEND reason worse than the one we */
    /* got when calling the SCR, so the SM aborts the measurement */
    if (pMeasurementMgr->currentState == MEASUREMENTMGR_STATE_WAITING_FOR_SCR)
    {
        if (requestStatus == SCR_CRS_RUN)
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status RUN, running...\n");

            event = MEASUREMENTMGR_EVENT_SCR_RUN;
        }
        else
        {
            if (requestStatus == SCR_CRS_PEND)
            {
                TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status PEND with reason %d, aborting...\n", pendReason);
            }
            else
            {
                TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status ABORT/FW_RESET, aborting...\n");
            }

            event = MEASUREMENTMGR_EVENT_ABORT;
        }
    }
    else
    {   
        /* This can only occur if FW reset occurs or when higher priority client is running. */

        if (requestStatus == SCR_CRS_FW_RESET)
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status FW_RESET\n");

            event = MEASUREMENTMGR_EVENT_FW_RESET;
        }
        else
        {
        TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgrSM current state is %d (which isn't WAITING_FOR_SCR), aborting...\n", pMeasurementMgr->currentState);

        event = MEASUREMENTMGR_EVENT_ABORT;
    }
    }

    measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        event, pMeasurementMgr);
}
/**
 * Signals the Measurement Manager that the STA is connected.
 *
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_connected(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    /* checking if measurement is enabled */
    if (pMeasurementMgr->Mode == MSR_MODE_NONE)
        return TI_OK;

    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_CONNECTED, pMeasurementMgr);
}
/**
 * Signals the Measurement Manager that the STA is connected.
 *
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_connected(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;

    /* checking if measurement is enabled */
    if (pMeasurementMgr->Mode == MSR_MODE_NONE)
        return TI_OK;

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to connected.\n");

    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_CONNECTED, pMeasurementMgr);
}
/**
 * The callback called by the MeasurementSRV module when then
 * measurement operation has ended.
 * 
 * @param clientObj A handle to the Measurement Manager module.
 * @param msrReply An array of replies sent by the MeasurementSRV module,
 * where each reply contains the result of a single measurement request.
 * 
 * @date 01-Jan-2006
 */
void measurementMgr_MeasurementCompleteCB(TI_HANDLE clientObj, TMeasurementReply * msrReply)
{
    measurementMgr_t    *pMeasurementMgr = (measurementMgr_t *) clientObj;
    TI_UINT8            index;

    /* build a report for each measurement request/reply pair */
    for (index = 0; index < msrReply->numberOfTypes; index++)
    {
        pMeasurementMgr->buildReport(pMeasurementMgr, *(pMeasurementMgr->currentRequest[index]), &msrReply->msrTypes[index]);
    }

    measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
            MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
}
Beispiel #10
0
/**
 * The callback called by the MeasurementSRV module when then
 * measurement operation has ended.
 * 
 * @param clientObj A handle to the Measurement Manager module.
 * @param msrReply An array of replies sent by the MeasurementSRV module,
 * where each reply contains the result of a single measurement request.
 * 
 * @date 01-Jan-2006
 */
void measurementMgr_MeasurementCompleteCB(TI_HANDLE clientObj, TMeasurementReply * msrReply)
{
    measurementMgr_t    *pMeasurementMgr = (measurementMgr_t *) clientObj;
    TI_UINT8            index;

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Building reports for measurement requests\n");
    
    /* build a report for each measurement request/reply pair */
    for (index = 0; index < msrReply->numberOfTypes; index++)
    {
        TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, "measurementMgr_MeasurementCompleteCB: call buildReport... \n");
        pMeasurementMgr->buildReport(pMeasurementMgr, *(pMeasurementMgr->currentRequest[index]), &msrReply->msrTypes[index]);
    }

    measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
            MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
}
Beispiel #11
0
/**
 * The callback called when the SCR responds to the SCR request.
 * 
 * @param hClient A handle to the Measurement Manager module.
 * @param requestStatus The request's status
 * @param eResource The resource for which the CB is issued
 * @param pendReason The reason of a PEND status.
 * 
 * @date 01-Jan-2006
 */
void measurementMgr_scrResponseCB(TI_HANDLE hClient, EScrClientRequestStatus requestStatus,
                                  EScrResourceId eResource, EScePendReason pendReason )
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hClient;
    measurementMgrSM_Events event;

    /* If the SM is in a state where it waits for the CB, status of RUN */
    /* results in the SM asking the measurementSRV to start measurement; */
    /* otherwise we got an ABORT or a PEND reason worse than the one we */
    /* got when calling the SCR, so the SM aborts the measurement */
    if (pMeasurementMgr->currentState == MEASUREMENTMGR_STATE_WAITING_FOR_SCR)
    {
        if (requestStatus == SCR_CRS_RUN)
        {
            event = MEASUREMENTMGR_EVENT_SCR_RUN;
        }
        else
        {
            event = MEASUREMENTMGR_EVENT_ABORT;
        }
    }
    else
    {   
        /* This can only occur if FW reset occurs or when higher priority client is running. */

        if (requestStatus == SCR_CRS_FW_RESET)
        {
            event = MEASUREMENTMGR_EVENT_FW_RESET;
        }
        else
        {
        event = MEASUREMENTMGR_EVENT_ABORT;
    }
    }

    measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        event, pMeasurementMgr);
}
Beispiel #12
0
/**
 * Activates the next measurement request.
 * 
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_activateNextRequest(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;
    requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH;
    MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
    TI_UINT8 numOfRequestsInParallel = 0;
    TI_BOOL valid;
    TI_UINT8 index;

	/* Keep note of the time we started processing the request. this will be used */
    /* to give the measurementSRV a time frame to perform the measurement operation */
    pMeasurementMgr->currentRequestStartTime = os_timeStampMs(pMeasurementMgr->hOs);

    do
    {
        TI_STATUS status;

        pRequestH->activeRequestID += numOfRequestsInParallel;
        pRequestH->numOfWaitingRequests -= numOfRequestsInParallel;

        for (index = 0; index < MAX_NUM_REQ; index++)
        {
            pRequestArr[index] = NULL;
        }
        numOfRequestsInParallel = 0;

        /* Getting the next request/requests from the request handler */
        status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_FALSE, pRequestArr, 
                                           &numOfRequestsInParallel);
        
        /* Checking if there are no waiting requests */
        if (status != TI_OK)
        {
            return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
        }

        /* Checking validity of request/s */
        valid = measurementMgr_isRequestValid(pMeasurementMgr, pRequestArr, 
                                numOfRequestsInParallel);

        /* Checking if the current request is Beacon Table */
        if( (numOfRequestsInParallel == 1) && 
            (pRequestArr[0]->Type == MSR_TYPE_BEACON_MEASUREMENT) &&
            (pRequestArr[0]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) )
        {
            pMeasurementMgr->buildReport(hMeasurementMgr, *(pRequestArr[0]), NULL);
            valid = TI_FALSE; /* In order to get the next request/s*/
        }
        
    } while (valid == TI_FALSE);
    

    /* Ignore requests if traffic intensity is high */
    if (measurementMgr_isTrafficIntensityHigherThanThreshold(pMeasurementMgr) == TI_TRUE)
    {
        measurementMgr_rejectPendingRequests(pMeasurementMgr, MSR_REJECT_TRAFFIC_INTENSITY_TOO_HIGH);

        return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
    }
    
    pMeasurementMgr->measuredChannelID = pRequestArr[0]->channelNumber;
  
    /* Request resource from the SCR */
    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        MEASUREMENTMGR_EVENT_REQUEST_SCR, pMeasurementMgr);    
}   
/**
 * Called when the SCR callbacks with a RUN response or if the SCR
 * returned a RUN response when we requested it.
 *
 * @date 05-Jan-2006
 */
static TI_STATUS measurementMgrSM_acStartMeasurement(void * pData)
{
	measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData;

	/* Cryptic: the first struct is the requestHandler request while */
	/* the second one is the measurementSRV request */
	MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
	TMeasurementRequest request;

	paramInfo_t	*pParam;
	TI_UINT8 numOfRequestsInParallel;
	TI_UINT8 requestIndex;
	TI_UINT32 timePassed;
	TI_BOOL requestedBeaconMeasurement= TI_FALSE;
	TI_STATUS status;

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Starting Measurement operation\n");

	pParam = (paramInfo_t *)os_memoryAlloc(pMeasurementMgr->hOs, sizeof(paramInfo_t));
	if (!pParam) {
		return TI_NOK;
	}

	request.channel = pMeasurementMgr->measuredChannelID;
	request.startTime = 0;	/* ignored by MeasurementSRV for now - for .11k */
	request.numberOfTypes = 0;

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measured Channel = %d\n", pMeasurementMgr->measuredChannelID);

	pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
	pParam->content.channelCapabilityReq.channelNum = pMeasurementMgr->measuredChannelID;
	pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;

	if (pMeasurementMgr->measuredChannelID <= MAX_CHANNEL_IN_BAND_2_4) {
		request.band = RADIO_BAND_2_4_GHZ;
		pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ;
	} else {
		request.band = RADIO_BAND_5_0_GHZ;
		pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ;
	}

	regulatoryDomain_getParam(pMeasurementMgr->hRegulatoryDomain, pParam);

	request.txPowerDbm = pParam->content.channelCapabilityRet.maxTxPowerDbm;

	request.eTag = SCAN_RESULT_TAG_MEASUREMENT;
	os_memoryFree(pMeasurementMgr->hOs, pParam, sizeof(paramInfo_t));

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Querying Request Handler for the next request in the queue\n");

	/* Getting the next request/requests from the request handler */
	status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_TRUE, pRequestArr,
	                                   &numOfRequestsInParallel);

	if (status != TI_OK) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Failed getting next request from Request Handler\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
	}

	/* Save the number of requests in parallel so that once the */
	/* measurement operation ends we can get rid of this amount of requests */
	/* from the requestHandler */
	pMeasurementMgr->currentNumOfRequestsInParallel = numOfRequestsInParallel;

	for (requestIndex = 0; requestIndex < numOfRequestsInParallel; requestIndex++) {
		if (pRequestArr[requestIndex]->Type == MSR_TYPE_BEACON_MEASUREMENT) {
			requestedBeaconMeasurement = TI_TRUE;

			if (pRequestArr[requestIndex]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) {
				TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Beacon Table request encountered, building report now\n");

				/* building Report for beacon table request */
				pMeasurementMgr->buildReport(pMeasurementMgr, *pRequestArr[requestIndex], NULL);

				continue;
			}
		}

		/* save the request so we can reference it when results arrive */
		pMeasurementMgr->currentRequest[request.numberOfTypes] = pRequestArr[requestIndex];

		/* add the measurement type to the request's list */
		request.msrTypes[request.numberOfTypes].duration = pRequestArr[requestIndex]->DurationTime;
		request.msrTypes[request.numberOfTypes].scanMode = pRequestArr[requestIndex]->ScanMode;
		request.msrTypes[request.numberOfTypes].msrType = pRequestArr[requestIndex]->Type;

		TRACE3(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ":\n\nMeasurement Request #%d Details: Type = %d, Duration = %d\n\n",						request.numberOfTypes+1,						request.msrTypes[request.numberOfTypes].msrType,						request.msrTypes[request.numberOfTypes].duration);

		request.numberOfTypes++;
	}

	if (requestedBeaconMeasurement == TI_TRUE) {
		/* build a probe request template and send it to the HAL */
		TSetTemplate templateStruct;
		probeReqTemplate_t probeReqTemplate;
		TSsid broadcastSSID;

		templateStruct.ptr = (TI_UINT8 *) &probeReqTemplate;
		templateStruct.type = PROBE_REQUEST_TEMPLATE;
		templateStruct.eBand = request.band;
		templateStruct.uRateMask = RATE_MASK_UNSPECIFIED;
		broadcastSSID.len = 0;

		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Sending probe request template...\n");

		buildProbeReqTemplate( pMeasurementMgr->hSiteMgr, &templateStruct, &broadcastSSID, request.band );
#ifdef XCC_MODULE_INCLUDED
		{	/* Insert Radio Mngt Capability IE according XCC4*/
			TI_UINT32				len = 0;
			measurementMgr_radioMngtCapabilityBuild (pMeasurementMgr,
			        templateStruct.ptr + templateStruct.len,
			        (TI_UINT8*)&len);
			templateStruct.len += len;
		}
#endif

		TWD_CmdTemplate (pMeasurementMgr->hTWD, &templateStruct, NULL, NULL);
	}

	/* Check if the maximum time to wait for the measurement request to */
	/* finish has already passed */
	timePassed = os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime;
	if (timePassed > MSR_START_MAX_DELAY) {
		TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Maximum delay to perform measurement operation has passed (%d / %d)\n",						MSR_START_MAX_DELAY, (os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime));

		pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequestsInParallel, MSR_REJECT_MAX_DELAY_PASSED);

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
	}

	/* Yalla, start measuring */
	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Finished preparing request. Handing over to MeasurementSRV...\n");

	TWD_StartMeasurement (pMeasurementMgr->hTWD,
	                      &request,
	                      MSR_START_MAX_DELAY - timePassed,
	                      NULL, NULL,
	                      measurementMgr_MeasurementCompleteCB,
	                      pMeasurementMgr);

	return TI_OK;
}
/**
 * Called when the SM is in an idle state and we receive a new measurement frame.
 *
 * @date 05-Jan-2006
 */
static TI_STATUS measurementMgrSM_acFrameReceived_fromIdle(void * pData)
{
	measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData;
	TI_UINT16 activationDelay;
	TI_STATUS status;
	paramInfo_t param;
	TI_UINT16 tbtt;

	/* handle frame request only if we're connected and measurement is enabled */
	if (pMeasurementMgr->Connected == TI_FALSE ||
	    pMeasurementMgr->Enabled == TI_FALSE) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Frame received while SM is in disconnected/disabled state\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	/* Setting the frame Type */
	pMeasurementMgr->currentFrameType = pMeasurementMgr->newFrameRequest.frameType;

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Frame Type = %d\n", pMeasurementMgr->currentFrameType);

	/* Getting the Beacon Interval from the Site Mgr */
	param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
	status = siteMgr_getParam(pMeasurementMgr->hSiteMgr, &param);
	if (status != TI_OK) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Failed to retrieve beacon interval - not connected?\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	/* converting beacon interval to msec */
	tbtt = (param.content.beaconInterval * 1024) / 1000;	/* from TU to msec */

	/* Initializing Activation Delay Time */
	activationDelay	= pMeasurementMgr->newFrameRequest.hdr->activatioDelay;
	activationDelay	*= tbtt;
	/* Adding the Measurement Offset to the activation delay */
	activationDelay	+= pMeasurementMgr->newFrameRequest.hdr->measurementOffset;

	/* Inserting all received measurement requests into the queue */
	status = requestHandler_insertRequests(pMeasurementMgr->hRequestH,
	                                       pMeasurementMgr->Mode,
	                                       pMeasurementMgr->newFrameRequest);

	/* Clean New Frame Params */
	os_memoryZero(pMeasurementMgr->hOs, &pMeasurementMgr->newFrameRequest,
	              sizeof(TMeasurementFrameRequest));

	if (status != TI_OK) {
		pMeasurementMgr->currentFrameType = MSR_FRAME_TYPE_NO_ACTIVE;

		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Could not insert request into the queue\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": New frame has been inserted into the queue\n");

	/* If frame type isn't Unicast add to Activation Delay a random delay */
	if ((pMeasurementMgr->currentFrameType != MSR_FRAME_TYPE_UNICAST) && (activationDelay > 0)) {
		activationDelay	+= ((os_timeStampMs(pMeasurementMgr->hOs) % MSR_ACTIVATION_DELAY_RANDOM)
		                    + MSR_ACTIVATION_DELAY_OFFSET);
	}

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Activation Delay in ms = %d\n", activationDelay);

	if (activationDelay > 0) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Going to wait for activation delay timer callback\n");

		/* Starting the Activation Delay Timer */
		tmr_StartTimer (pMeasurementMgr->hActivationDelayTimer,
		                measurementMgrSM_uponActivationDelayTimeout,
		                (TI_HANDLE)pMeasurementMgr,
		                activationDelay,
		                TI_FALSE);

		return TI_OK;
	} else {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Activating the next request immediately without waiting for callback\n");

		/* Calling to schedule the first waiting request */
		return measurementMgr_activateNextRequest(pData);
	}
}
/**
 * Activates the next measurement request.
 * 
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_activateNextRequest(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;
    requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH;
    MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
    TI_UINT8 numOfRequestsInParallel = 0;
    TI_BOOL valid;
    TI_UINT8 index;

	/* Keep note of the time we started processing the request. this will be used */
    /* to give the measurementSRV a time frame to perform the measurement operation */
    pMeasurementMgr->currentRequestStartTime = os_timeStampMs(pMeasurementMgr->hOs);

    TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Timer started at %d, we have 20ms to begin measurement...\n", pMeasurementMgr->currentRequestStartTime);

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Looking for a valid request\n");

    do
    {
        TI_STATUS status;

        if (numOfRequestsInParallel != 0)
        {
            TRACE4(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Changing activeRequestID from %d to %d, and numOfWaitingRequests from %d to %d.\n", pRequestH->activeRequestID, pRequestH->activeRequestID + numOfRequestsInParallel, pRequestH->numOfWaitingRequests, pRequestH->numOfWaitingRequests - numOfRequestsInParallel);
        }

        pRequestH->activeRequestID += numOfRequestsInParallel;
        pRequestH->numOfWaitingRequests -= numOfRequestsInParallel;

        for (index = 0; index < MAX_NUM_REQ; index++)
        {
            pRequestArr[index] = NULL;
        }
        numOfRequestsInParallel = 0;

        /* Getting the next request/requests from the request handler */
        status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_FALSE, pRequestArr, 
                                           &numOfRequestsInParallel);
        
        /* Checking if there are no waiting requests */
        if (status != TI_OK)
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": There are no waiting requests in the queue\n");

            return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
        }

        /* Checking validity of request/s */
        valid = measurementMgr_isRequestValid(pMeasurementMgr, pRequestArr, 
                                numOfRequestsInParallel);

        /* Checking if the current request is Beacon Table */
        if( (numOfRequestsInParallel == 1) && 
            (pRequestArr[0]->Type == MSR_TYPE_BEACON_MEASUREMENT) &&
            (pRequestArr[0]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) )
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received Beacon Table request, building a report for it and continuing\n");

            pMeasurementMgr->buildReport(hMeasurementMgr, *(pRequestArr[0]), NULL);
            valid = TI_FALSE; /* In order to get the next request/s*/
        }
        
    } while (valid == TI_FALSE);
    
    
    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request(s) for activation:\n");

    for (index = 0; index < numOfRequestsInParallel; index++)
    {
        TRACE6(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": \n\nRequest #%d:\n Type: %d\n Measured Channel: %d (Serving Channel: %d)\n Scan Mode: %d\n Duration: %d\n\n", index+1, pRequestArr[index]->Type, pRequestArr[index]->channelNumber, pMeasurementMgr->servingChannelID, pRequestArr[index]->ScanMode, pRequestArr[index]->DurationTime);
    }

    /* Ignore requests if traffic intensity is high */
    if (measurementMgr_isTrafficIntensityHigherThanThreshold(pMeasurementMgr) == TI_TRUE)
    {
        TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Traffic intensity too high, giving up...\n");

        measurementMgr_rejectPendingRequests(pMeasurementMgr, MSR_REJECT_TRAFFIC_INTENSITY_TOO_HIGH);

        return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
    }

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request is Valid, about to start\n");
    
    pMeasurementMgr->measuredChannelID = pRequestArr[0]->channelNumber;
  
    /* Request resource from the SCR */
    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        MEASUREMENTMGR_EVENT_REQUEST_SCR, pMeasurementMgr);    
}