Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 187 additions & 10 deletions arch/arm/src/nrf91/nrf91_modem_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,124 @@ static int nrf91_modem_actpdn(FAR lte_apn_setting_t *apn,
return OK;
}

/****************************************************************************
* Name: nrf91_modem_bits
*
* Description:
* Format the low 'nbits' of 'value' as a binary string (MSB first), as
* used by the 3GPP timer fields of AT+CPSMS and AT+CEDRXS.
*
Comment thread
raiden00pl marked this conversation as resolved.
* Input Parameters:
* value - Value to format.
* nbits - Number of low-order bits to emit.
* out - Output buffer (must hold at least nbits + 1 bytes).
*
* Returned Value:
* None.
*
****************************************************************************/

static void nrf91_modem_bits(uint8_t value, int nbits, FAR char *out)
{
int i;

for (i = 0; i < nbits; i++)
{
out[i] = (value & (1 << (nbits - 1 - i))) ? '1' : '0';
}

out[nbits] = '\0';
}

/****************************************************************************
* Name: nrf91_modem_setpsm
*
* Description:
* Apply PSM settings (LTE_CMDID_SETPSM) by translating the LAPI
* lte_psm_setting_t into the AT+CPSMS command.
*
Comment thread
raiden00pl marked this conversation as resolved.
* Input Parameters:
* psm - PSM settings to apply.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/

static int nrf91_modem_setpsm(FAR lte_psm_setting_t *psm)
{
/* LAPI timer-unit enums -> 3GPP encoded unit bits (TS 24.008 GPRS timers).
* T3412 extended (periodic TAU) and T3324 (active time).
*/

static const uint8_t t3412[] =
{
3, 4, 5, 0, 1, 2, 6, 7 /* 2s,30s,1m,10m,1h,10h,320h,deact */
};

static const uint8_t t3324[] =
{
0, 1, 2, 7 /* 2s,1m,6m,deact */
};

char tau[9];
char act[9];
uint8_t b;

if (!psm->enable)
{
return nrf_modem_at_printf("AT+CPSMS=0");
}

b = (uint8_t)((t3412[psm->ext_periodic_tau_time.unit & 0x7] << 5) |
(psm->ext_periodic_tau_time.time_val & 0x1f));
nrf91_modem_bits(b, 8, tau);

b = (uint8_t)((t3324[psm->req_active_time.unit & 0x3] << 5) |
(psm->req_active_time.time_val & 0x1f));
nrf91_modem_bits(b, 8, act);

return nrf_modem_at_printf("AT+CPSMS=1,,,\"%s\",\"%s\"", tau, act);
}

/****************************************************************************
* Name: nrf91_modem_setedrx
*
* Description:
* Apply eDRX settings (LTE_CMDID_SETEDRX) by translating the LAPI
* lte_edrx_setting_t into the AT+CEDRXS command.
*
Comment thread
raiden00pl marked this conversation as resolved.
* Input Parameters:
* edrx - eDRX settings to apply.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/

static int nrf91_modem_setedrx(FAR lte_edrx_setting_t *edrx)
{
char value[5];
int acttype;

if (!edrx->enable || edrx->act_type == LTE_EDRX_ACTTYPE_NOTUSE)
{
/* Disable eDRX and discard any stored value */

return nrf_modem_at_printf("AT+CEDRXS=3");
}

/* AT+CEDRXS access technology: 4 = E-UTRAN WB-S1 (LTE-M),
* 5 = E-UTRAN NB-S1 (NB-IoT). The LAPI eDRX cycle enum matches the 4-bit
* 3GPP requested-eDRX value directly.
*/

acttype = (edrx->act_type == LTE_EDRX_ACTTYPE_NBS1) ? 5 : 4;
nrf91_modem_bits((uint8_t)(edrx->edrx_cycle & 0xf), 4, value);

return nrf_modem_at_printf("AT+CEDRXS=2,%d,\"%s\"", acttype, value);
}

/****************************************************************************
* Name: nrf91_ioctl_ltecmd
****************************************************************************/
Expand Down Expand Up @@ -683,42 +801,101 @@ static int nrf91_ioctl_ltecmd(int fd, int cmd, unsigned long arg)
{
lte_quality_t **quality =
(lte_quality_t **)(ltecmd->outparam + 1);
bool valid = false;
int cresult;
int tmp;
int rsrp;
int rsrq;
int rssi;
int snr;

(*quality)->rsrp = 0;
(*quality)->rsrq = 0;
(*quality)->rssi = 0;
(*quality)->sinr = 0;

/* RSRP/RSRQ via AT+CESQ - available whenever the modem is camped. */

ret = nrf_modem_at_scanf("AT+CESQ",
"+CESQ: %d,%d,%d,%d,%d,%d",
&tmp, &tmp, &tmp, &tmp,
&rsrq, &rsrp);
if (ret > 0)
{
(*quality)->rsrq = (rsrq / 2) - 19;
(*quality)->rsrp = rsrp - 140;
(*quality)->rsrq = (rsrq / 2) - 19;
(*quality)->rsrp = rsrp - 140;
valid = true;
}
else
{
nerr("AT+CESQ failed %d\n", ret);
}

ret = nrf_modem_at_scanf("AT+CSQ",
"+CSQ: %d,%d",
&rssi, &tmp);
/* SNR via AT%CONEVAL - the only SNR source on this modem (AT+CSQ is
* not answered and carries no SNR). Reported SNR is the raw
* value - 24.
*/

ret = nrf_modem_at_scanf("AT%CONEVAL",
"%%CONEVAL: %d,%d,%d,%d,%d,%d",
&cresult, &tmp, &tmp, &tmp, &tmp, &snr);
if (ret >= 6 && cresult == 0)
{
(*quality)->sinr = snr - 24;
}

(*quality)->valid = valid;
ret = OK;
break;
}

case LTE_CMDID_GETCELL:
{
lte_cellinfo_t **cell =
(lte_cellinfo_t **)(ltecmd->outparam + 1);
int band = 0;

(*cell)->valid = false;
(*cell)->phycell_id = 0;
(*cell)->earfcn = 0;
(*cell)->option = 0;
(*cell)->nr_neighbor = 0;

/* The modem AT set does not expose the raw EARFCN in a form the
* scanf parser here can extract from AT%XMONITOR (quoted fields), so
* report the serving band number via AT%XCBAND in the earfcn field.
*/

ret = nrf_modem_at_scanf("AT%XCBAND", "%%XCBAND: %d", &band);
if (ret > 0)
{
(*quality)->rssi = rssi;
(*quality)->sinr = 0;
(*cell)->earfcn = (uint32_t)band;
(*cell)->valid = true;
}
else
{
nerr("AT+CSQ failed %d\n", ret);
nerr("AT%%XCBAND failed %d\n", ret);
}

(*quality)->valid = true;
ret = OK;
break;
}

case LTE_CMDID_SETPSM:
{
lte_psm_setting_t **psm =
(lte_psm_setting_t **)(ltecmd->inparam);
ret = nrf91_modem_setpsm(*psm);
break;
}

case LTE_CMDID_SETEDRX:
{
lte_edrx_setting_t **edrx =
(lte_edrx_setting_t **)(ltecmd->inparam);
ret = nrf91_modem_setedrx(*edrx);
break;
}

/* TODO: commands from include/nuttx/wireless/lte/lte.h */

default:
Expand Down
Loading