{"id":50867852,"url":"https://github.com/dunknowcoding/arduinonrf-zigbee","last_synced_at":"2026-06-15T03:01:19.950Z","repository":{"id":363011664,"uuid":"1261613610","full_name":"dunknowcoding/ArduinoNRF-Zigbee","owner":"dunknowcoding","description":"Zigbee Arduino library designed specially for ArduinoNRF board library","archived":false,"fork":false,"pushed_at":"2026-06-14T15:08:36.000Z","size":382,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T17:09:51.447Z","etag":null,"topics":["aliexpress","arduinonrf","cc2530","zigbee"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dunknowcoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-06T23:37:13.000Z","updated_at":"2026-06-14T15:08:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dunknowcoding/ArduinoNRF-Zigbee","commit_stats":null,"previous_names":["dunknowcoding/arduinonrf-zigbee"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dunknowcoding/ArduinoNRF-Zigbee","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FArduinoNRF-Zigbee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FArduinoNRF-Zigbee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FArduinoNRF-Zigbee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FArduinoNRF-Zigbee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dunknowcoding","download_url":"https://codeload.github.com/dunknowcoding/ArduinoNRF-Zigbee/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FArduinoNRF-Zigbee/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34345578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aliexpress","arduinonrf","cc2530","zigbee"],"created_at":"2026-06-15T03:01:19.122Z","updated_at":"2026-06-15T03:01:19.936Z","avatar_url":"https://github.com/dunknowcoding.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NiusZigbee\n\nHost-side drivers that let an **ArduinoNRF (nRF52840)** board drive external\n**Zigbee / IEEE 802.15.4 radio modules** over a hardware UART. The companion to\nthe [ArduinoNRF](https://github.com/dunknowcoding/ArduinoNRF) board package —\nkept as a **separate library** so the board package stays small.\n\nIt ships a complete, verified driver + firmware for the cheap **AliExpress\nCC2530 module** (raw 802.15.4 **send / receive / sniff**) and, on top of it, a\ngrowing **host-side Zigbee PRO stack** built natively on the nRF52840 — active\nscan + join, AODV route discovery, multi-hop forwarding, AES-CCM* NWK **and**\nAPS security, end-to-end acked delivery, fragmentation, binding, persistence,\nTrust-Center key-transport tooling, sleepy-end-device support, and network\nmanagement (Mgmt_Lqi, broadcast transaction table, PAN-ID conflict). No TI\nZ-Stack required; a future ZNP backend can still live beside the raw driver.\n\n## How it works\n\n```\n   ArduinoNRF (nRF52840)                         CC2530 module\n   ┌───────────────────┐    UART  115200    ┌────────────────────┐\n   │ CC2530Radio (this │  D0 ─► P0.2 (RX)   │  SDCC 802.15.4     │\n   │ library)          │  D1 ◄─ P0.3 (TX)   │  transceiver fw    │──))) 2.4 GHz\n   │                   │                    │                    │\n   │ CCDebugger (board │  D8 ─► P2.1 (DD)   │  (flashed once via │\n   │ package) flashes  │  D9 ─► P2.2 (DC)   │   the debug port)  │\n   │ the module        │  D10─► RST         │                    │\n   └───────────────────┘                    └────────────────────┘\n```\n\n- **Flashing** the module needs no external programmer — the ArduinoNRF board\n  package's built‑in **`CCDebugger`** does it over the 2‑wire debug port.\n- **At runtime** the nRF talks to the module over UART with a small framed\n  protocol; the CC2530 does the actual radio PHY/MAC.\n\n## Install\n\n1. Install the **ArduinoNRF board package** (it provides the board + the\n   `CCDebugger` flasher library).\n2. Install **this library**: *Sketch ▸ Include Library ▸ Add .ZIP Library…*, or\n   clone into your Arduino `libraries/` folder, or via Library Manager once\n   published.\n\nIn Arduino Library Manager it is published as **NiusZigbee**. The GitHub\nrepository keeps the historical `ArduinoNRF-Zigbee` name because it is developed\nalongside the ArduinoNRF core.\n\n## Quick start\n\n1. **Wire it up** — debug pins (D8/D9/D10) and UART pins (D0/D1). See\n   [docs/WIRING.md](docs/WIRING.md). 3.3 V only. **P2.0 (CFG1) is not used by this\n   library's firmware** (it's a TI Z-Stack-only strap) — leave it floating or tie\n   it to GND, either works. Grounding it is recommended only to future-proof for\n   a later Z-Stack flash.\n2. **Flash the module firmware once** — open *Examples ▸ ArduinoNRF-Zigbee ▸\n   **CC2530_FlashFirmware*** and upload. It uses the built‑in CC‑Debugger; details\n   in [docs/FLASHING.md](docs/FLASHING.md).\n3. **Use it** — open one of:\n   - **CC2530_Info** — confirm the link, read the firmware version\n   - **CC2530_Sniffer** — promiscuous 802.15.4 packet sniffer\n   - **CC2530_Link** — a two-node radio link (flash onto two setups)\n   - **CC2530_MacLink** — a two-node short-address MAC data-frame link\n   - **CC2530_NwkLink** — a two-node Zigbee NWK data-frame link\n   - **CC2530_ZclLink** — a two-node APS/ZCL On/Off command-frame link\n   - **CC2530_OnOffCluster** — a tiny two-node On/Off cluster behavior demo\n   - **CC2530_ClusterNode** — reusable Basic + On/Off cluster node demo\n   - **CC2530_ReportingNode** — Configure Reporting + Report Attributes demo\n   - **CC2530_BeaconJoin** — the full mesh demo: scan/join, AODV routing,\n     multi-hop forwarding, NWK security, acked APS, Mgmt_Lqi, persistence\n     (build the roles with `-DNIUS_ZIGBEE_THIS_NODE=0x0001/0x0002/0x0003`)\n\n   Protocol self-tests (run on one board, e.g. board1 over a J-Link):\n   - **CC2530_ApsSecurity** — APS key-transport crypto (AES-MMO, HMAC,\n     specialized keys, CCM* Transport-Key envelope), 25/25\n   - **CC2530_Fragmentation** / **CC2530_KeyTransport** / **CC2530_Binding** —\n     APS fragment reassembly, TC key-transport frames, source binding table\n   - **CC2530_BroadcastTable** — broadcast dedup + passive-ack table, 22/22\n   - **CC2530_IndirectQueue** — sleepy-child Data Request + parent queue, 27/27\n   - **CC2530_EndDeviceTimeout** — SED keep-alive negotiation, 18/18\n   - **CC2530_PanIdConflict** — PAN-ID conflict detect + Network Report/Update, 16/16\n\n\u003e Board layout note: some nice!nano-compatible bootloaders report\n\u003e `SoftDevice: not found` in `INFO_UF2.TXT`. For those boards, select the\n\u003e ArduinoNRF no-SoftDevice bootloader option (`bootloader=promicroserialnosd`) so\n\u003e the sketch is linked at `0x1000`. A SoftDevice layout can upload successfully\n\u003e but never start.\n\n```cpp\n#include \u003cCC2530Radio.h\u003e\nCC2530Radio radio;                 // uses Serial1 (D0/D1)\n\nvoid onFrame(const uint8_t* p, uint8_t n, int8_t rssi, uint8_t lqi) { /* ... */ }\n\nvoid setup() {\n  radio.begin(11);                 // 115200 UART, channel 11\n  radio.onReceive(onFrame);\n}\nvoid loop() {\n  radio.poll();\n  radio.send((const uint8_t*)\"hi\", 2);\n}\n```\n\n## API (`CC2530Radio`)\n\n| Method | Purpose |\n|--------|---------|\n| `begin(channel=11, baud=115200)` | open the UART, ping, select channel |\n| `ping()` / `firmwareVersion()` | liveness check / firmware version |\n| `setChannel(11..26)` / `channel()` | select / read the 802.15.4 channel |\n| `setPromiscuous(bool)` | receive all frames (sniffer) vs filtered |\n| `setAddress(pan, short, ieee)` | program CC2530 PAN ID, short address, and IEEE address registers |\n| `configureMac(flags, retries)` / `getMacInfo(info)` | control/read hardware filtering, Auto ACK, CCA TX, and retry count |\n| `setTxPowerRaw(value)` | write the CC2530 TXPOWER register |\n| `send(payload, len)` | transmit a raw 802.15.4 frame (radio adds FCS) |\n| `sendWithRetries(payload, len, retries)` / `lastTxAttempts()` | transmit with per-call retry count and read attempt count |\n| `sendData(pan, dst, src, payload, len)` | build + transmit a short-address 802.15.4 data frame |\n| `sendNwkData(pan, macDst, macSrc, nwkDst, nwkSrc, payload, len)` | build + transmit a simple Zigbee NWK data frame |\n| `sendNwkCommand(...)` | build + transmit a Zigbee NWK command frame |\n| `sendApsData(...)` | build + transmit a simple unicast Zigbee APS data frame |\n| `sendZdoCommand(...)` | build + transmit a Zigbee Device Profile command on endpoint 0 |\n| `sendZclCommand(...)` | build + transmit a basic ZCL command frame |\n| `onReceive(cb)` + `poll()` | deliver received frames to your callback |\n| `onDataReceive(cb)` + `poll()` | parse and deliver short-address MAC data frames |\n| `onNwkReceive(cb)` + `poll()` | parse and deliver simple Zigbee NWK data frames |\n| `onNwkCommandReceive(cb)` + `poll()` | parse and deliver simple Zigbee NWK command frames |\n| `onApsReceive(cb)` + `poll()` | parse and deliver simple Zigbee APS data frames |\n| `onZdoReceive(cb)` + `poll()` | deliver endpoint 0 / profile 0 Zigbee Device Profile frames |\n| `onZclReceive(cb)` + `poll()` | parse and deliver basic ZCL command frames |\n\n`send()` carries **raw 802.15.4** payloads — perfect for CC2530↔CC2530 links and\nsniffing. Talking to real Zigbee devices needs a proper MAC header (and, for full\nZigbee networking, the future Z‑Stack backend).\n\n`sendData()` and `onDataReceive()` add the first reusable stack layer above raw\nradio I/O: IEEE 802.15.4 data frames with PAN ID, 16-bit source/destination\naddresses, sequence number, optional ACK request, and parsed RSSI/LQI metadata.\nThis is still not Zigbee PRO joining or ZCL control, but it is the MAC envelope\nthat future NWK / APS / ZCL code can build on.\n\n`sendNwkData()` and `onNwkReceive()` add the next frame layer: a minimal Zigbee\nNWK data frame with destination/source short address, radius, sequence number,\nand payload. Optional NWK fields such as security, multicast, source routing,\nand IEEE address extension are intentionally not accepted by this helper yet.\n\n`sendNwkCommand()` and `onNwkCommandReceive()` add the first NWK command path:\nRoute Request, Route Reply, Network Status, Route Record, Leave, and Rejoin\npayload builders/parsers. These are command-frame tools, not a full route\ndiscovery or rejoin state machine yet.\n\n`sendApsData()` / `sendZclCommand()` add unicast APS endpoint/profile/cluster\nframing and basic ZCL command-frame construction. They are useful for exercising\nframe layout and application-layer parsing between two library nodes; they do\nnot implement Zigbee device discovery, binding, reporting, attribute storage, or\ncluster behavior.\n\n`ZigbeeZdo` adds the first Zigbee Device Object payload helpers for endpoint 0:\nNWK/IEEE address, Active Endpoint, Simple Descriptor, and Match Descriptor\nrequests/responses. `CC2530_ZdoDiscovery` uses those helpers with CC2530\nhardware filtering and Auto ACK enabled, which is the next step from private\ntwo-node APS/ZCL frames toward real Zigbee PRO discovery.\n\n`ZigbeeDeviceObject` is a small static descriptor store that can answer those\nZDO requests from a sketch-provided endpoint table. It is the first reusable\npiece of local device identity, ahead of later join state, binding tables, and\npersistent network storage.\n\n`ZigbeeNeighborTable` and `ZigbeeRouteTable` provide fixed-storage local network\ntables for the next Zigbee PRO steps. They do not run routing by themselves, but\nthey give future association, parent selection, route discovery, and route aging\ncode a no-heap storage base.\n\n`ZigbeeNetwork`, `ZigbeePermitJoin`, and `ZigbeeAddressAllocator` add the first\nlocal join-state primitives: coordinator/joined-device identity, permit-join\ntiming, short-address allocation, child acceptance into the neighbor table, and\nparent bookkeeping. `CC2530_AssociationJoin` now exercises the first\nover-the-air join path: MAC Association Request/Response followed by ZDO\nDevice_annce.\n\nOn top of that, `ZigbeeNetwork` now runs a real **active scan**: the joiner\nbroadcasts Beacon Requests across a channel list, coordinators/routers answer\nwith 802.15.4 beacons carrying the 15-byte Zigbee beacon payload\n(`ZigbeeNwk::buildBeaconPayload`), received beacons land in a fixed candidate\ntable (`noteBeacon`), and `selectParent()` picks the best joinable parent by\npermit-join, capacity, stack profile, LQI, and depth. `CC2530_BeaconJoin`\ndemonstrates the full flow — the joiner needs **no preconfigured PAN, channel,\nor coordinator address** — with association retry, re-scan fallback, and a\n`rejoinParent()` primitive for later parent-loss recovery.\n\n`ZigbeeZcl` also includes small helpers for Read Attributes payloads, Default\nResponse payloads, boolean/uint8 attribute records, boolean reports, and applying\nOn/Off cluster commands to a local state variable. `CC2530_OnOffCluster` shows\nhow to combine those helpers into a minimal behavior loop.\n\n`ZigbeeOnOffCluster` and `ZigbeeBasicCluster` are the first reusable behavior\nhelpers. They can build ZCL responses for On/Off state changes, OnOff reads, and\nBasic cluster reads such as ManufacturerName, ModelIdentifier, and PowerSource.\n\n`ZigbeeBoolReportScheduler` adds the first small reporting helper: it stores the\nconfigured min/max interval for a boolean attribute, detects changes, and builds\nZCL Report Attributes frames when a sketch should publish a report.\n\n`begin()` also resynchronizes the CC2530 firmware's framed UART parser before\nthe first ping. This matters after host uploads/resets because the CC2530 may\nkeep running while the nRF resets, leaving the module mid-frame.\n\nThe bundled SDCC firmware is now a small MAC/PHY co-processor: the nRF can set\nthe CC2530 hardware PAN/short/IEEE address registers, enable frame filtering,\nuse the CC2530 Auto ACK path, request CCA transmit, and configure retry count.\nThat is still below full Zigbee PRO, but it removes the earlier all-promiscuous\nassumption and gives the future join/routing/security work a real MAC base.\n\n## Zigbee PRO networking \u0026 security\n\nLayered on the MAC base, these host-side pieces bring the stack a long way\ntoward Zigbee PRO. Each ships with a hardware self-test example.\n\n- **Network security (NWK).** `ZigbeeSecurity` protects every NWK frame with\n  AES-CCM* ENC-MIC-32 (Zigbee aux header, on-air level zeroing, frame-counter\n  replay table), computed on the nRF52840 hardware AES block. The CCM* core is\n  shared (`ZigbeeCcmStar.h`) with the APS layer.\n- **APS reliability.** `ZigbeeApsRetransmit` + `ZigbeeApsDuplicateTable` give\n  end-to-end acked delivery with retransmit and duplicate rejection;\n  `ZigbeeApsFragment` splits/reassembles payloads too large for one frame.\n- **Trust-Center key transport.** `ZigbeeApsKey` builds the APS Transport-Key /\n  Request-Key / Switch-Key commands; `ZigbeeApsSecurity` encrypts them at the\n  APS layer — AES-MMO hash, HMAC-MMO, the specialized key derivation\n  (key-transport / key-load keys from the link key), and an APS CCM* envelope.\n  `CC2530_BeaconJoin -DNIUS_ZIGBEE_SECURE_JOIN=1` wires it into the join so a\n  joiner that holds only the default link key \"ZigBeeAlliance09\" is given the\n  network key after associating — HW-verified end to end (the joiner decrypts\n  the key, installs it, and runs the secured data plane with `mic=0`). This\n  needs CC2530 firmware v0.4, which fixes a clone RXFIFO underrun that corrupted\n  the tail of large (~80 B) received frames.\n- **Routing \u0026 forwarding.** `ZigbeeRouting` runs AODV route discovery\n  (RREQ/RREP, reverse routes) and the example forwards multi-hop unicast with\n  per-hop re-encryption.\n- **Network management.** ZDO `Mgmt_Lqi` / `Mgmt_Rtg`, the `ZigbeeBroadcastTable`\n  (broadcast dedup + passive-ack), and `ZigbeePanIdConflict` (PAN-ID conflict\n  detection + Network Report/Update).\n- **Sleepy end devices.** `ZigbeeMac::buildDataRequest` + `ZigbeeIndirectQueue`\n  (parent-side buffered-frame store) + `ZigbeeEndDeviceTimeout` (keep-alive\n  negotiation). Setting the ack frame-pending bit on air needs CC2530 firmware\n  support; the host-side queue/keep-alive logic is done.\n- **Persistence \u0026 binding.** `ZigbeePersistence` serializes the network identity\n  + frame counter (anti-replay across reboots); `ZigbeeBindingTable` stores\n  source bindings with ZDO Bind/Unbind frames.\n\n## Verified behavior\n\nHardware verified with two ArduinoNRF ProMicro nRF52840 boards, each wired to a\nCC2530 module:\n\n- `CC2530_FlashFirmware` detects `0xA5xx`, flashes the SDCC transceiver, and\n  verifies read-back.\n- `CC2530_Info` reports firmware `v0.4` and repeated `ping -\u003e PONG`.\n- `CC2530_MacControl` writes PAN/short/IEEE address, enables filtering +\n  Auto ACK + CCA TX with three retries, and reads the settings back.\n- `CC2530_Link` on two boards shows `TX \"hello N\" ok` and reciprocal\n  `RX (... dBm): hello N` frames on channel 11.\n- `CC2530_MacLink` builds standards-shaped short-address MAC data frames and\n  filters received frames by PAN ID / destination short address in the sketch.\n- `CC2530_NwkLink` wraps those MAC frames with simple Zigbee NWK data frames and\n  shows reciprocal `NWK RX ... payload=\"nwk hello N\"` traffic on channel 11.\n- `CC2530_ZclLink` wraps ZCL On/Off Toggle command frames inside APS/NWK/MAC and\n  shows reciprocal `ZCL RX ... cmd=0x02` traffic on channel 11.\n- `CC2530_OnOffCluster` applies Toggle to a local OnOff state, replies with ZCL\n  Default Response, and answers Read Attributes for the OnOff attribute.\n- `CC2530_ClusterNode` dispatches incoming ZCL frames through reusable\n  `ZigbeeOnOffCluster` / `ZigbeeBasicCluster` helpers and answers Basic +\n  On/Off reads.\n- `CC2530_ReportingNode` accepts Configure Reporting for OnOff.OnOff and emits\n  Report Attributes on state change / max interval.\n- `CC2530_NwkCommandLink` exchanges Route Request/Reply and Network Status under\n  hardware filtering + Auto ACK + CCA TX.\n- `CC2530_ZdoDiscovery` exchanges IEEE/NWK address, Active Endpoint, Simple\n  Descriptor, and Match Descriptor requests/responses between two boards under\n  hardware filtering + Auto ACK + CCA TX.\n- `CC2530_AssociationJoin` runs board1 as a coordinator with permit join open,\n  accepts board2's MAC Association Request, assigns a short address, and receives\n  board2's ZDO Device_annce.\n- `CC2530_BeaconJoin` runs a parameterless joiner that scans channels 11/15/20/25\n  with Beacon Requests, hears the coordinator's Zigbee beacon on channel 15\n  (`pan=0x1A62 depth=0 permit=yes`), selects it as parent, associates on the\n  first attempt (addr `0x0001`), and announces — while the coordinator answers\n  beacon requests under hardware filtering. The scan also met two foreign\n  production Zigbee networks on channel 25 (`permit=no`) and correctly skipped\n  them as parents.\n- After joining, both nodes broadcast NWK Link Status every 15 s: both ends\n  settle at `in=1 out=1` link costs (outgoing cost read back from the entry\n  naming our own address in the neighbor's report), and silencing one node\n  makes the other print `aged out 1 stale router neighbor(s)` after three\n  missed periods. A stale parent instead reports parent-loss and re-enters\n  joining via `rejoinParent()`.\n- **Multi-hop, three boards (A coordinator, B router, C end).** With A and C\n  set to ignore each other's frames (a bench stand-in for being out of radio\n  range), C scans, finds only router B's beacon, and joins **through** B from\n  B's own address pool (`addr=0x0031`). C then routes an encrypted ping to\n  the coordinator: B forwards `0x0031-\u003e0x0000`, A decrypts it (`mic=0`) and\n  replies, and the pong comes back `A-\u003eB-\u003eC` over the reverse route each node\n  learned from the traffic — a full `C-\u003eB-\u003eA-\u003eB-\u003eC` encrypted round trip on\n  hardware. Build the three roles with\n  `-DNIUS_ZIGBEE_THIS_NODE=0x0001` (A), `0x0002` (B), `0x0003` (C).\n- **APS end-to-end acknowledged delivery.** The end device's data plane sends\n  an acked APS frame to the coordinator over the routed mesh; the coordinator\n  replies with an APS ACK (same APS counter) over the reverse route, and the\n  sender retransmits until the ACK arrives or the retry budget runs out. On\n  the 3-board line this lifts confirmed end-to-end delivery from ~11% (a raw\n  routed ping with no recovery) to ~55%, and the sender's\n  `aps[q=.. ok=.. rtx=.. drop=..]` status reports exactly which frames made it.\n- The joiner then discovers a route to the coordinator (Route Request\n  broadcast -\u003e unicast Route Reply, reverse route recorded on the way) and\n  pings over it every 10 s: routed `route ping`/`route pong` round trips run\n  at 100%. The full self-healing loop is verified: silencing the coordinator\n  ages the parent out at 54 s, the joiner's rejoin attempts fail, it falls\n  back to scanning (correctly skipping up to six foreign `permit=no` networks\n  heard on channel 25), and when the coordinator returns it rejoins on the\n  first attempt and rebuilds the route.\n- The entire flow above also runs with **NWK security enabled**: every NWK\n  frame (announce, link status, route discovery, routed data) carries the\n  Zigbee auxiliary header and is AES-CCM* ENC-MIC-32 protected, computed on\n  the nRF52840's hardware AES block. Status lines report\n  `sec[tx=18 rx=5 mic=0 rpl=0]`-style statistics. A joiner built with\n  `-DNIUS_ZIGBEE_WRONG_KEY=1` still associates at the MAC level but every\n  NWK frame it sends is MIC-rejected (`mic=` climbs, `rx=` freezes, its\n  link costs stay 0/0).\n- `CC2530_BeaconJoin` scales to a **multi-hop A-B-C line**: build the three\n  boards with `-DNIUS_ZIGBEE_THIS_NODE=0x0001/0x0002/0x0003` for\n  coordinator / router / end device. Routers answer beacon requests and\n  accept children from their own address pool, and unicast NWK data destined\n  elsewhere is forwarded to the route's next hop (radius-1, re-encrypted per\n  hop), so the end device reaches the coordinator through the router. An\n  optional range-simulation ignore list lets three co-located radios form a\n  real 2-hop topology. Verified on hardware so far: the router joins the\n  coordinator and becomes a parent (`children=1`, encrypted Link Status,\n  `mic=0`); the full A-B-C routed ping is the remaining bring-up step.\n- **ZDO Mgmt_Lqi network mapping.** The end device queries the coordinator's\n  neighbor table; the response is carried as an APS-acked frame with single-in-\n  flight retransmit (an earlier naive version caused a retransmit storm). On a\n  clean 1-hop link the request is answered on the first try every cycle and the\n  acked APS data plane runs at 100% (`q=44 ok=44 drop=0`).\n- **Protocol self-tests on hardware** (one board, J-Link): APS key-transport\n  security 25/25 (`CC2530_ApsSecurity`), broadcast transaction table 22/22\n  (`CC2530_BroadcastTable`), indirect transmission 27/27 (`CC2530_IndirectQueue`),\n  End Device Timeout 18/18 (`CC2530_EndDeviceTimeout`), PAN-ID conflict 16/16\n  (`CC2530_PanIdConflict`), plus fragmentation / key-transport / binding.\n- Promiscuous examples can still show unrelated 802.15.4 traffic on the channel;\n  filtered examples program PAN/short/IEEE addresses before exchanging frames.\n\n## Current stack boundary\n\nNiusZigbee now implements a large, hardware-verified subset of Zigbee PRO on top\nof the SDCC CC2530 MAC/PHY backend: active scan + parent selection, MAC\nassociation join/rejoin, neighbor aging, AODV route discovery + multi-hop\nforwarding, NWK **and** APS AES-CCM* security, end-to-end acked delivery,\nfragmentation, ZDO discovery + network management (Mgmt_Lqi/Rtg), binding,\npersistence, Trust-Center key-transport tooling, broadcast transaction table,\nsleepy-end-device queue + keep-alive, and PAN-ID conflict frames.\n\nIt is **not yet certified Zigbee PRO**. Remaining work includes: finishing the\non-air secure-join key install, many-to-one routing + source routing (Route\nRecord), setting the ack frame-pending bit (needs CC2530 firmware), full ZCL\ncluster libraries + groups, install codes, and APS-layer encrypted application\ndata. A future ZNP / Z-Stack backend can still live beside the raw driver. See\nthe milestone-by-milestone status in\n[docs/STACK_ROADMAP.md](docs/STACK_ROADMAP.md).\n\n## Extending to new modules\n\nDrop a driver in `src/modules/\u003cNAME\u003e/`, its firmware in\n`extras/firmware/\u003cname\u003e/`, a forwarder header in `src/`, and examples under\n`examples/`. See [src/ZigbeeModule.h](src/ZigbeeModule.h). The built‑in\n`CCDebugger` flashes any TI CC253x image (SDCC or Z‑Stack).\n\n## Firmware\n\nThe CC2530 transceiver firmware source (SDCC) and prebuilt binary live in\n[extras/firmware/cc2530/](extras/firmware/cc2530/). Build notes:\n[extras/firmware/cc2530/BUILD.md](extras/firmware/cc2530/BUILD.md).\n\n## License\n\nApache 2.0 — see [LICENSE](LICENSE). Author: **dunknowcoding** (YouTube:\n*NiusRobotLab*). If you use it in a product, please credit the original author and\nnote your changes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunknowcoding%2Farduinonrf-zigbee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdunknowcoding%2Farduinonrf-zigbee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunknowcoding%2Farduinonrf-zigbee/lists"}