Merge branch 'ieee802154'

This commit is contained in:
Gregory Nutt
2017-06-18 08:24:08 -06:00
6 changed files with 170 additions and 220 deletions
@@ -241,10 +241,11 @@ enum ieee802154_status_e
static const char *IEEE802154_STATUS_STRING[] = static const char *IEEE802154_STATUS_STRING[] =
{ {
"Success", "Success",
"Out of capacity",
"Denied",
"Failure", "Failure",
"Beacon loss", "Beacon loss",
"Channel access failure", "Channel access failure",
"Denied",
"Disable TRX failure", "Disable TRX failure",
"Failed security check", "Failed security check",
"Frame too long", "Frame too long",
@@ -255,7 +256,6 @@ static const char *IEEE802154_STATUS_STRING[] =
"No beacon", "No beacon",
"No data", "No data",
"No short address", "No short address",
"Out of cap",
"PAN ID conflict", "PAN ID conflict",
"Realignment", "Realignment",
"Transaction expired", "Transaction expired",
+137 -6
View File
@@ -75,7 +75,7 @@ static void mac802154_resetqueues(FAR struct ieee802154_privmac_s *priv);
/* IEEE 802.15.4 PHY Interface OPs */ /* IEEE 802.15.4 PHY Interface OPs */
static int mac802154_poll(FAR const struct ieee802154_radiocb_s *radiocb, static int mac802154_radiopoll(FAR const struct ieee802154_radiocb_s *radiocb,
bool gts, FAR struct ieee802154_txdesc_s **tx_desc); bool gts, FAR struct ieee802154_txdesc_s **tx_desc);
static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb, static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb,
@@ -232,6 +232,135 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
return OK; 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 * Name: mac802154_setupindirect
* *
@@ -363,7 +492,7 @@ static void mac802154_purge_worker(FAR void *arg)
} }
/**************************************************************************** /****************************************************************************
* Name: mac802154_poll * Name: mac802154_radiopoll
* *
* Description: * Description:
* Called from the radio driver through the callback struct. This function is * Called from the radio driver through the callback struct. This function is
@@ -373,7 +502,7 @@ static void mac802154_purge_worker(FAR void *arg)
* *
****************************************************************************/ ****************************************************************************/
static int mac802154_poll(FAR const struct ieee802154_radiocb_s *radiocb, static int mac802154_radiopoll(FAR const struct ieee802154_radiocb_s *radiocb,
bool gts, FAR struct ieee802154_txdesc_s **txdesc) bool gts, FAR struct ieee802154_txdesc_s **txdesc)
{ {
FAR struct mac802154_radiocb_s *cb = FAR struct mac802154_radiocb_s *cb =
@@ -810,8 +939,10 @@ static void mac802154_rxframe_worker(FAR void *arg)
* coordinator if beacon tracking was enabled during the Association * coordinator if beacon tracking was enabled during the Association
* operation. * operation.
* *
* txdesc = mac802154_assoc_getresp(priv); * mac802154_txdesc_alloc(priv, &respdec, false);
* sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue); * mac802154_create_datareq(priv, &req->coordaddr,
* IEEE802154_ADDRMODE_EXTENDED, respdesc);
* sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
*/ */
} }
break; break;
@@ -1381,7 +1512,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
mac->radiocb.priv = mac; mac->radiocb.priv = mac;
radiocb = &mac->radiocb.cb; radiocb = &mac->radiocb.cb;
radiocb->poll = mac802154_poll; radiocb->poll = mac802154_radiopoll;
radiocb->txdone = mac802154_txdone; radiocb->txdone = mac802154_txdone;
radiocb->rxframe = mac802154_rxframe; radiocb->rxframe = mac802154_rxframe;
+16 -116
View File
@@ -59,8 +59,6 @@
****************************************************************************/ ****************************************************************************/
static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv); 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 * Public MAC Functions
@@ -509,17 +507,30 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
* due to NO_DATA. * due to NO_DATA.
*/ */
mac802154_timerstart(priv, mac802154_timerstart(priv, (priv->resp_waittime *
priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION, IEEE802154_BASE_SUPERFRAME_DURATION),
mac802154_timeout_assoc); mac802154_timeout_assoc);
} }
else 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 /* Send the Data Request MAC command after macResponseWaitTime to
* extract the data from the coordinator. * 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->radio->txdelayed(priv->radio, respdesc,
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION)); (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); 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;
}
+5
View File
@@ -402,4 +402,9 @@ int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv,
void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_txdesc_s *txdesc); 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 */ #endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */
+6 -92
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 ieee802154_privmac_s *)mac;
FAR struct iob_s *iob; FAR struct iob_s *iob;
FAR struct ieee802154_txdesc_s *txdesc; FAR struct ieee802154_txdesc_s *txdesc;
FAR uint16_t *frame_ctrl;
int ret; int ret;
/* On receipt of the MLME-POLL.request primitive, the MLME requests data from /* 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; return ret;
} }
priv->curr_op = MAC802154_OP_POLL;
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
/* Get exclusive access to the MAC */ /* Get exclusive access to the MAC */
ret = mac802154_takesem(&priv->exclsem, true); 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; return ret;
} }
/* Allocate an IOB to put the frame in */ priv->curr_op = MAC802154_OP_POLL;
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
/* Allocate the txdesc, waiting if necessary */ /* Allocate the txdesc, waiting if necessary */
ret = mac802154_txdesc_alloc(priv, &txdesc, true); ret = mac802154_txdesc_alloc(priv, &txdesc, true);
if (ret < 0) if (ret < 0)
{ {
iob_free(iob);
mac802154_givesem(&priv->exclsem); mac802154_givesem(&priv->exclsem);
mac802154_givesem(&priv->op_sem); mac802154_givesem(&priv->op_sem);
return ret; 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 /* The Source Addressing Mode field shall be set according to the value of
* macShortAddress. If macShortAddress is less than 0xfffe, short addressing * macShortAddress. If macShortAddress is less than 0xfffe, short addressing
* shall be used. Extended addressing shall be used otherwise. * 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) if (priv->addr.saddr == IEEE802154_SADDR_BCAST)
{ {
*frame_ctrl |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED,
memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], IEEE802154_EADDR_LEN); txdesc);
iob->io_len += IEEE802154_EADDR_LEN;
} }
else else
{ {
*frame_ctrl |= (IEEE802154_ADDRMODE_SHORT << IEEE802154_FRAMECTRL_SHIFT_SADDR); mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT,
memcpy(&iob->io_data[iob->io_len], &priv->addr.saddr, 2); txdesc);
iob->io_len += 2;
} }
/* 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 */ /* Save a reference of the tx descriptor */
priv->cmd_desc = txdesc; priv->cmd_desc = txdesc;