} else if (security && security->SecurityLevel) {
status = IEEE154_UNSUPPORTED_SECURITY;
} if ((ScanType > 3) || (ScanType < 3 && ScanDuration > 14) ||
- (ChannelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
- !(supportedChannels & ScanChannels) ||
- ((ScanType != ORPHAN_SCAN) &&
- ((EnergyDetectListNumEntries && PANDescriptorListNumEntries) ||
+ (ChannelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
+ !(supportedChannels & ScanChannels) ||
+ ((ScanType != ORPHAN_SCAN) &&
+ ((EnergyDetectListNumEntries && PANDescriptorListNumEntries) ||
(EnergyDetectList != NULL && PANDescriptorList != NULL) ||
(EnergyDetectListNumEntries && EnergyDetectList == NULL) ||
(PANDescriptorListNumEntries && PANDescriptorList == NULL)))) {
status = IEEE154_INVALID_PARAMETER;
- } else if (ScanType != ENERGY_DETECTION_SCAN &&
- !(m_txFrame = call TxFramePool.get())) {
+ } else if ((ScanType == ACTIVE_SCAN || ScanType == ORPHAN_SCAN) &&
+ ((m_txFrame = call TxFramePool.get()) == NULL)) {
status = IEEE154_TRANSACTION_OVERFLOW;
- } else if (ScanType != ENERGY_DETECTION_SCAN &&
- !(txControl = call TxControlPool.get())) {
+ } else if ((ScanType == ACTIVE_SCAN || ScanType == ORPHAN_SCAN) &&
+ ((txControl = call TxControlPool.get()) == NULL)) {
call TxFramePool.put(m_txFrame);
m_txFrame = NULL;
status = IEEE154_TRANSACTION_OVERFLOW;
} else {
- m_txFrame->header = &txControl->header;
- m_txFrame->payload = m_payload;
- m_txFrame->metadata = &txControl->metadata;
+ if (m_txFrame != NULL){
+ m_txFrame->header = &txControl->header;
+ m_txFrame->payload = m_payload;
+ m_txFrame->metadata = &txControl->metadata;
+ }
m_busy = TRUE;
m_scanType = ScanType;
m_scanChannels = ScanChannels;
uint32_t unscannedChannels = 0;
if (m_terminateScan){
- // scan operation terminated prematurely because the max.
- // number of PAN descriptors/ED samples was reached
- result = IEEE154_LIMIT_REACHED;
-
- // mark the channel on which we received the last beacon
- // as unscanned, because it was not completely scanned
+ // 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;
+ 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) {
((uint8_t*) m_resultList)[m_resultIndex++] = EnergyLevel;
if (m_resultIndex == m_resultListNumEntries)
m_terminateScan = TRUE; // done
- call RadioOff.off();
+ if (call RadioOff.off() == EALREADY)
+ signal RadioOff.offDone();
}
/* ----------------------- Active/Orphan scan ----------------------- */
{
if (!m_busy)
return frame;
+
if (m_scanType == ORPHAN_SCAN) {
if (!m_resultIndex)
if ((MHR(frame)[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD &&
call RadioOff.off();
}
} else if ((((ieee154_header_t*) frame->header)->mhr[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON) {
- // PASSIVE_SCAN / ACTIVE_SCAN
+
+ // 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) {
IEEE154_SUPPORTED_CHANNELPAGE,
&((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex]) == SUCCESS) {
- // check uniqueness: both PAN ID and source address must not be in a previously received beacon
+ // 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);
- if (m_resultIndex)
- 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))
- return frame; // not unique
- m_resultIndex++; // was unique
+ 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;
}