📄 endpoint.c
字号:
sMlmeReqRsp.uParam.sReqScan.u8ScanType = MAC_MLME_SCAN_TYPE_ACTIVE;
sMlmeReqRsp.uParam.sReqScan.u32ScanChannels = DEMO_CHANNEL_BITMAP;
sMlmeReqRsp.uParam.sReqScan.u8ScanDuration = 3;
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
/* Check immediate response */
if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
{
/* Unexpected result: scan request should result in a deferred
confirmation (i.e. we will receive it later) */
vDisplayError("Scan request returned error",
((uint32)sMlmeSyncCfm.u8Status) << 8
| (uint32)sMlmeSyncCfm.uParam.sCfmScan.u8Status);
}
}
/****************************************************************************
*
* NAME: vStartSync
*
* DESCRIPTION:
* Sends an MLME request to the 802.15.4 to start synchronisation on the
* channel determined by a previous scan. There is no confirmation for this.
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vStartSync(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
sDemoData.sSystem.eState = E_STATE_SYNCING;
#ifdef UART0_DEBUG
vDebug("Sy ");
#endif
/* Set the coordinator source address before syncing to avoid PAN conflict
indication */
s_psMacPib->u16CoordShortAddr = DEMO_COORD_ADDR;
/* Create sync request on channel selected during scan */
sMlmeReqRsp.u8Type = MAC_MLME_REQ_SYNC;
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqSync_s);
sMlmeReqRsp.uParam.sReqSync.u8Channel = sDemoData.sSystem.u8Channel;
sMlmeReqRsp.uParam.sReqSync.u8TrackBeacon = TRUE;
/* Put in sync request. There is no deferred confirm for this, we just get
a SYNC-LOSS later if it didn't work */
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
}
/****************************************************************************
*
* NAME: vStartAssociate
*
* DESCRIPTION:
* Sends an MLME request to the 802.15.4 to request an association with the
* coordinator found during a previous scan. If the returned confirmation is
* not 'deferred', a fatal error is assumed.
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vStartAssociate(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
sDemoData.sSystem.eState = E_STATE_ASSOCIATING;
#ifdef UART0_DEBUG
vDebug("As ");
#endif
/* Create associate request. We know short address and PAN ID of
coordinator as this is preset and we have checked that received
beacon matched this */
sMlmeReqRsp.u8Type = MAC_MLME_REQ_ASSOCIATE;
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqAssociate_s);
sMlmeReqRsp.uParam.sReqAssociate.u8LogicalChan = sDemoData.sSystem.u8Channel;
sMlmeReqRsp.uParam.sReqAssociate.u8Capability = 0x80; /* We want short address, other features off */
sMlmeReqRsp.uParam.sReqAssociate.u8SecurityEnable = FALSE;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.u8AddrMode = 2;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.u16PanId = DEMO_PAN_ID;
sMlmeReqRsp.uParam.sReqAssociate.sCoord.uAddr.u16Short = DEMO_COORD_ADDR;
/* Put in associate request and check immediate confirm. Should be
deferred, in which case response is handled by event handler */
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
if (sMlmeSyncCfm.u8Status != MAC_MLME_CFM_DEFERRED)
{
/* Unexpected result */
vDisplayError("Associate request returned error",
((uint32)sMlmeSyncCfm.u8Status) << 8
| (uint32)sMlmeSyncCfm.uParam.sCfmAssociate.u8Status);
}
}
/****************************************************************************
*
* NAME: vProcessInterrupts
*
* DESCRIPTION:
* Loops around checking for upward events from the Application Queue API.
* To save power, the CPU is set to doze at the start of the loop. If an event
* is generated, the CPU is woken up and processes it, then the code here is
* allowed to continue.
*
* For each type of event, the queue is checked and, if there is something to
* process, the appropriate handler is called. The buffer is then returned to
* the Application Queue API. This continues until all events have been
* processed. If the hardware event handler detects that a 'reset' button
* press sequence has happened, the loop is exited.
*
* Note that the buttons are configured to generate interrupts when they are
* pressed.
*
* RETURNS:
* void when a 'reset' button press sequence is detected.
*
****************************************************************************/
PRIVATE void vProcessInterrupts(void)
{
MAC_MlmeDcfmInd_s *psMlmeInd;
MAC_McpsDcfmInd_s *psMcpsInd;
AppQApiHwInd_s *psAHI_Ind;
bool_t bDone;
/* Wait for events */
bDone = FALSE;
do
{
/* Doze CPU: it will wake when interrupt occurs, then process
interrupts, then this code will be able to process queue */
vAHI_CpuDoze();
/* Check for anything on the MCPS upward queue */
do
{
psMcpsInd = psAppQApiReadMcpsInd();
if (psMcpsInd != NULL)
{
vProcessIncomingMcps(psMcpsInd);
vAppQApiReturnMcpsIndBuffer(psMcpsInd);
}
} while (psMcpsInd != NULL);
/* Check for anything on the MLME upward queue */
do
{
psMlmeInd = psAppQApiReadMlmeInd();
if (psMlmeInd != NULL)
{
vProcessIncomingMlme(psMlmeInd);
vAppQApiReturnMlmeIndBuffer(psMlmeInd);
}
} while (psMlmeInd != NULL);
/* Check for anything on the AHI upward queue */
do
{
psAHI_Ind = psAppQApiReadHwInd();
if (psAHI_Ind != NULL)
{
/* We don't bother to pass the queue data as we are only
expecting key press interrupts and, if we get anything else,
reading the keys won't have any unfortunate side effects */
if (bProcessKeyPress() == TRUE)
{
bDone = TRUE;
}
vAppQApiReturnHwIndBuffer(psAHI_Ind);
}
} while (psAHI_Ind != NULL);
} while (bDone == FALSE);
}
/****************************************************************************
*
* NAME: vProcessIncomingMcps
*
* DESCRIPTION:
* Deals with any incoming MCPS data events. Only deferred confirmations of
* frame transmission requests are specifically handled, to move the state
* machine forward.
*
* PARAMETERS: Name RW Usage
* psMcpsInd R Pointer to structure containing MCPS event
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessIncomingMcps(MAC_McpsDcfmInd_s *psMcpsInd)
{
/* Process MCPS indication by checking if it is a confirmation of our
outgoing frame */
if ((psMcpsInd->u8Type == MAC_MCPS_DCFM_DATA)
&& (sDemoData.sSystem.eState == E_STATE_TX_DATA))
{
if (psMcpsInd->uParam.sDcfmData.u8Handle == sDemoData.sTransceiver.u8CurrentTxHandle)
{
/* Increment handle for next time. Increment failures */
sDemoData.sTransceiver.u8CurrentTxHandle++;
/* Start to read sensors. This takes a while but rather than
wait for an interrupt we just poll and, once finished, move back
to the running state to wait for the next beacon. Not a power
saving solution! */
sDemoData.sSystem.eState = E_STATE_READ_SENSORS;
vProcessRead();
sDemoData.sSystem.eState = E_STATE_RUNNING;
}
}
}
/****************************************************************************
*
* NAME: vProcessIncomingMlme
*
* DESCRIPTION:
* Deals with any incoming MCPS events. There are 4 events that are handled:
*
* 1. Scan deferred confirmation
* If the scan saw a beacon from the expected coordinator, the stack is
* asked to start synchronisation. Otherwise, it tries to scan again.
*
* 2. Associate deferred confirmation
* If the association was successful, the short address is stored and the
* device enters the 'running' state, in which it will respond to beacons
* by sending back a frame of sensor information. If the association was
* not successful, it is attempted again.
*
* 3. Becon notify indication
* If synchronising, this is used to indicate that synchronisation is
* complete and association is atempted. If in 'running' state, it is
* used to trigger the sending of a frame containing sensor information
* to the coordinator.
*
* 4. Sync loss indication
* Device starts another scan.
*
* PARAMETERS: Name RW Usage
* psMlmeInd R Pointer to structure containing MLME event
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd)
{
MAC_PanDescr_s *psPanDesc;
int i;
/* We respond to several MLME indications and confirmations, depending
on mode */
switch (psMlmeInd->u8Type)
{
case MAC_MLME_DCFM_SCAN:
#ifdef UART0_DEBUG
vDebug("MSc ");
#endif
/* Only respond to this if scanning */
if (sDemoData.sSystem.eState == E_STATE_SCANNING)
{
#ifdef UART0_DEBUG
vDebug("MScSt ");
#endif
/* Make sure it is what we're after */
switch (psMlmeInd->uParam.sDcfmScan.u8Status)
{
case MAC_ENUM_SUCCESS:
if (psMlmeInd->uParam.sDcfmScan.u8ScanType == MAC_MLME_SCAN_TYPE_ACTIVE)
{
#ifdef UART0_DEBUG
vDebug("MScOk ");
#endif
/* Determine which, if any, network contains demo coordinator.
Algorithm for determining which network to connect to is
beyond the scope of 802.15.4, and we use a simple approach
of matching the required PAN ID and short address, both of
which we already know */
i = 0;
while (i < psMlmeInd->uParam.sDcfmScan.u8ResultListSize)
{
psPanDesc = &psMlmeInd->uParam.sDcfmScan.uList.asPanDescr[i];
#ifdef UART0_DEBUG
vDisplayHex(psPanDesc->u8LogicalChan, 2);
vDebug(":");
vDisplayHex(psPanDesc->sCoord.u16PanId, 4);
vDebug(":");
vDisplayHex(psPanDesc->sCoord.uAddr.u16Short, 4);
vDebug(" ");
#endif
if ((psPanDesc->sCoord.u16PanId == DEMO_PAN_ID)
&& (psPanDesc->sCoord.u8AddrMode == 2)
&& (psPanDesc->sCoord.uAddr.u16Short == DEMO_COORD_ADDR))
{
#ifdef UART0_DEBUG
vDebug("MScUs ");
#endif
/* Matched so start to synchronise and associate */
sDemoData.sSystem.u8Channel = psPanDesc->u8LogicalChan;
vStartSync();
return;
}
i++;
}
/* Failed to find coordinator: keep trying */
vStartScan();
}
break;
case MAC_ENUM_NO_BEACON:
/* Failed to find coordinator: keep trying */
vStartScan();
break;
default:
break;
}
}
break;
case MAC_MLME_DCFM_ASSOCIATE:
/* Only respond if in associating mode */
switch (sDemoData.sSystem.eState)
{
case E_STATE_ASSOCIATING:
if (psMlmeInd->uParam.sDcfmAssociate.u8Status == MAC_ENUM_SUCCESS)
{
/* Store short address */
sDemoData.sSystem.u16ShortAddr = psMlmeInd->uParam.sDcfmAssociate.u16AssocShortAddr;
/* Node is a value between 0 and the number of endpoints - 1.
It is determined by the short address */
sDemoData.sSystem.u8ThisNode = sDemoData.sSystem.u16ShortAddr - DEMO_ENDPOINT_ADDR_BASE;
/* We are now in the running state */
sDemoData.sSystem.eState = E_STATE_RUNNING;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -