ieee802154: Finishes beacon association functionality
This commit is contained in:
parent
6b17d5ccc9
commit
b981ced4d4
File diff suppressed because it is too large
Load Diff
@ -593,19 +593,10 @@ struct ieee802154_pandesc_s
|
||||
* in symbols */
|
||||
};
|
||||
|
||||
struct ieee802154_pend_addr_s
|
||||
struct ieee802154_pendaddr_s
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t pa_spec;
|
||||
struct
|
||||
{
|
||||
uint8_t num_short_addr : 3; /* Number of short addresses pending */
|
||||
uint8_t reserved_3 : 1; /* Reserved bit */
|
||||
uint8_t num_ext_addr : 3; /* Number of extended addresses pending */
|
||||
uint8_t reserved_7 : 1; /* Reserved bit */
|
||||
} pa_addr;
|
||||
} u;
|
||||
uint8_t nsaddr : 3; /* Number of short addresses pending */
|
||||
uint8_t neaddr : 3; /* Number of extended addresses pending */
|
||||
struct ieee802154_addr_s addr[7]; /* Array of at most 7 addresses */
|
||||
};
|
||||
|
||||
@ -632,7 +623,7 @@ union ieee802154_macattr_u
|
||||
|
||||
bool is_assoc;
|
||||
bool assocpermit;
|
||||
bool auto_req;
|
||||
bool autoreq;
|
||||
bool batt_life_ext;
|
||||
bool gts_permit;
|
||||
bool promisc_mode;
|
||||
@ -1112,7 +1103,7 @@ struct ieee802154_disassoc_conf_s
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
struct ieee802154_beaconnotify_ind_s
|
||||
struct ieee802154_beacon_ind_s
|
||||
{
|
||||
uint8_t bsn; /* Beacon sequence number */
|
||||
|
||||
@ -1122,20 +1113,11 @@ struct ieee802154_beaconnotify_ind_s
|
||||
|
||||
/* Beacon pending addresses */
|
||||
|
||||
struct ieee802154_pend_addr_s pend_addr;
|
||||
|
||||
uint8_t sdu_length; /* Number of octets contained in the beacon
|
||||
* payload of the received beacond frame */
|
||||
|
||||
/* Beacon payload */
|
||||
|
||||
uint8_t sdu[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
|
||||
struct ieee802154_pendaddr_s pendaddr;
|
||||
uint8_t payloadlength; /* # of octets contained in the beacon payload */
|
||||
uint8_t payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
|
||||
};
|
||||
|
||||
#define SIZEOF_IEEE802154_BEACONNOTIFY_IND_S(n) \
|
||||
(sizeof(struct ieee802154_beaconnotify_ind_s) \
|
||||
- IEEE802154_MAX_BEACON_PAYLOAD_LEN + (n))
|
||||
|
||||
/*****************************************************************************
|
||||
* Primitive: MLME-COMM-STATUS.indication
|
||||
*
|
||||
@ -1538,21 +1520,21 @@ union ieee802154_notif_u
|
||||
|
||||
/* MLME Notifications */
|
||||
|
||||
struct ieee802154_assoc_conf_s assocconf;
|
||||
struct ieee802154_disassoc_conf_s disassocconf;
|
||||
struct ieee802154_gts_conf_s gtsconf;
|
||||
struct ieee802154_rxenable_conf_s rxenableconf;
|
||||
struct ieee802154_scan_conf_s scanconf;
|
||||
struct ieee802154_start_conf_s startconf;
|
||||
struct ieee802154_poll_conf_s pollconf;
|
||||
struct ieee802154_assoc_conf_s assocconf;
|
||||
struct ieee802154_disassoc_conf_s disassocconf;
|
||||
struct ieee802154_gts_conf_s gtsconf;
|
||||
struct ieee802154_rxenable_conf_s rxenableconf;
|
||||
struct ieee802154_scan_conf_s scanconf;
|
||||
struct ieee802154_start_conf_s startconf;
|
||||
struct ieee802154_poll_conf_s pollconf;
|
||||
|
||||
struct ieee802154_assoc_ind_s assocind;
|
||||
struct ieee802154_disassoc_ind_s disassocind;
|
||||
struct ieee802154_beaconnotify_ind_s beaconnotifyind;
|
||||
struct ieee802154_gts_ind_s gtsind;
|
||||
struct ieee802154_orphan_ind_s orphanind;
|
||||
struct ieee802154_commstatus_ind_s commstatusind;
|
||||
struct ieee802154_syncloss_ind_s synclossind;
|
||||
struct ieee802154_assoc_ind_s assocind;
|
||||
struct ieee802154_disassoc_ind_s disassocind;
|
||||
struct ieee802154_beacon_ind_s beaconind;
|
||||
struct ieee802154_gts_ind_s gtsind;
|
||||
struct ieee802154_orphan_ind_s orphanind;
|
||||
struct ieee802154_commstatus_ind_s commstatusind;
|
||||
struct ieee802154_syncloss_ind_s synclossind;
|
||||
};
|
||||
|
||||
struct ieee802154_notif_s
|
||||
|
@ -1528,51 +1528,181 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
* Function called from the generic RX Frame worker to parse and handle the
|
||||
* reception of a beacon frame.
|
||||
*
|
||||
* Assumptions: MAC is locked
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
||||
FAR struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
FAR struct iob_s *iob = ind->frame;
|
||||
struct ieee802154_pandesc_s pandesc;
|
||||
FAR struct ieee802154_txdesc_s *respdesc;
|
||||
uint8_t numgtsdesc;
|
||||
FAR struct ieee802154_notif_s *notif;
|
||||
FAR struct ieee802154_beacon_ind_s *beacon;
|
||||
FAR struct iob_s *iob = ind->frame;
|
||||
uint8_t ngtsdesc;
|
||||
uint8_t gtsdirmask;
|
||||
uint8_t npendsaddr;
|
||||
uint8_t npendeaddr;
|
||||
bool pending_saddr = false;
|
||||
bool pending_eaddr = false;
|
||||
int i;
|
||||
|
||||
/* Even though we may not use the notification, we use a notification to
|
||||
* hold all the parsed beacon information. Freeing the notification is quick,
|
||||
* so it's worth saving a copy (If you were to parse all the info in locally,
|
||||
* you would have to copy the data over in the case that you actually need
|
||||
* to notify the next highest layer)
|
||||
*/
|
||||
|
||||
mac802154_notif_alloc(priv, ¬if, false);
|
||||
beacon = ¬if->u.beaconind;
|
||||
|
||||
/* Make sure there is another 2 bytes to process */
|
||||
|
||||
if (iob->io_len < iob->io_offset + 2)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Copy the coordinator address and channel info into the pan descriptor */
|
||||
|
||||
memcpy(&pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s));
|
||||
pandesc.chan = priv->currscan.channels[priv->scanindex];
|
||||
pandesc.chpage = priv->currscan.chpage;
|
||||
pandesc.lqi = ind->lqi;
|
||||
pandesc.timestamp = ind->timestamp;
|
||||
memcpy(&beacon->pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s));
|
||||
beacon->pandesc.chan = priv->currscan.channels[priv->scanindex];
|
||||
beacon->pandesc.chpage = priv->currscan.chpage;
|
||||
beacon->pandesc.lqi = ind->lqi;
|
||||
beacon->pandesc.timestamp = ind->timestamp;
|
||||
|
||||
/* Parse the superframe specification field */
|
||||
|
||||
pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data,
|
||||
iob->io_offset);
|
||||
beacon->pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data,
|
||||
iob->io_offset);
|
||||
|
||||
beacon->pandesc.sfspec.sforder =
|
||||
IEEE802154_GETSFORDER(iob->io_data, iob->io_offset);
|
||||
|
||||
beacon->pandesc.sfspec.final_capslot =
|
||||
IEEE802154_GETFINCAPSLOT(iob->io_data, iob->io_offset);
|
||||
|
||||
beacon->pandesc.sfspec.ble =
|
||||
IEEE802154_GETBLE(iob->io_data, iob->io_offset);
|
||||
|
||||
beacon->pandesc.sfspec.pancoord =
|
||||
IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset);
|
||||
|
||||
beacon->pandesc.sfspec.assocpermit =
|
||||
IEEE802154_GETASSOCPERMIT(iob->io_data, iob->io_offset);
|
||||
|
||||
pandesc.sfspec.sforder = IEEE802154_GETSFORDER(iob->io_data, iob->io_offset);
|
||||
pandesc.sfspec.final_capslot = IEEE802154_GETFINCAPSLOT(iob->io_data,
|
||||
iob->io_offset);
|
||||
pandesc.sfspec.ble = IEEE802154_GETBLE(iob->io_data, iob->io_offset);
|
||||
pandesc.sfspec.pancoord = IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset);
|
||||
pandesc.sfspec.assocpermit = IEEE802154_GETASSOCPERMIT(iob->io_data,
|
||||
iob->io_offset);
|
||||
iob->io_offset += 2;
|
||||
|
||||
/* Make sure there is another byte to process (GTS Spec) */
|
||||
|
||||
if (iob->io_len < iob->io_offset + 1)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Parse the GTS Specification field */
|
||||
|
||||
numgtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset);
|
||||
pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset);
|
||||
ngtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset);
|
||||
beacon->pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset);
|
||||
iob->io_offset++;
|
||||
|
||||
/* We only need to parse the rest of the frame if we are not performing a
|
||||
* scan
|
||||
*/
|
||||
/* If there are any GTS descriptors, handle the GTS Dir and GTS List fields */
|
||||
|
||||
if (ngtsdesc > 0)
|
||||
{
|
||||
/* Make sure there is another bytes to process (GTS Direction) */
|
||||
|
||||
if (iob->io_len < iob->io_offset + 1)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset);
|
||||
iob->io_offset++;
|
||||
|
||||
/* Make sure there are enough bytes left to represent the GTS List */
|
||||
|
||||
if (iob->io_len < iob->io_offset + (3 * ngtsdesc))
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (i = 0; i < ngtsdesc; i++)
|
||||
{
|
||||
/* For now we just discard the data by skipping over it */
|
||||
|
||||
iob->io_offset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pending address fields. Min 1 byte, the Pending Address Specification */
|
||||
|
||||
if (iob->io_len < iob->io_offset + 1)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
beacon->pendaddr.nsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset);
|
||||
beacon->pendaddr.neaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset);
|
||||
iob->io_offset++;
|
||||
|
||||
/* Make sure there are enough bytes left to represent the address list */
|
||||
|
||||
if (iob->io_len < (iob->io_offset +
|
||||
(IEEE802154_SADDRSIZE * beacon->pendaddr.nsaddr) +
|
||||
(IEEE802154_EADDRSIZE * beacon->pendaddr.neaddr)))
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Copy in the pending addresses */
|
||||
|
||||
for (i = 0; i < beacon->pendaddr.nsaddr; i++)
|
||||
{
|
||||
beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_SHORT;
|
||||
mac802154_takesaddr(iob, beacon->pendaddr.addr[i].saddr);
|
||||
|
||||
/* Check if the short address matches our short address */
|
||||
|
||||
if (IEEE802154_SADDRCMP(beacon->pendaddr.addr[i].saddr, priv->addr.saddr))
|
||||
{
|
||||
/* Wait to actually decide how to handle this until we parse
|
||||
* the rest of the frame
|
||||
*/
|
||||
wlinfo("Data pending for us in coord\n");
|
||||
pending_saddr = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = beacon->pendaddr.nsaddr;
|
||||
i < (beacon->pendaddr.nsaddr + beacon->pendaddr.neaddr);
|
||||
i++)
|
||||
{
|
||||
beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_EXTENDED;
|
||||
|
||||
mac802154_takeeaddr(iob, beacon->pendaddr.addr[i].eaddr);
|
||||
|
||||
/* If the extended address matches our extended address */
|
||||
|
||||
if (IEEE802154_EADDRCMP(beacon->pendaddr.addr[i].eaddr, priv->addr.eaddr))
|
||||
{
|
||||
/* Wait to actually decide how to handle this until we parse
|
||||
* the rest of the frame
|
||||
*/
|
||||
wlinfo("Data pending for us in coord\n");
|
||||
pending_eaddr = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is anything left in the frame, process it as the beacon payload */
|
||||
|
||||
beacon->payloadlength = iob->io_len - iob->io_offset;
|
||||
|
||||
if (beacon->payloadlength > 0)
|
||||
{
|
||||
memcpy(beacon->payload, &iob->io_data[iob->io_offset], beacon->payloadlength);
|
||||
}
|
||||
|
||||
/* At this point, we have extracted all relevant info from the incoming frame */
|
||||
|
||||
if (priv->curr_op == MAC802154_OP_SCAN)
|
||||
{
|
||||
@ -1586,19 +1716,30 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
||||
}
|
||||
|
||||
if (memcmp(&ind->src, &priv->pandescs[i].coordaddr,
|
||||
sizeof(struct ieee802154_addr_s)))
|
||||
sizeof(struct ieee802154_addr_s)) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The beacon is the same as another, so discard it */
|
||||
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: There is supposed to be different logic for the scanning procedure
|
||||
* based on the macAutoRequest attribute. Currently, we perform scan
|
||||
* operations as if macAutoRequest is set to TRUE, without actually checking
|
||||
* the value. Basically, if macAutoRequest is TRUE, we are supposed to
|
||||
* round up all of the pandesc results and pass them all up via the
|
||||
* SCAN.confirm primitive. If macAutoRequest is FALSE, we are supposed
|
||||
* to notify the next highest layer each time a unique beacon is received
|
||||
* via the BEACON.notify primitive, and pass a NULLed out list of pandesc
|
||||
* when SCAN.confirm is sent.
|
||||
*/
|
||||
|
||||
/* Copy the pan desc to the list of pan desc */
|
||||
|
||||
memcpy(&priv->pandescs[priv->npandesc], &pandesc,
|
||||
memcpy(&priv->pandescs[priv->npandesc], &beacon->pandesc,
|
||||
sizeof(struct ieee802154_pandesc_s));
|
||||
priv->npandesc++;
|
||||
|
||||
@ -1607,101 +1748,116 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
||||
mac802154_scanfinish(priv, IEEE802154_STATUS_LIMITREACHED);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are not performing a SCAN operation */
|
||||
|
||||
else
|
||||
{
|
||||
/* If there are any GTS descriptors, handle the GTS Directions and
|
||||
* GTS List fields
|
||||
*/
|
||||
|
||||
if (numgtsdesc > 0)
|
||||
{
|
||||
gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset);
|
||||
iob->io_offset++;
|
||||
|
||||
for (i = 0; i < numgtsdesc; i++)
|
||||
{
|
||||
/* For now we just discard the data by skipping over it */
|
||||
|
||||
iob->io_offset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pending address fields. Min 1 byte, the Pending Address Specification */
|
||||
|
||||
npendsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset);
|
||||
npendeaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset);
|
||||
iob->io_offset++;
|
||||
|
||||
/* The pending address field tells us whether or not there is any data
|
||||
* pending for us.
|
||||
*/
|
||||
|
||||
for (i = 0; i < npendsaddr; i++)
|
||||
{
|
||||
/* If the short address matches our short address */
|
||||
|
||||
if (IEEE802154_SADDRCMP(&iob->io_data[iob->io_offset], priv->addr.saddr))
|
||||
{
|
||||
/* TODO: Handle data pending in coordinator for us */
|
||||
}
|
||||
iob->io_offset += IEEE802154_SADDRSIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < npendeaddr; i++)
|
||||
{
|
||||
/* If the extended address matches our extended address */
|
||||
|
||||
if (IEEE802154_EADDRCMP(&iob->io_data[iob->io_offset], priv->addr.eaddr))
|
||||
{
|
||||
/* If we are associating, polling, or if macAutoRequest is TRUE,
|
||||
* extract the data.
|
||||
*/
|
||||
|
||||
if ((priv->autoreq) || (priv->curr_op == MAC802154_OP_ASSOC) ||
|
||||
(priv->curr_op == MAC802154_OP_POLL))
|
||||
{
|
||||
mac802154_txdesc_alloc(priv, &respdesc, false);
|
||||
|
||||
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
||||
|
||||
if (priv->curr_op == MAC802154_OP_ASSOC ||
|
||||
priv->curr_op == MAC802154_OP_POLL)
|
||||
{
|
||||
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||
}
|
||||
|
||||
/* Link the transaction into the CSMA transaction list */
|
||||
|
||||
sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
|
||||
|
||||
/* Notify the radio driver that there is data available */
|
||||
|
||||
priv->radio->txnotify(priv->radio, false);
|
||||
}
|
||||
}
|
||||
iob->io_offset += IEEE802154_EADDRSIZE;
|
||||
}
|
||||
|
||||
/* TODO: Process incoming beacon payload
|
||||
* If there is anything left in the frame, process it as the beacon payload
|
||||
*/
|
||||
|
||||
/* Check the superframe structure and update the appropriate attributes. */
|
||||
|
||||
if (memcmp(&priv->sfspec, &pandesc.sfspec,
|
||||
sizeof(struct ieee802154_superframespec_s)) != 0)
|
||||
if (memcmp(&priv->sfspec, &beacon->pandesc.sfspec,
|
||||
sizeof(struct ieee802154_superframespec_s)) != 0)
|
||||
{
|
||||
/* Copy in the new superframe spec */
|
||||
|
||||
memcpy(&priv->sfspec, &pandesc.sfspec,
|
||||
sizeof(struct ieee802154_superframespec_s));
|
||||
memcpy(&priv->sfspec, &beacon->pandesc.sfspec,
|
||||
sizeof(struct ieee802154_superframespec_s));
|
||||
|
||||
/* Tell the radio layer about the superframe spec update */
|
||||
|
||||
priv->radio->sfupdate(priv->radio, &pandesc.sfspec);
|
||||
priv->radio->sfupdate(priv->radio, &priv->sfspec);
|
||||
}
|
||||
|
||||
/* If we are performing an association and there is data pending for us
|
||||
* we ignore the autoRequest logic and just extract it. We also don't
|
||||
* send a BEACON-NOTFIY.indication in this case, not sure if that
|
||||
* is the right thing to do, can't find anything definitive in standard.
|
||||
*/
|
||||
|
||||
if (priv->curr_op == MAC802154_OP_ASSOC && pending_eaddr)
|
||||
{
|
||||
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||
mac802154_txdesc_alloc(priv, &respdesc, false);
|
||||
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
||||
|
||||
/* Link the transaction into the CSMA transaction list */
|
||||
|
||||
sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
|
||||
|
||||
/* Notify the radio driver that there is data available */
|
||||
|
||||
priv->radio->txnotify(priv->radio, false);
|
||||
}
|
||||
else if (!priv->autoreq)
|
||||
{
|
||||
/* If a valid beacon frame is received and macAutoRequest is set to FALSE,
|
||||
* the MLME shall indicate the beacon parameters to the next higher layer
|
||||
* by issuing the MLME-BEACON-NOTIFY.indication primitive. [1] pg. 38
|
||||
*/
|
||||
|
||||
/* Unlock the MAC, notify, then lock again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
return; /* Return so that we don't free the notificaiton */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If a beacon frame is received and macAutoRequest is set to TRUE, the
|
||||
* MLME shall first issue the MLME- BEACON-NOTIFY.indication primitive if
|
||||
* the beacon contains any payload.
|
||||
*/
|
||||
|
||||
if (beacon->payloadlength > 0)
|
||||
{
|
||||
/* Unlock the MAC, notify, then lock again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
return; /* Return so that we don't free the notificaiton */
|
||||
}
|
||||
|
||||
/* If we have data pending for us, attempt to extract it. If for some
|
||||
* reason we have data pending under our short address and our
|
||||
* extended address, let the short address arbitrarily take precedence
|
||||
*/
|
||||
|
||||
if (pending_saddr | pending_eaddr)
|
||||
{
|
||||
mac802154_txdesc_alloc(priv, &respdesc, false);
|
||||
|
||||
if (pending_saddr)
|
||||
{
|
||||
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||
IEEE802154_ADDRMODE_SHORT, respdesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
||||
}
|
||||
|
||||
/* Link the transaction into the CSMA transaction list */
|
||||
|
||||
sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
|
||||
|
||||
/* Notify the radio driver that there is data available */
|
||||
|
||||
priv->radio->txnotify(priv->radio, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
mac802154_notif_free_locked(priv, notif);
|
||||
return;
|
||||
|
||||
errout:
|
||||
wlwarn("Received beacon with bad format\n");
|
||||
mac802154_notif_free_locked(priv, notif);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1864,6 +2020,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
||||
|
||||
if (mac == NULL)
|
||||
{
|
||||
wlinfo("Failed allocation privmac structure\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1883,8 +2040,6 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
||||
|
||||
mac->radio = radiodev;
|
||||
|
||||
mac802154_req_reset((MACHANDLE)mac, true);
|
||||
|
||||
/* Initialize the Radio callbacks */
|
||||
|
||||
mac->radiocb.priv = mac;
|
||||
@ -1904,16 +2059,16 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
||||
ieee802154_indpool_initialize();
|
||||
mac802154_resetqueues(mac);
|
||||
|
||||
mac802154_req_reset((MACHANDLE)mac, true);
|
||||
|
||||
/* Set the default extended address */
|
||||
|
||||
for (i = 0; i < IEEE802154_EADDRSIZE; i++)
|
||||
{
|
||||
eaddr[i] = (CONFIG_IEEE802154_DEFAULT_EADDR >> (8 * i)) & 0xFF;
|
||||
}
|
||||
|
||||
IEEE802154_EADDRCOPY(mac->addr.eaddr, eaddr);
|
||||
mac->radio->setattr(mac->radio, IEEE802154_ATTR_MAC_EADDR,
|
||||
(union ieee802154_attr_u *)&eaddr[0]);
|
||||
|
||||
mac802154_seteaddr(mac, eaddr);
|
||||
|
||||
return (MACHANDLE)mac;
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ int mac802154_req_associate(MACHANDLE mac,
|
||||
FAR struct iob_s *iob;
|
||||
bool rxonidle;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (req->coordaddr.mode == IEEE802154_ADDRMODE_NONE)
|
||||
{
|
||||
@ -248,14 +249,68 @@ int mac802154_req_associate(MACHANDLE mac,
|
||||
|
||||
priv->cmd_desc = txdesc;
|
||||
|
||||
/* Search the list of PAN descriptors, that would have been populated by the
|
||||
* latest scan procedure. If we have seen a beacon from the coordinator that
|
||||
* we are about to associate with, we can check the beacon order to determine
|
||||
* whether we can send the command during the CAP. If we haven't received
|
||||
* a beacon frame from the desired coordinator address, we have to just
|
||||
* send the frame out immediately.
|
||||
*/
|
||||
|
||||
for (i = 0; i < priv->npandesc; i++)
|
||||
{
|
||||
/* Check to make sure the beacon is from the same channel as the request */
|
||||
|
||||
if (req->chan != priv->pandescs[i].chan)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(&req->coordaddr, &priv->pandescs[i].coordaddr,
|
||||
sizeof(struct ieee802154_addr_s)) == 0)
|
||||
{
|
||||
wlinfo("Found matching beacon to use for settings\n");
|
||||
|
||||
/* We have a beacon frame from this coordinator, we can set the
|
||||
* sfspec and send accordingly.
|
||||
*/
|
||||
|
||||
/* Copy in the new superframe spec */
|
||||
|
||||
memcpy(&priv->sfspec, &priv->pandescs[i].sfspec,
|
||||
sizeof(struct ieee802154_superframespec_s));
|
||||
|
||||
/* Tell the radio layer about the superframe spec update */
|
||||
|
||||
priv->radio->sfupdate(priv->radio, &priv->pandescs[i].sfspec);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->sfspec.beaconorder == 15)
|
||||
{
|
||||
wlinfo("Transmitting assoc request\n");
|
||||
|
||||
/* Association Request command gets sent out immediately */
|
||||
|
||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
wlinfo("Queuing assoc request for CAP\n");
|
||||
|
||||
/* Link the transaction into the CSMA transaction list */
|
||||
|
||||
sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue);
|
||||
|
||||
/* Notify the radio driver that there is data available */
|
||||
|
||||
priv->radio->txnotify(priv->radio, false);
|
||||
}
|
||||
|
||||
/* We no longer need to have the MAC layer locked. */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
/* Association Request command gets sent out immediately */
|
||||
|
||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -173,8 +173,8 @@ static void macnet_ind_associate(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_assoc_ind_s *conf);
|
||||
static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_disassoc_ind_s *conf);
|
||||
static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_beaconnotify_ind_s *conf);
|
||||
static void macnet_ind_beacon(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_beacon_ind_s *conf);
|
||||
static void macnet_ind_gts(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_gts_ind_s *conf);
|
||||
static void macnet_ind_orphan(FAR struct macnet_driver_s *priv,
|
||||
@ -589,15 +589,15 @@ static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_ind_beaconnotify
|
||||
* Name: macnet_ind_beacon
|
||||
*
|
||||
* Description:
|
||||
* Beacon notification
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_beaconnotify_ind_s *ind)
|
||||
static void macnet_ind_beacon(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_beacon_ind_s *ind)
|
||||
{
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user