📄 myapp_ex07b.c
字号:
return errorNoError;
}
else
{
Uart_Print("Invalid parameter!\n");
return errorInvalidParameter;
}
}
else
{
/* Allocation of a message buffer failed. */
Uart_Print("Message allocation failed!\n");
return errorAllocFailed;
}
}
/******************************************************************************
* The App_HandleScanPassiveConfirm(nwkMessage_t *pMsg) function will handle the
* Passive Scan confirm message received from the MLME when the Passive scan has
* completed. The message contains a list of PAN descriptors. Based on link
* quality inforamtion in the pan descriptors the nearest coordinator is chosen.
* The corresponding pan descriptor is stored in the global variable coordInfo.
*
* If a suitable coordinator was found, we synchronize to it immediately.
*
* The function may return either of the following values:
* errorNoError: A suitable pan descriptor was found.
* errorNoScanResults: No scan results were present in the confirm message.
*
******************************************************************************/
uint8_t App_HandleScanPassiveConfirm(nwkMessage_t *pMsg)
{
uint8_t panDescListSize = pMsg->msgData.scanCnf.resultListSize;
panDescriptor_t *pPanDesc = pMsg->msgData.scanCnf.resList.pPanDescriptorList;
uint8_t rc = errorNoScanResults;
/* Check if the scan resulted in any coordinator responses. */
if(panDescListSize != 0)
{
/* Initialize link quality to very poor. */
uint8_t i, bestLinkQuality = 0;
/* Check all PAN descriptors. */
for(i=0; i<panDescListSize; i++, pPanDesc++)
{
/* Only attempt to associate if the coordinator accepts associations. */
if(pPanDesc->superFrameSpec[1] & gSuperFrameSpecMsbAssocPermit_c)
{
/* Find the nearest coordinator using the link quality measure. */
if(pPanDesc->linkQuality > bestLinkQuality)
{
/* Save the information of the coordinator candidate. If we
find a better candiate, the information will be replaced. */
memcpy(&coordInfo, pPanDesc, sizeof(panDescriptor_t));
bestLinkQuality = pPanDesc->linkQuality;
rc = errorNoError;
}
}
}
}
if(rc == errorNoError)
{
/* If we have found a beaconing coodinator we must setup the MAC to
synchronize to the beacon frames. This requires us to set the
PAN ID attribute of the MAC PIB to the PAN ID of the coordinator.
Furthermore, if we want to take advantage of the automatic
polling feature we must set the Auto Request MAC PIB attribute. */
if((coordInfo.superFrameSpec[0] & gSuperFrameSpecLsbBO_c) < 0xF)
{
mlmeMessage_t *pMsgOut = MSG_AllocType(mlmeMessage_t);
if(pMsgOut != NULL)
{
uint8_t value = TRUE;
/* Set MAC PIB auto request to TRUE. In this way the device will
automatically poll for data if the pending address list of the
beacon frame contains our address. */
pMsgOut->msgType = gMlmeSetReq_c;
pMsgOut->msgData.setReq.pibAttribute = gMacPibAutoRequest_c;
pMsgOut->msgData.setReq.pibAttributeValue = &value;
/* Get/Set/Reset Request messages are NOT freed by the MLME. */
NR MSG_Send(NWK_MLME, pMsgOut);
/* Since we are going to receive data from the coordinator
using automatic polling we must synchronize to the beacon
and keep tracking it. Before synchronizing it is required
that the MAC PIB PAN ID, and the MAC PIB coordinator
address is set. */
pMsgOut->msgData.setReq.pibAttribute = gMacPibPanId_c;
pMsgOut->msgData.setReq.pibAttributeValue = coordInfo.coordPanId;
/* Get/Set/Reset Request messages are NOT freed by the MLME. */
NR MSG_Send(NWK_MLME, pMsgOut);
/* Set coordinator address PIB attribute according the the
address mode of the coordinator (short or long address). */
pMsgOut->msgData.setReq.pibAttribute =
coordInfo.coordAddrMode == gAddrModeShort_c ? gMacPibCoordShortAddress_c :
gMacPibCoordExtendedAddress_c;
pMsgOut->msgData.setReq.pibAttributeValue = coordInfo.coordAddress;
/* Get/Set/Reset Request messages are NOT freed by the MLME. */
NR MSG_Send(NWK_MLME, pMsgOut);
/* Now send the MLME-Sync Request. We choose to let the MAC track
the beacons on the logical channel obtained by the passive scan.*/
pMsgOut->msgType = gMlmeSyncReq_c;
pMsgOut->msgData.syncReq.trackBeacon = TRUE;
pMsgOut->msgData.syncReq.logicalChannel = coordInfo.logicalChannel;
NR MSG_Send(NWK_MLME, pMsgOut);
}
}
}
/* ALWAYS free the PAN descriptor list */
MSG_Free(pMsg->msgData.scanCnf.resList.pPanDescriptorList);
return rc;
}
/******************************************************************************
* The App_SendAssociateRequest(void) will create an Associate Request message
* and send it to the coordinator it wishes to associate to. The function uses
* information gained about the coordinator during the scan procedure.
*
* The function may return either of the following values:
* errorNoError: The Associate Request message was sent successfully.
* errorInvalidParameter: The MLME service access point rejected the
* message due to an invalid parameter.
* errorAllocFailed: A message buffer could not be allocated.
*
******************************************************************************/
uint8_t App_SendAssociateRequest(void)
{
mlmeMessage_t *pMsg;
mlmeAssociateReq_t *pAssocReq;
Uart_Print("Sending the MLME-Associate Request message to the MAC...");
/* Allocate a message for the MLME message. */
pMsg = MSG_AllocType(mlmeMessage_t);
if(pMsg != NULL)
{
/* This is a MLME-ASSOCIATE.req command. */
pMsg->msgType = gMlmeAssociateReq_c;
/* Create the Associate request message data. */
pAssocReq = &pMsg->msgData.associateReq;
/* Use the coordinator info we got from the Passive Scan. */
memcpy(pAssocReq->coordAddress, coordInfo.coordAddress, 8);
memcpy(pAssocReq->coordPanId, coordInfo.coordPanId, 2);
pAssocReq->coordAddrMode = coordInfo.coordAddrMode;
pAssocReq->logicalChannel = coordInfo.logicalChannel;
pAssocReq->securityEnable = FALSE;
/* We want the coordinator to assign a short address to us. */
pAssocReq->capabilityInfo = gCapInfoAllocAddr_c;
/* Send the Associate Request to the MLME. */
if(MSG_Send(NWK_MLME, pMsg) == gSuccess_c)
{
Uart_Print("Done\n");
return errorNoError;
}
else
{
/* One or more parameters in the message were invalid. */
Uart_Print("Invalid parameter!\n");
return errorInvalidParameter;
}
}
else
{
/* Allocation of a message buffer failed -
the state machine will call us again. */
Uart_Print("Message allocation failed - retrying...\n");
return errorAllocFailed;
}
}
/******************************************************************************
* The App_HandleAssociateConfirm(nwkMessage_t *pMsg) function will handle the
* Associate confirm message received from the MLME when the Association
* procedure has completed. The message contains the short address that the
* coordinator has assigned to us. This address is 0xfffe if we did not specify
* the gCapInfoAllocAddr_c flag in the capability info field of the Associate
* request. The address and address mode are saved in global variables. They
* will be used in the next demo application when sending data.
*
******************************************************************************/
void App_HandleAssociateConfirm(nwkMessage_t *pMsg)
{
/* This is our own extended address (MAC address). It cannot be modified. */
extern const uint8_t aExtendedAddress[8];
/* If the coordinator assigns a short address of 0xfffe then,
that means we must use our own extended address in all
communications with the coordinator. Otherwise, we use
the short address assigned to us. */
if( (pMsg->msgData.associateCnf.assocShortAddress[0] >= 0xFE) &&
(pMsg->msgData.associateCnf.assocShortAddress[1] == 0xFF) )
{
myAddrMode = gAddrModeLong_c;
memcpy(myAddress, (void *)aExtendedAddress, 8);
}
else
{
myAddrMode = gAddrModeShort_c;
memcpy(myAddress, pMsg->msgData.associateCnf.assocShortAddress, 2);
}
}
/******************************************************************************
* The App_HandleMcpsInput(mcpsToNwkMessage_t *pMsgIn) function will handle
* messages from the MCPS, e.g. Data Confirm, and Data Indication.
*
******************************************************************************/
void App_HandleMcpsInput(mcpsToNwkMessage_t *pMsgIn)
{
switch(pMsgIn->msgType)
{
/* The MCPS-Data confirm is sent by the MAC to the network
or application layer when data has been sent. */
case gMcpsDataCnf_c:
if(numPendingPackets)
numPendingPackets--;
break;
case gMcpsDataInd_c:
/* Copy the received data to the UART. */
Uart_Tx(pMsgIn->msgData.dataInd.msdu, pMsgIn->msgData.dataInd.msduLength);
break;
}
}
/******************************************************************************
* The App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType) function does not, as
* the name implies, wait for a message, thus blocking the execution of the
* state machine. Instead the function analyzes the supplied message to
* determine whether or not the message is of the expected type.
* The function may return either of the following values:
* errorNoError: The message was of the expected type.
* errorNoMessage: The message pointer is NULL.
* errorWrongConfirm: The message is not of the expected type.
*
******************************************************************************/
uint8_t App_WaitMsg(nwkMessage_t *pMsg, uint8_t msgType)
{
/* Do we have a message? If not, the exit with error code */
if(pMsg == NULL)
return errorNoMessage;
/* Is it the expected message type? If not then exit with error code */
if(pMsg->msgType != msgType)
return errorWrongConfirm;
/* Found the expected message. Return with success code */
return errorNoError;
}
/******************************************************************************
* The App_TransmitUartData() function will perform (single/multi buffered)
* data transmissions of data received by the UART. Data could also come from
* other sources such as sensors etc. This is completely determined by the
* application. The constant MAX_PENDING_DATA_PACKETS determine the maximum
* number of packets pending for transmission in the MAC. A global variable
* is incremented each time a data packet is sent to the MCPS, and decremented
* when the corresponding MCPS-Data Confirm message is received. If the counter
* reaches the defined maximum no more data buffers are allocated until the
* counter is decreased below the maximum number of pending packets.
*
* The function uses the coordinator information gained during the Passive Scan,
* and the short address assigned to us by coordinator, for building an MCPS-
* Data Request message. The message is sent to the MCPS service access point
* in the MAC.
******************************************************************************/
void App_TransmitUartData(void)
{
/* Use multi buffering for increased TX performance. It does not really
have any effect at a UART baud rate of 19200bps but serves as an
example of how the throughput may be improved in a real-world
application where the data rate is of concern. */
if( (numPendingPackets < MAX_PENDING_DATA_PACKETS) && (pPacket == NULL) )
{
/* If the maximum number of pending data buffes is below maximum limit
and we do not have a data buffer already then allocate one. */
pPacket = MSG_Alloc(sizeof(nwkToMcpsMessage_t) - 1 + DEFAULT_DATA_LENGTH);
}
if(pPacket != NULL)
{
/* If we have a buffer, then get data from the UART. */
uint8_t msduLength = Uart_Poll(pPacket->msgData.dataReq.msdu);
if(msduLength)
{
/* Data was available in the UART receive buffer. Now create an
MCPS-Data Request message containing the UART data. */
pPacket->msgType = gMcpsDataReq_c;
/* Create the header using coordinator information gained during
the scan procedure. Also use the short address we were assigned
by the coordinator during association. */
memcpy(pPacket->msgData.dataReq.dstAddr, coordInfo.coordAddress, 8);
memcpy(pPacket->msgData.dataReq.srcAddr, myAddress, 8);
memcpy(pPacket->msgData.dataReq.dstPanId, coordInfo.coordPanId, 2);
memcpy(pPacket->msgData.dataReq.srcPanId, coordInfo.coordPanId, 2);
pPacket->msgData.dataReq.dstAddrMode = coordInfo.coordAddrMode;
pPacket->msgData.dataReq.srcAddrMode = myAddrMode;
pPacket->msgData.dataReq.msduLength = msduLength;
/* Request MAC level acknowledgement of the data packet */
pPacket->msgData.dataReq.txOptions = gTxOptsAck_c;
/* Give the data packet a handle. The handle is
returned in the MCPS-Data Confirm message. */
pPacket->msgData.dataReq.msduHandle = msduHandle++;
/* Send the Data Request to the MCPS */
NR MSG_Send(NWK_MCPS, pPacket);
/* Prepare for another data buffer */
pPacket = NULL;
numPendingPackets++;
}
}
}
/******************************************************************************
* The following functions are called by the MAC to put messages into the
* Application's queue. They need to be defined even if they are not used
* in order to avoid linker errors.
******************************************************************************/
uint8_t MLME_NWK_SapHandler(nwkMessage_t * pMsg)
{
/* Put the incoming MLME message in the applications input queue. */
MSG_Queue(&mMlmeNwkInputQueue, pMsg);
return gSuccess_c;
}
uint8_t MCPS_NWK_SapHandler(mcpsToNwkMessage_t *pMsg)
{
/* Put the incoming MCPS message in the applications input queue. */
MSG_Queue(&mMcpsNwkInputQueue, pMsg);
return gSuccess_c;
}
uint8_t ASP_APP_SapHandler(aspToAppMsg_t *pMsg)
{
/* If the message is not handled anywhere it must be freed. */
MSG_Free(pMsg);
return gSuccess_c;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -