python-aaronia 0.5.1__tar.gz → 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. python_aaronia-0.6.1/CHANGELOG.md +391 -0
  2. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/Cargo.lock +321 -362
  3. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/Cargo.toml +1 -1
  4. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/DESIGN.md +2 -2
  5. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/PKG-INFO +40 -23
  6. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/PLUGINS.md +10 -2
  7. python_aaronia-0.6.1/README.md +212 -0
  8. python_aaronia-0.6.1/docs/APPS.md +107 -0
  9. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/docs/HTTPSPEC.md +67 -5
  10. python_aaronia-0.6.1/docs/QUICKSTART.md +196 -0
  11. python_aaronia-0.6.1/docs/USAGE.md +337 -0
  12. python_aaronia-0.6.1/docs/VERIFICATION.md +47 -0
  13. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/include/aaronia.h +7 -0
  14. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/python-aaronia/Cargo.toml +5 -5
  15. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/python-aaronia/README.md +39 -22
  16. python_aaronia-0.6.1/python-aaronia/aaronia.pyi +143 -0
  17. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/python-aaronia/src/lib.rs +61 -33
  18. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/soapy-aaronia/AaroniaSoapyDevice.cpp +48 -7
  19. python_aaronia-0.6.1/soapy-aaronia/README.md +131 -0
  20. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/soapy-aaronia/Registration.cpp +19 -0
  21. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/c_api.rs +41 -0
  22. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/http_endpoints.rs +21 -7
  23. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/http_streaming.rs +13 -0
  24. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/lib.rs +18 -2
  25. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/native_sdk.rs +14 -7
  26. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/sdr_source_impl.rs +15 -2
  27. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/unified_source.rs +473 -58
  28. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/utils.rs +134 -0
  29. python_aaronia-0.6.1/tests/http_resilience_test.rs +424 -0
  30. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/live_smoke.rs +39 -0
  31. python_aaronia-0.5.1/CHANGELOG.md +0 -395
  32. python_aaronia-0.5.1/README.md +0 -503
  33. python_aaronia-0.5.1/soapy-aaronia/README.md +0 -86
  34. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/.cargo/config.toml +0 -0
  35. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/.gitattributes +0 -0
  36. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/.gitignore +0 -0
  37. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/CONTRIBUTING.md +0 -0
  38. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/LICENSE +0 -0
  39. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/benches/decompress_block.rs +0 -0
  40. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/benches/deinterleave_dual_iq.rs +0 -0
  41. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/benches/parse_int16_packet.rs +0 -0
  42. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/benches/rtsa_open_and_read.rs +0 -0
  43. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/deny.toml +0 -0
  44. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/docs/FILESPEC.md +0 -0
  45. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/docs/SDKSPEC.md +0 -0
  46. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/channel_hopping.rs +0 -0
  47. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/device_control.rs +0 -0
  48. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/dump_metadata.rs +0 -0
  49. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/http_iq_quickstart.rs +0 -0
  50. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/native_sdk_basic.rs +0 -0
  51. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/native_sdk_transmit.rs +0 -0
  52. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/noaa_scanner.rs +0 -0
  53. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/python_arrow_example.py +0 -0
  54. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/read_rtsa_file.rs +0 -0
  55. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/examples/soapy_python_example.py +0 -0
  56. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/pyproject.toml +0 -0
  57. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/python-aaronia/test_basic.py +0 -0
  58. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/scripts/ci-local.sh +0 -0
  59. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/soapy-aaronia/AaroniaSoapyDevice.hpp +0 -0
  60. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/soapy-aaronia/CMakeLists.txt +0 -0
  61. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/decompression.rs +0 -0
  62. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/detection.rs +0 -0
  63. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/error.rs +0 -0
  64. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/file_source.rs +0 -0
  65. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/http_sink.rs +0 -0
  66. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/http_source.rs +0 -0
  67. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/sdk_sink.rs +0 -0
  68. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/sdk_source.rs +0 -0
  69. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/seify_impl.rs +0 -0
  70. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/src/unified_sink.rs +0 -0
  71. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/c_api_test.rs +0 -0
  72. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/http_mock_test.rs +0 -0
  73. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/http_sink_test.rs +0 -0
  74. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/integration_test.rs +0 -0
  75. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/native_sdk_load.rs +0 -0
  76. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/properties.proptest-regressions +0 -0
  77. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/properties.rs +0 -0
  78. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/rtsa_negative_test.rs +0 -0
  79. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/sdr_source_impl_test.rs +0 -0
  80. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/spec_coverage.rs +0 -0
  81. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/test_cw_mag.rs +0 -0
  82. {python_aaronia-0.5.1 → python_aaronia-0.6.1}/tests/test_cw_meta.rs +0 -0
@@ -0,0 +1,391 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [v0.6.1] - 2026-08-12
8
+
9
+ ### Fixed
10
+ - **The SoapySDR plugin advertised sample rates the hardware cannot
11
+ produce.** Seven of the ten rates it listed, 1, 2, 5, 10 and 20 MHz
12
+ among them, do not exist on the device, which runs at 61.44 MHz
13
+ divided by a power of two. Applications build their rate dropdowns
14
+ from that list, so choosing 10 MHz ran the device at a different rate
15
+ while the application went on displaying 10. The list is now the real
16
+ ladder, 61.44 MHz down to 120 kHz, and `setSampleRate` snaps to the
17
+ nearest one and logs when it has to.
18
+ - **The crate reported the requested sample rate rather than the one in
19
+ use.** The device adjusts a rate it cannot produce, so
20
+ `get_source_info()` described a capture that was not happening. HTTP
21
+ sources now report the rate, centre frequency and usable bandwidth
22
+ from the stream's own metadata once packets arrive.
23
+
24
+ ### Added
25
+ - `iq_sample_rates`, `usable_bandwidth_hz`, `nearest_iq_sample_rate` and
26
+ `iq_sample_rate_for_bandwidth` in `utils`, with the constants
27
+ `IQ_CLOCK_HZ` and `USABLE_BANDWIDTH_RATIO`. The device samples at
28
+ 61.44 MHz divided by a power of two and delivers 0.8 of that as
29
+ alias-free bandwidth. Callers were deriving their own rates from
30
+ guesses, so the relationships now live in one tested place. Wanting
31
+ 8 MHz of spectrum needs 10 MHz of sampling, and
32
+ `iq_sample_rate_for_bandwidth` returns the 15.36 MHz that provides it.
33
+
34
+ ### Fixed (native SDK)
35
+ - **Sweep mode set the wrong resolution-bandwidth key.** It sent
36
+ `main/rbw`, which no Aaronia sample uses; the key is `main/rbwfreq`.
37
+ Checked against Aaronia's published `SweepSpectrumEco` sample, which
38
+ also confirms `main/startfreq`, `main/stopfreq`, `main/reflevel` and
39
+ the `spectranv6eco/sweepsa` open string that this crate already used.
40
+ The sweep path remains hardware-unverified.
41
+
42
+ ### Documentation
43
+ - **GPS time needs GPS switched on, and the crate does not do it.**
44
+ Devices ship with `device/gpsmode` disabled, so `get_gps_time` would
45
+ return `None` indefinitely and appear broken. Aaronia's `GPSTime`
46
+ sample sets `device/gpsmode` to "Location and Time" and
47
+ `device/sclksource` to "GPS Provider" before starting the device;
48
+ `get_gps_time` now says so.
49
+ - Documented what `/control`'s `frequencySpan` actually means. It is a
50
+ request for usable bandwidth, not a sample rate: the device picks the
51
+ rate whose alias-free span is nearest, so 2.5 MHz yields 3.84 MHz and
52
+ 10 MHz yields 15.36 MHz. Values on the rate ladder round-trip exactly,
53
+ which is why the field looks like a sample rate in ordinary use.
54
+ Verified across nine requests on a V6 ECO.
55
+
56
+ ## [v0.6.0] - 2026-08-11
57
+
58
+ Reliability and documentation release. The HTTP backend now handles a
59
+ server that is still starting up and a stream that drops mid-session.
60
+ The documentation now says which features have been tested on real
61
+ hardware and which have not.
62
+
63
+ ### Breaking
64
+ - `AaroniaConfig` has two new public fields, `read_timeout` and
65
+ `auto_reconnect`. Struct-literal construction needs updating. The
66
+ builder methods are unchanged.
67
+ - Dropped HTTP streams now reconnect by default. Previously a dropped
68
+ stream ended the session and every later read failed. Reads can now
69
+ block for up to about 8 seconds while reconnecting. Call
70
+ `auto_reconnect(false)` for the old behaviour.
71
+ - SoapySDR plugin downloads are now per-platform archives named
72
+ `SoapyAaronia-<version>-<os>-<arch>.tar.gz`, or `.zip` on Windows.
73
+ The bare `.so`, `.dll` and `.dmg` files are gone. Scripts that
74
+ download them by name need to unpack the archive instead.
75
+
76
+ ### Added
77
+ - **Connect retry.** Reaching the server now retries transient failures
78
+ up to 4 times over at most 10 seconds. A `*.local` hostname often
79
+ refuses the first connection while mDNS resolves, which used to look
80
+ like the server was down. Client errors still fail immediately.
81
+ - **Automatic stream reconnection** (`auto_reconnect`, on by default).
82
+ The reader reopens the stream up to 5 times, re-applies the current
83
+ tuning, and marks the first packet after the gap as an overrun.
84
+ Re-applying tuning matters because a restarted server returns to its
85
+ mission's frequency, which would otherwise stream the wrong band
86
+ unnoticed. The retry budget resets only after a connection survives
87
+ 30 seconds, so a server that accepts and immediately hangs up cannot
88
+ reconnect forever. Also available through
89
+ `aaronia_source_builder_auto_reconnect` and the SoapySDR argument
90
+ `reconnect=0|1`.
91
+ - **Configurable read timeout** (`read_timeout`, default 30 seconds),
92
+ replacing a hard-coded value. Available on both builders, as a Python
93
+ property, through `aaronia_source_builder_read_timeout_us`, and as a
94
+ `read_timeout=<seconds>` SoapySDR argument. `read_samples_deadline`,
95
+ which the SoapySDR and seify paths use, still takes its deadline from
96
+ the caller.
97
+ - `DropDetector::resync()` clears the packet-timing history but keeps
98
+ the counters. `reset()` clears both, which would make the running
99
+ total jump backwards after a reconnect.
100
+ - **Python type stubs.** Editors and type checkers now understand the
101
+ module.
102
+
103
+ ### Fixed
104
+ - **Channel hopping could stall for up to 30 seconds.** The hop loop
105
+ waited for a full block of samples, far longer than a 20-40 ms dwell,
106
+ so a slow server starved the remaining hops. It now stops waiting at
107
+ the dwell deadline.
108
+
109
+ ### Documentation
110
+ - **The README says what has been tested on hardware.** Each feature is
111
+ marked live-verified, verified manually, mock-tested, or
112
+ hardware-unverified. Transmit, dual-channel and the native-SDK paths
113
+ have never run against a device.
114
+ - **New quickstart** (`docs/QUICKSTART.md`) covering RTSA-Suite mission
115
+ setup, which everything depends on and nothing documented: adding the
116
+ HTTP Server block, connecting the device output to it, checking it
117
+ with `curl`, and the mistakes that cost the most time.
118
+ - **New application guide** (`docs/APPS.md`) for SDR++, GQRX, GNU Radio
119
+ and SoapySDR from Python. It explains that the single `REF` gain
120
+ element is a reference level in dBm, so raising it reduces
121
+ sensitivity.
122
+ - **New usage guide** (`docs/USAGE.md`) holding the worked examples that
123
+ were 60% of the README. They are compiled as doctests now, so they
124
+ cannot fall out of date. The README is down from 516 lines to 291.
125
+ - **Install instructions for the prebuilt SoapySDR plugin.** Releases
126
+ always attached built modules, but the README only explained building
127
+ from source.
128
+
129
+ ### Release
130
+ - Release archives now carry the module, install instructions and the
131
+ licence, and their names state the version, OS and architecture.
132
+ - The Linux module ships stripped of debug symbols, 19.1 MB down to
133
+ 15.4 MB. The rest is statically linked Rust, not symbols. The release
134
+ job checks the stripped module still loads before publishing it.
135
+ - GitHub releases now use this file's entry for the tag as their
136
+ description, with the generated commit list below it.
137
+
138
+ ## [v0.5.1] - 2026-08-11
139
+
140
+ ### Fixed
141
+ - **Retuning silently did nothing on real hardware.** The `/control`
142
+ endpoint only applies a frequency change when `frequencyCenter` and
143
+ `frequencySpan` are both present. Sending one of them returns
144
+ `{"success":true}` and is ignored, so `set_center_frequency` reported
145
+ success while the device kept streaming at its old frequency. This
146
+ affected hop mode and the SoapySDR, seify and Python retune paths. All
147
+ of them now send the full set of values, and `configure_capture` warns
148
+ when given a partial one. Reference-level changes were unaffected;
149
+ they apply on their own.
150
+ - Corrected the documents that blamed this on the Aaronia "Remote
151
+ Config" licence. Retuning uses the licence-free `/control` endpoint;
152
+ the licence only gates `/remoteconfig` writes.
153
+
154
+ ### CI
155
+ - Clippy now runs across the whole workspace. The `python-aaronia`
156
+ member was never linted and had accumulated 12 errors.
157
+
158
+ ## [v0.5.0] - 2026-08-11
159
+
160
+ Adds Python bindings, a SoapySDR plugin, transmit support and GPS time,
161
+ alongside verification of the RTSA file format against the vendor
162
+ specification. Receive paths were tested against real hardware.
163
+ Transmit and dual-channel paths were not, and are marked as such in the
164
+ documentation.
165
+
166
+ ### Breaking
167
+ - `RtsaMetadata` lost `device_name`, `stream_sample_rate` and
168
+ `stream_center_frequency`, and `RtsaSource::stream_info()` returns a
169
+ 3-tuple. Those fields came from a file layout no real capture uses and
170
+ were always `None`.
171
+ - `SdkConfig` and `AaroniaConfig` gained a public `receiver_channel`
172
+ field, which breaks struct-literal construction.
173
+ `NativeSdkSource::configure_iq_receiver` takes the channel as a fourth
174
+ argument so retunes keep it.
175
+
176
+ ### Added
177
+ - **Python bindings** (`python-aaronia`), published to PyPI: abi3
178
+ wheels for CPython 3.9 and later, typed exceptions, live retuning, and
179
+ single-copy reads into NumPy or PyArrow. Blocking calls release the
180
+ GIL, so other Python threads keep running.
181
+ - **SoapySDR plugin** (`soapy-aaronia`): receive streaming in CF32 and
182
+ CS16, honoured timeouts with partial reads, safe retuning while
183
+ streaming, and device arguments for URL, file, serial, frequency,
184
+ rate, reference level, wire format and RX channel.
185
+ - **Transmit support** through the native SDK, via `UnifiedSink` and the
186
+ `aaronia_sink_*` C API. Hardware-unverified, and unavailable outside
187
+ Windows and Linux.
188
+ - **GPS time** through `get_gps_time`, native SDK only.
189
+ - **Receiver channel selection** (`Rx1`, `Rx2`, `Rx1And2`) and true
190
+ dual-channel capture through `read_samples_dual`. A read-mode latch
191
+ stops single- and dual-channel reads being mixed by accident.
192
+ - `StrmChunk::capture_start_offset`, an undocumented field in RTSA files
193
+ identified as the capture start. Reported time spans now match the
194
+ recorded data.
195
+ - `scripts/ci-local.sh`, which runs CI's checks locally, including a
196
+ Linux VM step covering the OS-gated native-SDK code.
197
+ - Property tests: opening arbitrary bytes as an RTSA file must never
198
+ panic.
199
+
200
+ ### Fixed
201
+ - RTSA chunk parsing corrected against the vendor specification and real
202
+ captures: chunk padding and tail offsets, fixed field sizes, the STRM
203
+ layout, enum numbering, and end-time treated as a duration.
204
+ - Compressed spectra chunks now report an error instead of returning
205
+ compressed bytes as if they were samples.
206
+ - Native SDK: a corrupt packet no longer blocks every later read, and
207
+ buffers are flushed when streaming stops.
208
+
209
+ ## [v0.3.5] - 2026-08-06
210
+
211
+ Documentation release. Every Markdown file was checked against the code
212
+ and corrected. No API changes.
213
+
214
+ ### Changed
215
+ - DESIGN.md, the README, CONTRIBUTING and the three specifications in
216
+ `docs/` corrected against the implementation, with explicit notes
217
+ where only hardware can settle a question.
218
+ - Clarified that HTTP retuning uses the licence-free `/control`
219
+ endpoint.
220
+ - Examples cleaned up. `http_iq_quickstart` takes the server URL as an
221
+ argument instead of hardcoding a private hostname.
222
+ - Five tests that asserted nothing now assert something.
223
+
224
+ ### Fixed
225
+ - Stale comments about symbol counts, renamed tests, and inverted
226
+ `?scale=` semantics.
227
+
228
+ ## [v0.3.4] - 2026-07-31
229
+
230
+ ### Fixed
231
+ - **Native SDK: the end of every oversized packet was discarded.** The
232
+ reader copied out only what the caller asked for, then released the
233
+ whole packet back to the SDK. The SDK chooses its own packet size, so
234
+ everything past the request was lost. This left holes in the IQ
235
+ stream, which breaks the phase continuity that downstream correlation
236
+ and frequency tracking depend on. Extra samples are now kept and
237
+ returned by later calls.
238
+ - **Native SDK: a zero-sized read destroyed a packet.** It now returns
239
+ immediately.
240
+ - **Transmit bursts were scheduled at the Unix epoch.** The FutureSDR
241
+ sink set every burst's start time to zero, against the device's own
242
+ master clock. Timestamps now come from the master clock, falling back
243
+ to immediate dispatch when it cannot be read. Hardware-unverified.
244
+ - **`http_source` reported a buffer capacity it did not enforce.** With
245
+ a buffer size of zero, a consumer computing a fill ratio divided by
246
+ zero.
247
+ - **Diagnostic previews could panic on non-ASCII text.** They cut
248
+ strings at byte offsets, so one accented character in a mission name
249
+ was enough.
250
+
251
+ ### Changed
252
+ - `cargo clippy --all-targets` compiles on a default checkout again.
253
+ - `SdkConfig::timeout` and `SdkSinkConfig::timeout` documented as
254
+ inert. Nothing reads them. They are kept because they are public.
255
+
256
+ ## [v0.3.3] - 2026-07-31
257
+
258
+ ### Fixed
259
+ - **A chunk scan could loop forever** on a file whose signature was
260
+ missing, reachable by opening an untrusted file.
261
+ - **A failed configuration probe left the device 1 dB off.** The restore
262
+ now runs on every exit path.
263
+
264
+ ## [v0.3.2] - 2026-07-13
265
+
266
+ ### Added
267
+ - `DwellAdvice::channel_override` is honoured, and hop mode no longer
268
+ requires the Remote Config licence.
269
+
270
+ ## [v0.3.1] - 2026-07-11
271
+
272
+ ### Fixed
273
+ - **Decompression rejects an out-of-range compression factor** instead
274
+ of overflowing on it. The value can come from a network packet, so a
275
+ corrupt header could previously cause a panic.
276
+ - **Decompression truncates over-long coefficient streams**, having
277
+ previously only padded short ones.
278
+ - **The capture thread is panic-guarded**, so a panic is logged instead
279
+ of killing the thread silently.
280
+ - **HTTP overrun detection reaches `IqPacket::overrun`.** Hop and
281
+ single-channel modes report real overrun status instead of always
282
+ `false`.
283
+ - **The C API sample copy is bounds-checked** against the source length
284
+ as well as the caller's capacity.
285
+ - Raised the `orecchiette-sdr-source-rs` floor to 0.1.2.
286
+
287
+ ## [v0.3.0] - 2026-07-11
288
+
289
+ ### Removed
290
+ - **Breaking: the `file_performance` module is gone**, along with the
291
+ `memmap2` dependency. This memory-mapped reader was never used by the
292
+ crate's actual file path and had no callers. `RtsaSource` covers the
293
+ same needs through buffered I/O.
294
+
295
+ ### Fixed
296
+ - A misplaced doc comment marked `with_shared_stats` a no-op when it is
297
+ not.
298
+ - `HttpSink` counts a batch as dropped when its sender task has died,
299
+ not only on a failed push. It also stops that task on drop.
300
+
301
+ ### Changed
302
+ - The last four native-SDK methods that hand-rolled error checks now use
303
+ the shared path, so failures carry structured errors.
304
+ - Shared device-type parsing extracted out of `SdkConfig` and
305
+ `SdkSinkConfig`.
306
+
307
+ ## [v0.2.6] - 2026-07-10
308
+
309
+ ### Added
310
+ - **Transmit through the native SDK** (`SdkSink`, `SdkSinkConfig`) with
311
+ FutureSDR integration, matching the receive path.
312
+ - `examples/native_sdk_transmit.rs`, sending a LoRa-style chirp.
313
+
314
+ ### Changed
315
+ - Replaced the opaque `Error::Sdk(String)` with a structured
316
+ `Error::SdkApi`, so callers can react to specific failures.
317
+ - SDK warnings are logged as warnings instead of being treated as fatal,
318
+ matching Aaronia's own drivers.
319
+
320
+ ## [v0.2.4] - 2026-07-10
321
+
322
+ ### Performance
323
+ - **HTTP parser:** binary formats read packet headers directly instead
324
+ of building and discarding a JSON document for every packet. Small
325
+ packets parse about 41% faster.
326
+ - **Float32 samples** are bulk-copied on little-endian hosts instead of
327
+ decoded one value at a time.
328
+ - **File replay** reads a block at a time instead of one sample per
329
+ call.
330
+ - Native SDK per-read logging moved to `trace`, off the hot path.
331
+
332
+ ### Fixed
333
+ - **Native SDK unsound read path.** A zero-sample request underflowed a
334
+ length calculation and produced an enormous slice. Packet counts and
335
+ strides are now bounds-checked.
336
+ - **The HTTP reader task leaked.** It is now stopped when streaming
337
+ stops and on drop, instead of holding the connection open and leaving
338
+ the device streaming.
339
+ - **Decompression rejects zero dimensions** instead of looping forever.
340
+ - **`MmapRtsaReader::read_chunk` bounds check** no longer wraps on a
341
+ pathological offset.
342
+ - **Default reference level corrected** from +20 dBm to -20 dBm. The old
343
+ default desensitised the receiver.
344
+ - `HttpSource` reschedules itself after reconnecting.
345
+
346
+ ### Changed
347
+ - `HttpSink` honours `timeout_ms`, which was previously ignored.
348
+
349
+ ## [v0.2.3] - 2026-07-05
350
+
351
+ ### Fixed
352
+ - **The HTTP source did not tune the device.** It opened the stream
353
+ without sending a control request, so it streamed whatever the
354
+ RTSA-Suite was already set to and ignored the requested frequency and
355
+ span.
356
+
357
+ ### Changed
358
+ - `http_iq_quickstart` takes frequency and sample rate arguments and
359
+ logs signal power.
360
+
361
+ ## [v0.2.2] - 2026-07-05
362
+
363
+ ### Changed
364
+ - Dropped the explicit minimum Rust version and track stable instead, so
365
+ a dependency raising its own floor cannot break CI.
366
+
367
+ ## [v0.2.1] - 2026-07-05
368
+
369
+ ### Added
370
+ - Native SDK receiver channel selection (`Rx1`, `Rx2`, `Rx1And2`).
371
+ - HTTP wire format and stream scale settings on `AaroniaConfig` and
372
+ `AaroniaSourceBuilder`.
373
+
374
+ ### Fixed
375
+ - Raised the minimum Rust version to 1.86 to fix CI builds. (v0.2.2
376
+ dropped the fixed minimum entirely.)
377
+ - Default HTTP format changed from JSON to Float32, fixing crashes at
378
+ high bandwidth.
379
+ - Fixed FutureSDR deadlocks in `HttpSink` by moving blocking HTTP calls
380
+ onto a background task.
381
+
382
+ ## [v0.1.1] - 2026-07-03
383
+
384
+ ### Changed
385
+ - Disable `futuresdr` on docs.rs.
386
+ - Fix the licence badge.
387
+
388
+ ## [v0.1.0] - 2026-07-03
389
+
390
+ ### Added
391
+ - Initial release.