📄 scanp.nc
字号:
for (i=0; i<4; i++) // broadcast dest PAN ID + broadcast dest addr
m_txFrame->header->mhr[MHR_INDEX_ADDRESS + i] = 0xFF;
call FrameUtility.copyLocalExtendedAddressLE((uint8_t*) &(m_txFrame->header->mhr[MHR_INDEX_ADDRESS + i]));
m_txFrame->headerLen = 15;
m_payload[0] = CMD_FRAME_ORPHAN_NOTIFICATION;
m_txFrame->payloadLen = 1;
break;
}
nextIteration();
}
void nextIteration()
{
ieee154_phyChannelsSupported_t supportedChannels = call MLME_GET.phyChannelsSupported();
uint32_t currentChannelBit = (uint32_t) 1 << m_currentChannelNum;
error_t radioStatus = SUCCESS;
if (!m_terminateScan){
while (m_currentChannelNum <= LAST_CHANNEL &&
!(m_scanChannels & currentChannelBit & supportedChannels)){
m_currentChannelNum++;
currentChannelBit <<= 1;
}
}
if (m_currentChannelNum <= LAST_CHANNEL && !m_terminateScan) {
// scan the next channel
call MLME_SET.phyCurrentChannel(m_currentChannelNum);
dbg_serial("ScanP", "Scanning channel %lu...\n", (uint32_t) m_currentChannelNum);
switch (m_scanType) {
case PASSIVE_SCAN:
radioStatus = call RadioRx.enableRx(0, 0);
break;
case ACTIVE_SCAN: // fall through
case ORPHAN_SCAN:
radioStatus = call RadioTx.transmit(m_txFrame, NULL, 0);
break;
case ENERGY_DETECTION_SCAN:
radioStatus = call EnergyDetection.start(m_scanDuration);
break;
}
ASSERT(radioStatus == SUCCESS);
} else {
// we're done
ieee154_status_t result = IEEE154_SUCCESS;
uint32_t unscannedChannels = 0;
if (m_terminateScan){
// Scan operation terminated because the max.
// number of PAN descriptors/ED samples was reached.
// Check if there are channels that were unscanned.
// In active/passive scan we consider a channel
// unscanned if it was not completely scanned.
if (m_scanType == PASSIVE_SCAN || m_scanType == ACTIVE_SCAN)
currentChannelBit >>= 1; // last (partially) scanned channel
while (!(currentChannelBit & INVALID_CHANNEL_BITMASK) &&
(m_scanChannels & currentChannelBit)){
unscannedChannels |= currentChannelBit;
currentChannelBit <<= 1;
}
if (unscannedChannels) // some channels were not (completely) scanned
result = IEEE154_LIMIT_REACHED;
} else if (m_scanType != ENERGY_DETECTION_SCAN && !m_resultIndex)
result = IEEE154_NO_BEACON;
if (m_scanType == PASSIVE_SCAN || m_scanType == ACTIVE_SCAN)
call MLME_SET.macPANId(m_PANID);
if (m_txFrame != NULL) {
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) m_txFrame->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(m_txFrame);
}
m_txFrame = NULL;
if (call RadioToken.isOwner())
call RadioToken.release();
m_busy = FALSE;
dbg_serial("ScanP", "MLME_SCAN.confirm()\n");
signal MLME_SCAN.confirm (
result,
m_scanType,
IEEE154_SUPPORTED_CHANNELPAGE,
unscannedChannels,
(m_scanType == ENERGY_DETECTION_SCAN) ? m_resultIndex : 0,
(m_scanType == ENERGY_DETECTION_SCAN) ? (int8_t*) m_resultList : NULL,
((m_scanType == ACTIVE_SCAN ||
m_scanType == PASSIVE_SCAN) && call MLME_GET.macAutoRequest()) ? m_resultIndex : 0,
((m_scanType == ACTIVE_SCAN ||
m_scanType == PASSIVE_SCAN) && call MLME_GET.macAutoRequest()) ? (ieee154_PANDescriptor_t*) m_resultList : NULL);
}
dbg_serial_flush();
}
async event void RadioRx.enableRxDone()
{
post startTimerTask();
}
/* ----------------------- EnergyDetection ----------------------- */
event void EnergyDetection.done(error_t status, int8_t EnergyLevel)
{
if (status == SUCCESS && m_resultListNumEntries)
((uint8_t*) m_resultList)[m_resultIndex++] = EnergyLevel;
if (m_resultIndex == m_resultListNumEntries)
m_terminateScan = TRUE; // done
if (call RadioOff.off() == EALREADY)
signal RadioOff.offDone();
}
/* ----------------------- Active/Orphan scan ----------------------- */
async event void RadioTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result)
{
ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
}
/* -------- Receive events (for Active/Passive/Orphan scan) -------- */
event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
if (!m_busy)
return frame;
if (m_scanType == ORPHAN_SCAN) {
uint8_t *payload = call Frame.getPayload(frame);
if (!m_resultIndex)
if ((MHR(frame)[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD &&
payload[0] == CMD_FRAME_COORDINATOR_REALIGNMENT) {
// Sect. 7.5.4.3: "the device shall update its MAC PIB with the PAN
// information contained in the coordinator realignment command"
call MLME_SET.macPANId( *((nxle_uint16_t*) &payload[1]) );
call MLME_SET.macCoordShortAddress( *((nxle_uint16_t*) &payload[3]) );
call MLME_SET.phyCurrentChannel( *((nxle_uint16_t*) &payload[5]) );
call MLME_SET.macShortAddress( *((nxle_uint16_t*) &payload[6]) );
m_resultIndex++;
dbg_serial("ScanP", "Received coordinator realignment frame.\n");
m_terminateScan = TRUE;
call RadioOff.off();
}
} else if ((((ieee154_header_t*) frame->header)->mhr[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON) {
// PASSIVE_SCAN / ACTIVE_SCAN:
// A beacon frame containing a non-empty payload is always signalled
// to the next higher layer (regardless of the value of macAutoRequest);
// when macAutoRequest is set to TRUE, then the beacon is always
// stored in the PAN Descriptor list (see 7.1.11.2.1 - Table 68)
if (!call MLME_GET.macAutoRequest())
return signal MLME_BEACON_NOTIFY.indication (frame);
else if (m_resultIndex >= m_resultListNumEntries) {
m_terminateScan = TRUE;
call RadioOff.off();
} else if (call BeaconFrame.parsePANDescriptor(
frame,
m_currentChannelNum,
IEEE154_SUPPORTED_CHANNELPAGE,
&((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex]) == SUCCESS) {
// check uniqueness: PAN ID and source address must
// not be found in a previously received beacon
uint8_t i;
ieee154_PANDescriptor_t* descriptor = (ieee154_PANDescriptor_t*) m_resultList;
dbg_serial("ScanP", "Received beacon, source: 0x%lx, channel: %lu.\n",
(uint32_t) descriptor[m_resultIndex].CoordAddress.shortAddress, (uint32_t) m_currentChannelNum);
for (i=0; i<m_resultIndex; i++)
if (descriptor[i].CoordPANId == descriptor[m_resultIndex].CoordPANId &&
descriptor[i].CoordAddrMode == descriptor[m_resultIndex].CoordAddrMode)
if ((descriptor[i].CoordAddrMode == ADDR_MODE_SHORT_ADDRESS &&
descriptor[i].CoordAddress.shortAddress ==
descriptor[m_resultIndex].CoordAddress.shortAddress) ||
(descriptor[i].CoordAddrMode == ADDR_MODE_EXTENDED_ADDRESS &&
descriptor[i].CoordAddress.extendedAddress ==
descriptor[m_resultIndex].CoordAddress.extendedAddress))
break; // not unique
if (i == m_resultIndex)
m_resultIndex++; // was unique
}
if (call BeaconFrame.getBeaconPayloadLength(frame) > 0)
return signal MLME_BEACON_NOTIFY.indication (frame);
} // PASSIVE_SCAN / ACTIVE_SCAN
return frame;
}
/* ----------------------- Common ----------------------- */
task void startTimerTask()
{
call ScanTimer.startOneShot(m_scanDuration);
}
event void ScanTimer.fired()
{
call RadioOff.off();
}
async event void RadioOff.offDone()
{
if (m_currentChannelNum == 0)
post continueScanRequestTask();
else {
m_currentChannelNum++;
post nextIterationTask();
}
}
task void nextIterationTask()
{
nextIteration();
}
async command token_requested_t IsRadioTokenRequested.getNow(){ return m_busy;}
async event void RadioToken.transferredFrom(uint8_t id){ ASSERT(0);}
default event message_t* MLME_BEACON_NOTIFY.indication (message_t *beaconFrame) {return beaconFrame;}
default event void MLME_SCAN.confirm (
ieee154_status_t status,
uint8_t ScanType,
uint8_t ChannelPage,
uint32_t UnscannedChannels,
uint8_t EnergyDetectListNumEntries,
int8_t* EnergyDetectList,
uint8_t PANDescriptorListNumEntries,
ieee154_PANDescriptor_t* PANDescriptorList) {}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -