📄 beacontransmitp.nc
字号:
(m_beaconInterval>BEACON_PAYLOAD_UPDATE_INTERVAL) ? (m_beaconInterval - BEACON_PAYLOAD_UPDATE_INTERVAL): 0);
if (m_requestBitmap & REQUEST_CONFIRM_PENDING) {
m_requestBitmap &= ~REQUEST_CONFIRM_PENDING;
signal MLME_START.confirm(IEEE154_SUCCESS);
}
m_txState = S_TX_IDLE;
signal IEEE154TxBeaconPayload.beaconTransmitted();
dbg_serial_flush();
}
/* ----------------------- Beacon Payload ----------------------- */
/*
* All access to the payload fields in the beacon happen
* through a set of temporary variables/flags, and just before
* the frame is loaded into the radio these changes are
* written into the actual payload portion of the beacon frame.
*/
command error_t IEEE154TxBeaconPayload.setBeaconPayload(void *beaconPayload, uint8_t length)
{
if (length > IEEE154_aMaxBeaconPayloadLength)
return ESIZE;
else {
if (m_payloadState & MODIFIED_BEACON_PAYLOAD)
return EBUSY;
m_updateBeaconPayload = beaconPayload;
m_updateBeaconLength = length;
m_updateBeaconOffset = 0;
m_payloadState |= (MODIFIED_BEACON_PAYLOAD | MODIFIED_BEACON_PAYLOAD_NEW);
}
return SUCCESS;
}
command const void* IEEE154TxBeaconPayload.getBeaconPayload()
{
return &m_payload[IEEE154_aMaxBeaconOverhead];
}
command uint8_t IEEE154TxBeaconPayload.getBeaconPayloadLength()
{
return m_beaconFrame.payloadLen - (m_pendingAddrLen + m_pendingGtsLen + 2);
}
command error_t IEEE154TxBeaconPayload.modifyBeaconPayload(uint8_t offset, void *buffer, uint8_t bufferLength)
{
uint16_t totalLen = offset + bufferLength;
if (totalLen > IEEE154_aMaxBeaconPayloadLength ||
call IEEE154TxBeaconPayload.getBeaconPayloadLength() < totalLen)
return ESIZE;
else {
if (m_payloadState & MODIFIED_BEACON_PAYLOAD)
return EBUSY;
m_updateBeaconPayload = buffer;
m_updateBeaconOffset = offset;
m_updateBeaconLength = bufferLength;
m_payloadState |= MODIFIED_BEACON_PAYLOAD;
}
return SUCCESS;
}
event void PIBUpdate.notify[uint8_t attributeID](const void* attributeValue)
{
switch (attributeID)
{
case IEEE154_macAssociationPermit:
atomic m_payloadState |= MODIFIED_SF_SPEC;
break;
case IEEE154_macGTSPermit:
atomic m_payloadState |= MODIFIED_GTS_FIELD;
break;
default:
break;
}
}
event void PendingAddrSpecUpdated.notify(bool val)
{
atomic m_payloadState |= MODIFIED_PENDING_ADDR_FIELD;
}
event void GtsSpecUpdated.notify(bool val)
{
atomic m_payloadState |= MODIFIED_GTS_FIELD;
}
uint8_t getNumGtsSlots(uint8_t *gtsInfoField)
{
uint8_t i, num=0;
for (i=0; i<((gtsInfoField[0] & GTS_DESCRIPTOR_COUNT_MASK) >> GTS_DESCRIPTOR_COUNT_OFFSET); i++)
num += ((gtsInfoField[4+i*3] & GTS_LENGTH_MASK) >> GTS_LENGTH_OFFSET);
return num;
}
event void BeaconPayloadUpdateTimer.fired()
{
// in this order the MAC payload is updated:
// (1) pending addresses
// (2) GTS spec
// (3) SF spec
// (4) beacon payload (if there's enough time)
uint8_t len=0, *beaconSpecs = &m_payload[IEEE154_aMaxBeaconOverhead]; // going backwards
uint8_t beaconPayloadUpdated = 0, numGtsSlots = m_numGtsSlots;
atomic {
if (m_txState == S_TX_LOCKED)
{
dbg_serial("BeaconTransmitP", "BeaconPayloadUpdateTimer fired too late!\n");
return; // too late !
}
// (1) update pending addresses
if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD) {
len = call PendingAddrWrite.getLength();
beaconSpecs -= len;
call PendingAddrWrite.write(beaconSpecs, len);
if (len != m_pendingAddrLen) {
m_pendingAddrLen = len;
m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
}
} else
beaconSpecs -= m_pendingAddrLen;
// (2) update GTS spec
if (m_payloadState & MODIFIED_GTS_FIELD) {
len = call GtsInfoWrite.getLength();
beaconSpecs -= len;
call GtsInfoWrite.write(beaconSpecs, len);
numGtsSlots = getNumGtsSlots(beaconSpecs);
if (len != m_pendingGtsLen || ((15-numGtsSlots) != m_numCapSlots-1)) {
m_pendingGtsLen = len;
m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
}
} else
beaconSpecs -= m_pendingGtsLen;
// (3) update SF spec
beaconSpecs -= 2; // sizeof SF Spec
if (m_payloadState & MODIFIED_SF_SPEC) {
beaconSpecs[BEACON_INDEX_SF_SPEC1] =
(m_beaconOrder << SF_SPEC1_BO_OFFSET) | (m_superframeOrder << SF_SPEC1_SO_OFFSET);
beaconSpecs[BEACON_INDEX_SF_SPEC2] = 0;
if (call MLME_GET.macAssociationPermit())
beaconSpecs[BEACON_INDEX_SF_SPEC2] |= SF_SPEC2_ASSOCIATION_PERMIT;
if (call MLME_GET.macPanCoordinator())
beaconSpecs[BEACON_INDEX_SF_SPEC2] |= SF_SPEC2_PAN_COORD;
beaconSpecs[BEACON_INDEX_SF_SPEC2] |=
((15-numGtsSlots) & SF_SPEC2_FINAL_CAPSLOT_MASK);
}
m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
m_beaconFrame.payload = beaconSpecs;
m_payloadState &= ~MODIFIED_SPECS_MASK; // clear flags
} // end atomic (give BeaconSendAlarm.fired() the chance to execute)
signal IEEE154TxBeaconPayload.aboutToTransmit();
atomic {
// (4) try to update beacon payload
if (m_txState == S_TX_LOCKED)
{
dbg_serial("BeaconTransmitP", "Not enough time for beacon payload update!\n");
return; // too late !
}
if (m_payloadState & MODIFIED_BEACON_PAYLOAD) {
memcpy(&m_payload[IEEE154_aMaxBeaconOverhead + m_updateBeaconOffset],
m_updateBeaconPayload, m_updateBeaconLength);
beaconPayloadUpdated = (m_payloadState & MODIFIED_BEACON_PAYLOAD_MASK);
if (beaconPayloadUpdated & MODIFIED_BEACON_PAYLOAD_NEW)
m_beaconPayloadLen = m_updateBeaconOffset + m_updateBeaconLength;
}
m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
m_payloadState &= ~MODIFIED_BEACON_PAYLOAD_MASK;
}
if (beaconPayloadUpdated) {
if ((beaconPayloadUpdated & MODIFIED_BEACON_PAYLOAD_NEW))
signal IEEE154TxBeaconPayload.setBeaconPayloadDone(m_updateBeaconPayload, m_updateBeaconLength);
else
signal IEEE154TxBeaconPayload.modifyBeaconPayloadDone(m_updateBeaconOffset,
m_updateBeaconPayload, m_updateBeaconLength);
}
}
/* ----------------------- Realignment ----------------------- */
/* In beaconenabled mode a realignment frame is broadcast in the CAP
* immediately after the beacon was transmitted. In non-beaconenabled mode a
* realignment frame is sent using unslotted CSMA. In both cases, if the
* transmission was successful, the superframe spec should be updated now.
**/
event void RealignmentBeaconEnabledTx.transmitDone(ieee154_txframe_t *frame, ieee154_status_t status)
{
finishRealignment(frame, status);
}
event void RealignmentNonBeaconEnabledTx.transmitDone(ieee154_txframe_t *frame, ieee154_status_t status)
{
finishRealignment(frame, status);
}
void finishRealignment(ieee154_txframe_t *frame, ieee154_status_t status)
{
call GetSetRealignmentFrame.set(frame);
if (status == IEEE154_SUCCESS) {
continueStartRequest();
m_requestBitmap &= ~REQUEST_REALIGNMENT_DONE_PENDING; // unlock
// signal confirm where we calculate the next beacon transmission time
} else {
m_requestBitmap = 0;
signal MLME_START.confirm(status);
}
}
/* ----------------------- BeaconRequest ----------------------- */
event message_t* BeaconRequestRx.received(message_t* frame)
{
if (m_beaconOrder == 15) {
// transmit the beacon frame using unslotted CSMA-CA
// TODO
}
return frame;
}
/* ----------------------- SF Structure, etc. ----------------------- */
async command uint32_t OutgoingSF.sfStartTime()
{
return m_lastBeaconTxTime;
}
async command uint16_t OutgoingSF.sfSlotDuration()
{
return m_sfSlotDuration;
}
async command uint8_t OutgoingSF.numCapSlots()
{
return m_numCapSlots;
}
async command uint8_t OutgoingSF.numGtsSlots()
{
return m_numGtsSlots;
}
async command uint16_t OutgoingSF.battLifeExtDuration()
{
return m_battLifeExtDuration;
}
async command const uint8_t* OutgoingSF.gtsFields()
{
return m_gtsField;
}
async command uint16_t OutgoingSF.guardTime()
{
return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_TX_DELAY;
}
async command const ieee154_timestamp_t* OutgoingSF.sfStartTimeRef()
{
return &m_lastBeaconTxRefTime;
}
async command bool OutgoingSF.isBroadcastPending()
{
return m_framePendingBit;
}
async command bool IsSendingBeacons.getNow()
{
return (m_beaconOrder < 15) || ((m_requestBitmap & REQUEST_CONFIRM_PENDING) && m_updateBeaconOrder < 15);
}
default event void MLME_START.confirm(ieee154_status_t status) {}
default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length) {}
default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength) {}
default event void IEEE154TxBeaconPayload.aboutToTransmit() {}
default event void IEEE154TxBeaconPayload.beaconTransmitted() {}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -