Intermittent DNS resolution failure on nRF9151 after repeated short-interval events (Telstra eSIM, Australia)

We are observing an intermittent issue on an nRF9151-based custom PCB where DNS resolution fails after repeated events occurring within a short time window, even though cellular connectivity appears to be available.

Setup and context:

  • Hardware: Custom PCB based on nRF9151

  • Firmware: nRF Connect SDK, using the CoAP sample from Nordic Dev Academy (Cellular IoT – CoAP chapter)

  • Network: Telstra (Australia) using eSIM

  • Application behavior:

    • The device wakes and attempts to send a payload whenever an alarm/event (for example, a tilt event) is triggered

    • Each event results in a cellular connect attempt, data send, and modem shutdown

    • If sending fails, a retry mechanism is used

Observed behavior:

Below is example of how device behaves
1. Leave for long time and heartbeat as expected
2. Tilt >> quick response to connect and upload
3. Tilt agin 2 mins later >> quick response to connect and upload
4. Tilt again 2 mins later >> delay then error
Missed message, missed frame count
5. Tilt again 5 mins later >> quick response to connect and upload
[15:02:48.322,601] <inf> water_rat_payload: Entering FULL zone (tilt < 30.00)
[15:02:48.330,230] <inf> water_rat_payload: Sampling started: Temp=23.95, Tilt=1.00
[15:02:48.338,409] <inf> water_rat_payload: Sample[0] => Temp=23.95, Tilt=1.00
[15:02:48.346,282] <inf> water_rat_cellular: cellular_run
[15:02:48.352,111] <inf> water_rat_cellular: Post sensor data
[15:02:48.358,428] <inf> cellular_manager: post_sensor_data_to_coap
[15:02:48.565,521] <inf> cellular_manager: H:54.28,T:23.95,Z:1.00,B:3648mV
[15:02:48.572,875] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:02:48.580,993] <inf> cellular_manager: Timer status: Running
[15:02:48.587,493] <inf> cellular_manager: Remaining ticks: 30287248
[15:02:49.451,293] <inf> water_rat_payload: Sample[1] => Temp=23.96, Tilt=0.80
[15:02:49.459,106] <inf> water_rat_cellular: cellular_run
[15:02:49.464,965] <inf> water_rat_cellular: Post sensor data
[15:02:49.471,252] <inf> cellular_manager: post_sensor_data_to_coap
[15:02:49.678,375] <inf> cellular_manager: H:54.28,T:23.96,Z:0.80,B:3664mV
[15:02:49.685,729] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:02:49.693,847] <inf> cellular_manager: Timer status: Running
[15:02:49.700,378] <inf> cellular_manager: Remaining ticks: 30286135
[15:02:50.564,086] <inf> water_rat_payload: Sample[2] => Temp=23.96, Tilt=0.32
[15:02:50.571,899] <inf> water_rat_cellular: cellular_run
[15:02:50.577,728] <inf> water_rat_cellular: Post sensor data
[15:02:50.584,045] <inf> cellular_manager: post_sensor_data_to_coap
[15:02:50.791,137] <inf> cellular_manager: H:54.28,T:23.96,Z:0.32,B:3656mV
[15:02:50.798,492] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:02:50.806,610] <inf> cellular_manager: Timer status: Running
[15:02:50.813,140] <inf> cellular_manager: Remaining ticks: 30285022
[15:02:51.676,788] <inf> water_rat_payload: Sample[3] => Temp=23.97, Tilt=0.50
DotcomWR 2243 testing
[15:02:51.684,570] <inf> water_rat_cellular: cellular_run
[15:02:51.690,429] <inf> water_rat_cellular: Post sensor data
[15:02:51.696,746] <inf> cellular_manager: post_sensor_data_to_coap
[15:02:51.903,839] <inf> cellular_manager: H:54.28,T:23.97,Z:0.50,B:3658mV
[15:02:51.911,193] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:02:51.919,311] <inf> cellular_manager: Timer status: Running
[15:02:51.925,842] <inf> cellular_manager: Remaining ticks: 30283910
[15:02:52.789,459] <inf> water_rat_payload: Sample[4] => Temp=23.98, Tilt=0.50
[15:02:52.797,180] <inf> water_rat_payload: Tilt FULL confirmed -> Alarm triggered
[15:02:53.005,432] <inf> water_rat_payload: Sampling cycle complete, system ready for
next trigger.
[15:02:53.015,075] <inf> water_rat_cellular: cellular_run
[15:02:53.020,904] <inf> water_rat_cellular: Post sensor data
[15:02:53.027,221] <inf> cellular_manager: post_sensor_data_to_coap
[15:02:53.234,313] <inf> cellular_manager: H:54.28,T:23.98,Z:0.50,B:3650mV
[15:02:53.241,668] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:02:53.248,992] <inf> cellular_manager: Initializing modem...
[15:02:53.527,557] <inf> cellular_manager: Modem initialized successfully.
[15:02:53.542,419] <inf> cellular_manager: Connecting to LTE network
[15:02:53.622,375] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:02:57.619,750] <inf> cellular_manager: RRC mode: Connected
[15:02:58.461,334] <inf> cellular_manager: Network registration status: Connected - home
network
[15:02:58.470,916] <inf> cellular_manager: Connected to LTE network
[15:02:58.477,661] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:02:58.804,229] <inf> cellular_manager: IPv4 Address found 3.104.31.166
[15:02:58.812,347] <inf> cellular_manager: Successfully connected to server
[15:02:59.022,857] <inf> cellular_manager: CoAP POST request sent: Token 0x1b74
[15:02:59.030,639] <inf> cellular_manager: CoAP POST sensor data request sent
[15:02:59.038,299] <inf> cellular_manager: CoAP POST sensor data request done
[15:02:59.046,051] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:02:59.053,436] <inf> cellular_retry_handler: set_sensor_retry_flag for attemp: 1
[15:02:59.061,767] <inf> cellular_manager: Timer status: Running
[15:02:59.068,267] <inf> cellular_manager: Remaining ticks: 30276767
[15:02:59.339,691] <inf> cellular_manager: CoAP response: Code 0x44, Token 0x1b74,
Payload: 2.03
[15:02:59.349,334] <inf> cellular_manager: Shutting down modem...
[15:02:59.861,907] <inf> cellular_manager: RRC mode: Idle
[15:03:00.646,209] <inf> cellular_manager: Modem shutdown complete.
[15:03:53.120,025] <inf> water_rat_cellular: cellular_run
[15:03:53.125,885] <inf> water_rat_cellular: Post sensor data
[15:03:53.132,171] <inf> cellular_manager: post_sensor_data_to_coap
[15:03:53.339,294] <inf> cellular_manager: H:54.31,T:24.01,Z:0.32,B:3650mV
[15:03:53.346,649] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:03:53.354,766] <inf> cellular_manager: Timer status: Running
[15:03:53.361,297] <inf> cellular_manager: Remaining ticks: 30222474
[15:04:53.225,036] <inf> water_rat_payload: Entering EMPTY zone (tilt >= 30.00)
[15:04:53.232,849] <inf> water_rat_payload: Sampling started: Temp=24.10, Tilt=55.84
DotcomWR 2243 testing
[15:04:53.241,149] <inf> water_rat_payload: Sample[0] => Temp=24.10, Tilt=55.84
[15:04:53.249,053] <inf> water_rat_cellular: cellular_run
[15:04:53.254,913] <inf> water_rat_cellular: Post sensor data
[15:04:53.261,230] <inf> cellular_manager: post_sensor_data_to_coap
[15:04:53.468,322] <inf> cellular_manager: H:54.33,T:24.10,Z:55.84,B:3654mV
[15:04:53.475,769] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:04:53.483,886] <inf> cellular_manager: Timer status: Running
[15:04:53.490,417] <inf> cellular_manager: Remaining ticks: 30162345
[15:04:54.354,125] <inf> water_rat_payload: Sample[1] => Temp=24.11, Tilt=55.31
[15:04:54.361,999] <inf> water_rat_cellular: cellular_run
[15:04:54.367,858] <inf> water_rat_cellular: Post sensor data
[15:04:54.374,176] <inf> cellular_manager: post_sensor_data_to_coap
[15:04:54.581,268] <inf> cellular_manager: H:54.31,T:24.11,Z:55.31,B:3654mV
[15:04:54.588,714] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:04:54.596,832] <inf> cellular_manager: Timer status: Running
[15:04:54.603,424] <inf> cellular_manager: Remaining ticks: 30161232
[15:04:55.467,041] <inf> water_rat_payload: Sample[2] => Temp=24.11, Tilt=55.90
[15:04:55.474,914] <inf> water_rat_cellular: cellular_run
[15:04:55.480,773] <inf> water_rat_cellular: Post sensor data
[15:04:55.487,091] <inf> cellular_manager: post_sensor_data_to_coap
[15:04:55.694,183] <inf> cellular_manager: H:54.33,T:24.11,Z:55.90,B:3656mV
[15:04:55.701,629] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:04:55.709,747] <inf> cellular_manager: Timer status: Running
[15:04:55.716,278] <inf> cellular_manager: Remaining ticks: 30160119
[15:04:56.579,956] <inf> water_rat_payload: Sample[3] => Temp=24.12, Tilt=55.59
[15:04:56.587,860] <inf> water_rat_cellular: cellular_run
[15:04:56.593,719] <inf> water_rat_cellular: Post sensor data
[15:04:56.600,006] <inf> cellular_manager: post_sensor_data_to_coap
[15:04:56.807,128] <inf> cellular_manager: H:54.32,T:24.12,Z:55.59,B:3662mV
[15:04:56.814,605] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:04:56.822,692] <inf> cellular_manager: Timer status: Running
[15:04:56.829,284] <inf> cellular_manager: Remaining ticks: 30159006
[15:04:57.692,749] <inf> water_rat_payload: Sample[4] => Temp=24.11, Tilt=55.42
[15:04:57.700,592] <inf> water_rat_payload: Tilt EMPTY confirmed -> Alarm triggered
[15:04:57.908,935] <inf> water_rat_payload: Sampling cycle complete, system ready for
next trigger.
[15:04:57.918,579] <inf> water_rat_cellular: cellular_run
[15:04:57.924,438] <inf> water_rat_cellular: Post sensor data
[15:04:57.930,725] <inf> cellular_manager: post_sensor_data_to_coap
[15:04:58.137,786] <inf> cellular_manager: H:54.34,T:24.11,Z:55.42,B:3658mV
[15:04:58.145,233] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:04:58.152,557] <inf> cellular_manager: Initializing modem...
[15:04:58.431,060] <inf> cellular_manager: Modem initialized successfully.
[15:04:58.445,922] <inf> cellular_manager: Connecting to LTE network
[15:04:58.525,909] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:05:06.325,286] <inf> cellular_manager: RRC mode: Connected
[15:05:07.210,540] <inf> cellular_manager: Network registration status: Connected - home
network
DotcomWR 2243 testing
[15:05:07.220,153] <inf> cellular_manager: Connected to LTE network
[15:05:07.226,928] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:05:10.805,725] <inf> cellular_manager: IPv4 Address found 3.104.31.166
[15:05:10.813,873] <inf> cellular_manager: Successfully connected to server
[15:05:11.024,688] <inf> cellular_manager: CoAP POST request sent: Token 0xac56
[15:05:11.032,501] <inf> cellular_manager: CoAP POST sensor data request sent
[15:05:11.040,161] <inf> cellular_manager: CoAP POST sensor data request done
[15:05:11.047,821] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:05:11.055,236] <inf> cellular_retry_handler: set_sensor_retry_flag for attemp: 1
[15:05:11.063,537] <inf> cellular_manager: Timer status: Running
[15:05:11.070,098] <inf> cellular_manager: Remaining ticks: 30144765
[15:05:14.365,417] <inf> cellular_manager: CoAP response: Code 0x44, Token 0xac56,
Payload: 2.03
[15:05:14.375,061] <inf> cellular_manager: Shutting down modem...
[15:05:14.840,606] <inf> cellular_manager: RRC mode: Idle
[15:05:15.022,552] <inf> cellular_manager: Modem shutdown complete.
[15:05:58.023,559] <inf> water_rat_cellular: cellular_run
[15:05:58.029,418] <inf> water_rat_cellular: Post sensor data
[15:05:58.035,736] <inf> cellular_manager: post_sensor_data_to_coap
[15:05:58.242,828] <inf> cellular_manager: H:54.33,T:24.21,Z:55.43,B:3650mV
[15:05:58.250,274] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:05:58.258,392] <inf> cellular_manager: Timer status: Running
[15:05:58.264,984] <inf> cellular_manager: Remaining ticks: 30097570
[15:06:58.128,540] <inf> water_rat_cellular: cellular_run
[15:06:58.134,399] <inf> water_rat_cellular: Post sensor data
[15:06:58.140,686] <inf> cellular_manager: post_sensor_data_to_coap
[15:06:58.347,808] <inf> cellular_manager: H:54.28,T:24.20,Z:55.66,B:3650mV
[15:06:58.355,255] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:06:58.363,372] <inf> cellular_manager: Timer status: Running
[15:06:58.369,964] <inf> cellular_manager: Remaining ticks: 30037465
[15:07:58.233,276] <inf> water_rat_payload: Entering FULL zone (tilt < 30.00)
[15:07:58.240,997] <inf> water_rat_payload: Sampling started: Temp=24.21, Tilt=2.55
[15:07:58.249,206] <inf> water_rat_payload: Sample[0] => Temp=24.21, Tilt=2.55
[15:07:58.257,049] <inf> water_rat_cellular: cellular_run
[15:07:58.262,908] <inf> water_rat_cellular: Post sensor data
[15:07:58.269,226] <inf> cellular_manager: post_sensor_data_to_coap
[15:07:58.476,318] <inf> cellular_manager: H:54.28,T:24.21,Z:2.55,B:3648mV
[15:07:58.483,703] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:07:58.491,790] <inf> cellular_manager: Timer status: Running
[15:07:58.498,382] <inf> cellular_manager: Remaining ticks: 29977337
[15:07:59.362,060] <inf> water_rat_payload: Sample[1] => Temp=24.20, Tilt=2.57
[15:07:59.369,842] <inf> water_rat_cellular: cellular_run
[15:07:59.375,701] <inf> water_rat_cellular: Post sensor data
[15:07:59.382,019] <inf> cellular_manager: post_sensor_data_to_coap
[15:07:59.589,111] <inf> cellular_manager: H:54.24,T:24.20,Z:2.57,B:3656mV
[15:07:59.596,496] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:07:59.604,583] <inf> cellular_manager: Timer status: Running
[15:07:59.611,175] <inf> cellular_manager: Remaining ticks: 29976224
DotcomWR 2243 testing
[15:08:00.474,884] <inf> water_rat_payload: Sample[2] => Temp=24.20, Tilt=2.56
[15:08:00.482,696] <inf> water_rat_cellular: cellular_run
[15:08:00.488,555] <inf> water_rat_cellular: Post sensor data
[15:08:00.494,842] <inf> cellular_manager: post_sensor_data_to_coap
[15:08:00.701,934] <inf> cellular_manager: H:54.28,T:24.20,Z:2.56,B:3650mV
[15:08:00.709,320] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:08:00.717,407] <inf> cellular_manager: Timer status: Running
[15:08:00.723,999] <inf> cellular_manager: Remaining ticks: 29975111
[15:08:01.587,707] <inf> water_rat_payload: Sample[3] => Temp=24.20, Tilt=2.56
[15:08:01.595,520] <inf> water_rat_cellular: cellular_run
[15:08:01.601,379] <inf> water_rat_cellular: Post sensor data
[15:08:01.607,696] <inf> cellular_manager: post_sensor_data_to_coap
[15:08:01.814,788] <inf> cellular_manager: H:54.29,T:24.20,Z:2.56,B:3640mV
[15:08:01.822,174] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:08:01.830,291] <inf> cellular_manager: Timer status: Running
[15:08:01.836,853] <inf> cellular_manager: Remaining ticks: 29973999
[15:08:02.700,439] <inf> water_rat_payload: Sample[4] => Temp=24.20, Tilt=2.33
[15:08:02.708,190] <inf> water_rat_payload: Tilt FULL confirmed -> Alarm triggered
[15:08:02.916,442] <inf> water_rat_payload: Sampling cycle complete, system ready for
next trigger.
[15:08:02.926,086] <inf> water_rat_cellular: cellular_run
[15:08:02.931,945] <inf> water_rat_cellular: Post sensor data
[15:08:02.938,232] <inf> cellular_manager: post_sensor_data_to_coap
[15:08:03.145,294] <inf> cellular_manager: H:54.29,T:24.20,Z:2.33,B:3654mV
[15:08:03.152,648] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:08:03.159,973] <inf> cellular_manager: Initializing modem...
[15:08:03.438,598] <inf> cellular_manager: Modem initialized successfully.
[15:08:03.453,460] <inf> cellular_manager: Connecting to LTE network
[15:08:03.533,447] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:08:09.623,291] <inf> cellular_manager: RRC mode: Connected
[15:09:02.976,287] <wrn> water_rat_sensor_manager: SENSOR MANAGER PAUSE
[15:10:02.983,764] <wrn> water_rat_sensor_manager: SENSOR MANAGER PAUSE
[15:11:02.991,241] <wrn> water_rat_sensor_manager: SENSOR MANAGER PAUSE
[15:12:02.998,718] <wrn> water_rat_sensor_manager: SENSOR MANAGER PAUSE
[15:12:23.118,865] <inf> cellular_manager: RRC mode: Idle
[15:12:31.797,332] <inf> cellular_manager: RRC mode: Connected
[15:12:34.587,615] <inf> cellular_manager: Network registration status: Connected - home
network
[15:12:34.597,229] <inf> cellular_manager: Connected to LTE network
[15:12:34.603,973] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:13:03.060,943] <inf> water_rat_cellular: cellular_run
[15:13:03.066,772] <inf> water_rat_cellular: Post sensor data
[15:13:03.823,120] <inf> cellular_manager: RRC mode: Idle
[15:14:03.165,924] <inf> water_rat_cellular: cellular_run
[15:14:03.171,752] <inf> water_rat_cellular: Post sensor data
[15:14:57.597,503] <err> cellular_manager: ERROR: getaddrinfo failed -11
[15:14:57.604,949] <inf> cellular_manager: Failed to resolve server name
[15:14:57.612,182] <inf> cellular_manager: Shutting down modem...
DotcomWR 2243 testing
[15:15:03.270,721] <inf> water_rat_cellular: cellular_run
[15:15:03.276,672] <inf> water_rat_cellular: Post sensor data
[15:15:11.798,706] <inf> cellular_manager: Modem shutdown complete.
[15:15:12.006,103] <err> water_rat_esim: AT+CESQ(err: -1): +CESQ: 99,99,255,255,19,43
OK
[15:15:12.015,197] <err> water_rat_payload: Error: -1
[15:15:12.021,636] <err> cellular_manager: Failed to send CoAP request, 9
[15:15:12.029,174] <err> cellular_manager: Failed to send CoAP POST request: -9
[15:15:12.037,292] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:15:12.044,708] <inf> cellular_retry_handler: set_sensor_retry_flag for attemp: 1
[15:15:12.053,100] <inf> cellular_manager: Timer status: Running
[15:15:12.059,570] <inf> cellular_manager: Remaining ticks: 29543776
[15:15:12.066,467] <inf> cellular_manager: post_sensor_data_to_coap
[15:15:12.273,620] <inf> cellular_manager: H:54.18,T:24.74,Z:3.05,B:3614mV
[15:15:12.281,066] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:15:12.289,184] <inf> cellular_manager: Timer status: Running
[15:15:12.295,715] <inf> cellular_manager: Remaining ticks: 29543540
[15:15:12.302,612] <inf> cellular_manager: post_sensor_data_to_coap
[15:15:12.509,735] <inf> cellular_manager: H:54.18,T:24.74,Z:3.05,B:3620mV
[15:15:12.517,089] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:15:12.525,207] <inf> cellular_manager: Timer status: Running
[15:15:12.531,738] <inf> cellular_manager: Remaining ticks: 29543304
[15:15:12.538,604] <inf> cellular_manager: post_sensor_data_to_coap
[15:15:12.745,727] <inf> cellular_manager: H:54.18,T:24.74,Z:3.05,B:3606mV
[15:15:12.753,082] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:15:12.761,199] <inf> cellular_manager: Timer status: Running
[15:15:12.767,730] <inf> cellular_manager: Remaining ticks: 29543068
[15:16:03.375,823] <inf> water_rat_cellular: cellular_run
[15:16:03.381,683] <inf> water_rat_cellular: Post sensor data
[15:16:03.387,969] <inf> cellular_manager: post_sensor_data_to_coap
[15:16:03.595,092] <inf> cellular_manager: H:54.14,T:24.72,Z:2.34,B:3610mV
[15:16:03.602,447] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:16:03.610,565] <inf> cellular_manager: Timer status: Running
[15:16:03.617,095] <inf> cellular_manager: Remaining ticks: 29492218
[15:17:03.480,926] <inf> water_rat_cellular: cellular_run
[15:17:03.486,785] <inf> water_rat_cellular: Post sensor data
[15:17:03.493,072] <inf> cellular_manager: post_sensor_data_to_coap
[15:17:03.700,195] <inf> cellular_manager: H:54.10,T:24.64,Z:2.12,B:3612mV
[15:17:03.707,580] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:17:03.715,698] <inf> cellular_manager: Timer status: Running
[15:17:03.722,259] <inf> cellular_manager: Remaining ticks: 29432113
[15:18:03.586,029] <inf> water_rat_cellular: cellular_run
[15:18:03.591,888] <inf> water_rat_cellular: Post sensor data
[15:18:03.598,205] <inf> cellular_manager: post_sensor_data_to_coap
[15:18:03.805,297] <inf> cellular_manager: H:54.06,T:24.62,Z:2.89,B:3628mV
[15:18:03.812,683] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
DotcomWR 2243 testing
[15:18:03.820,800] <inf> cellular_manager: Timer status: Running
[15:18:03.827,362] <inf> cellular_manager: Remaining ticks: 29372008
[15:19:03.690,917] <inf> water_rat_payload: Entering EMPTY zone (tilt >= 30.00)
[15:19:03.698,730] <inf> water_rat_payload: Sampling started: Temp=24.64, Tilt=49.80
[15:19:03.707,031] <inf> water_rat_payload: Sample[0] => Temp=24.64, Tilt=49.80
[15:19:03.714,965] <inf> water_rat_cellular: cellular_run
[15:19:03.720,825] <inf> water_rat_cellular: Post sensor data
[15:19:03.727,142] <inf> cellular_manager: post_sensor_data_to_coap
[15:19:03.934,234] <inf> cellular_manager: H:54.06,T:24.64,Z:49.80,B:3642mV
[15:19:03.941,680] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:19:03.949,829] <inf> cellular_manager: Timer status: Running
[15:19:03.956,390] <inf> cellular_manager: Remaining ticks: 29311879
[15:19:04.819,854] <inf> water_rat_payload: Sample[1] => Temp=24.64, Tilt=49.45
[15:19:04.827,758] <inf> water_rat_cellular: cellular_run
[15:19:04.833,618] <inf> water_rat_cellular: Post sensor data
[15:19:04.839,935] <inf> cellular_manager: post_sensor_data_to_coap
[15:19:05.047,027] <inf> cellular_manager: H:54.08,T:24.64,Z:49.45,B:3628mV
[15:19:05.054,504] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:19:05.062,622] <inf> cellular_manager: Timer status: Running
[15:19:05.069,183] <inf> cellular_manager: Remaining ticks: 29310766
[15:19:05.932,647] <inf> water_rat_payload: Sample[2] => Temp=24.64, Tilt=50.11
[15:19:05.940,551] <inf> water_rat_cellular: cellular_run
[15:19:05.946,411] <inf> water_rat_cellular: Post sensor data
[15:19:05.952,728] <inf> cellular_manager: post_sensor_data_to_coap
[15:19:06.159,820] <inf> cellular_manager: H:54.09,T:24.64,Z:50.11,B:3632mV
[15:19:06.167,297] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:19:06.175,415] <inf> cellular_manager: Timer status: Running
[15:19:06.181,945] <inf> cellular_manager: Remaining ticks: 29309653
[15:19:07.045,440] <inf> water_rat_payload: Sample[3] => Temp=24.64, Tilt=49.79
[15:19:07.053,344] <inf> water_rat_cellular: cellular_run
[15:19:07.059,204] <inf> water_rat_cellular: Post sensor data
[15:19:07.065,490] <inf> cellular_manager: post_sensor_data_to_coap
[15:19:07.272,583] <inf> cellular_manager: H:54.05,T:24.64,Z:49.79,B:3642mV
[15:19:07.280,059] <inf> cellular_manager: No alarm triggered. Skipping CoAP POST.
[15:19:07.288,177] <inf> cellular_manager: Timer status: Running
[15:19:07.294,708] <inf> cellular_manager: Remaining ticks: 29308541
[15:19:08.158,203] <inf> water_rat_payload: Sample[4] => Temp=24.64, Tilt=49.33
[15:19:08.166,046] <inf> water_rat_payload: Tilt EMPTY confirmed -> Alarm triggered
[15:19:08.374,420] <inf> water_rat_payload: Sampling cycle complete, system ready for
next trigger.
[15:19:08.384,063] <inf> water_rat_cellular: cellular_run
[15:19:08.389,923] <inf> water_rat_cellular: Post sensor data
[15:19:08.396,240] <inf> cellular_manager: post_sensor_data_to_coap
[15:19:08.603,332] <inf> cellular_manager: H:54.09,T:24.64,Z:49.33,B:3630mV
[15:19:08.610,778] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:19:08.618,103] <inf> cellular_manager: Initializing modem...
[15:19:08.896,759] <inf> cellular_manager: Modem initialized successfully.
[15:19:08.911,621] <inf> cellular_manager: Connecting to LTE network
DotcomWR 2243 testing
[15:19:08.991,577] <inf> water_rat_sensor_manager: Sensor sampling paused
[15:19:15.562,255] <inf> cellular_manager: RRC mode: Connected
[15:19:17.284,515] <inf> cellular_manager: Network registration status: Connected - home
network
[15:19:17.294,097] <inf> cellular_manager: Connected to LTE network
[15:19:17.300,964] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:19:20.491,638] <inf> cellular_manager: IPv4 Address found 3.104.31.166
[15:19:20.500,000] <inf> cellular_manager: Successfully connected to server
[15:19:20.710,418] <inf> cellular_manager: CoAP POST request sent: Token 0x3ed9
[15:19:20.718,231] <inf> cellular_manager: CoAP POST sensor data request sent
[15:19:20.725,921] <inf> cellular_manager: CoAP POST sensor data request done
[15:19:20.733,642] <inf> water_rat_sensor_manager: Sensor sampling resumed
[15:19:20.741,058] <inf> cellular_retry_handler: set_sensor_retry_flag for attemp: 2
[15:19:20.749,389] <inf> cellular_manager: Timer status: Running
[15:19:20.755,889] <inf> cellular_manager: Remaining ticks: 29295080
[15:19:23.292,358] <inf> cellular_manager: CoAP response: Code 0x44, Token 0x3ed9,
Payload: 2.03
[15:19:23.302,032] <inf> cellular_manager: Shutting down modem...
[15:19:23.671,997] <inf> cellular_manager: RRC mode: Idle
[15:19:24.456,268] <inf> cellular_manager: Modem shutdown complete.

  • When multiple events are triggered within a few minutes, the device eventually fails to send a message

  • The logs show that the modem successfully initializes and connects to the LTE network, but then fails during DNS resolution

Example log sequence:

In some cases, the time to reach “Connected to LTE network” is unusually long (several minutes), whereas in this location we typically see 10–15 seconds.

This behavior can be reproduced by triggering multiple events in close succession. Allowing a longer idle period or rebooting the device usually restores normal operation.

What we have ruled out so far:

  • This does not appear to be a general nRF9151 issue, as the nRF9151 DK does not show this behavior under similar conditions

  • The modem does successfully register on the network and enter RRC Connected state before the failure

  • The failure point is consistently DNS resolution (getaddrinfo), not socket creation or CoAP transmission

Questions:

  1. Are there known conditions where repeated connect / disconnect cycles in a short time frame can cause transient DNS failures on LTE-M or NB-IoT networks, particularly with Telstra in Australia?

  2. Are there recommended delays, cleanup sequences, or best practices after a DNS failure before attempting a new connection?

  3. Could this behavior be related to PDP context handling, DNS caching, or network-side throttling?

  4. Are there recommended approaches when using the Nordic Dev Academy CoAP sample for applications that generate frequent short-interval uplinks?

Any insights or similar experiences would be appreciated.

Parents
  • Hi, Priyesh.

    When I was previously experimenting with the nRF9160 and nRF7002, it seemed that the first name resolution using getaddrinfo was failing. To work around this, I tried calling getaddrinfo multiple times.

    This may not be a very elegant solution, but I’ve attached the MQTT main.c for the nRF7002 that I used at the time, so please feel free to use it as a reference.

    A friend suggested that the failure might be because a DNS query is being sent before the device is fully connected to the DNS server. In any case, I handled it as a workaround, as shown in the attached main.c.

    Best regards.
    - Kenta

    /*
     * Copyright (c) 2022 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     * @brief WiFi station sample
     */
    
    #include <zephyr/logging/log.h>
    
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    
    #include <nrfx_clock.h>
    #include <zephyr/kernel.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/shell/shell.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/init.h>
    
    #include <zephyr/net/net_if.h>
    #include <zephyr/net/net_core.h>
    #include <zephyr/net/wifi.h>
    #include <zephyr/net/wifi_mgmt.h>
    #include <zephyr/net/net_event.h>
    #include <zephyr/net/dns_resolve.h>
    #include <zephyr/drivers/gpio.h>
    
    #include <qspi_if.h>
    
    #include <zephyr/net/socket.h>
    #include <zephyr/net/mqtt.h>
    #include <dk_buttons_and_leds.h>
    #include <zephyr/random/rand32.h>
    
    
    #define WIFI_SHELL_MODULE "wifi"
    
    #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_CONNECT_RESULT |		\
    				NET_EVENT_WIFI_DISCONNECT_RESULT)
    
    #define MAX_SSID_LEN        32
    #define DHCP_TIMEOUT        70
    #define CONNECTION_TIMEOUT  100
    #define DNS_TIMEOUT         CONNECTION_TIMEOUT
    #define STATUS_POLLING_MS   300
    
    
    LOG_MODULE_REGISTER(MQTT_OVER_WIFI, LOG_LEVEL_INF);
    
    
    /* The mqtt client struct */
    static struct mqtt_client client;
    
    /* File descriptor */
    static struct pollfd fds;
    
    #define RANDOM_LEN 10
    #define CLIENT_ID_LEN sizeof(CONFIG_BOARD) + 1 + RANDOM_LEN
    
    /* Buffers for MQTT client. */
    static uint8_t rx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t tx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];
    
    /* MQTT Broker details. */
    static struct sockaddr_storage broker;
    
    /**@brief Function to get the payload of recived data.
     */
    static int get_received_payload(struct mqtt_client *c, size_t length)
    {
        int ret;
        int err = 0;
    
        /* Return an error if the payload is larger than the payload buffer.
         * Note: To allow new messages, we have to read the payload before returning.
         */
        if (length > sizeof(payload_buf)) {
            err = -EMSGSIZE;
        }
    
        /* Truncate payload until it fits in the payload buffer. */
        while (length > sizeof(payload_buf)) {
            ret = mqtt_read_publish_payload_blocking(
                    c, payload_buf, (length - sizeof(payload_buf)));
            if (ret == 0) {
                return -EIO;
            } else if (ret < 0) {
                return ret;
            }
    
            length -= ret;
        }
    
        ret = mqtt_readall_publish_payload(c, payload_buf, length);
        if (ret) {
            return ret;
        }
    
        return err;
    }
    
    /**@brief Function to subscribe to the configured topic
     */
    
    static int subscribe(struct mqtt_client *const c)
    {
        struct mqtt_topic subscribe_topic = {
            .topic = {
                .utf8 = CONFIG_MQTT_SUB_TOPIC,
                .size = strlen(CONFIG_MQTT_SUB_TOPIC)
            },
            .qos = MQTT_QOS_1_AT_LEAST_ONCE
        };
    
        const struct mqtt_subscription_list subscription_list = {
            .list = &subscribe_topic,
            .list_count = 1,
            .message_id = 1234
        };
    
        LOG_INF("Subscribing to: %s len %u", CONFIG_MQTT_SUB_TOPIC,
            (unsigned int)strlen(CONFIG_MQTT_SUB_TOPIC));
    
        return mqtt_subscribe(c, &subscription_list);
    }
    
    /**@brief Function to print strings without null-termination
     */
    static void data_print(uint8_t *prefix, uint8_t *data, size_t len)
    {
        char buf[len + 1];
    
        memcpy(buf, data, len);
        buf[len] = 0;
        LOG_INF("%s%s", (char *)prefix, (char *)buf);
    }
    
    /**@brief Function to publish data on the configured topic
     */
    int data_publish(struct mqtt_client *c, enum mqtt_qos qos,
        uint8_t *data, size_t len)
    {
        struct mqtt_publish_param param;
    
        param.message.topic.qos = qos;
        param.message.topic.topic.utf8 = CONFIG_MQTT_SUB_TOPIC; //CONFIG_MQTT_PUB_TOPIC;
        param.message.topic.topic.size = strlen(CONFIG_MQTT_SUB_TOPIC); //strlen(CONFIG_MQTT_PUB_TOPIC);
        param.message.payload.data = data;
        param.message.payload.len = len;
        param.message_id = sys_rand32_get();
        param.dup_flag = 0;
        param.retain_flag = 0;
    
        data_print("Publishing: ", data, len);
        LOG_INF("to topic: %s len: %u",
            CONFIG_MQTT_PUB_TOPIC,
            (unsigned int)strlen(CONFIG_MQTT_PUB_TOPIC));
    
        return mqtt_publish(c, &param);
    }
    /**@brief MQTT client event handler
     */
    void mqtt_evt_handler(struct mqtt_client *const c,
                  const struct mqtt_evt *evt)
    {
        int err;
    
        switch (evt->type) {
        case MQTT_EVT_CONNACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT connect failed: %d", evt->result);
                break;
            }
    
            LOG_INF("MQTT client connected");
            subscribe(c);
            break;
    
        case MQTT_EVT_DISCONNECT:
            LOG_INF("MQTT client disconnected: %d", evt->result);
            break;
    
        case MQTT_EVT_PUBLISH:
        {
            const struct mqtt_publish_param *p = &evt->param.publish;
            //Print the length of the recived message
            LOG_INF("MQTT PUBLISH result=%d len=%d",
                evt->result, p->message.payload.len);
    
            //Extract the data of the recived message
            err = get_received_payload(c, p->message.payload.len);
            
            //Send acknowledgment to the broker on receiving QoS1 publish message
            if (p->message.topic.qos == MQTT_QOS_1_AT_LEAST_ONCE) {
                const struct mqtt_puback_param ack = {
                    .message_id = p->message_id
                };
    
                /* Send acknowledgment. */
                mqtt_publish_qos1_ack(c, &ack);
            }
    
            if (err >= 0) {
                data_print("Received: ", payload_buf, p->message.payload.len);
                // Control LED1 and LED2
                if(strncmp(payload_buf,CONFIG_TURN_LED1_ON_CMD,sizeof(CONFIG_TURN_LED1_ON_CMD)-1) == 0){
                    dk_set_led_on(DK_LED1);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED1_OFF_CMD,sizeof(CONFIG_TURN_LED1_OFF_CMD)-1) == 0){
                    dk_set_led_off(DK_LED1);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED2_ON_CMD,sizeof(CONFIG_TURN_LED2_ON_CMD)-1) == 0){
                    dk_set_led_on(DK_LED2);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED2_OFF_CMD,sizeof(CONFIG_TURN_LED2_OFF_CMD)-1) == 0){
                    dk_set_led_off(DK_LED2);
                }
    
            // Payload buffer is smaller than the received data
            } else if (err == -EMSGSIZE) {
                LOG_ERR("Received payload (%d bytes) is larger than the payload buffer size (%d bytes).",
                    p->message.payload.len, sizeof(payload_buf));
            // Failed to extract data, disconnect
            } else {
                LOG_ERR("get_received_payload failed: %d", err);
                LOG_INF("Disconnecting MQTT client...");
    
                err = mqtt_disconnect(c);
                if (err) {
                    LOG_ERR("Could not disconnect: %d", err);
                }
            }
        } break;
    
        case MQTT_EVT_PUBACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT PUBACK error: %d", evt->result);
                break;
            }
    
            LOG_INF("PUBACK packet id: %u", evt->param.puback.message_id);
            break;
    
        case MQTT_EVT_SUBACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT SUBACK error: %d", evt->result);
                break;
            }
    
            LOG_INF("SUBACK packet id: %u", evt->param.suback.message_id);
            break;
    
        case MQTT_EVT_PINGRESP:
            if (evt->result != 0) {
                LOG_ERR("MQTT PINGRESP error: %d", evt->result);
            }
            break;
    
        default:
            LOG_INF("Unhandled MQTT event type: %d", evt->type);
            break;
        }
    }
    
    /**@brief Resolves the configured hostname and
     * initializes the MQTT broker structure
     */
    static int broker_init(void)
    {
        int err=0;
        
        struct addrinfo *addr;
        
        static struct addrinfo *result;
        struct addrinfo hints = {
            .ai_family = AF_INET,
            .ai_socktype = SOCK_STREAM
        };
        
        err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
        
        if (err) {
            LOG_ERR("getaddrinfo failed: %d", err);
            return -ECHILD;
        }
    
        addr = result;
    
        /* Look for address of the broker. */
        while (addr != NULL) {
            /* IPv4 Address. */
            if (addr->ai_addrlen == sizeof(struct sockaddr_in)) {
                struct sockaddr_in *broker4 =
                    ((struct sockaddr_in *)&broker);
                char ipv4_addr[NET_IPV4_ADDR_LEN];
    
                broker4->sin_addr.s_addr =
                    ((struct sockaddr_in *)addr->ai_addr)
                    ->sin_addr.s_addr;
                broker4->sin_family = AF_INET;
                broker4->sin_port = htons(CONFIG_MQTT_BROKER_PORT);
    
                inet_ntop(AF_INET, &broker4->sin_addr.s_addr,
                      ipv4_addr, sizeof(ipv4_addr));
                LOG_INF("IPv4 Address found %s", (char *)(ipv4_addr));
    
                break;
            } else {
                LOG_ERR("ai_addrlen = %u should be %u or %u",
                    (unsigned int)addr->ai_addrlen,
                    (unsigned int)sizeof(struct sockaddr_in),
                    (unsigned int)sizeof(struct sockaddr_in6));
            }
    
            addr = addr->ai_next;
        }
    
        /* Free the address. */
        freeaddrinfo(result);
    
        return err;
    }
    
    /* Function to get the client id */
    static const uint8_t* client_id_get(void)
    {
        static uint8_t client_id[MAX(sizeof(CONFIG_MQTT_CLIENT_ID),
                         CLIENT_ID_LEN)];
    
        if (strlen(CONFIG_MQTT_CLIENT_ID) > 0) {
            snprintf(client_id, sizeof(client_id), "%s",
                 CONFIG_MQTT_CLIENT_ID);
            goto exit;
        }
    
        uint32_t id = sys_rand32_get();
        snprintf(client_id, sizeof(client_id), "%s-%010u", CONFIG_BOARD, id);
    
    exit:
        LOG_DBG("client_id = %s", (char *)client_id);
    
        return client_id;
    }
    
    
    /**@brief Initialize the MQTT client structure
     */
    int client_init(struct mqtt_client *client)
    {
        int err;
        /* Initializes the client instance. */
        mqtt_client_init(client);
    
        /* Resolves the configured hostname and initializes the MQTT broker structure */
        err = broker_init();
        if (err) {
            LOG_ERR("Failed to initialize broker connection");
            return err;
        }
    
        /* MQTT client configuration */
        client->broker = &broker;
        client->evt_cb = mqtt_evt_handler;
        client->client_id.utf8 = client_id_get();
        client->client_id.size = strlen(client->client_id.utf8);
        client->password = NULL;
        client->user_name = NULL;
        client->protocol_version = MQTT_VERSION_3_1_1;
    
        /* MQTT buffers configuration */
        client->rx_buf = rx_buffer;
        client->rx_buf_size = sizeof(rx_buffer);
        client->tx_buf = tx_buffer;
        client->tx_buf_size = sizeof(tx_buffer);
    
        /* We are not using TLS */
        client->transport.type = MQTT_TRANSPORT_NON_SECURE;
    
        return err;
    }
    
    /**@brief Initialize the file descriptor structure used by poll.
     */
    int fds_init(struct mqtt_client *c, struct pollfd *fds)
    {
        if (c->transport.type == MQTT_TRANSPORT_NON_SECURE) {
            fds->fd = c->transport.tcp.sock;
        } else {
            return -ENOTSUP;
        }
    
        fds->events = POLLIN;
    
        return 0;
    }
    
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    
    static struct net_mgmt_event_callback wifi_shell_mgmt_cb;
    static struct net_mgmt_event_callback net_shell_mgmt_cb;
    
    static struct {
    	const struct shell *sh;
    	union {
    		struct {
    			uint8_t connected	: 1;
    			uint8_t connect_result	: 1;
    			uint8_t disconnect_requested	: 1;
    			uint8_t _unused		: 5;
    		};
    		uint8_t all;
    	};
    } context;
    
    
    static int cmd_wifi_status(void)
    {
    	struct net_if *iface = net_if_get_default();
    	struct wifi_iface_status status = { 0 };
    
    	if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status,
    				sizeof(struct wifi_iface_status))) {
    		LOG_INF("Status request failed");
    
    		return -ENOEXEC;
    	}
    
    	LOG_INF("==================");
    	LOG_INF("State: %s", wifi_state_txt(status.state));
    
    	if (status.state >= WIFI_STATE_ASSOCIATED) {
    		uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
    
    		LOG_INF("Interface Mode: %s",
    		       wifi_mode_txt(status.iface_mode));
    		LOG_INF("Link Mode: %s",
    		       wifi_link_mode_txt(status.link_mode));
    		LOG_INF("SSID: %-32s", status.ssid);
    		LOG_INF("BSSID: %s",
    		       net_sprint_ll_addr_buf(
    				status.bssid, WIFI_MAC_ADDR_LEN,
    				mac_string_buf, sizeof(mac_string_buf)));
    		LOG_INF("Band: %s", wifi_band_txt(status.band));
    		LOG_INF("Channel: %d", status.channel);
    		LOG_INF("Security: %s", wifi_security_txt(status.security));
    		LOG_INF("MFP: %s", wifi_mfp_txt(status.mfp));
    		LOG_INF("RSSI: %d", status.rssi);
    	}
    	return 0;
    }
    
    static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb)
    {
    	const struct wifi_status *status =
    		(const struct wifi_status *) cb->info;
    
    	if (context.connected) {
    		return;
    	}
    
    	if (status->status) {
    		LOG_ERR("Connection failed (%d)", status->status);
    	} else {
    		LOG_INF("Connected");
    		context.connected = true;
    	}
        
    	context.connect_result = true;
    }
    
    static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb)
    {
    	const struct wifi_status *status =
    		(const struct wifi_status *) cb->info;
    
    	if (!context.connected) {
    		return;
    	}
    
    	if (context.disconnect_requested) {
    		LOG_INF("Disconnection request %s (%d)",
    			 status->status ? "failed" : "done",
    					status->status);
    		context.disconnect_requested = false;
    	} else {
    		LOG_INF("Received Disconnected");
    		context.connected = false;
    	}
        
    	cmd_wifi_status();
    }
    
    static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    				     uint32_t mgmt_event, struct net_if *iface)
    {
    	switch (mgmt_event) {
                
            case NET_EVENT_WIFI_CONNECT_RESULT:
                handle_wifi_connect_result(cb);
                break;
            case NET_EVENT_WIFI_DISCONNECT_RESULT:
                handle_wifi_disconnect_result(cb);
                break;
            default:
                break;
    	}
        
    }
    
    static void print_dhcp_ip(struct net_mgmt_event_callback *cb)
    {
    	/* Get DHCP info from struct net_if_dhcpv4 and print */
    	const struct net_if_dhcpv4 *dhcpv4 = cb->info;
    	const struct in_addr *addr = &dhcpv4->requested_ip;
    	char dhcp_info[128];
    
    	net_addr_ntop(AF_INET, addr, dhcp_info, sizeof(dhcp_info));
    
    	LOG_INF("DHCP IP address: %s", dhcp_info);
    }
    static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    				    uint32_t mgmt_event, struct net_if *iface)
    {
    	switch (mgmt_event) {
            case NET_EVENT_IPV4_DHCP_BOUND:
                print_dhcp_ip(cb);
                break;
            default:
                break;
    	}
    }
    
    static int __wifi_args_to_params(struct wifi_connect_req_params *params)
    {
    	params->timeout = SYS_FOREVER_MS;
    
    	/* SSID */
    	params->ssid = CONFIG_STA_SAMPLE_SSID;
    	params->ssid_length = strlen(params->ssid);
    
    #if defined(CONFIG_STA_KEY_MGMT_WPA2)
    	params->security = 1;
    #elif defined(CONFIG_STA_KEY_MGMT_WPA2_256)
    	params->security = 2;
    #elif defined(CONFIG_STA_KEY_MGMT_WPA3)
    	params->security = 3;
    #else
    	params->security = 0;
    #endif
    
    #if !defined(CONFIG_STA_KEY_MGMT_NONE)
    	params->psk = CONFIG_STA_SAMPLE_PASSWORD;
    	params->psk_length = strlen(params->psk);
    #endif
    	params->channel = WIFI_CHANNEL_ANY;
    
    	/* MFP (optional) */
    	params->mfp = WIFI_MFP_OPTIONAL;
    
    	return 0;
    }
    
    static int wifi_connect(void)
    {
    	struct net_if *iface = net_if_get_default();
    	static struct wifi_connect_req_params cnx_params;
    
    	context.connected = false;
    	context.connect_result = false;
    	__wifi_args_to_params(&cnx_params);
    
    	if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface,
    		     &cnx_params, sizeof(struct wifi_connect_req_params))) {
    		LOG_ERR("Connection request failed");
    
    		return -ENOEXEC;
    	}
    
    	LOG_INF("Connection requested");
    
    	return 0;
    }
    
    int bytes_from_str(const char *str, uint8_t *bytes, size_t bytes_len)
    {
    	size_t i;
    	char byte_str[3];
    
    	if (strlen(str) != bytes_len * 2) {
    		LOG_ERR("Invalid string length: %zu (expected: %d)\n",
    			strlen(str), bytes_len * 2);
    		return -EINVAL;
    	}
    
    	for (i = 0; i < bytes_len; i++) {
    		memcpy(byte_str, str + i * 2, 2);
    		byte_str[2] = '\0';
    		bytes[i] = strtol(byte_str, NULL, 16);
    	}
    
    	return 0;
    }
    
    
    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
        switch (has_changed) {
        case DK_BTN1_MSK:
            if (button_state & DK_BTN1_MSK){
                int err = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
                       CONFIG_BUTTON1_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON1_EVENT_PUBLISH_MSG)-1);
                if (err) {
                    LOG_ERR("Failed to send message, %d", err);
                    return;
                }
            }
            break;
        case DK_BTN2_MSK:
            if (button_state & DK_BTN2_MSK){
                int err = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
                       CONFIG_BUTTON2_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON2_EVENT_PUBLISH_MSG)-1);
                if (err) {
                    LOG_ERR("Failed to send message, %d", err);
                    return;
                }
            }
            break;
        }
    }
    
    static void connect_mqtt(void)
    {
        int err;
        uint32_t connect_attempt = 0;
    
        if (dk_leds_init() != 0) {
            LOG_ERR("Failed to initialize the LED library");
        }
    
        if (dk_buttons_init(button_handler) != 0) {
            LOG_ERR("Failed to initialize the buttons library");
        }
    
        err = client_init(&client);
        if (err) {
            LOG_ERR("Failed to initialize MQTT client: %d", err);
            return;
        }
    
    do_connect:
        if (connect_attempt++ > 0) {
            LOG_INF("Reconnecting in %d seconds...",
                CONFIG_MQTT_RECONNECT_DELAY_S);
            k_sleep(K_SECONDS(CONFIG_MQTT_RECONNECT_DELAY_S));
        }
        err = mqtt_connect(&client);
        if (err) {
            LOG_ERR("Error in mqtt_connect: %d", err);
            goto do_connect;
        }
    
        err = fds_init(&client,&fds);
        if (err) {
            LOG_ERR("Error in fds_init: %d", err);
            return;
        }
    
        while (1) {
            err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
            if (err < 0) {
                LOG_ERR("Error in poll(): %d", errno);
                break;
            }
    
            err = mqtt_live(&client);
            if ((err != 0) && (err != -EAGAIN)) {
                LOG_ERR("Error in mqtt_live: %d", err);
                break;
            }
    
            if ((fds.revents & POLLIN) == POLLIN) {
                err = mqtt_input(&client);
                if (err != 0) {
                    LOG_ERR("Error in mqtt_input: %d", err);
                    break;
                }
            }
    
            if ((fds.revents & POLLERR) == POLLERR) {
                LOG_ERR("POLLERR");
                break;
            }
    
            if ((fds.revents & POLLNVAL) == POLLNVAL) {
                LOG_ERR("POLLNVAL");
                break;
            }
        }
    
        LOG_INF("Disconnecting MQTT client");
    
        err = mqtt_disconnect(&client);
        if (err) {
            LOG_ERR("Could not disconnect MQTT client: %d", err);
        }
        goto do_connect;
    }
    
    
    static void wifi_config_init(void) {
        
        memset(&context, 0, sizeof(context));
    
        net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
                         wifi_mgmt_event_handler,
                         WIFI_SHELL_MGMT_EVENTS);
    
        net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);
    
    
        net_mgmt_init_event_callback(&net_shell_mgmt_cb,
                         net_mgmt_event_handler,
                         NET_EVENT_IPV4_DHCP_BOUND);
    
        net_mgmt_add_event_callback(&net_shell_mgmt_cb);
    }
    
    /***************************************************************
     * Omajinai.
     * Call getaddrinfo() twice, as the first getaddrinfo() may fail.
    ***************************************************************/
    static int lookup_dns_resolv(void) {
    
        int err;
    
        struct addrinfo *result;
        struct addrinfo hints = {
            .ai_family = AF_INET,
            .ai_socktype = SOCK_STREAM
        };
        
        err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
    
        /* Free the address. */
        freeaddrinfo(result);
    
        return err;
    }
    
    
    void main(void)
    {
        /* Wait for the NET_EVENT_WIFI_CONNECT_RESULT event*/
        wifi_config_init();
        
        LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1));
        k_sleep(K_SECONDS(1));
    
    #ifdef CONFIG_BOARD_NRF7002DK_NRF5340
       if (strlen(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY)) {
           char key[QSPI_KEY_LEN_BYTES];
           int ret;
    
           ret = bytes_from_str(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY, key, sizeof(key));
           if (ret) {
               LOG_ERR("Failed to parse encryption key: %d\n", ret);
               return;
           }
    
           LOG_DBG("QSPI Encryption key: ");
           for (int i = 0; i < QSPI_KEY_LEN_BYTES; i++) {
               LOG_DBG("%02x", key[i]);
           }
           LOG_DBG("\n");
    
           ret = qspi_enable_encryption(key);
           if (ret) {
               LOG_ERR("Failed to enable encryption: %d\n", ret);
               return;
           }
           LOG_INF("QSPI Encryption enabled");
       } else {
           LOG_INF("QSPI Encryption disabled");
       }
    #endif
    
        LOG_INF("Static IP address (overridable): %s/%s -> %s",
            CONFIG_NET_CONFIG_MY_IPV4_ADDR,
            CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
            CONFIG_NET_CONFIG_MY_IPV4_GW);
    
        /* Wait for the interface to be up */
        k_sleep(K_SECONDS(5));
    
        /* Wi-Fi connecting loop */
        while (1) {
    
            wifi_connect();
    
            for (int i = 0; i < CONNECTION_TIMEOUT; i++) {
                k_sleep(K_MSEC(STATUS_POLLING_MS));
                cmd_wifi_status();
    
                if (context.connect_result) {
                    break;
                }
            }
            if (context.connected) {
                LOG_INF("Wi-Fi connected !");
                break;
            } else if (!context.connect_result) {
                LOG_ERR("Connection Timed Out");
                return;
            }
    
        } // end while loop
    
        /* DNS resolv */
        bool lookup_sate = false;
        for (int i = 0; i < DNS_TIMEOUT; i++) {
            if(context.connected){
                if(lookup_dns_resolv() == 0){
                    lookup_sate = true;
                    break;
                }
            }
        }
        
        if(!lookup_sate){
            LOG_ERR("DNS resolv faild.");
            return ;
        }
        
        k_sleep(K_SECONDS(5));
    
        /* Connect to MQTT Broker */
        LOG_INF("Connecting to MQTT Broker... ");
        connect_mqtt();
    
    }
    

Reply
  • Hi, Priyesh.

    When I was previously experimenting with the nRF9160 and nRF7002, it seemed that the first name resolution using getaddrinfo was failing. To work around this, I tried calling getaddrinfo multiple times.

    This may not be a very elegant solution, but I’ve attached the MQTT main.c for the nRF7002 that I used at the time, so please feel free to use it as a reference.

    A friend suggested that the failure might be because a DNS query is being sent before the device is fully connected to the DNS server. In any case, I handled it as a workaround, as shown in the attached main.c.

    Best regards.
    - Kenta

    /*
     * Copyright (c) 2022 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     * @brief WiFi station sample
     */
    
    #include <zephyr/logging/log.h>
    
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    
    #include <nrfx_clock.h>
    #include <zephyr/kernel.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/shell/shell.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/init.h>
    
    #include <zephyr/net/net_if.h>
    #include <zephyr/net/net_core.h>
    #include <zephyr/net/wifi.h>
    #include <zephyr/net/wifi_mgmt.h>
    #include <zephyr/net/net_event.h>
    #include <zephyr/net/dns_resolve.h>
    #include <zephyr/drivers/gpio.h>
    
    #include <qspi_if.h>
    
    #include <zephyr/net/socket.h>
    #include <zephyr/net/mqtt.h>
    #include <dk_buttons_and_leds.h>
    #include <zephyr/random/rand32.h>
    
    
    #define WIFI_SHELL_MODULE "wifi"
    
    #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_CONNECT_RESULT |		\
    				NET_EVENT_WIFI_DISCONNECT_RESULT)
    
    #define MAX_SSID_LEN        32
    #define DHCP_TIMEOUT        70
    #define CONNECTION_TIMEOUT  100
    #define DNS_TIMEOUT         CONNECTION_TIMEOUT
    #define STATUS_POLLING_MS   300
    
    
    LOG_MODULE_REGISTER(MQTT_OVER_WIFI, LOG_LEVEL_INF);
    
    
    /* The mqtt client struct */
    static struct mqtt_client client;
    
    /* File descriptor */
    static struct pollfd fds;
    
    #define RANDOM_LEN 10
    #define CLIENT_ID_LEN sizeof(CONFIG_BOARD) + 1 + RANDOM_LEN
    
    /* Buffers for MQTT client. */
    static uint8_t rx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t tx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];
    
    /* MQTT Broker details. */
    static struct sockaddr_storage broker;
    
    /**@brief Function to get the payload of recived data.
     */
    static int get_received_payload(struct mqtt_client *c, size_t length)
    {
        int ret;
        int err = 0;
    
        /* Return an error if the payload is larger than the payload buffer.
         * Note: To allow new messages, we have to read the payload before returning.
         */
        if (length > sizeof(payload_buf)) {
            err = -EMSGSIZE;
        }
    
        /* Truncate payload until it fits in the payload buffer. */
        while (length > sizeof(payload_buf)) {
            ret = mqtt_read_publish_payload_blocking(
                    c, payload_buf, (length - sizeof(payload_buf)));
            if (ret == 0) {
                return -EIO;
            } else if (ret < 0) {
                return ret;
            }
    
            length -= ret;
        }
    
        ret = mqtt_readall_publish_payload(c, payload_buf, length);
        if (ret) {
            return ret;
        }
    
        return err;
    }
    
    /**@brief Function to subscribe to the configured topic
     */
    
    static int subscribe(struct mqtt_client *const c)
    {
        struct mqtt_topic subscribe_topic = {
            .topic = {
                .utf8 = CONFIG_MQTT_SUB_TOPIC,
                .size = strlen(CONFIG_MQTT_SUB_TOPIC)
            },
            .qos = MQTT_QOS_1_AT_LEAST_ONCE
        };
    
        const struct mqtt_subscription_list subscription_list = {
            .list = &subscribe_topic,
            .list_count = 1,
            .message_id = 1234
        };
    
        LOG_INF("Subscribing to: %s len %u", CONFIG_MQTT_SUB_TOPIC,
            (unsigned int)strlen(CONFIG_MQTT_SUB_TOPIC));
    
        return mqtt_subscribe(c, &subscription_list);
    }
    
    /**@brief Function to print strings without null-termination
     */
    static void data_print(uint8_t *prefix, uint8_t *data, size_t len)
    {
        char buf[len + 1];
    
        memcpy(buf, data, len);
        buf[len] = 0;
        LOG_INF("%s%s", (char *)prefix, (char *)buf);
    }
    
    /**@brief Function to publish data on the configured topic
     */
    int data_publish(struct mqtt_client *c, enum mqtt_qos qos,
        uint8_t *data, size_t len)
    {
        struct mqtt_publish_param param;
    
        param.message.topic.qos = qos;
        param.message.topic.topic.utf8 = CONFIG_MQTT_SUB_TOPIC; //CONFIG_MQTT_PUB_TOPIC;
        param.message.topic.topic.size = strlen(CONFIG_MQTT_SUB_TOPIC); //strlen(CONFIG_MQTT_PUB_TOPIC);
        param.message.payload.data = data;
        param.message.payload.len = len;
        param.message_id = sys_rand32_get();
        param.dup_flag = 0;
        param.retain_flag = 0;
    
        data_print("Publishing: ", data, len);
        LOG_INF("to topic: %s len: %u",
            CONFIG_MQTT_PUB_TOPIC,
            (unsigned int)strlen(CONFIG_MQTT_PUB_TOPIC));
    
        return mqtt_publish(c, &param);
    }
    /**@brief MQTT client event handler
     */
    void mqtt_evt_handler(struct mqtt_client *const c,
                  const struct mqtt_evt *evt)
    {
        int err;
    
        switch (evt->type) {
        case MQTT_EVT_CONNACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT connect failed: %d", evt->result);
                break;
            }
    
            LOG_INF("MQTT client connected");
            subscribe(c);
            break;
    
        case MQTT_EVT_DISCONNECT:
            LOG_INF("MQTT client disconnected: %d", evt->result);
            break;
    
        case MQTT_EVT_PUBLISH:
        {
            const struct mqtt_publish_param *p = &evt->param.publish;
            //Print the length of the recived message
            LOG_INF("MQTT PUBLISH result=%d len=%d",
                evt->result, p->message.payload.len);
    
            //Extract the data of the recived message
            err = get_received_payload(c, p->message.payload.len);
            
            //Send acknowledgment to the broker on receiving QoS1 publish message
            if (p->message.topic.qos == MQTT_QOS_1_AT_LEAST_ONCE) {
                const struct mqtt_puback_param ack = {
                    .message_id = p->message_id
                };
    
                /* Send acknowledgment. */
                mqtt_publish_qos1_ack(c, &ack);
            }
    
            if (err >= 0) {
                data_print("Received: ", payload_buf, p->message.payload.len);
                // Control LED1 and LED2
                if(strncmp(payload_buf,CONFIG_TURN_LED1_ON_CMD,sizeof(CONFIG_TURN_LED1_ON_CMD)-1) == 0){
                    dk_set_led_on(DK_LED1);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED1_OFF_CMD,sizeof(CONFIG_TURN_LED1_OFF_CMD)-1) == 0){
                    dk_set_led_off(DK_LED1);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED2_ON_CMD,sizeof(CONFIG_TURN_LED2_ON_CMD)-1) == 0){
                    dk_set_led_on(DK_LED2);
                }
                else if(strncmp(payload_buf,CONFIG_TURN_LED2_OFF_CMD,sizeof(CONFIG_TURN_LED2_OFF_CMD)-1) == 0){
                    dk_set_led_off(DK_LED2);
                }
    
            // Payload buffer is smaller than the received data
            } else if (err == -EMSGSIZE) {
                LOG_ERR("Received payload (%d bytes) is larger than the payload buffer size (%d bytes).",
                    p->message.payload.len, sizeof(payload_buf));
            // Failed to extract data, disconnect
            } else {
                LOG_ERR("get_received_payload failed: %d", err);
                LOG_INF("Disconnecting MQTT client...");
    
                err = mqtt_disconnect(c);
                if (err) {
                    LOG_ERR("Could not disconnect: %d", err);
                }
            }
        } break;
    
        case MQTT_EVT_PUBACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT PUBACK error: %d", evt->result);
                break;
            }
    
            LOG_INF("PUBACK packet id: %u", evt->param.puback.message_id);
            break;
    
        case MQTT_EVT_SUBACK:
            if (evt->result != 0) {
                LOG_ERR("MQTT SUBACK error: %d", evt->result);
                break;
            }
    
            LOG_INF("SUBACK packet id: %u", evt->param.suback.message_id);
            break;
    
        case MQTT_EVT_PINGRESP:
            if (evt->result != 0) {
                LOG_ERR("MQTT PINGRESP error: %d", evt->result);
            }
            break;
    
        default:
            LOG_INF("Unhandled MQTT event type: %d", evt->type);
            break;
        }
    }
    
    /**@brief Resolves the configured hostname and
     * initializes the MQTT broker structure
     */
    static int broker_init(void)
    {
        int err=0;
        
        struct addrinfo *addr;
        
        static struct addrinfo *result;
        struct addrinfo hints = {
            .ai_family = AF_INET,
            .ai_socktype = SOCK_STREAM
        };
        
        err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
        
        if (err) {
            LOG_ERR("getaddrinfo failed: %d", err);
            return -ECHILD;
        }
    
        addr = result;
    
        /* Look for address of the broker. */
        while (addr != NULL) {
            /* IPv4 Address. */
            if (addr->ai_addrlen == sizeof(struct sockaddr_in)) {
                struct sockaddr_in *broker4 =
                    ((struct sockaddr_in *)&broker);
                char ipv4_addr[NET_IPV4_ADDR_LEN];
    
                broker4->sin_addr.s_addr =
                    ((struct sockaddr_in *)addr->ai_addr)
                    ->sin_addr.s_addr;
                broker4->sin_family = AF_INET;
                broker4->sin_port = htons(CONFIG_MQTT_BROKER_PORT);
    
                inet_ntop(AF_INET, &broker4->sin_addr.s_addr,
                      ipv4_addr, sizeof(ipv4_addr));
                LOG_INF("IPv4 Address found %s", (char *)(ipv4_addr));
    
                break;
            } else {
                LOG_ERR("ai_addrlen = %u should be %u or %u",
                    (unsigned int)addr->ai_addrlen,
                    (unsigned int)sizeof(struct sockaddr_in),
                    (unsigned int)sizeof(struct sockaddr_in6));
            }
    
            addr = addr->ai_next;
        }
    
        /* Free the address. */
        freeaddrinfo(result);
    
        return err;
    }
    
    /* Function to get the client id */
    static const uint8_t* client_id_get(void)
    {
        static uint8_t client_id[MAX(sizeof(CONFIG_MQTT_CLIENT_ID),
                         CLIENT_ID_LEN)];
    
        if (strlen(CONFIG_MQTT_CLIENT_ID) > 0) {
            snprintf(client_id, sizeof(client_id), "%s",
                 CONFIG_MQTT_CLIENT_ID);
            goto exit;
        }
    
        uint32_t id = sys_rand32_get();
        snprintf(client_id, sizeof(client_id), "%s-%010u", CONFIG_BOARD, id);
    
    exit:
        LOG_DBG("client_id = %s", (char *)client_id);
    
        return client_id;
    }
    
    
    /**@brief Initialize the MQTT client structure
     */
    int client_init(struct mqtt_client *client)
    {
        int err;
        /* Initializes the client instance. */
        mqtt_client_init(client);
    
        /* Resolves the configured hostname and initializes the MQTT broker structure */
        err = broker_init();
        if (err) {
            LOG_ERR("Failed to initialize broker connection");
            return err;
        }
    
        /* MQTT client configuration */
        client->broker = &broker;
        client->evt_cb = mqtt_evt_handler;
        client->client_id.utf8 = client_id_get();
        client->client_id.size = strlen(client->client_id.utf8);
        client->password = NULL;
        client->user_name = NULL;
        client->protocol_version = MQTT_VERSION_3_1_1;
    
        /* MQTT buffers configuration */
        client->rx_buf = rx_buffer;
        client->rx_buf_size = sizeof(rx_buffer);
        client->tx_buf = tx_buffer;
        client->tx_buf_size = sizeof(tx_buffer);
    
        /* We are not using TLS */
        client->transport.type = MQTT_TRANSPORT_NON_SECURE;
    
        return err;
    }
    
    /**@brief Initialize the file descriptor structure used by poll.
     */
    int fds_init(struct mqtt_client *c, struct pollfd *fds)
    {
        if (c->transport.type == MQTT_TRANSPORT_NON_SECURE) {
            fds->fd = c->transport.tcp.sock;
        } else {
            return -ENOTSUP;
        }
    
        fds->events = POLLIN;
    
        return 0;
    }
    
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    
    static struct net_mgmt_event_callback wifi_shell_mgmt_cb;
    static struct net_mgmt_event_callback net_shell_mgmt_cb;
    
    static struct {
    	const struct shell *sh;
    	union {
    		struct {
    			uint8_t connected	: 1;
    			uint8_t connect_result	: 1;
    			uint8_t disconnect_requested	: 1;
    			uint8_t _unused		: 5;
    		};
    		uint8_t all;
    	};
    } context;
    
    
    static int cmd_wifi_status(void)
    {
    	struct net_if *iface = net_if_get_default();
    	struct wifi_iface_status status = { 0 };
    
    	if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status,
    				sizeof(struct wifi_iface_status))) {
    		LOG_INF("Status request failed");
    
    		return -ENOEXEC;
    	}
    
    	LOG_INF("==================");
    	LOG_INF("State: %s", wifi_state_txt(status.state));
    
    	if (status.state >= WIFI_STATE_ASSOCIATED) {
    		uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
    
    		LOG_INF("Interface Mode: %s",
    		       wifi_mode_txt(status.iface_mode));
    		LOG_INF("Link Mode: %s",
    		       wifi_link_mode_txt(status.link_mode));
    		LOG_INF("SSID: %-32s", status.ssid);
    		LOG_INF("BSSID: %s",
    		       net_sprint_ll_addr_buf(
    				status.bssid, WIFI_MAC_ADDR_LEN,
    				mac_string_buf, sizeof(mac_string_buf)));
    		LOG_INF("Band: %s", wifi_band_txt(status.band));
    		LOG_INF("Channel: %d", status.channel);
    		LOG_INF("Security: %s", wifi_security_txt(status.security));
    		LOG_INF("MFP: %s", wifi_mfp_txt(status.mfp));
    		LOG_INF("RSSI: %d", status.rssi);
    	}
    	return 0;
    }
    
    static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb)
    {
    	const struct wifi_status *status =
    		(const struct wifi_status *) cb->info;
    
    	if (context.connected) {
    		return;
    	}
    
    	if (status->status) {
    		LOG_ERR("Connection failed (%d)", status->status);
    	} else {
    		LOG_INF("Connected");
    		context.connected = true;
    	}
        
    	context.connect_result = true;
    }
    
    static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb)
    {
    	const struct wifi_status *status =
    		(const struct wifi_status *) cb->info;
    
    	if (!context.connected) {
    		return;
    	}
    
    	if (context.disconnect_requested) {
    		LOG_INF("Disconnection request %s (%d)",
    			 status->status ? "failed" : "done",
    					status->status);
    		context.disconnect_requested = false;
    	} else {
    		LOG_INF("Received Disconnected");
    		context.connected = false;
    	}
        
    	cmd_wifi_status();
    }
    
    static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    				     uint32_t mgmt_event, struct net_if *iface)
    {
    	switch (mgmt_event) {
                
            case NET_EVENT_WIFI_CONNECT_RESULT:
                handle_wifi_connect_result(cb);
                break;
            case NET_EVENT_WIFI_DISCONNECT_RESULT:
                handle_wifi_disconnect_result(cb);
                break;
            default:
                break;
    	}
        
    }
    
    static void print_dhcp_ip(struct net_mgmt_event_callback *cb)
    {
    	/* Get DHCP info from struct net_if_dhcpv4 and print */
    	const struct net_if_dhcpv4 *dhcpv4 = cb->info;
    	const struct in_addr *addr = &dhcpv4->requested_ip;
    	char dhcp_info[128];
    
    	net_addr_ntop(AF_INET, addr, dhcp_info, sizeof(dhcp_info));
    
    	LOG_INF("DHCP IP address: %s", dhcp_info);
    }
    static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    				    uint32_t mgmt_event, struct net_if *iface)
    {
    	switch (mgmt_event) {
            case NET_EVENT_IPV4_DHCP_BOUND:
                print_dhcp_ip(cb);
                break;
            default:
                break;
    	}
    }
    
    static int __wifi_args_to_params(struct wifi_connect_req_params *params)
    {
    	params->timeout = SYS_FOREVER_MS;
    
    	/* SSID */
    	params->ssid = CONFIG_STA_SAMPLE_SSID;
    	params->ssid_length = strlen(params->ssid);
    
    #if defined(CONFIG_STA_KEY_MGMT_WPA2)
    	params->security = 1;
    #elif defined(CONFIG_STA_KEY_MGMT_WPA2_256)
    	params->security = 2;
    #elif defined(CONFIG_STA_KEY_MGMT_WPA3)
    	params->security = 3;
    #else
    	params->security = 0;
    #endif
    
    #if !defined(CONFIG_STA_KEY_MGMT_NONE)
    	params->psk = CONFIG_STA_SAMPLE_PASSWORD;
    	params->psk_length = strlen(params->psk);
    #endif
    	params->channel = WIFI_CHANNEL_ANY;
    
    	/* MFP (optional) */
    	params->mfp = WIFI_MFP_OPTIONAL;
    
    	return 0;
    }
    
    static int wifi_connect(void)
    {
    	struct net_if *iface = net_if_get_default();
    	static struct wifi_connect_req_params cnx_params;
    
    	context.connected = false;
    	context.connect_result = false;
    	__wifi_args_to_params(&cnx_params);
    
    	if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface,
    		     &cnx_params, sizeof(struct wifi_connect_req_params))) {
    		LOG_ERR("Connection request failed");
    
    		return -ENOEXEC;
    	}
    
    	LOG_INF("Connection requested");
    
    	return 0;
    }
    
    int bytes_from_str(const char *str, uint8_t *bytes, size_t bytes_len)
    {
    	size_t i;
    	char byte_str[3];
    
    	if (strlen(str) != bytes_len * 2) {
    		LOG_ERR("Invalid string length: %zu (expected: %d)\n",
    			strlen(str), bytes_len * 2);
    		return -EINVAL;
    	}
    
    	for (i = 0; i < bytes_len; i++) {
    		memcpy(byte_str, str + i * 2, 2);
    		byte_str[2] = '\0';
    		bytes[i] = strtol(byte_str, NULL, 16);
    	}
    
    	return 0;
    }
    
    
    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
        switch (has_changed) {
        case DK_BTN1_MSK:
            if (button_state & DK_BTN1_MSK){
                int err = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
                       CONFIG_BUTTON1_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON1_EVENT_PUBLISH_MSG)-1);
                if (err) {
                    LOG_ERR("Failed to send message, %d", err);
                    return;
                }
            }
            break;
        case DK_BTN2_MSK:
            if (button_state & DK_BTN2_MSK){
                int err = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
                       CONFIG_BUTTON2_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON2_EVENT_PUBLISH_MSG)-1);
                if (err) {
                    LOG_ERR("Failed to send message, %d", err);
                    return;
                }
            }
            break;
        }
    }
    
    static void connect_mqtt(void)
    {
        int err;
        uint32_t connect_attempt = 0;
    
        if (dk_leds_init() != 0) {
            LOG_ERR("Failed to initialize the LED library");
        }
    
        if (dk_buttons_init(button_handler) != 0) {
            LOG_ERR("Failed to initialize the buttons library");
        }
    
        err = client_init(&client);
        if (err) {
            LOG_ERR("Failed to initialize MQTT client: %d", err);
            return;
        }
    
    do_connect:
        if (connect_attempt++ > 0) {
            LOG_INF("Reconnecting in %d seconds...",
                CONFIG_MQTT_RECONNECT_DELAY_S);
            k_sleep(K_SECONDS(CONFIG_MQTT_RECONNECT_DELAY_S));
        }
        err = mqtt_connect(&client);
        if (err) {
            LOG_ERR("Error in mqtt_connect: %d", err);
            goto do_connect;
        }
    
        err = fds_init(&client,&fds);
        if (err) {
            LOG_ERR("Error in fds_init: %d", err);
            return;
        }
    
        while (1) {
            err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
            if (err < 0) {
                LOG_ERR("Error in poll(): %d", errno);
                break;
            }
    
            err = mqtt_live(&client);
            if ((err != 0) && (err != -EAGAIN)) {
                LOG_ERR("Error in mqtt_live: %d", err);
                break;
            }
    
            if ((fds.revents & POLLIN) == POLLIN) {
                err = mqtt_input(&client);
                if (err != 0) {
                    LOG_ERR("Error in mqtt_input: %d", err);
                    break;
                }
            }
    
            if ((fds.revents & POLLERR) == POLLERR) {
                LOG_ERR("POLLERR");
                break;
            }
    
            if ((fds.revents & POLLNVAL) == POLLNVAL) {
                LOG_ERR("POLLNVAL");
                break;
            }
        }
    
        LOG_INF("Disconnecting MQTT client");
    
        err = mqtt_disconnect(&client);
        if (err) {
            LOG_ERR("Could not disconnect MQTT client: %d", err);
        }
        goto do_connect;
    }
    
    
    static void wifi_config_init(void) {
        
        memset(&context, 0, sizeof(context));
    
        net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
                         wifi_mgmt_event_handler,
                         WIFI_SHELL_MGMT_EVENTS);
    
        net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);
    
    
        net_mgmt_init_event_callback(&net_shell_mgmt_cb,
                         net_mgmt_event_handler,
                         NET_EVENT_IPV4_DHCP_BOUND);
    
        net_mgmt_add_event_callback(&net_shell_mgmt_cb);
    }
    
    /***************************************************************
     * Omajinai.
     * Call getaddrinfo() twice, as the first getaddrinfo() may fail.
    ***************************************************************/
    static int lookup_dns_resolv(void) {
    
        int err;
    
        struct addrinfo *result;
        struct addrinfo hints = {
            .ai_family = AF_INET,
            .ai_socktype = SOCK_STREAM
        };
        
        err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
    
        /* Free the address. */
        freeaddrinfo(result);
    
        return err;
    }
    
    
    void main(void)
    {
        /* Wait for the NET_EVENT_WIFI_CONNECT_RESULT event*/
        wifi_config_init();
        
        LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1));
        k_sleep(K_SECONDS(1));
    
    #ifdef CONFIG_BOARD_NRF7002DK_NRF5340
       if (strlen(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY)) {
           char key[QSPI_KEY_LEN_BYTES];
           int ret;
    
           ret = bytes_from_str(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY, key, sizeof(key));
           if (ret) {
               LOG_ERR("Failed to parse encryption key: %d\n", ret);
               return;
           }
    
           LOG_DBG("QSPI Encryption key: ");
           for (int i = 0; i < QSPI_KEY_LEN_BYTES; i++) {
               LOG_DBG("%02x", key[i]);
           }
           LOG_DBG("\n");
    
           ret = qspi_enable_encryption(key);
           if (ret) {
               LOG_ERR("Failed to enable encryption: %d\n", ret);
               return;
           }
           LOG_INF("QSPI Encryption enabled");
       } else {
           LOG_INF("QSPI Encryption disabled");
       }
    #endif
    
        LOG_INF("Static IP address (overridable): %s/%s -> %s",
            CONFIG_NET_CONFIG_MY_IPV4_ADDR,
            CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
            CONFIG_NET_CONFIG_MY_IPV4_GW);
    
        /* Wait for the interface to be up */
        k_sleep(K_SECONDS(5));
    
        /* Wi-Fi connecting loop */
        while (1) {
    
            wifi_connect();
    
            for (int i = 0; i < CONNECTION_TIMEOUT; i++) {
                k_sleep(K_MSEC(STATUS_POLLING_MS));
                cmd_wifi_status();
    
                if (context.connect_result) {
                    break;
                }
            }
            if (context.connected) {
                LOG_INF("Wi-Fi connected !");
                break;
            } else if (!context.connect_result) {
                LOG_ERR("Connection Timed Out");
                return;
            }
    
        } // end while loop
    
        /* DNS resolv */
        bool lookup_sate = false;
        for (int i = 0; i < DNS_TIMEOUT; i++) {
            if(context.connected){
                if(lookup_dns_resolv() == 0){
                    lookup_sate = true;
                    break;
                }
            }
        }
        
        if(!lookup_sate){
            LOG_ERR("DNS resolv faild.");
            return ;
        }
        
        k_sleep(K_SECONDS(5));
    
        /* Connect to MQTT Broker */
        LOG_INF("Connecting to MQTT Broker... ");
        connect_mqtt();
    
    }
    

Children
  • Hi Kenta,

    Thank you for sharing the details and the MQTT main.c reference. I appreciate you sending that over.

    I am currently testing with a similar loop around getaddrinfo as a workaround and will observe if there are any changes or improvements in the results.

    Thanks again for the insight and for pointing out the possible DNS timing issue.

    Best regards,
    Priyesh

Related