📄 mac_scan.c
字号:
// No match
return FALSE;
} // mscPanDescriptorExists
//-------------------------------------------------------------------------------------------------------
// BOOL mscSetNextChannel(void)
//
// DESCRIPTION:
// Finds the next valid channel during scan (changes the mscInfo.currentChannel variable), and
// updates the unscanned channels mask.
//
// RETURN VALUE:
// BOOL
// FALSE when there are no more channels to scan.
//-------------------------------------------------------------------------------------------------------
ROOT BOOL mscSetNextChannel(void) {
UINT8 n;
DWORD bitmask = 0x00000001;
// Go through the channels
mscInfo.currentChannel++;
for (n = 0; n < 27; n++) {
if (n >= mscInfo.currentChannel) {
if (bitmask & mscInfo.scanChannels) {
mscInfo.currentChannel = n;
mscInfo.pScanResult->unscannedChannels &= ~bitmask;
return TRUE;
}
}
bitmask = bitmask << 1;
}
return FALSE;
} // mscSetNextChannel
//-------------------------------------------------------------------------------------------------------
// void mscChannelTimeout(void)
//
// DESCRIPTION:
// Callback used by the scanning mechanism to indicate that the current channel has been finished.
//-------------------------------------------------------------------------------------------------------
void mscChannelTimeout(void) NEAR {
mscInfo.channelComplete = TRUE;
} // mscChannelTimeout
//-------------------------------------------------------------------------------------------------------
// void mscChannelTimeout(void)
//
// DESCRIPTION:
// This task implements the scan state machine.
//
// TASK DATA:
// 0
//-------------------------------------------------------------------------------------------------------
void mscScanProcedure(MAC_TASK_INFO *pTask) NEAR {
INT8 maxRssi;
MAC_STATE_TYPE macState = MAC_STATE_DEFAULT;
switch (pTask->state) {
case MSC_STATE_INITIALIZE_SCAN:
// If the state cannot be switched now, then reschedule this task (move it to the back of the
// queue) to avoid potential deadlock...
switch (mscInfo.scanType) {
case ENERGY_SCAN: macState = MAC_STATE_ENERGY_SCAN; break;
case PASSIVE_SCAN:
case ACTIVE_SCAN: macState = MAC_STATE_ACTIVE_OR_PASSIVE_SCAN; break;
case ORPHAN_SCAN: macState = MAC_STATE_ORPHAN_SCAN; break;
}
if (!macSetState(macState)) {
mschRescheduleTask(pTask, MSC_STATE_INITIALIZE_SCAN);
break;
}
// Configure CC2430 for scanning
if (mscInfo.scanType != ORPHAN_SCAN) {
DISABLE_GLOBAL_INT(); // TBD: Can this line be removed?
WRITE_RFR16(PANID, 0xFFFF);
}
// Increment the RX on counter, so that other events don't turn it off
mrxIncrOnCounter();
pTask->state = MSC_STATE_UNREQUEST_INDIRECT;
break;
case MSC_STATE_UNREQUEST_INDIRECT:
// At this point we can be sure that RX has been shut down, that the RX engine is not running, including
// the high-priority processing tasks. There are no direct packet transmissions in progress, because
// that would have blocked this task. The beacon transmission and reception tasks, and the force RX off
// function are blocked by the MAC state.
#if MAC_OPT_FFD
// Unrequest all indirect packets to avoid that the miqTransmitRequestedPackets() function eats up the
// whole task pool (requested packets are usually transmitted in between).
miqUnrequestAll();
#endif
// Remove invalid channels from the mask, and go to the first channel to be scanned
mscInfo.pScanResult->unscannedChannels = mscInfo.scanChannels;
mscInfo.scanChannels &= MSC_VALID_CHANNELS;
mscInfo.pScanResult->resultListSize = 0;
mscInfo.currentChannel = 0;
mscInfo.oldPhyCurrentChannel = ppib.phyCurrentChannel;
if (mscSetNextChannel()) {
pTask->state = MSC_STATE_SET_CHANNEL;
} else {
pTask->state = MSC_STATE_FINISH;
}
break;
case MSC_STATE_SET_CHANNEL:
// Set the timer which will tell us when to move on to the next channel
mscInfo.channelComplete = FALSE;
// Set the new channel and turn on RX
msupSetChannel(mscInfo.currentChannel, TRUE);
// Set the channel timeout
switch (mscInfo.scanType) {
case ENERGY_SCAN:
case PASSIVE_SCAN:
mtimSetCallback(mscChannelTimeout, ((UINT32) aBaseSuperframeDuration / (UINT32) aUnitBackoffPeriod) * (((UINT32) 1 << mscInfo.scanDuration) + 1));
break;
case ACTIVE_SCAN:
case ORPHAN_SCAN:
// The channel timeout is set by mtxFinishTransmission (when the packet has been transmitted)
break;
}
// Jump to the next state
switch (mscInfo.scanType) {
case ENERGY_SCAN: pTask->state = MSC_STATE_E_SAMPLE; break;
case ACTIVE_SCAN: pTask->state = MSC_STATE_A_TX_BEACON_REQUEST; break;
case PASSIVE_SCAN: pTask->state = MSC_STATE_APO_WAIT; break;
case ORPHAN_SCAN: pTask->state = MSC_STATE_O_TX_ORPHAN_NOTIFICATION; break;
}
break;
case MSC_STATE_E_SAMPLE:
// Reset the peak value
maxRssi = -128;
// Continuously update the RSSI peak value
do {
maxRssi = MAX(RSSIL, maxRssi);
} while (!(mscInfo.channelComplete));
// Add the peak value to the energy detection list
mscInfo.pScanResult->list.pEnergyDetectList[mscInfo.pScanResult->resultListSize++] = RSSI_2_ED(maxRssi);
pTask->state = MSC_STATE_NEXT_CHANNEL;
break;
case MSC_STATE_A_TX_BEACON_REQUEST:
// Transmit a beacon request (the channel listening timeout is set by mtxFinishTransmission)
if (mscTransmitBeaconRequest()) {
mschRescheduleTask(pTask, MSC_STATE_APO_WAIT);
} else {
pTask->state = MSC_STATE_APO_WAIT;
}
break;
case MSC_STATE_O_TX_ORPHAN_NOTIFICATION:
// Transmit an orphan notification (the channel listening timeout is set by mtxFinishTransmission)
if (mscTransmitOrphanNotification()) {
mschRescheduleTask(pTask, MSC_STATE_APO_WAIT);
} else {
pTask->state = MSC_STATE_APO_WAIT;
}
break;
case MSC_STATE_APO_WAIT:
// Wait for the active or passive scan to complete
while (!mscInfo.channelComplete && (macInfo.state != MAC_STATE_ORPHAN_REALIGNED));
pTask->state = MSC_STATE_NEXT_CHANNEL;
break;
case MSC_STATE_NEXT_CHANNEL:
// Finish, or jump to the next channel
if ((macInfo.state != MAC_STATE_ORPHAN_REALIGNED) && (macInfo.state != MAC_STATE_SCAN_RESULT_BUFFER_FULL)) {
if (mscSetNextChannel()) {
pTask->state = MSC_STATE_SET_CHANNEL;
} else {
pTask->state = MSC_STATE_FINISH;
}
} else {
pTask->state = MSC_STATE_FINISH;
}
break;
case MSC_STATE_FINISH:
// Indicate that the scan is complete
if (macInfo.state == MAC_STATE_ORPHAN_REALIGNED) {
mscInfo.scanStatus = MSC_STATUS_ORPHAN_REALIGNED;
} else {
mscInfo.scanStatus = MSC_STATUS_FINISHED;
}
// Return to normal operation
macSetState(MAC_STATE_DEFAULT);
// Restore CC2430 settings
if (mscInfo.scanType != ORPHAN_SCAN) {
DISABLE_GLOBAL_INT();
WRITE_RFR16(PANID, mpib.macPANId);
ENABLE_GLOBAL_INT();
}
// Restore the earlier RX state (could possibly mess up a transmission, but we don't care...)
mrxDecrOnCounter();
msupSetChannel(mscInfo.oldPhyCurrentChannel, TRUE);
// Remove the task
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
break;
}
} // mscScanProcedure
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -