JorgeGzm opened a new pull request, #3696: URL: https://github.com/apache/nuttx-apps/pull/3696
## Summary <img width="434" height="800" alt="nucleo-f746zg-lora-sx1301" src="https://github.com/user-attachments/assets/7c55f5f8-d40a-40b4-b799-f8deea400c9c" /> <img width="653" height="306" alt="b-l072z-lrwan1" src="https://github.com/user-attachments/assets/6cfcabea-589b-4791-995e-a18faf79d91f" /> Adds `wireless/lora_pkt_fwd`, the Semtech UDP packet forwarder of a LoRaWAN gateway, and the `lora` command that drives it. The forwarder sends what an SX1301 concentrator receives to a network server with the Semtech UDP protocol version 2, and turns the downlink requests of the server into transmissions. Two loops share the concentrator character device: one polls it, serialises what it gets into a `rxpk` object and sends it as PUSH_DATA; the other keeps the PULL_DATA keepalive going and answers every PULL_RESP with a transmission and a TX_ACK. The server is given as a name or as an address and is resolved with `getaddrinfo()`, so a gateway can point at a cluster of a public network without hard coding an address that changes. No floating point is used anywhere: frequencies are printed from their integer value in Hz, and the signal levels arrive from the driver already scaled by ten. The `lora` command mirrors the AT command set of the vendor gateway firmwares: `sys`, `ver`, `status`, `ch`, `server`, `ip`, `mac`, `reset`, `start` and `stop`. It shows the identity of the gateway, the network configuration, the channel plan and the counters of both the radio and the forwarder, and it changes the channel plan and the server at runtime. One more subcommand, `tx`, sends a single packet with the polarity of an uplink, which brings a gateway up against any LoRa receiver without needing a network server at all. The `sx127x` example gains a configurable default mode, so that it can be used as a beacon on a board whose console is not wired and only a debug probe is attached. ## Impact New application, off by default (`WIRELESS_LORA_PKT_FWD`), which selects `NETUTILS_CODECS` and `CODECS_BASE64` for the payload encoding and needs `NETDB_DNSCLIENT` to resolve a server given by name. The only change outside it is one line of `examples/sx127x_demo`, where the initial application mode comes from the new `CONFIG_EXAMPLES_SX127X_MODE_DEFAULT` instead of being hard coded to receive. The default of that symbol is the previous behaviour, so no existing configuration changes. The counters shown by `lora status` for the UDP side are read from the daemon through the flat address space, which is how they are shared in a flat build. The radio side counters come from the driver with an ioctl and are correct in any build. ## Dependency This needs the SX1301 driver of the nuttx repository. The application depends on `LPWAN_SX1301` in Kconfig, so until that driver is merged the symbol does not exist, the application cannot be selected and nothing here is compiled: the build against the master of the other repository is unaffected, and the code only becomes reachable once the driver lands. See the companion pull request there. Verified both ways, with one repository at the pull request and the other at master: - `nucleo-f746zg:lorawan_gw` built against `nuttx-apps` master: builds, 343816 bytes of text, and the resulting image simply has no `lora` command. - This branch against `nuttx` master: `CONFIG_WIRELESS_LORA_PKT_FWD` is dropped by `make olddefconfig` because its dependency is unmet, and no object of this application is compiled. ## Testing Host: Ubuntu 24.04.4 LTS, x86_64, Linux 7.0.0-28-generic, arm-none-eabi-gcc 13.2.1 (Arm GNU Toolchain 13.2.rel1). Target: `nucleo-f746zg:lorawan_gw`, built against the nuttx branch of the companion pull request with the warning flags of the CI: `make EXTRAFLAGS="-Wno-cpp -Werror"`. No warning, no error. ``` $ arm-none-eabi-size nuttx text data bss dec hex filename 362536 1672 41496 405704 630c8 nuttx ``` `nxstyle` reports nothing on the four C files and the header. Hardware: Nucleo F746ZG with a RisingHF RHF0M301 shield (SX1301 with two SX1257), Ethernet on the local network, and two B-L072Z-LRWAN1 boards as end devices. ### Uplink to a network server The forwarder resolves a public cluster by name, a LoRaWAN device sends its join request and the packet reaches the server: ``` nsh> lora server au1.cloud.thethings.network 1700 1700 nsh> lora start lora: forwarding to au1.cloud.thethings.network (up 1700, down 1700) sx1301_receive: RX chain 3 SF10 915800000 Hz snr -2.5 dB size 26 status 0x10 lora: forwarded 1 packet(s) nsh> lora status Concentrator: RUNNING Pkt Forwarder: RUNNING RX OK: 1 RX FWD: 1 PUSH: 4 sent, 3 acked PULL: 19 sent, 18 acked ``` ### Downlink from a network server With a Semtech protocol sink on the local network, a PULL_RESP is turned into a transmission and acknowledged: ``` [ 30.2s] >>> PULL_RESP sent (917.0 MHz SF7BW125 imme) [ 30.3s] TX_ACK: {"txpk_ack":{"error":"NONE"}} [ 52.2s] stat {"time": "...", "rxnb": 0, "rxok": 0, "rxfw": 0, "ackr": 0.0, "dwnb": 1, "txnb": 1} ``` The same sink acknowledges the keepalives and the status pushes, which is where the `PULL 19 sent, 18 acked` above comes from. ### The lora command ``` nsh> lora ch AU915 Channel Plan (AU915 sub-band 2, ch 8-15+65 (BR/AU, TTN)): Radio A: 917100000 Hz Radio B: 917900000 Hz CHANNEL0: 916800000, A, SF7/SF12, BW125KHz (LORA_MULTI_SF) ... CHANNEL8: 917500000, A, SF8, BW500KHz (LORA_STANDARD) CHANNEL9: OFF (FSK) Available regions: AU915 AU915-1 US915 US915-1 EU868 AS923 KR920 IN866 ``` `lora sys` prints the same plan together with the gateway identifier, the network configuration and the state of both sides; `lora ch EU868` changes the plan and restarts the concentrator. ### The tx subcommand One packet from the gateway, received by two boards listening on that frequency: ``` gateway> lora tx 917200000 7 hello-from-gateway lora: sent 18 bytes at 917200000 Hz, SF7 board A> Received: SNR = 6 RSSI = -29 len = 18 board B> Received: SNR = 7 RSSI = -30 len = 18 0x68 0x65 0x6c 0x6c 0x6f 0x2d 0x66 0x72 0x6f 0x6d ``` Five transmissions, five receptions on each board. The Docker based CI lists were not run locally; they are left to the CI of the pull request. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
