wireless/ieee802154: Merges shard logic for sending data request commands

This commit is contained in:
Anthony Merlino 2017-06-17 14:56:42 -04:00
parent 74bc930551
commit 30568ee04f
4 changed files with 162 additions and 212 deletions

View File

@ -232,6 +232,135 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
return OK;
}
/****************************************************************************
* Name: mac802154_create_datareq
*
* Description:
* Internal function used by various parts of the MAC layer. This function
* allocates an IOB, populates the frame according to input args, and links
* the IOB into the provided tx descriptor.
*
* Assumptions:
* Called with the MAC locked
*
****************************************************************************/
void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_addr_s *coordaddr,
enum ieee802154_addrmode_e srcmode,
FAR struct ieee802154_txdesc_s *txdesc)
{
FAR struct iob_s *iob;
FAR uint16_t *u16;
/* The only node allowed to use a source address of none is the PAN Coordinator.
* PAN coordinators should not be sending data request commans.
*/
DEBUGASSERT(srcmode != IEEE802154_ADDRMODE_NONE);
/* Allocate an IOB to put the frame in */
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
/* Get a uin16_t reference to the first two bytes. ie frame control field */
u16 = (FAR uint16_t *)&iob->io_data[iob->io_len];
iob->io_len = 2;
*u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE);
*u16 |= IEEE802154_FRAMECTRL_ACKREQ;
*u16 |= (coordaddr->mode << IEEE802154_FRAMECTRL_SHIFT_DADDR);
*u16 |= (srcmode << IEEE802154_FRAMECTRL_SHIFT_SADDR);
/* Each time a data or a MAC command frame is generated, the MAC sublayer
* shall copy the value of macDSN into the Sequence Number field of the
* MHR of the outgoing frame and then increment it by one. [1] pg. 40.
*/
iob->io_data[iob->io_len++] = priv->dsn++;
/* If the destination address is present, copy the PAN ID and one of the
* addresses, depending on mode, into the MHR.
*/
if (coordaddr->mode != IEEE802154_ADDRMODE_NONE)
{
memcpy(&iob->io_data[iob->io_len], &coordaddr->panid, 2);
iob->io_len += 2;
if (coordaddr->mode == IEEE802154_ADDRMODE_SHORT)
{
memcpy(&iob->io_data[iob->io_len], &coordaddr->saddr, 2);
iob->io_len += 2;
}
else if (coordaddr->mode == IEEE802154_ADDRMODE_EXTENDED)
{
memcpy(&iob->io_data[iob->io_len], &coordaddr->eaddr,
IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
}
}
*u16 |= (coordaddr->mode << IEEE802154_FRAMECTRL_SHIFT_DADDR);
/* If the Destination Addressing Mode field is set to indicate that
* destination addressing information is not present, the PAN ID Compression
* field shall be set to zero and the source PAN identifier shall contain the
* value of macPANId. Otherwise, the PAN ID Compression field shall be set to
* one. In this case and in accordance with the PAN ID Compression field, the
* Destination PAN Identifier field shall contain the value of macPANId, while
* the Source PAN Identifier field shall be omitted. [1] pg. 72
*/
if (coordaddr->mode != IEEE802154_ADDRMODE_NONE &&
coordaddr->panid == priv->addr.panid)
{
*u16 |= IEEE802154_FRAMECTRL_PANIDCOMP;
}
else
{
memcpy(&iob->io_data[iob->io_len], &priv->addr.panid, 2);
iob->io_len += 2;
}
if (srcmode == IEEE802154_ADDRMODE_SHORT)
{
memcpy(&iob->io_data[iob->io_len], &priv->addr.saddr, 2);
iob->io_len += 2;
}
else if (srcmode == IEEE802154_ADDRMODE_EXTENDED)
{
memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr, IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
}
/* Copy in the Command Frame Identifier */
iob->io_data[iob->io_len++] = IEEE802154_CMD_DATA_REQ;
/* Copy the IOB reference to the descriptor */
txdesc->frame = iob;
txdesc->frametype = IEEE802154_FRAME_COMMAND;
/* Save a copy of the destination addressing infromation into the tx descriptor.
* We only do this for commands to help with handling their progession.
*/
memcpy(&txdesc->destaddr, &coordaddr, sizeof(struct ieee802154_addr_s));
/* Copy the IOB reference to the descriptor */
txdesc->frame = iob;
}
/****************************************************************************
* Name: mac802154_setupindirect
*
@ -810,8 +939,10 @@ static void mac802154_rxframe_worker(FAR void *arg)
* coordinator if beacon tracking was enabled during the Association
* operation.
*
* txdesc = mac802154_assoc_getresp(priv);
* sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue);
* mac802154_txdesc_alloc(priv, &respdec, false);
* mac802154_create_datareq(priv, &req->coordaddr,
* IEEE802154_ADDRMODE_EXTENDED, respdesc);
* sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
*/
}
break;

View File

@ -59,8 +59,6 @@
****************************************************************************/
static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv);
static FAR struct ieee802154_txdesc_s *
mac802154_assoc_getresp(FAR struct ieee802154_privmac_s *priv);
/****************************************************************************
* Public MAC Functions
@ -509,17 +507,30 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
* due to NO_DATA.
*/
mac802154_timerstart(priv,
priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION,
mac802154_timeout_assoc);
mac802154_timerstart(priv, (priv->resp_waittime *
IEEE802154_BASE_SUPERFRAME_DURATION),
mac802154_timeout_assoc);
}
else
{
/* Make sure the coordinator address mode is not set to none. This shouldn't
* happen since the association request should have set the mode to short or
* extended
*/
DEBUGASSERT(priv->coordaddr.mode != IEEE802154_ADDRMODE_NONE);
/* Send the Data Request MAC command after macResponseWaitTime to
* extract the data from the coordinator.
*/
respdesc = mac802154_assoc_getresp(priv);
mac802154_txdesc_alloc(priv, &respdesc, false);
mac802154_create_datareq(priv, &priv->coordaddr,
IEEE802154_ADDRMODE_EXTENDED, respdesc);
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
priv->radio->txdelayed(priv->radio, respdesc,
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION));
}
@ -844,114 +855,3 @@ static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv)
priv->cb->notify(priv->cb, notif);
}
/****************************************************************************
* Name: mac802154_assoc_getresp
*
* Description:
* Send a data request to the coordinator to extract the association response.
*
* Assumptions:
* MAC is locked when called.
*
* TODO: Can this be used for general data extraction?
*
****************************************************************************/
static FAR struct ieee802154_txdesc_s *
mac802154_assoc_getresp(FAR struct ieee802154_privmac_s *priv)
{
FAR struct iob_s *iob;
FAR struct ieee802154_txdesc_s *txdesc;
FAR uint16_t *u16;
/* Allocate an IOB to put the frame in */
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
/* Allocate a tx descriptor */
mac802154_txdesc_alloc(priv, &txdesc, false);
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
/* Get a uin16_t reference to the first two bytes. ie frame control field */
u16 = (FAR uint16_t *)&iob->io_data[0];
*u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE);
*u16 |= IEEE802154_FRAMECTRL_ACKREQ;
*u16 |= (priv->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR);
*u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR);
/* If the Destination Addressing Mode field is set to indicate that
* destination addressing information is not present, the PAN ID Compression
* field shall be set to zero and the source PAN identifier shall contain the
* value of macPANId. Otherwise, the PAN ID Compression field shall be set to
* one. In this case and in accordance with the PAN ID Compression field, the
* Destination PAN Identifier field shall contain the value of macPANId, while
* the Source PAN Identifier field shall be omitted. [1] pg. 72
*
* The destination address for a data request to extract an assoication request
* should never be set to none. So we always set the PAN ID compression field
*/
DEBUGASSERT(priv->coordaddr.mode != IEEE802154_ADDRMODE_NONE);
*u16 |= IEEE802154_FRAMECTRL_PANIDCOMP;
iob->io_len = 2;
/* Each time a data or a MAC command frame is generated, the MAC sublayer
* shall copy the value of macDSN into the Sequence Number field of the
* MHR of the outgoing frame and then increment it by one. [1] pg. 40.
*/
iob->io_data[iob->io_len++] = priv->dsn++;
/* The Destination PAN Identifier field shall contain the identifier of
* the PAN to which to associate. [1] pg. 68
*/
memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.panid, 2);
iob->io_len += 2;
/* The Destination Address field shall contain the address from the
* beacon frame that was transmitted by the coordinator to which the
* association request command is being sent. [1] pg. 68
*/
if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT)
{
memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.saddr, 2);
iob->io_len += 2;
}
else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED)
{
memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.eaddr[0],
IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
}
/* The Source Address field shall contain the value of macExtendedAddress. */
memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0],
IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
/* Copy in the Command Frame Identifier */
iob->io_data[iob->io_len++] = IEEE802154_CMD_DATA_REQ;
/* Copy the IOB reference to the descriptor */
txdesc->frame = iob;
return txdesc;
}

