1/* 2 * measurementMgr.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 35/***************************************************************************/ 36/* */ 37/* MODULE: measurementMgr.c */ 38/* PURPOSE: measurement Manager module file */ 39/* */ 40/***************************************************************************/ 41 42 43 44 45#define __FILE_ID__ FILE_ID_1 46#include "measurementMgr.h" 47#include "regulatoryDomainApi.h" 48#include "healthMonitor.h" 49#include "DrvMainModules.h" 50#include "siteMgrApi.h" 51#include "TrafficMonitorAPI.h" 52#include "smeApi.h" 53#include "sme.h" 54#ifdef XCC_MODULE_INCLUDED 55#include "XCCTSMngr.h" 56#endif 57#include "TWDriver.h" 58 59/* default measurement parameters */ 60#define MEASUREMENT_CAPABILITIES_NONE 0x00 61#define MEASUREMENT_CAPABILITIES_DOT11H 0x01 62#define MEASUREMENT_CAPABILITIES_XCC_RM 0x02 63 64 65#define MEASUREMENT_BEACON_INTERVAL_IN_MICRO_SEC 1024 66#define MEASUREMENT_MSEC_IN_MICRO 1000 67 68 69 70 71/********************************************************************************/ 72/* Internal functions prototypes. */ 73/********************************************************************************/ 74 75static void measurementMgr_releaseModule(measurementMgr_t *pMeasurementMgr); 76 77static TI_BOOL measurementMgr_isTrafficIntensityHigherThanThreshold(measurementMgr_t * pMeasurementMgr); 78 79static TI_BOOL measurementMgr_isRequestValid(TI_HANDLE hMeasurementMgr, MeasurementRequest_t *pRequestArr[], TI_UINT8 numOfRequest); 80 81static TI_BOOL measurementMgrSM_measureInProgress(TI_HANDLE hMeasurementMgr); 82 83 84 85 86 87/********************************************************************************/ 88/* Interface functions Implementation. */ 89/********************************************************************************/ 90 91 92/** 93 * Creates the Measurement Manager moodule. 94 * 95 * @param hOs A handle to the OS object. 96 * 97 * @date 16-Dec-2005 98 */ 99TI_HANDLE measurementMgr_create(TI_HANDLE hOs) 100{ 101 measurementMgr_t * pMeasurementMgr = NULL; 102 TI_STATUS status; 103 104 /* allocating the MeasurementMgr object */ 105 pMeasurementMgr = os_memoryAlloc(hOs, sizeof(measurementMgr_t)); 106 107 if (pMeasurementMgr == NULL) 108 return NULL; 109 110 os_memoryZero(hOs, pMeasurementMgr, sizeof(measurementMgr_t)); 111 pMeasurementMgr->hOs = hOs; 112 113 /* creating the Measurement SM */ 114 status = fsm_Create(pMeasurementMgr->hOs, &(pMeasurementMgr->pMeasurementMgrSm), 115 MEASUREMENTMGR_NUM_STATES , MEASUREMENTMGR_NUM_EVENTS); 116 if(status != TI_OK) 117 { 118 measurementMgr_releaseModule(pMeasurementMgr); 119 return NULL; 120 } 121 122 /* creating the sub modules of measurement module */ 123 124 /* creating Request Handler sub module */ 125 if( (pMeasurementMgr->hRequestH = requestHandler_create(hOs)) == NULL) 126 { 127 measurementMgr_releaseModule(pMeasurementMgr); 128 return NULL; 129 } 130 131 return(pMeasurementMgr); 132} 133 134 135 136 137 138/** 139 * Configures the Measurement Manager module. 140 * 141 * @param pStadHandles Handles to other modules the Measurement Manager needs. 142 * 143 * @date 16-Dec-2005 144 */ 145void measurementMgr_init (TStadHandlesList *pStadHandles) 146{ 147 measurementMgr_t *pMeasurementMgr = (measurementMgr_t *)(pStadHandles->hMeasurementMgr); 148 paramInfo_t param; 149 150 /* Init Handlers */ 151 pMeasurementMgr->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; 152 pMeasurementMgr->hXCCMngr = pStadHandles->hXCCMngr; 153 pMeasurementMgr->hSiteMgr = pStadHandles->hSiteMgr; 154 pMeasurementMgr->hTWD = pStadHandles->hTWD; 155 pMeasurementMgr->hMlme = pStadHandles->hMlmeSm; 156 pMeasurementMgr->hTrafficMonitor = pStadHandles->hTrafficMon; 157 pMeasurementMgr->hReport = pStadHandles->hReport; 158 pMeasurementMgr->hOs = pStadHandles->hOs; 159 pMeasurementMgr->hScr = pStadHandles->hSCR; 160 pMeasurementMgr->hApConn = pStadHandles->hAPConnection; 161 pMeasurementMgr->hTxCtrl = pStadHandles->hTxCtrl; 162 pMeasurementMgr->hTimer = pStadHandles->hTimer; 163 pMeasurementMgr->hSme = pStadHandles->hSme; 164 165 /* initialize variables to default values */ 166 pMeasurementMgr->Enabled = TI_TRUE; 167 pMeasurementMgr->Connected = TI_FALSE; 168 pMeasurementMgr->Capabilities = MEASUREMENT_CAPABILITIES_NONE; 169 pMeasurementMgr->Mode = MSR_MODE_NONE; 170 171 /* Getting management capability status */ 172 param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; 173 regulatoryDomain_getParam (pMeasurementMgr->hRegulatoryDomain, ¶m); 174 if (param.content.spectrumManagementEnabled) 175 { 176 pMeasurementMgr->Capabilities |= MEASUREMENT_CAPABILITIES_DOT11H; 177 } 178 179 /* Init Functions */ 180 pMeasurementMgr->parserFrameReq = NULL; 181 pMeasurementMgr->isTypeValid = NULL; 182 pMeasurementMgr->buildReport = NULL; 183 pMeasurementMgr->buildRejectReport = NULL; 184 pMeasurementMgr->sendReportAndCleanObj = NULL; 185 186 /* initialize variables */ 187 pMeasurementMgr->currentState = MEASUREMENTMGR_STATE_IDLE; 188 pMeasurementMgr->isModuleRegistered = TI_FALSE; 189 pMeasurementMgr->currentFrameType = MSR_FRAME_TYPE_NO_ACTIVE; 190 pMeasurementMgr->measuredChannelID = 0; 191 pMeasurementMgr->currentNumOfRequestsInParallel = 0; 192 193 /* config sub modules */ 194 RequestHandler_config(pMeasurementMgr->hRequestH, pStadHandles->hReport, pStadHandles->hOs); 195 196 /* Register to the SCR module */ 197 scr_registerClientCB(pMeasurementMgr->hScr, SCR_CID_XCC_MEASURE, measurementMgr_scrResponseCB, (TI_HANDLE)pMeasurementMgr); 198 199 measurementMgrSM_config ((TI_HANDLE)pMeasurementMgr); 200 201 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INIT , ": Measurement Manager configured successfully\n"); 202} 203 204 205TI_STATUS measurementMgr_SetDefaults (TI_HANDLE hMeasurementMgr, measurementInitParams_t * pMeasurementInitParams) 206{ 207 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 208#ifdef XCC_MODULE_INCLUDED 209 TI_UINT32 currAC; 210#endif 211 212 pMeasurementMgr->trafficIntensityThreshold = pMeasurementInitParams->trafficIntensityThreshold; 213 pMeasurementMgr->maxDurationOnNonServingChannel = pMeasurementInitParams->maxDurationOnNonServingChannel; 214 215 /* allocating the measurement Activation Delay timer */ 216 pMeasurementMgr->hActivationDelayTimer = tmr_CreateTimer (pMeasurementMgr->hTimer); 217 if (pMeasurementMgr->hActivationDelayTimer == NULL) 218 { 219 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, "measurementMgr_SetDefaults(): Failed to create hActivationDelayTimer!\n"); 220 return TI_NOK; 221 } 222 223#ifdef XCC_MODULE_INCLUDED 224 /* allocating the per AC TS Metrics report timers */ 225 for (currAC = 0; currAC < MAX_NUM_OF_AC; currAC++) 226 { 227 pMeasurementMgr->isTsMetricsEnabled[currAC] = TI_FALSE; 228 229 pMeasurementMgr->hTsMetricsReportTimer[currAC] = tmr_CreateTimer (pMeasurementMgr->hTimer); 230 if (pMeasurementMgr->hTsMetricsReportTimer[currAC] == NULL) 231 { 232 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, "measurementMgr_SetDefaults(): Failed to create hTsMetricsReportTimer!\n"); 233 return TI_NOK; 234 } 235 } 236 237 /* Check in the Registry if the station supports XCC RM */ 238 if (pMeasurementInitParams->XCCEnabled == XCC_MODE_ENABLED) 239 { 240 pMeasurementMgr->Capabilities |= MEASUREMENT_CAPABILITIES_XCC_RM; 241 } 242#endif 243 244 return TI_OK; 245} 246 247 248 249 250 251/** 252 * Sets the specified Measurement Manager parameter. 253 * 254 * @param hMeasurementMgr A handle to the Measurement Manager module. 255 * @param pParam The parameter to set. 256 * 257 * @date 16-Dec-2005 258 */ 259TI_STATUS measurementMgr_setParam(TI_HANDLE hMeasurementMgr, paramInfo_t * pParam) 260{ 261 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 262 263 switch (pParam->paramType) 264 { 265 case MEASUREMENT_ENABLE_DISABLE_PARAM: 266 { 267 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MEASUREMENT_ENABLE_DISABLE_PARAM <- %d\n", pParam->content.measurementEnableDisableStatus); 268 269 if (pParam->content.measurementEnableDisableStatus) 270 { 271 measurementMgr_enable(pMeasurementMgr); 272 } 273 else 274 { 275 measurementMgr_disable(pMeasurementMgr); 276 } 277 278 break; 279 } 280 281 case MEASUREMENT_TRAFFIC_THRESHOLD_PARAM: 282 { 283 if ((pParam->content.measurementTrafficThreshold >= MEASUREMENT_TRAFFIC_THRSHLD_MIN) && 284 (pParam->content.measurementTrafficThreshold <= MEASUREMENT_TRAFFIC_THRSHLD_MAX)) 285 { 286 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MEASUREMENT_TRAFFIC_THRESHOLD_PARAM <- %d\n", pParam->content.measurementTrafficThreshold); 287 288 pMeasurementMgr->trafficIntensityThreshold = pParam->content.measurementTrafficThreshold; 289 } 290 else 291 { 292 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Invalid value for MEASUREMENT_TRAFFIC_THRESHOLD_PARAM (%d)\n", pParam->content.measurementTrafficThreshold); 293 } 294 295 break; 296 } 297 298 299 case MEASUREMENT_MAX_DURATION_PARAM: 300 { 301 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MEASUREMENT_MAX_DURATION_PARAM <- %d\n", pParam->content.measurementMaxDuration); 302 303 pMeasurementMgr->maxDurationOnNonServingChannel = pParam->content.measurementMaxDuration; 304 305 break; 306 } 307 308 309 default: 310 { 311 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Specified parameter is not supported (%d)\n", pParam->paramType); 312 313 return PARAM_NOT_SUPPORTED; 314 } 315 316 } 317 318 return TI_OK; 319} 320 321 322 323 324 325/** 326 * Gets the specified parameter from the Measurement Manager. 327 * 328 * @param hMeasurementMgr A handle to the Measurement Manager module. 329 * @param pParam The parameter to get. 330 * 331 * @date 16-Dec-2005 332 */ 333TI_STATUS measurementMgr_getParam(TI_HANDLE hMeasurementMgr, paramInfo_t * pParam) 334{ 335 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 336 337 switch(pParam->paramType) 338 { 339 340 case MEASUREMENT_GET_STATUS_PARAM: 341 { 342 WLAN_OS_REPORT(("%s: \n\n", __FUNCTION__)); 343 WLAN_OS_REPORT(("MeasurementMgr Status Report:\n\n")); 344 345 WLAN_OS_REPORT(("Current State: %d\n\n", pMeasurementMgr->currentState)); 346 347 WLAN_OS_REPORT(("Connected: %d\n", pMeasurementMgr->Connected)); 348 WLAN_OS_REPORT(("Enabled: %d\n\n", pMeasurementMgr->Enabled)); 349 350 WLAN_OS_REPORT(("Mode: %d\n", pMeasurementMgr->Mode)); 351 WLAN_OS_REPORT(("Capabilities: %d\n\n", pMeasurementMgr->Capabilities)); 352 353 WLAN_OS_REPORT(("current Frame Type: %d\n", pMeasurementMgr->currentFrameType)); 354 WLAN_OS_REPORT(("Measured Channel: %d\n", pMeasurementMgr->measuredChannelID)); 355 WLAN_OS_REPORT(("Serving Channel: %d\n", pMeasurementMgr->servingChannelID)); 356 WLAN_OS_REPORT(("Traffic Intensity Threshold: %d\n", pMeasurementMgr->trafficIntensityThreshold)); 357 WLAN_OS_REPORT(("Max Duration on Nonserving Channel: %d\n", pMeasurementMgr->maxDurationOnNonServingChannel)); 358 359 break; 360 } 361 362 363 default: 364 { 365 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Specified parameter is not supported (%d)\n", pParam->paramType); 366 367 return PARAM_NOT_SUPPORTED; 368 } 369 370 } 371 372 return TI_OK; 373} 374 375 376 377 378 379 380/** 381 * Signals the Measurement Manager that the STA is connected. 382 * 383 * @param hMeasurementMgr A handle to the Measurement Manager module. 384 * 385 * @date 16-Dec-2005 386 */ 387TI_STATUS measurementMgr_connected(TI_HANDLE hMeasurementMgr) 388{ 389 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 390 391 /* checking if measurement is enabled */ 392 if (pMeasurementMgr->Mode == MSR_MODE_NONE) 393 return TI_OK; 394 395 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to connected.\n"); 396 397 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 398 MEASUREMENTMGR_EVENT_CONNECTED, pMeasurementMgr); 399} 400 401 402 403 404 405/** 406 * Signals the Measurement Manager that the STA is disconnected. 407 * 408 * @param hMeasurementMgr A handle to the Measurement Manager module. 409 * 410 * @date 16-Dec-2005 411 */ 412TI_STATUS measurementMgr_disconnected(TI_HANDLE hMeasurementMgr) 413{ 414 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 415 416 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to disconnected.\n"); 417 418 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 419 MEASUREMENTMGR_EVENT_DISCONNECTED, pMeasurementMgr); 420} 421 422 423 424 425/** 426 * Enables the Measurement Manager module. 427 * 428 * @date 10-Jan-2006 429 */ 430TI_STATUS measurementMgr_enable(TI_HANDLE hMeasurementMgr) 431{ 432 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 433 434 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to enabled.\n"); 435 436 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 437 MEASUREMENTMGR_EVENT_ENABLE, pMeasurementMgr); 438} 439 440 441 442 443 444/** 445 * Disables the Measurement Manager module. 446 * 447 * @date 10-Jan-2006 448 */ 449TI_STATUS measurementMgr_disable(TI_HANDLE hMeasurementMgr) 450{ 451 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 452 453 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr set to disabled.\n"); 454 455 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 456 MEASUREMENTMGR_EVENT_DISABLE, pMeasurementMgr); 457} 458 459 460 461 462 463/** 464 * Destroys the Measurement Manager module. 465 * 466 * @param hMeasurementMgr A handle to the Measurement Manager module. 467 * 468 * @date 16-Dec-2005 469 */ 470TI_STATUS measurementMgr_destroy(TI_HANDLE hMeasurementMgr) 471{ 472 measurementMgr_t *pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 473 TI_UINT32 initVec; 474 475 if (pMeasurementMgr == NULL) 476 return TI_OK; 477 478 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr is being destroyed\n"); 479 480 initVec = 0xFFFF; /* release everything */ 481 482 measurementMgr_releaseModule (pMeasurementMgr); 483 484 return TI_OK; 485} 486 487 488 489 490 491 492/** 493 * Sets the Measurement Mode. 494 * 495 * @param hMeasurementMgr A handle to the Measurement Manager module. 496 * @param capabilities The AP capabilities. 497 * @param pIeBuffer Pointer to the list of IEs. 498 * @param length Length of the IE list. 499 * 500 * @date 16-Dec-2005 501 */ 502TI_STATUS measurementMgr_setMeasurementMode(TI_HANDLE hMeasurementMgr, TI_UINT16 capabilities, 503 TI_UINT8 * pIeBuffer, TI_UINT16 length) 504{ 505 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 506 507 /* 508 * 11h Measurement is not supported in the current version. 509 */ 510/* if( (pMeasurementMgr->Capabilities & MEASUREMENT_CAPABILITIES_DOT11H) && 511 (capabilities & DOT11_SPECTRUM_MANAGEMENT) ) 512 { 513 pMeasurementMgr->Mode = MSR_MODE_SPECTRUM_MANAGEMENT; 514 } 515 else 516 { 517*/ 518#ifdef XCC_MODULE_INCLUDED 519 520 if(pMeasurementMgr->Capabilities & MEASUREMENT_CAPABILITIES_XCC_RM) 521 { 522 pMeasurementMgr->Mode = MSR_MODE_XCC; 523 } 524 else 525#endif 526 { 527 pMeasurementMgr->Mode = MSR_MODE_NONE; 528 } 529 530 531 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgr mode changed to: %d\n", pMeasurementMgr->Mode); 532 533 return TI_OK; 534} 535 536 537 538 539 540 541/** 542 * Called when a frame with type measurement request is received. 543 * 544 * @param hMeasurementMgr A handle to the Measurement Manager module. 545 * @param frameType The frame type. 546 * @param dataLen The length of the frame. 547 * @param pData A pointer to the frame's content. 548 * 549 * @date 16-Dec-2005 550 */ 551TI_STATUS measurementMgr_receiveFrameRequest(TI_HANDLE hMeasurementMgr, 552 EMeasurementFrameType frameType, 553 TI_INT32 dataLen, 554 TI_UINT8 * pData) 555{ 556 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 557 558 TMeasurementFrameRequest * frame = &(pMeasurementMgr->newFrameRequest); 559 TI_UINT16 currentFrameToken; 560 561 /* checking if measurement is enabled */ 562 if (pMeasurementMgr->Mode == MSR_MODE_NONE) 563 return TI_NOK; 564 565 /* ignore broadcast/multicast request if unicast request is active */ 566 if (frameType != MSR_FRAME_TYPE_UNICAST && pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) 567 { 568 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Broadcast/Multicast measurement frame has been ignored\n"); 569 570 return TI_NOK; 571 } 572 573 /* ignore broadcast request if multicast request is active */ 574 if (frameType == MSR_FRAME_TYPE_BROADCAST && pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_MULTICAST) 575 { 576 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Broadcast measurement frame has been ignored\n"); 577 578 return TI_NOK; 579 } 580 581 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame received\n"); 582 583 /* Parsing the Frame Request Header */ 584 pMeasurementMgr->parserFrameReq(hMeasurementMgr, pData, dataLen, 585 frame); 586 587 frame->frameType = frameType; 588 589 /* checking if the received token frame is the same as the one that is being processed */ 590 if ((requestHandler_getFrameToken(pMeasurementMgr->hRequestH, ¤tFrameToken) == TI_OK) 591 && (currentFrameToken == frame->hdr->dialogToken)) 592 { 593 os_memoryZero(pMeasurementMgr->hOs, &pMeasurementMgr->newFrameRequest, 594 sizeof(TMeasurementFrameRequest)); 595 596 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame token %d is identical to current frame token - ignoring frame\n", currentFrameToken); 597 598 return TI_NOK; 599 } 600 601 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement frame token is %d\n", frame->hdr->dialogToken); 602 603 /* Frame is Received for processing */ 604 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 605 MEASUREMENTMGR_EVENT_FRAME_RECV, pMeasurementMgr); 606} 607 608 609 610 611 612/** 613 * Activates the next measurement request. 614 * 615 * @param hMeasurementMgr A handle to the Measurement Manager module. 616 * 617 * @date 16-Dec-2005 618 */ 619TI_STATUS measurementMgr_activateNextRequest(TI_HANDLE hMeasurementMgr) 620{ 621 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 622 requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH; 623 MeasurementRequest_t * pRequestArr[MAX_NUM_REQ]; 624 TI_UINT8 numOfRequestsInParallel = 0; 625 TI_BOOL valid; 626 TI_UINT8 index; 627 628 /* Keep note of the time we started processing the request. this will be used */ 629 /* to give the measurementSRV a time frame to perform the measurement operation */ 630 pMeasurementMgr->currentRequestStartTime = os_timeStampMs(pMeasurementMgr->hOs); 631 632 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Timer started at %d, we have 20ms to begin measurement...\n", pMeasurementMgr->currentRequestStartTime); 633 634 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Looking for a valid request\n"); 635 636 do 637 { 638 TI_STATUS status; 639 640 if (numOfRequestsInParallel != 0) 641 { 642 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); 643 } 644 645 pRequestH->activeRequestID += numOfRequestsInParallel; 646 pRequestH->numOfWaitingRequests -= numOfRequestsInParallel; 647 648 for (index = 0; index < MAX_NUM_REQ; index++) 649 { 650 pRequestArr[index] = NULL; 651 } 652 numOfRequestsInParallel = 0; 653 654 /* Getting the next request/requests from the request handler */ 655 status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_FALSE, pRequestArr, 656 &numOfRequestsInParallel); 657 658 /* Checking if there are no waiting requests */ 659 if (status != TI_OK) 660 { 661 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": There are no waiting requests in the queue\n"); 662 663 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 664 MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr); 665 } 666 667 /* Checking validity of request/s */ 668 valid = measurementMgr_isRequestValid(pMeasurementMgr, pRequestArr, 669 numOfRequestsInParallel); 670 671 /* Checking if the current request is Beacon Table */ 672 if( (numOfRequestsInParallel == 1) && 673 (pRequestArr[0]->Type == MSR_TYPE_BEACON_MEASUREMENT) && 674 (pRequestArr[0]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) ) 675 { 676 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received Beacon Table request, building a report for it and continuing\n"); 677 678 pMeasurementMgr->buildReport(hMeasurementMgr, *(pRequestArr[0]), NULL); 679 valid = TI_FALSE; /* In order to get the next request/s*/ 680 } 681 682 } while (valid == TI_FALSE); 683 684 685 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request(s) for activation:\n"); 686 687 for (index = 0; index < numOfRequestsInParallel; index++) 688 { 689 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); 690 } 691 692 /* Ignore requests if traffic intensity is high */ 693 if (measurementMgr_isTrafficIntensityHigherThanThreshold(pMeasurementMgr) == TI_TRUE) 694 { 695 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Traffic intensity too high, giving up...\n"); 696 697 measurementMgr_rejectPendingRequests(pMeasurementMgr, MSR_REJECT_TRAFFIC_INTENSITY_TOO_HIGH); 698 699 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 700 MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr); 701 } 702 703 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request is Valid, about to start\n"); 704 705 pMeasurementMgr->measuredChannelID = pRequestArr[0]->channelNumber; 706 707 /* Request resource from the SCR */ 708 return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 709 MEASUREMENTMGR_EVENT_REQUEST_SCR, pMeasurementMgr); 710} 711 712 713 714void measurementMgr_rejectPendingRequests(TI_HANDLE hMeasurementMgr, EMeasurementRejectReason rejectReason) 715{ 716 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 717 requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH; 718 MeasurementRequest_t * pRequestArr[MAX_NUM_REQ]; 719 TI_UINT8 numOfRequestsInParallel; 720 721 /* reject all pending measurement requests */ 722 while (requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_TRUE, 723 pRequestArr, &numOfRequestsInParallel) == TI_OK) 724 { 725 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Rejecting pending request (activeRequestID = %d)...\n", pRequestH->activeRequestID); 726 727 pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, 728 numOfRequestsInParallel, rejectReason); 729 730 pRequestH->activeRequestID += numOfRequestsInParallel; 731 } 732} 733 734 735 736 737 738/********************************************************************************/ 739/* Callback functions Implementation. */ 740/********************************************************************************/ 741 742 743/** 744 * The callback called by the MeasurementSRV module when then 745 * measurement operation has ended. 746 * 747 * @param clientObj A handle to the Measurement Manager module. 748 * @param msrReply An array of replies sent by the MeasurementSRV module, 749 * where each reply contains the result of a single measurement request. 750 * 751 * @date 01-Jan-2006 752 */ 753void measurementMgr_MeasurementCompleteCB(TI_HANDLE clientObj, TMeasurementReply * msrReply) 754{ 755 measurementMgr_t *pMeasurementMgr = (measurementMgr_t *) clientObj; 756 TI_UINT8 index; 757 758 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Building reports for measurement requests\n"); 759 760 /* build a report for each measurement request/reply pair */ 761 for (index = 0; index < msrReply->numberOfTypes; index++) 762 { 763 pMeasurementMgr->buildReport(pMeasurementMgr, *(pMeasurementMgr->currentRequest[index]), &msrReply->msrTypes[index]); 764 } 765 766 measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 767 MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr); 768} 769 770 771/** 772 * The callback called when the SCR responds to the SCR request. 773 * 774 * @param hClient A handle to the Measurement Manager module. 775 * @param requestStatus The request's status 776 * @param eResource The resource for which the CB is issued 777 * @param pendReason The reason of a PEND status. 778 * 779 * @date 01-Jan-2006 780 */ 781void measurementMgr_scrResponseCB(TI_HANDLE hClient, EScrClientRequestStatus requestStatus, 782 EScrResourceId eResource, EScePendReason pendReason ) 783{ 784 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hClient; 785 measurementMgrSM_Events event; 786 787 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": SCR callback entered\n"); 788 789 /* If the SM is in a state where it waits for the CB, status of RUN */ 790 /* results in the SM asking the measurementSRV to start measurement; */ 791 /* otherwise we got an ABORT or a PEND reason worse than the one we */ 792 /* got when calling the SCR, so the SM aborts the measurement */ 793 if (pMeasurementMgr->currentState == MEASUREMENTMGR_STATE_WAITING_FOR_SCR) 794 { 795 if (requestStatus == SCR_CRS_RUN) 796 { 797 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status RUN, running...\n"); 798 799 event = MEASUREMENTMGR_EVENT_SCR_RUN; 800 } 801 else 802 { 803 if (requestStatus == SCR_CRS_PEND) 804 { 805 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status PEND with reason %d, aborting...\n", pendReason); 806 } 807 else 808 { 809 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status ABORT/FW_RESET, aborting...\n"); 810 } 811 812 event = MEASUREMENTMGR_EVENT_ABORT; 813 } 814 } 815 else 816 { 817 /* This can only occur if FW reset occurs or when higher priority client is running. */ 818 819 if (requestStatus == SCR_CRS_FW_RESET) 820 { 821 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received SCR status FW_RESET\n"); 822 823 event = MEASUREMENTMGR_EVENT_FW_RESET; 824 } 825 else 826 { 827 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MeasurementMgrSM current state is %d (which isn't WAITING_FOR_SCR), aborting...\n", pMeasurementMgr->currentState); 828 829 event = MEASUREMENTMGR_EVENT_ABORT; 830 } 831 } 832 833 measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 834 event, pMeasurementMgr); 835} 836 837 838 839 840 841 842/** 843 * The callback called by the MLME. 844 * 845 * @param hMeasurementMgr A handle to the Measurement Manager module. 846 * 847 * @date 01-Jan-2006 848 */ 849void measurementMgr_mlmeResultCB(TI_HANDLE hMeasurementMgr, TMacAddr * bssid, mlmeFrameInfo_t * frameInfo, 850 TRxAttr * pRxAttr, TI_UINT8 * buffer, TI_UINT16 bufferLength) 851{ 852 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 853 TScanFrameInfo tScanFrameInfo; 854 855 if (measurementMgrSM_measureInProgress(pMeasurementMgr) == TI_FALSE) 856 { 857 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION , "measurementMgr_mlmeResultCB: measurement not in progress, return\n"); 858 return; 859 } 860 861 862 /* erroneous frames are notifed to the measurmenet manager to update counter 863 (add counter sometimes in the future) Look at: scanCncn_ScanCompleteNotificationCB and 864 scanCncn_MlmeResultCB */ 865 if (NULL == bssid) 866 { 867 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION , "measurementMgr_mlmeResultCB: received an empty frame notification from MLME\n"); 868 return; 869 } 870 871 if (pMeasurementMgr == NULL || pRxAttr == NULL) 872 { 873 if(pMeasurementMgr != NULL) 874 { 875 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": MLME callback called with NULL object\n"); 876 } 877 return; 878 } 879 880 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MLME callback entered\n"); 881 882 /* build the scan frame info object */ 883 tScanFrameInfo.bssId = bssid; 884 tScanFrameInfo.band = (ERadioBand)pRxAttr->band; 885 tScanFrameInfo.channel = pRxAttr->channel; 886 tScanFrameInfo.parsedIEs = frameInfo; 887 tScanFrameInfo.rate = pRxAttr->Rate; 888 tScanFrameInfo.rssi = pRxAttr->Rssi; 889 tScanFrameInfo.snr = pRxAttr->SNR; 890 tScanFrameInfo.staTSF = pRxAttr->TimeStamp; 891 tScanFrameInfo.buffer = buffer; 892 tScanFrameInfo.bufferLength = bufferLength; 893 894 /* update the driver (SME) result table */ 895 sme_MeansurementScanResult (pMeasurementMgr->hSme, SCAN_CRS_RECEIVED_FRAME, &tScanFrameInfo); 896 897 TRACE8(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": MLME Frame: Subtype = %d, MAC = %x-%x-%x-%x-%x-%x, RSSI = %d\n", frameInfo->subType, (*bssid)[0], (*bssid)[1], (*bssid)[2], (*bssid)[3], (*bssid)[4], (*bssid)[5], pRxAttr->Rssi); 898} 899 900 901/********************************************************************************/ 902/* Internal functions Implementation. */ 903/********************************************************************************/ 904 905 906/** 907 * Releases the module's allocated objects according to the given init vector. 908 * 909 * @param pMeasurementMgr A handle to the Measurement Manager module. 910 * @param initVec The init vector with a bit set for each allocated object. 911 * 912 * @date 01-Jan-2006 913 */ 914static void measurementMgr_releaseModule (measurementMgr_t * pMeasurementMgr) 915{ 916#ifdef XCC_MODULE_INCLUDED 917 TI_UINT32 currAC; 918#endif 919 920 if (pMeasurementMgr->hActivationDelayTimer) 921 { 922 tmr_DestroyTimer (pMeasurementMgr->hActivationDelayTimer); 923 } 924 925#ifdef XCC_MODULE_INCLUDED 926 for (currAC = 0; currAC < MAX_NUM_OF_AC; currAC++) 927 { 928 if (pMeasurementMgr->hTsMetricsReportTimer[currAC]) 929 { 930 tmr_DestroyTimer (pMeasurementMgr->hTsMetricsReportTimer[currAC]); 931 } 932 } 933#endif 934 935 if (pMeasurementMgr->pMeasurementMgrSm) 936 { 937 fsm_Unload(pMeasurementMgr->hOs, pMeasurementMgr->pMeasurementMgrSm); 938 } 939 940 if (pMeasurementMgr->hRequestH) 941 { 942 requestHandler_destroy(pMeasurementMgr->hRequestH); 943 } 944 945 os_memoryFree(pMeasurementMgr->hOs, pMeasurementMgr, sizeof(measurementMgr_t)); 946} 947 948 949 950/** 951 * Checks whether the traffic intensity, i.e. number of packets per seconds, is higher 952 * than the preconfigured threshold. 953 * 954 * @param pMeasurementMgr A handle to the Measurement Manager module. 955 * 956 * @return True iff the traffic intensity is high 957 * 958 * @date 01-Jan-2006 959 */ 960static TI_BOOL measurementMgr_isTrafficIntensityHigherThanThreshold(measurementMgr_t * pMeasurementMgr) 961{ 962 TI_BOOL trafficIntensityHigh = TI_FALSE; 963 int pcksPerSec; 964 965 pcksPerSec = TrafficMonitor_GetFrameBandwidth(pMeasurementMgr->hTrafficMonitor); 966 967 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": pcksPerSec = %d\n", pcksPerSec); 968 969 if (pcksPerSec >= pMeasurementMgr->trafficIntensityThreshold) 970 trafficIntensityHigh = TI_TRUE; 971 972 return trafficIntensityHigh; 973} 974 975 976 977 978/** 979 * Checks whether the given measurement request is valid. 980 * 981 * @param hMeasurementMgr A handle to the Measurement Manager module. 982 * @param pRequestArr The measurement request. 983 * @param numOfRequest Number of type requests 984 * 985 * @return True iff the request is valid 986 * 987 * @date 01-Jan-2006 988 */ 989static TI_BOOL measurementMgr_isRequestValid(TI_HANDLE hMeasurementMgr, MeasurementRequest_t *pRequestArr[], 990 TI_UINT8 numOfRequest) 991{ 992 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; 993 TI_UINT8 requestIndex; 994 paramInfo_t param; 995 996 /* Checking validity of the measured channel number */ 997 param.content.channel = pRequestArr[0]->channelNumber; 998 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; 999 regulatoryDomain_getParam(pMeasurementMgr->hRegulatoryDomain, ¶m); 1000 if ( !param.content.bIsChannelSupprted ) 1001 { 1002 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request rejected due to invalid channel\n"); 1003 1004 if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) 1005 pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, 1006 MSR_REJECT_INVALID_CHANNEL); 1007 1008 return TI_FALSE; 1009 } 1010 else 1011 { 1012 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request channel is Valid\n"); 1013 } 1014 1015 TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Starting to check each request:\n"); 1016 1017 /* Check Validity of each request */ 1018 for (requestIndex = 0; requestIndex < numOfRequest; requestIndex++) 1019 { 1020 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Checking request #%d:\n", requestIndex+1); 1021 1022 /* Checking validity of the Request Type */ 1023 if (pMeasurementMgr->isTypeValid(hMeasurementMgr, pRequestArr[requestIndex]->Type, 1024 pRequestArr[requestIndex]->ScanMode) == TI_FALSE) 1025 { 1026 TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request rejected due to invalid measurement type of request #%d (type = %d)\n", requestIndex+1, pRequestArr[requestIndex]->Type); 1027 1028 if(pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) 1029 pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, 1030 MSR_REJECT_INVALID_MEASUREMENT_TYPE); 1031 1032 return TI_FALSE; 1033 } 1034 else 1035 { 1036 TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement type of request #%d is supported (type = %d)\n", requestIndex+1, pRequestArr[requestIndex]->Type); 1037 } 1038 1039 /* For measurement types different than Beacon Table */ 1040 if ((pRequestArr[requestIndex]->Type != MSR_TYPE_BEACON_MEASUREMENT) || 1041 (pRequestArr[requestIndex]->ScanMode != MSR_SCAN_MODE_BEACON_TABLE)) 1042 { 1043 /* Checking Measurement request's duration only when request is on a non-serving channel */ 1044 if (pMeasurementMgr->servingChannelID != pRequestArr[requestIndex]->channelNumber) 1045 { 1046 TI_UINT8 dtimPeriod; 1047 TI_UINT32 beaconInterval; 1048 TI_UINT32 dtimDuration; 1049 1050 1051 /* Checking duration doesn't exceed given max duration */ 1052 if (pRequestArr[requestIndex]->DurationTime > pMeasurementMgr->maxDurationOnNonServingChannel) 1053 { 1054 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request #%d rejected because duration exceeds maximum duration\n", requestIndex+1); 1055 1056 TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Duration = %d, MaxDurationOnNonServingChannel = %d\n", pRequestArr[requestIndex]->DurationTime, pMeasurementMgr->maxDurationOnNonServingChannel); 1057 1058 if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) 1059 pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, 1060 MSR_REJECT_DURATION_EXCEED_MAX_DURATION); 1061 1062 return TI_FALSE; 1063 } 1064 else 1065 { 1066 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Duration of request #%d doesn't exceed max duration\n", requestIndex+1); 1067 } 1068 1069 1070 /* Checking DTIM */ 1071 1072 /* Getting the DTIM count */ 1073 param.paramType = SITE_MGR_DTIM_PERIOD_PARAM; 1074 siteMgr_getParam(pMeasurementMgr->hSiteMgr, ¶m); 1075 dtimPeriod = param.content.siteMgrDtimPeriod; 1076 1077 /* Getting the beacon Interval */ 1078 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; 1079 siteMgr_getParam(pMeasurementMgr->hSiteMgr, ¶m); 1080 beaconInterval = param.content.beaconInterval; 1081 1082 dtimDuration = beaconInterval * MEASUREMENT_BEACON_INTERVAL_IN_MICRO_SEC/MEASUREMENT_MSEC_IN_MICRO*dtimPeriod; 1083 if (pRequestArr[requestIndex]->DurationTime > dtimDuration) 1084 { 1085 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_WARNING, ": Request rejected due to DTIM overlap of request #%d\n", requestIndex+1); 1086 1087 TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_WARNING, ": Duration = %d, DTIM Duration = %d\n", pRequestArr[requestIndex]->DurationTime, dtimDuration); 1088 1089 if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) 1090 pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, 1091 MSR_REJECT_DTIM_OVERLAP); 1092 1093 return TI_FALSE; 1094 } 1095 else 1096 { 1097 TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": DTIM of request #%d doesn't overlap\n", requestIndex+1); 1098 } 1099 } 1100 } 1101 } 1102 1103 return TI_TRUE; 1104} 1105 1106static TI_BOOL measurementMgrSM_measureInProgress(TI_HANDLE hMeasurementMgr) 1107{ 1108 measurementMgr_t * pMeasurementMgr = (measurementMgr_t *)hMeasurementMgr; 1109 1110 if (pMeasurementMgr->currentState == MEASUREMENTMGR_STATE_MEASURING) 1111 return TI_TRUE; 1112 1113 else 1114 return TI_FALSE; 1115} 1116 1117 1118