Dawn Framework 1.0
Universal data acquisition framework for embedded systems
lte.cxx
1// dawn/src/porting/nuttx/lte.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// LTE data-connection bring-up implemented on top of the common (target
6// independent) NuttX LTE API (lapi). This works with any modem that
7// provides an LTE API backend - there must be NO chip-specific dependency
8// here. If a target's modem lacks a lapi backend, that backend must be
9// added in nuttx (arch) / nuttx-apps, not worked around here.
10
11#include <cerrno>
12#include <cstring>
13
14#include <lte/lapi.h>
15#include <lte/lte_api.h>
16#include <nuttx/wireless/lte/lte.h>
17
18#include "dawn/debug.hxx"
19#include "dawn/porting/lte.hxx"
20
21using namespace dawn;
22
23//***************************************************************************
24// Private Data
25//***************************************************************************
26
27static uint32_t g_lte_status = DAWN_LTE_STATUS_DOWN;
28
29//***************************************************************************
30// Public Functions
31//***************************************************************************
32
33//***************************************************************************
34// Name: lte_port_set_psave
35//***************************************************************************
36
37int lte_port_set_psave(uint8_t mode)
38{
39 // Apply a power-save mode (PSM / eDRX / none) through the LTE API - the
40 // chip-specific AT translation lives in the modem's lapi backend. "none"
41 // keeps the device reachable for server-initiated requests; PSM and eDRX
42 // trade reachability for power. Can be called at runtime to retune (e.g. a
43 // userspace coexistence policy switching modes to let GNSS acquire).
44
45 lte_psm_setting_t psm;
46 lte_edrx_setting_t edrx;
47 int ret;
48
49 std::memset(&psm, 0, sizeof(psm));
50 std::memset(&edrx, 0, sizeof(edrx));
51
52 if (mode == DAWN_LTE_PSAVE_PSM)
53 {
54 // PSM on, matching Nordic's GNSS sample: long TAU so the device sleeps
55 // (freeing the radio for a GNSS cold fix) but a non-zero active time so
56 // it keeps a downlink window for server reads after each uplink. The
57 // sample uses RAT = 6 s active, RPTAU = several hours.
58
59 psm.enable = LTE_ENABLE;
60 psm.req_active_time.unit = LTE_PSM_T3324_UNIT_2SEC;
61 psm.req_active_time.time_val = 3; // 3 x 2 s = 6 s active time
62 psm.ext_periodic_tau_time.unit = LTE_PSM_T3412_UNIT_10MIN;
63 psm.ext_periodic_tau_time.time_val = 6; // 6 x 10 min = 60 min TAU
64 edrx.act_type = LTE_EDRX_ACTTYPE_NOTUSE;
65 edrx.enable = LTE_DISABLE;
66 }
67 else if (mode == DAWN_LTE_PSAVE_EDRX)
68 {
69 // eDRX on (~20 s cycle), PSM off.
70
71 psm.enable = LTE_DISABLE;
72 edrx.act_type = LTE_EDRX_ACTTYPE_WBS1;
73 edrx.enable = LTE_ENABLE;
74 edrx.edrx_cycle = LTE_EDRX_CYC_2048;
75 edrx.ptw_val = LTE_EDRX_PTW_512;
76 }
77 else
78 {
79 // none: disable both, stay always reachable.
80
81 psm.enable = LTE_DISABLE;
82 edrx.act_type = LTE_EDRX_ACTTYPE_NOTUSE;
83 edrx.enable = LTE_DISABLE;
84 }
85
86 ret = lte_set_psm_sync(&psm);
87 if (ret < 0)
88 {
89 DAWNERR("lte_set_psm_sync failed %d\n", ret);
90 }
91
92 ret = lte_set_edrx_sync(&edrx);
93 if (ret < 0)
94 {
95 DAWNERR("lte_set_edrx_sync failed %d\n", ret);
96 }
97
98 return OK;
99}
100
101//***************************************************************************
102// Name: lte_port_connect
103//***************************************************************************
104
105int lte_port_connect(const struct dawn::SLteParams *params)
106{
107 lte_apn_setting_t apn;
108 lte_pdn_t pdn;
109 int ret;
110
111 // Initialize the LTE API. -EALREADY just means it is already up.
112
113 ret = lte_initialize();
114 if (ret < 0 && ret != -EALREADY)
115 {
116 DAWNERR("lte_initialize failed %d\n", ret);
117 return ret;
118 }
119
120 // Power on the modem.
121
122 ret = lte_power_on();
123 if (ret < 0 && ret != -EALREADY)
124 {
125 DAWNERR("lte_power_on failed %d\n", ret);
126 return ret;
127 }
128
129 // Apply the requested power-save mode. Best effort: handled inside.
130
131 lte_port_set_psave(params->psave_mode);
132
133 // Turn the radio on and search/attach to the network (blocking).
134
135 ret = lte_radio_on_sync();
136 if (ret < 0)
137 {
138 DAWNERR("lte_radio_on_sync failed %d\n", ret);
139 return ret;
140 }
141
142 // Activate the packet data network (assigns an IP address). An APN is
143 // generally required; when none is configured we still pass an empty APN
144 // with the initial-attach type to let the network/SIM pick the default.
145
146 std::memset(&apn, 0, sizeof(apn));
147
148 apn.apn = const_cast<char *>(params->apn != nullptr ? params->apn : "");
149 apn.ip_type = params->ip_type;
150 apn.auth_type = params->auth_type;
151 apn.apn_type = LTE_APN_TYPE_DEFAULT | LTE_APN_TYPE_IA;
152
153 if (params->username != nullptr && params->username[0] != '\0')
154 {
155 apn.user_name = const_cast<char *>(params->username);
156 }
157
158 if (params->password != nullptr && params->password[0] != '\0')
159 {
160 apn.password = const_cast<char *>(params->password);
161 }
162
163 ret = lte_activate_pdn_sync(&apn, &pdn);
164 if (ret < 0)
165 {
166 DAWNERR("lte_activate_pdn_sync failed %d (apn='%s')\n", ret, apn.apn);
167 return ret;
168 }
169
170 DAWNINFO("LTE connected: session %d, %d address(es)\n", pdn.session_id, pdn.ipaddr_num);
171
172 g_lte_status = DAWN_LTE_STATUS_CONNECTED;
173
174 return OK;
175}
176
177//***************************************************************************
178// Name: lte_port_disconnect
179//***************************************************************************
180
181int lte_port_disconnect(void)
182{
183 int ret;
184
185 ret = lte_power_off();
186 if (ret < 0 && ret != -EALREADY)
187 {
188 DAWNERR("lte_power_off failed %d\n", ret);
189 }
190
191 g_lte_status = DAWN_LTE_STATUS_DOWN;
192
193 return OK;
194}
195
196//***************************************************************************
197// Name: lte_port_status
198//***************************************************************************
199
200int lte_port_status(uint32_t *status)
201{
202 *status = g_lte_status;
203 return OK;
204}
205
206//***************************************************************************
207// Name: lte_port_get_quality
208//***************************************************************************
209
210int lte_port_get_quality(struct dawn::SLteQuality *quality)
211{
212 lte_quality_t q;
213 int ret;
214
215 ret = lte_get_quality_sync(&q);
216 if (ret < 0)
217 {
218 return ret;
219 }
220
221 quality->valid = q.valid;
222 quality->rsrp = q.rsrp;
223 quality->rsrq = q.rsrq;
224 quality->sinr = q.sinr;
225 quality->rssi = q.rssi;
226
227 return OK;
228}
229
230//***************************************************************************
231// Name: lte_port_get_cellinfo
232//***************************************************************************
233
234int lte_port_get_cellinfo(struct dawn::SLteCellinfo *info)
235{
236 lte_cellinfo_t cell;
237 int ret;
238
239 // No neighbor-cell list requested.
240
241 std::memset(&cell, 0, sizeof(cell));
242 cell.nr_neighbor = 0;
243 cell.neighbors = nullptr;
244
245 ret = lte_get_cellinfo_sync(&cell);
246 if (ret < 0)
247 {
248 return ret;
249 }
250
251 info->valid = cell.valid;
252 info->band = static_cast<uint16_t>(cell.earfcn);
253
254 return OK;
255}
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
@ DAWN_LTE_PSAVE_EDRX
extended DRX
Definition lte.hxx:42
@ DAWN_LTE_PSAVE_PSM
Power Saving Mode.
Definition lte.hxx:41
@ DAWN_LTE_STATUS_CONNECTED
Connected (PDN active, IP assigned)
Definition lte.hxx:52
@ DAWN_LTE_STATUS_DOWN
Not connected.
Definition lte.hxx:51
Parameters used to bring up an LTE data connection.
Definition lte.hxx:64
bool valid
Values are meaningful only when true (RF on, camped).
Definition lte.hxx:65
int16_t rssi
Received Signal Strength Indicator, dBm.
Definition lte.hxx:69
int16_t rsrp
Reference Signal Received Power, dBm (-140..0).
Definition lte.hxx:66
int16_t sinr
Signal to Interference + Noise Ratio, dB (-128..40).
Definition lte.hxx:68
int16_t rsrq
Reference Signal Received Quality, dB (-60..0).
Definition lte.hxx:67