Merged in antmerlino/nuttx/ieee802154_energydetect (pull request #977)
wireless/ieee8021254: Adds support for energy detect. Adds support for energy detect by introducing a new radio call/callback, as the PHY layer is required to perform the energy detect. Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
70186874e3
commit
90317a9eeb
@ -467,6 +467,7 @@ FAR struct ieee802154_radio_s *
|
||||
dev->radio.txnotify = mrf24j40_txnotify;
|
||||
dev->radio.txdelayed = mrf24j40_txdelayed;
|
||||
dev->radio.rxenable = mrf24j40_rxenable;
|
||||
dev->radio.energydetect = mrf24j40_energydetect;
|
||||
dev->radio.beaconstart = mrf24j40_beaconstart;
|
||||
dev->radio.beaconupdate = mrf24j40_beaconupdate;
|
||||
dev->radio.beaconstop = mrf24j40_beaconstop;
|
||||
|
@ -426,6 +426,11 @@ int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int mrf24j40_energydetect(FAR struct ieee802154_radio_s *radio, uint32_t nsymbols)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
int mrf24j40_reset(FAR struct ieee802154_radio_s *radio)
|
||||
{
|
||||
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||
|
@ -57,6 +57,8 @@ int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio,
|
||||
|
||||
int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable);
|
||||
|
||||
int mrf24j40_energydetect(FAR struct ieee802154_radio_s *radio, uint32_t nsymbols);
|
||||
|
||||
int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio,
|
||||
FAR const struct ieee802154_superframespec_s *sfspec,
|
||||
FAR struct ieee802154_beaconframe_s *beacon);
|
||||
|
@ -1425,11 +1425,14 @@ struct ieee802154_scan_conf_s
|
||||
enum ieee802154_status_e status;
|
||||
enum ieee802154_scantype_e type;
|
||||
uint8_t chpage;
|
||||
uint8_t unscanned[15];
|
||||
|
||||
uint8_t chlist[15]; /* Used for both scanned channels (ED) and unscanned
|
||||
* channels (Active/Passive) */
|
||||
uint8_t numunscanned;
|
||||
uint8_t numdesc;
|
||||
|
||||
struct ieee802154_pandesc_s pandescs[MAC802154_NPANDESC];
|
||||
uint8_t edlist[MAC802154_NPANDESC];
|
||||
uint8_t edlist[15];
|
||||
uint8_t numresults;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -118,6 +118,8 @@ struct ieee802154_radiocb_s
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
CODE void (*sfevent) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
enum ieee802154_sfevent_e sfevent);
|
||||
CODE void (*edresult) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
uint8_t edval);
|
||||
};
|
||||
|
||||
struct ieee802154_radio_s
|
||||
@ -136,6 +138,8 @@ struct ieee802154_radio_s
|
||||
FAR struct ieee802154_txdesc_s *txdesc,
|
||||
uint32_t symboldelay);
|
||||
CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable);
|
||||
CODE int (*energydetect) (FAR struct ieee802154_radio_s *radio,
|
||||
uint32_t symboldelay);
|
||||
CODE int (*beaconstart)(FAR struct ieee802154_radio_s *radio,
|
||||
FAR const struct ieee802154_superframespec_s *sfspec,
|
||||
FAR struct ieee802154_beaconframe_s *beacon);
|
||||
|
@ -88,6 +88,9 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
static void mac802154_rxframe_worker(FAR void *arg);
|
||||
|
||||
static void mac802154_edresult(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
uint8_t edval);
|
||||
|
||||
static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
enum ieee802154_sfevent_e sfevent);
|
||||
|
||||
@ -1635,6 +1638,45 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_edresult
|
||||
*
|
||||
* Description:
|
||||
* Called from the radio driver through the callback struct. This
|
||||
* function is called when the radio has finished an energy detect operation.
|
||||
* This is triggered by a SCAN.request primitive with ScanType set to Energy
|
||||
* Detect (ED)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_edresult(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
uint8_t edval)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
mac802154_lock(priv, false);
|
||||
|
||||
/* If we are actively performing a scan operation, notify the scan handler */
|
||||
|
||||
if (priv->curr_op == MAC802154_OP_SCAN)
|
||||
{
|
||||
mac802154_edscan_onresult(priv, edval);
|
||||
}
|
||||
|
||||
/* Relinquish control of the private structure */
|
||||
|
||||
mac802154_unlock(priv);
|
||||
}
|
||||
|
||||
static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
enum ieee802154_sfevent_e sfevent)
|
||||
{
|
||||
@ -2125,6 +2167,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
||||
radiocb->txdone = mac802154_txdone;
|
||||
radiocb->rxframe = mac802154_rxframe;
|
||||
radiocb->sfevent = mac802154_sfevent;
|
||||
radiocb->edresult = mac802154_edresult;
|
||||
|
||||
/* Bind our callback structure */
|
||||
|
||||
|
@ -150,9 +150,8 @@ struct ieee802154_privmac_s
|
||||
|
||||
/******************* Fields related to SCAN operation ***********************/
|
||||
|
||||
/* List of PAN descriptors to track during scan procedures */
|
||||
|
||||
uint8_t scanindex;
|
||||
uint8_t edlist[15];
|
||||
uint8_t npandesc;
|
||||
struct ieee802154_pandesc_s pandescs[MAC802154_NPANDESC];
|
||||
uint8_t panidbeforescan[IEEE802154_PANIDSIZE];
|
||||
|
@ -124,11 +124,13 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
||||
priv->scanindex = 0;
|
||||
priv->npandesc = 0;
|
||||
|
||||
priv->scansymdur = IEEE802154_BASE_SUPERFRAME_DURATION * ((1 << req->duration) + 1);
|
||||
|
||||
switch (req->type)
|
||||
{
|
||||
case IEEE802154_SCANTYPE_PASSIVE:
|
||||
{
|
||||
wlinfo("MLME: Starting Passive scan\n");
|
||||
wlinfo("MLME: Starting Passive Scan\n");
|
||||
|
||||
/* Set the channel to the first channel in the list */
|
||||
|
||||
@ -154,9 +156,6 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
||||
*/
|
||||
|
||||
mac802154_rxenable(priv);
|
||||
|
||||
priv->scansymdur = IEEE802154_BASE_SUPERFRAME_DURATION *
|
||||
((1 << req->duration) + 1);
|
||||
mac802154_timerstart(priv, priv->scansymdur, mac802154_scantimeout);
|
||||
}
|
||||
break;
|
||||
@ -168,8 +167,15 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
||||
break;
|
||||
case IEEE802154_SCANTYPE_ED:
|
||||
{
|
||||
ret = -ENOTTY;
|
||||
goto errout_with_sem;
|
||||
wlinfo("MLME: Starting Energy Scan\n");
|
||||
|
||||
/* Set the channel to the first channel in the list, and trigger an
|
||||
* energy detect operation with the radio layer.
|
||||
*/
|
||||
|
||||
mac802154_setchpage(priv, req->chpage);
|
||||
mac802154_setchannel(priv, req->channels[priv->scanindex]);
|
||||
priv->radio->energydetect(priv->radio, priv->scansymdur);
|
||||
}
|
||||
break;
|
||||
case IEEE802154_SCANTYPE_ORPHAN:
|
||||
@ -213,33 +219,105 @@ void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv,
|
||||
scanconf->type = priv->currscan.type;
|
||||
scanconf->chpage = priv->currscan.chpage;
|
||||
|
||||
/* Copy in the channels that did not get scanned */
|
||||
|
||||
if (priv->scanindex != priv->currscan.numchan)
|
||||
if (priv->currscan.type == IEEE802154_SCANTYPE_ED)
|
||||
{
|
||||
scanconf->numunscanned = priv->currscan.numchan - priv->scanindex;
|
||||
memcpy(scanconf->unscanned, &priv->currscan.channels[priv->scanindex],
|
||||
scanconf->numunscanned);
|
||||
/* "The list of energy measurements, one for each channel searched during an
|
||||
* ED scan. This parameter is null for active, passive, and orphan scans." [1]
|
||||
*/
|
||||
|
||||
memcpy(scanconf->edlist, priv->edlist, sizeof(scanconf->edlist));
|
||||
memcpy(scanconf->chlist, priv->currscan.channels, sizeof(scanconf->chlist));
|
||||
scanconf->numresults = priv->currscan.numchan;
|
||||
}
|
||||
|
||||
/* Copy the PAN descriptors into the primitive */
|
||||
else
|
||||
{
|
||||
/* "A list of the channels given in the request which were not scanned. This
|
||||
* parameter is not valid for ED scans." [1]
|
||||
*/
|
||||
|
||||
memcpy(scanconf->pandescs, priv->pandescs,
|
||||
sizeof(struct ieee802154_pandesc_s) * priv->npandesc);
|
||||
scanconf->numunscanned = priv->currscan.numchan - priv->scanindex;
|
||||
if (scanconf->numunscanned)
|
||||
{
|
||||
memcpy(scanconf->chlist, &priv->currscan.channels[priv->scanindex],
|
||||
scanconf->numunscanned);
|
||||
}
|
||||
|
||||
/* "The list of PAN descriptors, one for each beacon found during an active or
|
||||
* passive scan if macAutoRequest is set to TRUE. This parameter is null for
|
||||
* ED and orphan scans or when macAutoRequest is set to FALSE during an
|
||||
* active or passive scan." [1]
|
||||
*/
|
||||
|
||||
if (priv->currscan.type != IEEE802154_SCANTYPE_ORPHAN && priv->autoreq)
|
||||
{
|
||||
memcpy(scanconf->pandescs, priv->pandescs,
|
||||
sizeof(struct ieee802154_pandesc_s) * priv->npandesc);
|
||||
scanconf->numresults = priv->npandesc;
|
||||
}
|
||||
|
||||
if (priv->currscan.type == IEEE802154_SCANTYPE_PASSIVE)
|
||||
{
|
||||
/* Reset the PAN ID to the setting before the scan started */
|
||||
|
||||
mac802154_setpanid(priv, priv->panidbeforescan);
|
||||
}
|
||||
}
|
||||
|
||||
scanconf->numdesc = priv->npandesc;
|
||||
scanconf->status = status;
|
||||
|
||||
/* Reset the PAN ID to the setting before the scan started */
|
||||
|
||||
mac802154_setpanid(priv, priv->panidbeforescan);
|
||||
|
||||
priv->curr_op = MAC802154_OP_NONE;
|
||||
mac802154_givesem(&priv->opsem);
|
||||
|
||||
mac802154_notify(priv, primitive);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_edscan_onresult
|
||||
*
|
||||
* Description:
|
||||
* Function indirectly called from the radio layer via the radiocb edresult()
|
||||
* call.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the priv mac struct locked
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mac802154_edscan_onresult(FAR struct ieee802154_privmac_s *priv, uint8_t edval)
|
||||
{
|
||||
DEBUGASSERT(priv->curr_op == MAC802154_OP_SCAN &&
|
||||
priv->currscan.type == IEEE802154_SCANTYPE_ED);
|
||||
|
||||
/* Copy the energy value into our local list */
|
||||
|
||||
priv->edlist[priv->scanindex] = edval;
|
||||
|
||||
/* If we got here it means we are done scanning that channel */
|
||||
|
||||
priv->scanindex++;
|
||||
|
||||
/* Check to see if this was the last channel to scan */
|
||||
|
||||
if (priv->scanindex == priv->currscan.numchan)
|
||||
{
|
||||
mac802154_scanfinish(priv, IEEE802154_STATUS_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Continue on with the next channel in the list */
|
||||
|
||||
mac802154_setchannel(priv, priv->currscan.channels[priv->scanindex]);
|
||||
|
||||
/* ...after switching to the channel for a passive scan, the device
|
||||
* shall enable its receiver for at most
|
||||
* [aBaseSuperframeDuration × (2 * n + 1)],
|
||||
* where n is the value of the ScanDuration parameter. [1] pg. 25
|
||||
*/
|
||||
|
||||
priv->radio->energydetect(priv->radio, priv->scansymdur);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -60,6 +60,8 @@
|
||||
|
||||
struct ieee802154_privmac_s; /* Forward Reference */
|
||||
|
||||
void mac802154_edscan_onresult(FAR struct ieee802154_privmac_s *priv, uint8_t edval);
|
||||
|
||||
void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv,
|
||||
enum ieee802154_status_e status);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user