View File

@ -402,4 +402,9 @@ int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv,
void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_txdesc_s *txdesc);
void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_addr_s *coordaddr,
enum ieee802154_addrmode_e srcmode,
FAR struct ieee802154_txdesc_s *txdesc);
#endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */

View File

@ -85,7 +85,6 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
(FAR struct ieee802154_privmac_s *)mac;
FAR struct iob_s *iob;
FAR struct ieee802154_txdesc_s *txdesc;
FAR uint16_t *frame_ctrl;
int ret;
/* On receipt of the MLME-POLL.request primitive, the MLME requests data from
@ -108,9 +107,6 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
return ret;
}
priv->curr_op = MAC802154_OP_POLL;
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
/* Get exclusive access to the MAC */
ret = mac802154_takesem(&priv->exclsem, true);
@ -120,84 +116,19 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
return ret;
}
/* Allocate an IOB to put the frame in */
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
priv->curr_op = MAC802154_OP_POLL;
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
/* Allocate the txdesc, waiting if necessary */
ret = mac802154_txdesc_alloc(priv, &txdesc, true);
if (ret < 0)
{
iob_free(iob);
mac802154_givesem(&priv->exclsem);
mac802154_givesem(&priv->op_sem);
return ret;
}
/* Get a uin16_t reference to the first two bytes. ie frame control field */
frame_ctrl = (FAR uint16_t *)&iob->io_data[0];
iob->io_len = 2;
*frame_ctrl = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE);
*frame_ctrl |= IEEE802154_FRAMECTRL_ACKREQ;
/* Each time a data or a MAC command frame is generated, the MAC sublayer
* shall copy the value of macDSN into the Sequence Number field of the
* MHR of the outgoing frame and then increment it by one. [1] pg. 40.
*/
iob->io_data[iob->io_len++] = priv->dsn++;
/* If the destination address is present, copy the PAN ID and one of the
* addresses, depending on mode, into the MHR.
*/
if (req->coordaddr.mode != IEEE802154_ADDRMODE_NONE)
{
memcpy(&iob->io_data[iob->io_len], &req->coordaddr.panid, 2);
iob->io_len += 2;
if (req->coordaddr.mode == IEEE802154_ADDRMODE_SHORT)
{
memcpy(&iob->io_data[iob->io_len], &req->coordaddr.saddr, 2);
iob->io_len += 2;
}
else if (req->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED)
{
memcpy(&iob->io_data[iob->io_len], &req->coordaddr.eaddr,
IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
}
}
*frame_ctrl |= (req->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR);
/* If the PAN identifiers are identical, the PAN ID Compression field
* shall be set to one, and the source PAN identifier shall be omitted
* from the transmitted frame. [1] pg. 41.
*/
if (req->coordaddr.mode != IEEE802154_ADDRMODE_NONE &&
req->coordaddr.panid == priv->addr.panid)
{
*frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP;
}
else
{
memcpy(&iob->io_data[iob->io_len], &priv->addr.panid, 2);
iob->io_len += 2;
}
/* The Source Addressing Mode field shall be set according to the value of
* macShortAddress. If macShortAddress is less than 0xfffe, short addressing
* shall be used. Extended addressing shall be used otherwise.
@ -205,32 +136,15 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
if (priv->addr.saddr == IEEE802154_SADDR_BCAST)
{
*frame_ctrl |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR);
memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], IEEE802154_EADDR_LEN);
iob->io_len += IEEE802154_EADDR_LEN;
mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED,
txdesc);
}
else
{
*frame_ctrl |= (IEEE802154_ADDRMODE_SHORT << IEEE802154_FRAMECTRL_SHIFT_SADDR);
memcpy(&iob->io_data[iob->io_len], &priv->addr.saddr, 2);
iob->io_len += 2;
mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT,
txdesc);
}
/* Copy in the Command Frame Identifier */
iob->io_data[iob->io_len++] = IEEE802154_CMD_DATA_REQ;
/* Copy the IOB reference to the descriptor */
txdesc->frame = iob;
txdesc->frametype = IEEE802154_FRAME_COMMAND;
/* Save a copy of the destination addressing infromation into the tx descriptor.
* We only do this for commands to help with handling their progession.
*/
memcpy(&txdesc->destaddr, &req->coordaddr, sizeof(struct ieee802154_addr_s));
/* Save a reference of the tx descriptor */
priv->cmd_desc = txdesc;